接着上一节所说的,这一节主要还是分享有关数据集的分割组合。目前,我们已经明确了自己的目的,有以下几个:
进行10分类;
时域、频域、时频都要有条件实现;
样本大小设定为2048个点;
使用滑窗取值法,训练集、验证集、测试集的比例为7:1.5:1.5.
话不多说,先上一段代码(这段代码是我从别处参考的,有点找不到具体出处了),这段代码用来进行滑窗取值,返回值是序列的起始和结束位置。
def slide_window(rows, sw_width, sw_steps): #rows是序列长度,sw_width是样本长度,sw_steps是滑动步长
start = 0
s_num = (rows - sw_width) // sw_steps # 计算滑动次数
new_rows = sw_width + (sw_steps * s_num) # 完整窗口包含的行数,丢弃少于窗口宽度的采样数据;
while True:
if (start + sw_width) > new_rows: # 如果窗口结束索引超出最大索引,结束截取;
return
yield start, start + sw_width
start += sw_steps
接下来要完成3个步骤,按照2048的样本大小分块、随机打乱顺序和划分训练集、验证集、测试集。
我个人的理解,如果先划分训练集、验证集、测试集,那么其取值范围的相对位置就会固定,后续的随机打乱顺序就不均匀,这样的结果可靠性会大大下降。
for data in datalist: #依次读取文件夹中的文件
data = data[0:121100]
test_list = []
for start, end in slide_window(data.shape[0], 2048, steps): #滑窗取大小为2048的样本,依次添加至列表
test_list.append(data[start:end])
data = np.array(test_list[0:-1], dtype=object)
data = data.reshape(data.shape[0], 2048)
np.random.shuffle(data) #打乱顺序
a = int(data.shape[0] * (slice_rate[0] / (slice_rate[0] + slice_rate[1] + slice_rate[2]))/10)*10
b = int(data.shape[0] * ((slice_rate[0] + slice_rate[1]) / (slice_rate[0] + slice_rate[1] + slice_rate[2])))
c = data.shape[0]
print(a, b, c) #查看大小划分情况
接下来是打标签,这个比较简单,我的是和文件夹读取同步的
label_tr = np.array([label for i in range(0, a)])
label_val = np.array([label for i in range(0, b)])
label_te = np.array([label for i in range(0, c)])
label_tr = label_tr.reshape([a, 1])
label_val = label_val.reshape([b, 1])
label_te = label_te.reshape([c, 1])
data_DE = [data_tr, data_val, data_te, label_tr, label_val, label_te]
查看划分结果
print(a, b, c)
print(data_DE[0].shape,data_DE[1].shape,data_DE[2].shape,data_DE[3].shape,data_DE[4].shape,data_DE[5].shape)
结果为
650 790 930
(650, 2048) (140, 2048) (140, 2048) (650, 1) (790, 1) (930, 1)
这样,单个文件夹也就是单个类别的数据就分割完毕了,接下来就要对不同类别进行堆叠,同时将标签数据转换为独热编码。个人代码水平有限,写的不够美观,请大家多多包涵。
def to_one_hot(labels, dimension=10):
results = np.zeros((len(labels), dimension))
for i, label in enumerate(labels):
results[i, label] = 1
return results
def dataout_win(datas_all, num=650):
data_tr = datas_all[0][0][0:num, :]
data_val = datas_all[0][1][0:140, :]
data_te = datas_all[0][2][0:140, :]
label_tr = datas_all[0][3][0:num, :]
label_val = datas_all[0][4][0:140, :]
label_te = datas_all[0][5][0:140, :]
for i in range(9):
data_tr = np.vstack((data_tr, datas_all[i + 1][0][0:num, :]))
data_val = np.vstack((data_val, datas_all[i + 1][1][0:140, :]))
data_te = np.vstack((data_te, datas_all[i + 1][2][0:140, :]))
label_tr = np.vstack((label_tr, datas_all[i + 1][3][0:num, :]))
label_val = np.vstack((label_val, datas_all[i + 1][4][0:140, :]))
label_te = np.vstack((label_te, datas_all[i + 1][5][0:140, :]))
label_tr = label_tr.reshape(label_tr.shape[0], 1)
label_tr = label_tr.astype(int)
label_tr = to_one_hot(label_tr)
label_val = label_val.reshape(label_val.shape[0], 1)
label_val = label_val.astype(int)
label_val = to_one_hot(label_val)
label_te = label_te.reshape(label_te.shape[0], 1)
label_te = label_te.astype(int)
label_te = to_one_hot(label_te)
data_tr = data_tr.reshape(data_tr.shape[0], 2048)
data_val = data_val.reshape(data_val.shape[0], 2048)
data_te = data_te.reshape(data_te.shape[0], 2048)
data_tr = np.float32(data_tr)
data_val = np.float32(data_val)
data_te = np.float32(data_te)
return data_tr, label_tr, data_val, label_val , data_te, label_te
上述代码中num是为了进一步控制训练样本的取值,也可以稍加修改,对验证集、测试集进行微调。
最终进行整合运行
def data_DE_win(num,rpm,steps=128):
datas_all_DE = []
rpm=str(rpm)
for i in range(10):
path = 'D:\\BaiduNetdiskDownload\\轴承故障诊断数据\\case data\\caseABC10\\'+rpm+'\\{}\\'.format(i)
data_DE = readmat(path, i,name="_DE_time",steps=steps,slice_rate=[7, 1.5, 1.5])
datas_all_DE.append(data_DE)
return dataout_win(datas_all_DE, num)
data_tr,label_tr,data_val,label_val,data_te,label_te = data_DE_win(650,'A',steps=128)
print(data_tr.shape,label_tr.shape,data_val.shape,label_val.shape,data_te.shape,label_te.shape)
结果为(6500, 2048) (6500, 10) (1400, 2048) (1400, 10) (1400, 2048) (1400, 10)
这个数据就可以输入神经网络进行训练了