面向初学者的深度学习教程。
matlab 2021a
MNIST数据集
%% Instructions
%
% Train: dataset for training a neural network
% Test: dataset for test a trained neural network
% X: input / for Classification: image
% Y: output / for Classification: label
% angle: an image has been rotated by a certain angle
% Dimensionality of the image data: H*W*C*N
% (H: height; W: width; C: channel(RGB:3,gray:1); N: number)
%% setting up the way to load datasets
flag_use_dataset_matlab = 0;
flag_use_dataset_MNIST = 1;
%% 1. use the dataset from MATLAB
% https://www.mathworks.com/help/deeplearning/ug/data-sets-for-deep-learning.html
if flag_use_dataset_matlab == 1
[XTrain,YTrain,anglesTrain] = digitTrain4DArrayData;
[XTest,YTest,anglesTest] = digitTest4DArrayData;
end
%% 2. use the dataset from MNIST
% https://www.mathworks.com/help/deeplearning/ug/data-sets-for-deep-learning.html
% http://yann.lecun.com/exdb/mnist/
if flag_use_dataset_MNIST == 1
oldpath = addpath(fullfile(matlabroot,'examples','nnet','main'));
addpath dataset
filenameImagesTrain = 'train-images-idx3-ubyte.gz';
filenameLabelsTrain = 'train-labels-idx1-ubyte.gz';
filenameImagesTest = 't10k-images-idx3-ubyte.gz';
filenameLabelsTest = 't10k-labels-idx1-ubyte.gz';
XTrain = processImagesMNIST(filenameImagesTrain);
YTrain = processLabelsMNIST(filenameLabelsTrain);
XTest = processImagesMNIST(filenameImagesTest);
YTest = processLabelsMNIST(filenameLabelsTest);
end
%% Load Training Data
disp('Loading training data...')
if 1
[XTrain,YTrain] = digitTrain4DArrayData;
classes = categories(YTrain);
numClasses = numel(classes);
end
% classes_alt = {'0';'1';'2';'3';'4';'5';'6';'7';'8';'9'};
% A = [3,1,2,3]
% B = categorical(A)
% classes_test = categories(B)
image_input_size = [size(XTrain,1),size(XTrain,2),size(XTrain,3)];
image_size_h = size(XTrain,1);
image_size_w = size(XTrain,2);
%% define network
NN_layers = [
imageInputLayer(image_input_size, 'Name','input','Mean',mean(XTrain,4))
fullyConnectedLayer(image_size_h*image_size_w,'Name','fc1')
reluLayer('Name', 'relu1')
% fullyConnectedLayer(1024,'Name','fc2')
% reluLayer('Name','relu2')
fullyConnectedLayer(512,'Name','fc3')
reluLayer('Name','relu3')
fullyConnectedLayer(numClasses,'Name','fc')
softmaxLayer('Name','softmax')];
lgraph = layerGraph(NN_layers);
% Create a dlnetwork object from the layer graph.
dlnet = dlnetwork(lgraph);
% visualize the neural network
analyzeNetwork(dlnet)
%% Define Model Gradients Function
function [gradients,loss,dlYPred] = modelGradients(dlnet,dlX,Y)
dlYPred = forward(dlnet,dlX);
loss = crossentropy(dlYPred,Y);
gradients = dlgradient(loss,dlnet.Learnables);
end
%% Specify Training Options (hyperparameters)
miniBatchSize = 128;
numEpochs = 10;
learnRate = 0.001;
numObservations = numel(YTrain);
numIterationsPerEpoch = floor(numObservations./miniBatchSize);
% training on CPU or GPU(if available);
% 'auto': Use a GPU if one is available. Otherwise, use the CPU.
% 'cpu' : Use the CPU
% 'gpu' : Use the GPU.
% 'multi-gpu' :Use multiple GPUs
% 'parallel :
executionEnvironment = "auto";
print_frequency = 10;
%% Train neural network
% Visualize the training progress in a plot
plots = "training-progress";
if plots == "training-progress"
figure
lineLossTrain = animatedline('Color',[0.85 0.325 0.098]);
ylim([0 inf])
xlabel("Iteration")
ylabel("Loss")
grid on
end
% initialize the average gradients and squared average gradients
exist averageGrad;
if ans == 0
averageGrad = [];
averageSqGrad = [];
end
start = tic;
iteration = 0;
start_time = clock;
fprintf("|=======================================================================================|\n")
fprintf("|\t Epoch \t|\t Iteration \t|\t Time Elapsed \t|\t Mini-batch \t|\t Mini-batch \t|\n")
fprintf("|\t \t \t|\t \t \t \t|\t \t (s) \t \t|\t \tloss \t \t|\t Accuracy \t \t|\n")
fprintf("|=======================================================================================|\n")
for epoch = 1:numEpochs
% Shuffle data.
idx = randperm(numel(YTrain));
XTrain = XTrain(:,:,:,idx);
YTrain = YTrain(idx);
for i = 1:numIterationsPerEpoch
iteration = iteration + 1;
% Read mini-batch of data and convert the labels to dummy
% variables.
idx = (i-1)*miniBatchSize+1:i*miniBatchSize;
X = XTrain(:,:,:,idx);
Y = zeros(numClasses, miniBatchSize, 'single');
for c = 1:numClasses
Y(c,YTrain(idx)==classes(c)) = 1;
end
% Convert mini-batch of data to a dlarray.
dlX = dlarray(single(X),'SSCB');
% If training on a GPU, then convert data to a gpuArray.
if (executionEnvironment == "auto" && canUseGPU) || executionEnvironment == "gpu"
dlX = gpuArray(dlX);
end
% Evaluate the model gradients and loss using dlfeval and the
% modelGradients helper function.
[grad,loss,dlYPred] = dlfeval(@modelGradients,dlnet,dlX,Y);
% Update the network parameters using the Adam optimizer.
[dlnet,averageGrad,averageSqGrad] = adamupdate(dlnet,grad,averageGrad,averageSqGrad,iteration,learnRate);
% Display the training progress.
if plots == "training-progress"
D = duration(0,0,toc(start),'Format','hh:mm:ss');
addpoints(lineLossTrain,iteration,double(gather(extractdata(loss))))
title("Epoch: " + epoch + ", Elapsed: " + string(D) + ", Loss: " + num2str(double(gather(extractdata(loss)))))
drawnow
end
current_time=clock;
elapsed_time=etime(current_time,start_time);
if mod(i,print_frequency) == 0
[~,idx] = max(extractdata(dlYPred),[],1);
YPred = classes(idx);
[~,Y_label] = max(Y,[],1);
Y_label = classes(Y_label);
accuracy_test = mean(YPred==categorical(Y_label));
i_in_total = i + (epoch-1) *numIterationsPerEpoch;
% fprintf("| %10d | %13d | %20.4f | %20f | \n" , epoch,i_in_total,round(elapsed_time,3),round(gather(extractdata(loss)),5))
fprintf("| %9d | %13d | %17.4f | %16f | %17.2f |\n" , epoch,i_in_total,round(elapsed_time,3),round(gather(extractdata(loss)),5),round(accuracy_test,2))
end
end
end
fprintf("|=======================================================================================|\n")
%% test neural network
[XTest, YTest] = digitTest4DArrayData;
dlXTest = dlarray(XTest,'SSCB');
if (executionEnvironment == "auto" && canUseGPU) || executionEnvironment == "gpu"
dlXTest = gpuArray(dlXTest);
end
dlYPred = predict(dlnet,dlXTest);
[~,idx] = max(extractdata(dlYPred),[],1);
YPred = classes(idx);
accuracy_test = mean(YPred==YTest)
figure_show_test_result = figure;
figure_show_test_result.Name = ("test result");
for index_temp = 1:10
figure_show_test_result();
subplot(2,5,index_temp);imagesc(XTest(:,:,:,1 +(index_temp-1)*500 ));title(YPred(1 +(index_temp-1)*500 ))
axis image;set(gca,'XColor', 'none','YColor','none');
end