forward
R2026b计算深度学习网络输出以进行训练
语法
描述
一些深度学习层在训练期间的行为和其在推断(预测)期间的行为是不同的。例如,在训练期间,丢弃层会随机将输入元素设置为零以帮助防止过拟合,但在推断期间,丢弃层不会更改输入。类似地,批量归一化层在训练期间使用小批量统计量进行归一化,但在推断期间使用训练得到的均值和方差。
要计算网络输出以进行训练,请使用 forward 函数。要计算网络输出以进行推断,请使用 predict 函数。
[ 还返回由剪枝层的激活值组成的元胞数组。此语法仅在 Y1,...,YN,state,pruningActivations] = forward(net,X1,...,XM)net 为 TaylorPrunableNetwork 对象时才适用。
要对深度神经网络进行剪枝,您需要 Deep Learning Toolbox™ Model Compression Library 支持包。该支持包是一项免费附加功能,您可以使用附加功能资源管理器进行下载。或者,请参阅 Deep Learning Toolbox Model Compression Library。
___ = forward(___, 使用一个或多个名称-值参量指定其他选项。Name=Value)
示例
此示例说明如何使用自定义学习率调度来训练对手写数字进行分类的网络。
您可以使用 trainnet 和 trainingOptions 函数训练大多数类型的神经网络。如果 trainingOptions 函数没有提供您需要的选项(例如,自定义求解器),则您可以定义自己的自定义训练循环,使用 dlarray 和 dlnetwork 对象进行自动微分。有关说明如何使用 trainnet 函数重新训练已经过预训练的深度学习网络的示例,请参阅重新训练神经网络以对新图像进行分类。
训练深度神经网络是一项优化任务。通过将神经网络视为 函数(其中 是网络输入,而 是可学习参数集),您可以优化 ,以便根据训练数据最小化某些损失值。例如,优化可学习参数 ,以便对于给定的输入 和对应的目标值 ,它们可以最小化预测值 和 之间的误差。
使用的损失函数取决于任务的类型。例如:
对于分类任务,您可以最小化预测值和目标值之间的交叉熵误差。
对于回归任务,您可以最小化预测值和目标值之间的均方误差。
您可以使用梯度下降算法来优化目标,即:使用损失函数相对于可学习参数的梯度来逐步接近最小值,以通过迭代更新可学习参数 来最小化损失 。梯度下降算法通常使用 形式的更新步长变体来更新可学习参数,其中 是迭代序号, 是学习率, 表示梯度(损失函数相对于可学习参数的导数)。
此示例使用随机梯度下降算法(不带动量)训练网络对手写数字进行分类。
加载训练数据
使用 imageDatastore 函数将位数数据加载为图像数据存储,并指定包含图像数据的文件夹。
unzip("DigitsData.zip") imds = imageDatastore("DigitsData", ... IncludeSubfolders=true, ... LabelSource="foldernames");
将数据划分为训练集和测试集。留出 10% 的数据用于使用 splitEachLabel 函数进行测试。
[imdsTrain,imdsTest] = splitEachLabel(imds,0.9,"randomize");此示例中使用的网络需要大小为 28×28×1 的输入图像。要自动调整训练图像的大小,请使用增强的图像数据存储。指定要对训练图像额外执行的增强操作:在水平和垂直坐标区上随机平移图像最多 5 个像素。数据增强有助于防止网络过拟合和记忆训练图像的具体细节。
inputSize = [28 28 1]; pixelRange = [-5 5]; imageAugmenter = imageDataAugmenter( ... RandXTranslation=pixelRange, ... RandYTranslation=pixelRange); augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain,DataAugmentation=imageAugmenter);
要在不执行进一步数据增强的情况下自动调整测试图像的大小,请使用增强的图像数据存储,而不指定任何其他预处理操作。
augimdsTest = augmentedImageDatastore(inputSize(1:2),imdsTest);
确定训练数据中类的数量。
classes = categories(imdsTrain.Labels); numClasses = numel(classes);
定义网络
定义用于图像分类的网络。
对于图像输入,请指定输入大小与训练数据匹配的图像输入层。
不对图像输入进行归一化,将输入层的
Normalization选项设置为"none"。指定三个 convolution-batchnorm-ReLU 模块。
通过将
Padding选项设置为"same",填充卷积层的输入,使输出具有相同的大小。对于第一个卷积层,指定 20 个大小为 5 的滤波器。对于其余卷积层,指定 20 个大小为 3 的滤波器。
对于分类,指定一个大小与类数目匹配的全连接层
要将输出映射到概率,请包括一个 softmax 层。
使用自定义训练循环训练网络时,不要包含输出层。
layers = [
imageInputLayer(inputSize,Normalization="none")
convolution2dLayer(5,20,Padding="same")
batchNormalizationLayer
reluLayer
convolution2dLayer(3,20,Padding="same")
batchNormalizationLayer
reluLayer
convolution2dLayer(3,20,Padding="same")
batchNormalizationLayer
reluLayer
fullyConnectedLayer(numClasses)
softmaxLayer];基于层数组创建一个 dlnetwork 对象。
net = dlnetwork(layers)
net =
dlnetwork with properties:
Layers: [12×1 nnet.cnn.layer.Layer]
Connections: [11×2 table]
Learnables: [14×3 table]
State: [6×3 table]
InputNames: {'imageinput'}
OutputNames: {'softmax'}
Initialized: 1
View summary with summary.
定义模型损失函数
训练深度神经网络是一项优化任务。通过将神经网络视为 函数(其中 是网络输入,而 是可学习参数集),您可以优化 ,以便根据训练数据最小化某些损失值。例如,优化可学习参数 ,以便对于给定的输入 和对应的目标值 ,它们可以最小化预测值 和 之间的误差。
定义 modelLoss 函数。modelLoss 函数接受 dlnetwork 对象 net、小批量输入数据 X和相应目标 T,并返回损失、损失相对于 net 中可学习参数的梯度以及网络状态。要自动计算梯度,请使用 dlgradient 函数。
function [loss,gradients,state] = modelLoss(net,X,T) % Forward data through network. [Y,state] = forward(net,X); % Calculate cross-entropy loss. loss = crossentropy(Y,T); % Calculate gradients of loss with respect to learnable parameters. gradients = dlgradient(loss,net.Learnables); end
定义 SGD 函数
创建 sgdStep 函数,该函数采用参数和损失相对于参数的梯度,并使用随机梯度下降算法返回更新后的参数,表示为 ,其中 是迭代序号, 是学习率, 表示梯度(损失相对于可学习参数的导数)。
function parameters = sgdStep(parameters,gradients,learnRate) parameters = parameters - learnRate .* gradients; end
定义自定义更新函数不是自定义训练循环的必要步骤。或者,您也可以使用内置更新函数,如 sgdmupdate、adamupdate 和 rmspropupdate。
指定训练选项
使用 128 的小批量大小和 0.01 的学习率进行十五轮训练。
numEpochs = 15; miniBatchSize = 128; learnRate = 0.01;
训练模型
创建一个 minibatchqueue 对象,用于在训练期间处理和管理小批量图像。对于每个小批量:
使用自定义小批量预处理函数
preprocessMiniBatch(在此示例末尾定义)将目标值转换为 one-hot 编码向量。用维度标签
"SSCB"(空间、空间、通道、批量)格式化图像数据。默认情况下,minibatchqueue对象将数据转换为基础类型为single的dlarray对象。不要格式化目标值。放弃部分小批量。
在 GPU 上(如果有)进行训练。默认情况下,如果 GPU 可用,则
minibatchqueue对象会将每个输出都转换为一个gpuArray。使用 GPU 需要 Parallel Computing Toolbox™ 和支持的 GPU 设备。有关受支持设备的信息,请参阅GPU 计算要求 (Parallel Computing Toolbox)。
mbq = minibatchqueue(augimdsTrain,... MiniBatchSize=miniBatchSize,... MiniBatchFcn=@preprocessMiniBatch,... MiniBatchFormat=["SSCB" ""], ... PartialMiniBatch="discard");
计算训练进度监视器的总迭代次数。
numObservationsTrain = numel(imdsTrain.Files); numIterationsPerEpoch = floor(numObservationsTrain / miniBatchSize); numIterations = numEpochs * numIterationsPerEpoch;
初始化 TrainingProgressMonitor 对象。由于计时器在您创建监视器对象时启动,请确保您创建的对象靠近训练循环。
monitor = trainingProgressMonitor( ... Metrics="Loss", ... Info="Epoch", ... XLabel="Iteration");
使用自定义训练循环来训练网络。对于每轮训练,对数据进行乱序处理,并遍历小批量数据。对于每个小批量:
使用
dlfeval和modelLoss函数计算模型损失、梯度和状态,并更新网络状态。使用
dlupdate函数和自定义更新函数更新网络参数。更新训练进度监视器中的损失值和轮数值。
如果 monitor 的 Stop 属性为 true,则停止。当您点击“停止”按钮时,
TrainingProgressMonitor对象的 Stop 属性值会更改为 true。
epoch = 0; iteration = 0; % Loop over epochs. while epoch < numEpochs && ~monitor.Stop epoch = epoch + 1; % Shuffle data. shuffle(mbq); % Loop over mini-batches. while hasdata(mbq) && ~monitor.Stop iteration = iteration + 1; % Read mini-batch of data. [X,T] = next(mbq); % Evaluate the model gradients, state, and loss using dlfeval and the % modelLoss function and update the network state. [loss,gradients,state] = dlfeval(@modelLoss,net,X,T); net.State = state; % Update the network parameters using SGD. updateFcn = @(parameters,gradients) sgdStep(parameters,gradients,learnRate); net = dlupdate(updateFcn,net,gradients); % Update the training progress monitor. recordMetrics(monitor,iteration,Loss=loss); updateInfo(monitor,Epoch=epoch); monitor.Progress = 100 * iteration/numIterations; end end

