matlab训练卷积神经网络识别手写数字

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);

会弹出一个训练窗口,同时实时脚本右侧打印训练日志
matlab训练卷积神经网络识别手写数字_第1张图片
matlab训练卷积神经网络识别手写数字_第2张图片
完整代码如下

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)])


matlab训练卷积神经网络识别手写数字_第3张图片

你可能感兴趣的:(matlab,cnn,开发语言)