matlab卷积神经网络训练
文章目录
- matlab卷积神经网络训练
- 使用matlab内置数据集进行训练
- 使用mnist数据集训练
使用matlab内置数据集进行训练
首先加载数据集,该内置数据集的位置为matlab安装路径\toolbox\nnet\nndemos\nndatasets\DigitDataset
共10000张图片,新建一个实时脚本,输入以下代码
digitDatasetPath=fullfile(matlabroot,'toolbox','nnet','nndemos','nndatasets','DigitDataset');
imds=imageDatastore(digitDatasetPath,'IncludeSubfolders',true,'LabelSource','foldernames');
figure()
perm=randperm(10000,20);
for ii=1:20
subplot(4,5,ii);
imshow(imds.Files{perm(ii)})
end
其中imageDatastore
用来加载图片数据集,目前还没有发现matlab怎么加载图像原始数据,只能加载硬盘上已经存在的图片。该函数首先指定图片数据集的位置,然后加载该路径下的所有子文件夹,然后将图片的标签指定为子文件夹的名称,也就是标签为1的图片全都在名称为1的子文件夹内,标签为2的图片全都在名称为2的子文件夹内,以此类推。
然后将训练集划出一部分作为验证集,继续输入以下代码
numTrainFiles=750;
[imdsTrain,imdsValidation]=splitEachLabel(imds,numTrainFiles,'randomized');
其中750代表将每个标签抽出750个划给训练集imdsTrain,共有10个标签,因此训练集共有7500张图片,所以验证集imdsValidation共有2500张图片。
接着构建网络,这一部分可以直接在深度网络设计工具箱中用可视化的方式搭建,但是这里使用代码构建,效果是一样的,输入以下代码
layers=[
imageInputLayer([28,28,1]) % 图像输入层,每张图是28*28的单通道图
convolution2dLayer([3,3],8,"Padding","same") % 第一个卷积层,卷积核大小为3*3,共8个卷积核,因此输出是8张特征图
batchNormalizationLayer % 批量归一化层,
reluLayer % relu激活层
maxPooling2dLayer([2,2],"Stride",2)% 池化层
convolution2dLayer([3,3],16,'Padding','same')
batchNormalizationLayer
reluLayer
maxPooling2dLayer([2,2],'Stride',2)
fullyConnectedLayer(10) % 全连接层
softmaxLayer % softmax层
classificationLayer % 输出分类层,分类问题一定要有这个层
];
其中批量归一化层的作用如下图
然后需要指定该网络的训练参数,如学习率,优化方法等,输入以下代码
options=trainingOptions("sgdm", ... % 随机梯度下降法
'InitialLearnRate',0.01, ... % 初始学习率
'MaxEpochs',5, ... % 训练轮数
'Shuffle','every-epoch', ... % 在每次训练一轮后,都打乱数据
'ValidationData',imdsValidation, ... % 指定验证集
'ValidationFrequency',30, ... % 每迭代30次,就跑一遍验证集看准确度
'Verbose',true, ... % 控制台打印详细的训练过程
'Plots','training-progress', ... % 弹出一个窗口,可视化训练过程
'MiniBatchSize',75); % batchsize
接着开始训练网络,输入以下代码
net=trainNetwork(imdsTrain,layers,options);
会弹出一个训练窗口,同时实时脚本右侧打印训练日志
完整代码如下
clear
close all
digitDatasetPath=fullfile(matlabroot,'toolbox','nnet','nndemos','nndatasets','DigitDataset');
imds=imageDatastore(digitDatasetPath,'IncludeSubfolders',true,'LabelSource','foldernames');
figure()
perm=randperm(10000,20);
for ii=1:20
subplot(4,5,ii);
imshow(imds.Files{perm(ii)})
end
numTrainFiles=750;
[imdsTrain,imdsValidation]=splitEachLabel(imds,numTrainFiles,'randomized');
layers=[
imageInputLayer([28,28,1]) % 图像输入层,每张图是28*28的单通道图
convolution2dLayer([3,3],8,"Padding","same") % 第一个卷积层,卷积核大小为3*3,共8个卷积核,因此输出是8张特征图
batchNormalizationLayer % 批量归一化层,
reluLayer % relu激活层
maxPooling2dLayer([2,2],"Stride",2)% 池化层
convolution2dLayer([3,3],16,'Padding','same')
batchNormalizationLayer
reluLayer
maxPooling2dLayer([2,2],'Stride',2)
fullyConnectedLayer(10) % 全连接层
softmaxLayer % softmax层
classificationLayer % 输出分类层,分类问题一定要有这个层
];
options=trainingOptions("sgdm", ...
'InitialLearnRate',0.01, ...
'MaxEpochs',5, ...
'Shuffle','every-epoch', ...
'ValidationData',imdsValidation, ...
'ValidationFrequency',30, ...
'Verbose',true, ...
'Plots','training-progress', ...
'MiniBatchSize',75);
% 训练集一共7500张图片,minibatchsize为75,因此每75个样本进行一次梯度更新,也就是一次迭代,一共迭代100次
net=trainNetwork(imdsTrain,layers,options);
使用mnist数据集训练
首先将mnist保存成图片格式。保存图片的代码如下,给出的是保存测试图片的代码,事先创建好需要的文件夹,保存测试图片的代码可以直接修改代码得到。
for idx=1:1:60000
data=train_image_data(idx,:);
data=reshape(data,28,28)';
label=train_image_label(idx,:);
[M,I]=max(label);
label=I-1;
if label==0
imwrite(data,['./训练/0/',num2str(idx),'.png'])
elseif label==1
imwrite(data,['./训练/1/',num2str(idx),'.png'])
elseif label==2
imwrite(data,['./训练/2/',num2str(idx),'.png'])
elseif label==3
imwrite(data,['./训练/3/',num2str(idx),'.png'])
elseif label==4
imwrite(data,['./训练/4/',num2str(idx),'.png'])
elseif label==5
imwrite(data,['./训练/5/',num2str(idx),'.png'])
elseif label==6
imwrite(data,['./训练/6/',num2str(idx),'.png'])
elseif label==7
imwrite(data,['./训练/7/',num2str(idx),'.png'])
elseif label==8
imwrite(data,['./训练/8/',num2str(idx),'.png'])
else
imwrite(data,['./训练/9/',num2str(idx),'.png'])
end
if(rem(idx,100)==0)
disp(['完成',num2str(idx),'张'])
end
end
然后按照前述步骤操作,只是
这时候会单独有一个10000张图片的测试集。完整代码如下
% 训练集
% 训练集
clear
close all
datasetPath='D:\matlabR2021a\bin\main_vitalSigns_mimo\Vital_sign_CNM2\vitalSignSocket\mnisttest\训练';
imgs=imageDatastore(datasetPath,"IncludeSubfolders",true,"LabelSource","foldernames");
randidx=randperm(size(imgs.Files,1),64);
figure()
for idx=1:1:64
subplot(8,8,idx)
imshow(imgs.Files{randidx(idx)})
end
% 测试集
datasetPath='D:\matlabR2021a\bin\main_vitalSigns_mimo\Vital_sign_CNM2\vitalSignSocket\mnisttest\测试';
imgs_test=imageDatastore(datasetPath,"IncludeSubfolders",true,"LabelSource","foldernames");
% 划分验证集集和训练集
[valid_imgs,train_imgs]=splitEachLabel(imgs,100,'randomized');
size(valid_imgs.Files)
% 构建网络模型
model=[
imageInputLayer([28,28,1])
convolution2dLayer([4,4],64,'Padding','same')
batchNormalizationLayer
reluLayer
maxPooling2dLayer([2,2],'Stride',1)
convolution2dLayer([3,3],16,'Padding','same')
batchNormalizationLayer
reluLayer
maxPooling2dLayer([2,2],'Stride',2)
fullyConnectedLayer(10)
softmaxLayer
classificationLayer
]
% 指定训练参数和方式
options=trainingOptions("sgdm", ...
'InitialLearnRate',0.01, ...
'Verbose',true, ...
'MaxEpochs',3, ...
'MiniBatchSize',100, ...
'Shuffle','every-epoch', ...
'ValidationFrequency',20, ...
'Plots','training-progress', ...
'ValidationData',valid_imgs);
% 训练网络
net=trainNetwork(train_imgs,model,options);
pred=classify(net,imgs_test);
acc=sum(imgs_test.Labels==pred)/size(imgs_test.Labels,1);
disp(['准确度为',num2str(acc)])