基于上一篇文章对于CNN网络结构的整理,我们将用matlab实现一维数据的CNN网络单\多输入和单\多输出。
文中字母含义详情可见上一篇文章。
一、加载数据与数据集划分
clc;clear;close all;
data=load('data.csv')'; %总数据
label=load('label.csv')'; %总标签
[train_x,train_y,test_x,test_y,val_x,val_y]=spilt(data,label,0.8,0.1,0.1);
%划分训练集、测试集和验证集
data数据格式应为M×SN;M为一维数据的长度(即一个样本有多少个点),由于是一维数据,所以宽度N为1;SN则为样本个数。
label数据格式应为P×SN;P代表输出特征个数(也就是单输出和多输出),SN为样本个数。
spilt是个自定义函数,用来随机划分训练集、测试集和验证集,当然你也可以自行划分好后分别导入。
function [trainData,trainLabel,testData,testLabel,valData,valLabel]=spilt(data,label,trainRatio,testRatio,validationRatio)
% 生成随机分组索引
c = cvpartition(size(data,2), 'HoldOut', testRatio);
trainIdx = c.training;
testIdx = c.test;
% 对剩余数据再次进行随机分组
c = cvpartition(sum(trainIdx), 'HoldOut', validationRatio/(1-testRatio));
true_trainIdx=c.training;
valIdx = c.test;
% 将训练集、验证集和测试集分别保存到不同的变量中
trainData = data(:,trainIdx);
trainLabel = label(trainIdx);
valData = trainData(:,valIdx);
valLabel = trainLabel(valIdx);
testData = data(:,testIdx);
testLabel = label(testIdx);
trainData = trainData(:,true_trainIdx);
trainLabel = trainLabel(true_trainIdx);
总之,train_x、test_x和val_x数据格式应该分别为M×样本个数。
train_y、test_y和val_y数据格式应该分别为P×样本个数。
二、数据预处理
%method=@mapminmax; %归一化
method=@mapstd; %标准化
[train_x,train_ps]=method(train_x,0,1);
test_x=method('apply',test_x,train_ps);
val_x=method('apply',val_x,train_ps);
[train_y,output_ps]=method(train_y,0,1);
test_y=method('apply',test_y,output_ps);
val_y=method('apply',val_y,output_ps);
选择对数据进行归一化或者标准化。
三、数据输入格式转换
trainD=reshape(train_x,[M,N,D,SN]);
%训练集输入,[单个样本长度,单个样本宽度,输入特征个数,样本数]
testD=reshape(test_x,[M,N,D,SN]);
%测试集输入,[单个样本长度,单个样本宽度,输入特征个数,样本数]
valD=reshape(val_x,[M,N,D,SN]);
%验证集输入,[单个样本长度,单个样本宽度,输入特征个数,样本数]
其中,因为是一维数据,所以N=1,下文同。
CNN的输入数据格式应为【单个样本长度,单个样本宽度,输入特征个数,样本数】;
即【M,N,D,SN】。
D=1则代表单输入。
四、CNN网络结构建立
layers = [
imageInputLayer([M N D]) %输入层参数设置,[M,N,D]
%第一层卷积层和池化层
convolution2dLayer([64,1],128,'Padding','same')
%[64,1]是卷积核大小,128是个数
%对于一维数据,卷积核第二个参数为1就行了,这样就是一维卷积
reluLayer %relu激活函数
maxPooling2dLayer([32 1],'Stride',10)
%第二层卷积层和池化层
convolution2dLayer([32,1],128,'Padding','same')
reluLayer %relu激活函数
maxPooling2dLayer([16 1],'Stride',20)
%两层全连接层
fullyConnectedLayer(20) % 20个全连接层神经元
reluLayer %relu激活函数
fullyConnectedLayer(10) % 10个全连接层神经元
fullyConnectedLayer(P) % 输出层神经元个数P
regressionLayer];%添加回归层,用于计算损失值
上述代码中的卷积核大小、个数等参数不具备参考意义,应当根据自身数据结构自行调整。
convolution2dLayer代表卷积层;【64,1】是卷积核的大小,由于是一维数据,所以第二个参数为1;128是卷积核个数;'Padding','same'代表填充使得该层的神经元输入和输出个数相同。我们也可以自定义其他填充方式或者步幅大小。
详情可见官方文档:https://ww2.mathworks.cn/help/deeplearning/ref/nnet.cnn.layer.convolution2dlayer.html
maxPooling2dLayer代表最大池化层;【32,1】是池化层大小;'Stride',10代表池化步幅。
fullyConnectedLayer代表全连接层,最后一层全连接层需决定输出特征个数P;reluLayer代表激活函数的选择。
regressionLayer代表回归层,也可以换成分类层softmaxLayer和classificationLayer。
analyzeNetwork(net);
我们可以采用该指令来查看网络结构,包括层结构和每一层的输入输出大小。
有时候你的卷积核大小、个数、步幅以及池化层大小和步幅设置的不合理,导致网络出错,我们就可以通过该命令检查每一层的输入输出。比如,某一池化层的大小不能大于上一层的输出个数。
具体可见下一篇文章,CNN结合灰狼优化算法进行超参数优化。文章来源:https://www.toymoban.com/news/detail-744007.html
五、模型设置
options = trainingOptions('adam', ...%优化方法:sgdm、adam等
'MaxEpochs',30, ...
'MiniBatchSize',20, ...
'InitialLearnRate',0.001, ...
'GradientThreshold',1, ...
'Verbose',false,...
'ExecutionEnvironment','multi-gpu',...% GPU训练
'Plots','training-progress',...%'none'代表不显示训练过程
'ValidationData',{valD,val_y'});%验证集
值得一提的是验证集的输入,在很多书籍中,验证集和测试集是同一个数据集。文章来源地址https://www.toymoban.com/news/detail-744007.html
六、模型训练与测试
net = trainNetwork(trainD,train_y',layers,options);
% 预测
YPred = predict(net,testD);
% 结果
YPred=double(YPred');%输出是n*1的single型数据,要转换为1*n的double是数据形式
% 反归一化
predict_value=method('reverse',YPred,output_ps);predict_value=double(predict_value);
true_value=method('reverse',test_y,output_ps);true_value=double(true_value);
七、结果评估
rmse=sqrt(mean((true_value-predict_value).^2));
disp(['根均方差:',num2str(rmse)])
mae=mean(abs(true_value-predict_value));
disp(['平均绝对误差:',num2str(mae)])
maxape=max(abs((true_value-predict_value)./true_value));
disp(['最大相对百分误差:',num2str(maxape*100),'%'])
mape=mean(abs((true_value-predict_value)./true_value));
disp(['平均相对百分误差:',num2str(mape*100),'%'])
到了这里,关于matlab实现卷积神经网络CNN(二)——代码实现与解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!