测试模型
使用 testnet 函数测试神经网络。对于单标签分类,需评估准确度。准确度是指正确预测的百分比。默认情况下,testnet 函数使用 GPU(如果有)。要手动选择执行环境,请使用 testnet 函数的 ExecutionEnvironment 参量。
accuracy = testnet(net,augimdsTest,"accuracy")accuracy = 96.3000
在混淆图中可视化预测。使用 minibatchpredict 函数进行预测,并使用 scores2label 函数将分类分数转换为标签。默认情况下,minibatchpredict 函数使用 GPU(如果有)。要手动选择执行环境,请使用 minibatchpredict 函数的 ExecutionEnvironment 参量。
scores = minibatchpredict(net,augimdsTest); YTest = scores2label(scores,classes);
在混淆图中可视化预测。
TTest = imdsTest.Labels; figure confusionchart(TTest,YTest)

对角线上的较大值表示相应类的预测准确。非对角线上的较大值表示相应类之间的严重混淆。
支持函数
小批量预处理函数
preprocessMiniBatch 函数使用以下步骤预处理小批量预测变量和标签:
使用
preprocessMiniBatchPredictors函数预处理图像。从传入的元胞数组中提取标签数据,并沿第二个维度串联成一个分类数组。
将分类标签 one-hot 编码为数值数组。编码到第一个维度会生成与网络输出形状匹配的编码数组。
function [X,T] = preprocessMiniBatch(dataX,dataT) % Preprocess predictors. X = preprocessMiniBatchPredictors(dataX); % Extract label data from cell and concatenate. T = cat(2,dataT{:}); % One-hot encode labels. T = onehotencode(T,1); end
小批量预测变量预处理函数
preprocessMiniBatchPredictors 函数从输入元胞数组中提取图像数据并串联成一个数值数组,以此预处理小批量预测变量。对于灰度输入,在第四个维度上进行串联会向每个图像添加第三个维度,以用作单一通道维度。
function X = preprocessMiniBatchPredictors(dataX) % Concatenate. X = cat(4,dataX{:}); end
输入参数
神经网络,指定为下列值之一:
dlnetwork对象 - 神经网络。TaylorPrunableNetwork对象 - 用于自定义剪枝循环的神经网络。
要对深度神经网络进行剪枝,您需要 Deep Learning Toolbox Model Compression Library 支持包。该支持包是一项免费附加功能,您可以使用附加功能资源管理器进行下载。或者,请参阅 Deep Learning Toolbox Model Compression Library。
输入数据,每个输入数据指定为下列值之一:
格式化的
dlarray对象未格式化的
dlarray对象 (自 R2025a 起)数值数组 (自 R2025a 起)
输入 Xi 对应于网络输入 net.InputNames(i)。
要使用自动微分通过自定义训练循环来训练神经网络,输入数据必须为格式化或未格式化的 dlarray 对象。
提示
神经网络需要输入数据具有特定的布局。例如,向量序列分类网络通常需要向量序列表示形式为 t×c 数组,其中 t 和 c 分别是序列的时间步数和通道数。神经网络通常具有一个输入层,用于指定数据的预期布局。
大多数数据存储和函数会以网络需要的布局输出数据。如果您的数据布局与网络预期的布局不同,则可通过使用 InputDataFormats 选项或将输入数据指定为格式化的 dlarray 对象来表明您的数据具有不同的布局。通常,调整 InputDataFormats 训练选项比预处理输入数据更为便捷。
有关详细信息,请参阅Deep Learning Data Formats。
要创建接收未格式化数据的神经网络,请使用 inputLayer 对象并且不指定格式。要将未格式化的数据直接输入网络,请不要指定 InputDataFormats 参量 (自 R2025a 起)。
在 R2025a 之前的版本中: 对于没有输入层的神经网络,您必须使用 InputDataFormats 参量指定一种格式。
名称-值参数
将可选参量对组指定为 Name1=Value1,...,NameN=ValueN,其中 Name 是参量名称,Value 是对应的值。名称-值参量必须出现在其他参量之后,但对各个参量对组的顺序没有要求。
示例: forward(net,X,Outputs=["relu1" "relu2"]) 指定从名称为 "relu1" 和 "relu2" 的层提取输出。
神经网络输出,指定为层名称或层输出路径的字符串数组或字符向量元胞数组。使用以下形式之一指定输出:
"layerName",其中layerName是具有单个输出的层的名称。"layerName/outputName",其中layerName是层的名称,outputName是层输出的名称。对于具有多个输出的层,请使用此选项。
要使用 networkLayer 对象内部的层的输出,请先使用 expandLayers 函数展开嵌套网络。有关详细信息,请参阅网络层提示。
如果您未指定要从中提取输出的层,则默认情况下,软件会使用 net.Outputs 指定的输出。
性能优化,指定为下列值之一:
"auto"- 自动应用适用于输入网络和硬件资源的多项优化。"none"- 禁用所有优化。
使用 "auto" 加速选项可以提供性能优势,但会增加初始运行时间。使用兼容参数的后续调用会更快。当您计划使用大小和形状相同的不同输入数据多次调用函数时,请使用性能优化。
自 R2025a 起
输入数据维度的描述,指定为字符串数组、字符向量或字符向量元胞数组。
如果 InputDataFormats 为 "auto",则软件会使用网络输入所需要的格式。否则,软件会为对应的网络输入使用指定的格式。
深度学习数据格式是字符串,其中每个字符描述对应数据维度的类型。这些字符是:
"S"- 空间"C"- 通道"B"- 批量"T"- 时间"U"- 未指定
例如,假设您有一个表示一批序列的数组,其中第一个、第二个和第三个维度分别对应于通道、观测值和时间步。您可以将该数据描述为具有格式 "CBT"(通道、批量、时间)。
您可以指定多个标注为 "S" 或 "U" 的维度。每个 "C"、"B" 和 "T" 标签最多只能使用一次。该软件忽略第二个维度后的单一尾部 "U" 维度。
对于具有多个输入的神经网络 net,请指定一个输入数据格式数组,其中 InputDataFormats(i) 对应于输入 net.InputNames(i)。
有关详细信息,请参阅Deep Learning Data Formats。
要创建接收未格式化数据的神经网络,请使用 inputLayer 对象并且不指定格式。要将未格式化的数据直接输入网络,请不要指定 InputDataFormats 参量 (自 R2025a 起)。
在 R2025a 之前的版本中: 对于没有输入层的神经网络,您必须使用 InputDataFormats 参量指定一种格式。
数据类型: char | string | cell
自 R2025a 起
输出数据维度的描述,指定为下列值之一:
"auto"- 自动确定数据布局。如果网络输出格式化数据,则函数直接返回格式化的
dlarray。如果网络输出维度数与输入数据相同的未格式化数据,则函数使用
InputDataFormats排序。如果网络输出维度数与输入数据不同的未格式化数据,则函数会对输出维度进行排列,使批量维度和时间维度排在通道维度之前。例如,对于包含通道和批量输出维度的网络,输出数组的大小为
numObservations×numChannels。此排序与默认dlarray维度排序不同,在默认维度排序中,"C"(通道)维度排在"B"(批量)和"T"(时间)维度之前。
字符串、字符向量或字符向量元胞数组 -
forward函数使用指定的数据格式。
深度学习数据格式是字符串,其中每个字符描述对应数据维度的类型。这些字符是:
"S"- 空间"C"- 通道"B"- 批量"T"- 时间"U"- 未指定
例如,假设您有一个表示一批序列的数组,其中第一个、第二个和第三个维度分别对应于通道、观测值和时间步。您可以将该数据描述为具有格式 "CBT"(通道、批量、时间)。
您可以指定多个标注为 "S" 或 "U" 的维度。每个 "C"、"B" 和 "T" 标签最多只能使用一次。该软件忽略第二个维度后的单一尾部 "U" 维度。
有关详细信息,请参阅Deep Learning Data Formats。
数据类型: char | string | cell
输出参量
具有多个输出的网络的输出数据,以下列值之一的形式返回:
格式化的
dlarray对象未格式化的
dlarray对象 (自 R2025a 起)数值数组 (自 R2025a 起)
数据类型与输入数据的数据类型匹配。
输出 Y1, …, YN 的顺序与 Outputs 参量指定的输出顺序匹配。
对于分类神经网络,输出的元素对应于每个类的分数。分数的顺序与训练数据中类别的顺序匹配。例如,如果您使用分类标签 TTrain 训练神经网络,则分数的顺序与 categories(TTrain) 给出的类别顺序匹配。
如果输入网络为 TaylorPrunableNetwork 对象,则返回由剪枝层的激活值组成的元胞数组。
扩展功能
forward 函数支持 GPU 数组输入,但有以下用法说明和限制:
如果满足以下至少一个条件,此函数将在 GPU 上运行:
net.Learnables.Value中的任何网络可学习参数值是基础数据类型为gpuArray的dlarray对象。输入参量
X是基础数据类型为gpuArray的dlarray。
有关详细信息,请参阅在 GPU 上运行 MATLAB 函数 (Parallel Computing Toolbox)。
版本历史记录
在 R2019b 中推出可以分别使用 InputDataFormats 选项和 OutputDataFormats 选项指定输入数据格式和输出数据格式。如果您将未格式化数据指定为神经网络的输入且未指定 InputDataFormats 参量,则该函数会直接将未格式化数据传递给网络。
要创建接收未格式化数据的神经网络,请使用 inputLayer 对象并且不指定格式。
对于 dlnetwork 对象,forward 函数返回的 state 输出参量是一个包含网络中每个层的状态参数名称和值的表。
从 R2021a 开始,状态值是 dlarray 对象。进行此更改后可在使用 AcceleratedFunction 对象时提供更好的支持。为了加速具有频繁更改的输入值(例如包含网络状态的输入)的深度学习函数,必须将频繁更改的值指定为 dlarray 对象。
在以前的版本中,状态值是数值数组。
在大多数情况下,您不需要更新代码。如果您的代码要求状态值是数值数组,要重现以前的行为,请使用 extractdata 函数和 dlupdate 函数手动从状态值中提取数据。
state = dlupdate(@extractdata,net.State);
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
选择网站
选择网站以获取翻译的可用内容,以及查看当地活动和优惠。根据您的位置,我们建议您选择:。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)