这个例子展示了如何训练一个使用自定义学习率计划分类手写数字的网络。
如果trainingOptions
不提供您需要的选项(例如,自定义学习速率计划),那么您可以使用自动区分定义自己的自定义训练循环。
此示例训练网络对手写数字进行分类基于时间的衰减学习率计划:对于每次迭代,求解器使用 ,在那里t是迭代数, 初始学习率,和k就是衰变。
方法将数字数据加载为图像数据存储imageDatastore
函数并指定包含图像数据的文件夹。
dataFolder = fullfile(toolboxdir(“nnet”),“nndemos”,“nndatasets”,“DigitDataset”);imds = imageDatastore(数据文件夹,...“IncludeSubfolders”,真的,....“LabelSource”,“foldernames”);
将数据划分为训练集和验证集。方法留出10%的数据用于验证splitEachLabel
函数。
[imdsTrain,imdsValidation] = splitEachLabel(imds,0.9,“随机”);
本例中使用的网络需要大小为28 × 28 × 1的输入图像。要自动调整训练图像的大小,请使用增强图像数据存储。指定要对训练图像执行的附加增强操作:在水平轴和垂直轴上随机将图像平移到5个像素。数据增强有助于防止网络过度拟合和记忆训练图像的确切细节。
inputSize = [28 28 1];pixelRange = [-5 5];imageAugmenter = imageDataAugmenter(...“RandXTranslation”pixelRange,...“RandYTranslation”, pixelRange);augimdsTrain = augmentedimagedastore (inputSize(1:2)),imdsTrain,“DataAugmentation”, imageAugmenter);
若要自动调整验证图像的大小,而不执行进一步的数据增强,请使用增强图像数据存储,而不指定任何额外的预处理操作。
augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation);
确定训练数据中的类数。
classes = categories(imdsTrain.Labels);numClasses = nummel(类);
定义图像分类的网络。
图层= [imageInputLayer(inputSize,“归一化”,“没有”,“名字”,“输入”20岁的)convolution2dLayer (5“名字”,“conv1”) batchNormalizationLayer (“名字”,“bn1”) reluLayer (“名字”,“relu1”20岁的)convolution2dLayer (3“填充”,“相同”,“名字”,“conv2”) batchNormalizationLayer (“名字”,“bn2”) reluLayer (“名字”,“relu2”20岁的)convolution2dLayer (3“填充”,“相同”,“名字”,“conv3”) batchNormalizationLayer (“名字”,“bn3”) reluLayer (“名字”,“relu3”) fullyConnectedLayer (numClasses“名字”,“俱乐部”) softmaxLayer (“名字”,“softmax”));lgraph = layerGraph(图层);
创建一个dlnetwork
对象从图层图。
Dlnet = dlnetwork(lgraph)
dlnet = dlnetwork with properties: Layers: [12×1 nnet.cnn.layer.Layer] Connections: [11×2 table] Learnables: [14×3 table] State: [6×3 table] InputNames: {'input'} OutputNames: {'softmax'}
创建函数modelGradients
,列在示例末尾,它需要adlnetwork
对象,一个带有相应标签的小批量输入数据,并返回相对于网络中可学习参数的损失梯度和相应的损失。
用128个小批量训练10个epoch。
numEpochs = 10;miniBatchSize = 128;
指定用于SGDM优化的选项。指定初始学习速率为0.01,衰减为0.01,动量为0.9。
initialLearnRate = 0.01;衰减= 0.01;动量= 0.9;
创建一个minibatchqueue
对象,该对象在训练期间处理和管理小批量图像。对于每个小批量:
使用自定义小批量预处理功能preprocessMiniBatch
(在本例结束时定义)将标签转换为单热编码变量。
用尺寸标签格式化图像数据“SSCB”
(空间,空间,通道,批次)。默认情况下,minibatchqueue
对象将数据转换为dlarray
具有基础类型的对象单
.不要向类标签添加格式。
如果有GPU,可以在GPU上进行训练。默认情况下,minibatchqueue
对象将每个输出转换为gpuArray
如果GPU可用。使用GPU需要并行计算工具箱™和受支持的GPU设备。金宝app有关受支持设备的信息,请参见金宝appGPU支金宝app持版本(并行计算工具箱).
mbq = minibatchqueue(augimdsTrain,...“MiniBatchSize”miniBatchSize,...“MiniBatchFcn”@preprocessMiniBatch,...“MiniBatchFormat”, {“SSCB”,''});
初始化培训进度图。
图lineLossTrain = animatedline(“颜色”,[0.85 0.325 0.098]);Ylim ([0 inf]) xlabel(“迭代”) ylabel (“损失”网格)在
初始化SGDM求解器的速度参数。
速度= [];
使用自定义训练循环训练网络。对于每个纪元,洗牌数据并在小批量数据上循环。对于每个小批量:
方法评估模型梯度、状态和损失dlfeval
而且modelGradients
函数并更新网络状态。
确定基于时间的衰减学习率计划的学习率。
方法更新网络参数sgdmupdate
函数。
显示培训进度。
迭代= 0;开始= tic;%遍历epoch。为epoch = 1:numEpochs% Shuffle数据。洗牌(兆贝可);在小批上循环。而Hasdata (mbq)迭代=迭代+ 1;读取小批数据。[dlX, ly] = next(mbq);使用dlfeval和% modelGradients函数并更新网络状态。[gradients,state,loss] = dlfeval(@modelGradients,dlnet,dlX,dlY);dlnet。状态=状态;确定基于时间的衰减学习率计划的学习率。learnRate = initialLearnRate/(1 +衰减*迭代);使用SGDM优化器更新网络参数。[dlnet,velocity] = sgdmupdate(dlnet,gradients,velocity,learnRate,momentum);%显示培训进度。D = duration(0,0,toc(start),“格式”,“hh: mm: ss”);addpoints (lineLossTrain、迭代、失去)标题(”时代:“+ epoch +,消失:"+字符串(D))现在绘制结束结束
通过将验证集上的预测结果与真实标签进行比较,检验模型的分类精度。
经过训练后,对新数据进行预测不需要标签。创建minibatchqueue
对象,只包含测试数据的预测器:
为了忽略标签进行测试,将迷你批处理队列的输出数量设置为1。
指定用于训练的相同的小批大小。
属性预处理预测器preprocessMiniBatchPredictors
函数,在示例末尾列出。
对于数据存储的单个输出,指定迷你批处理格式“SSCB”
(空间,空间,通道,批次)。
numOutputs = 1;mbqTest = minibatchqueue(augimdsValidation,numOutputs,...“MiniBatchSize”miniBatchSize,...“MiniBatchFcn”@preprocessMiniBatchPredictors,...“MiniBatchFormat”,“SSCB”);
循环小批和分类图像使用modelPredictions
函数,在示例末尾列出。
预测= modelforecasts (dlnet,mbqTest,classes);
评估分类准确率。
YTest = imdsValidation.Labels;准确度=平均值(预测= YTest)
准确度= 0.9530
的modelGradients
函数的参数为dlnetwork
对象dlnet
,一小批输入数据dlX
有相应的标签Y
并返回损失相对于中可学习参数的梯度dlnet
、网络状态、丢失。要自动计算梯度,请使用dlgradient
函数。
函数[gradients,state,loss] = modelGradients(dlnet,dlX,Y) [dlYPred,state] = forward(dlnet,dlX);loss = crossentropy(dlYPred,Y);gradients = dlgradient(loss,dlnet.Learnables);损失= double(gather(extractdata(Loss)));结束
的modelPredictions
函数的参数为dlnetwork
对象dlnet
,一个minibatchqueue
输入数据的兆贝可
和网络类,并通过迭代中所有数据来计算模型预测minibatchqueue
对象。函数使用onehotdecode
函数来查找得分最高的预测班级。
函数forecasts = modelforecasts (dlnet,mbq,classes) forecasts = [];而hasdata(mbq) dlXTest = next(mbq);dlYPred = predict(dlnet,dlXTest);YPred = onehotdecode(dlYPred,classes,1)';预测=[预测;YPred];结束结束
的preprocessMiniBatch
函数使用以下步骤预处理一小批预测器和标签:
对图像进行预处理preprocessMiniBatchPredictors
函数。
从传入的单元格数组中提取标签数据,并沿着第二次维度连接到分类数组中。
One-hot将分类标签编码为数字数组。编码到第一个维度会产生一个与网络输出形状匹配的编码数组。
函数[X,Y] = preprocessMiniBatch(XCell,YCell)预处理预测器。X = preprocessMiniBatchPredictors(XCell);从单元格和级联中提取标签数据。Y = cat(2,YCell{1:end});单热编码标签。Y = onehotencode(Y,1);结束
的preprocessMiniBatchPredictors
函数通过从输入单元格数组中提取图像数据并将其连接到数值数组来预处理一小批预测器。对于灰度输入,在第四个维度上的连接将为每个图像添加第三个维度,以用作单个通道维度。
函数X = preprocessMiniBatchPredictors(XCell)%连接。X = cat(4,XCell{1:end});结束
dlarray
|dlgradient
|dlfeval
|dlnetwork
|向前
|adamupdate
|预测
|minibatchqueue
|onehotencode
|onehotdecode