您现在的位置是:首页 > 伤感句子

matlab实现卷积神经网络CNN(二)——代码实现与解析

作者:璐璐时间:2024-04-24 18:31:03分类:伤感句子

简介  文章浏览阅读6.9k次,点赞36次,收藏142次。用来随机划分训练集、测试集和验证集,当然你也可以自行划分好后分别导入。总之,train_x、test_x和val_x数据格式应该分别为。_卷积神经网络matlab代码

点击全文阅读

        基于上一篇文章对于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结合灰狼优化算法进行超参数优化。

五、模型设置

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'});%验证集

值得一提的是验证集的输入,在很多书籍中,验证集和测试集是同一个数据集。

六、模型训练与测试

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),'%'])

点击全文阅读

郑重声明:

本站所有活动均为互联网所得,如有侵权请联系本站删除处理

我来说两句