主要内容

检测梯度消失在深神经网络通过绘制梯度分布

这个例子展示了如何监视梯度消失而训练神经网络。

深陷网络培训是一个常见问题消失的梯度。深度学习训练算法的目标是最小化损失通过调整网络的可学的参数在训练。Gradient-based训练算法确定的水平调整使用渐变的损失函数对当前可学的参数。早些时候层,梯度计算使用以前的传播梯度层。因此,当一个网络包含激活函数总是产生梯度值小于1,梯度可以越来越小的值随着更新算法对初始层。因此,早期层网络中可以得到一个梯度项都很小,因此,网络无法学习。然而,如果激活函数的梯度总是大于或等于1,梯度可以在网络中流动,减少梯度消失的机会。

这个例子火车两个网络与不同的激活函数和比较他们的梯度分布。

比较激活函数

为了说明激活函数的不同属性,比较两个常见的深度学习激活功能:ReLU和乙状结肠。

线性整流函数(Rectified Linear Unit) ( x ) = { x x 0 0 x < 0

乙状结肠 ( x ) = ( 1 + 经验值 ( - - - - - - x ) ) - - - - - - 1

评估ReLU和乙状结肠激活函数的梯度。

x = linspace (5 5 1000);reluActivation = max (0, x);reluGradient =梯度(reluActivation, 0.01);sigmoidActivation = 1。/ (1 + exp (- x));sigmoidGradient =梯度(sigmoidActivation, 0.01);

情节ReLU和乙状结肠激活函数及其梯度。

图tiledlayout (1、2) nexttile情节(x, [reluActivation; reluGradient])传说(“ReLU”,“ReLU梯度”)nexttile情节(x, [sigmoidActivation; sigmoidGradient])传说(“乙状结肠”,“乙状结肠的梯度”)

ReLU梯度要么是0或1的整个范围。因此,梯度越来越小,因为它backpropagates不通过网络,减少梯度消失的机会。乙状结肠梯度曲线为整个范围小于1。因此,网络包含乙状结肠活化层可以遭受梯度消失的问题。

加载数据

负载组成的样本数据5000合成图像的手写的数字和他们的标签使用digitTrain4DArrayData

[XTrain, TTrain] = digitTrain4DArrayData;numObservations =长度(TTrain);

自动调整训练图像,使用一个增强图像数据存储。

inputSize =[1] 28日28日;augimdsTrain = augmentedImageDatastore (inputSize (1:2), XTrain, TTrain);

确定训练数据的类的数量。

类=类别(TTrain);numClasses =元素个数(类);

定义网络

比较活化层的影响,构造两个网络。每个网络包含ReLU或乙状结肠活化层分离四个完全连接层。通过比较这两个网络的训练过程,你可以看到激活层在训练的影响。这些网络只用于演示目的。为一个例子,演示如何创建和训练一个简单的图像分类网络,看到的创建简单的深度学习网络分类

activationTypes = [“ReLU”,“乙状结肠”];numNetworks =长度(activationTypes);i = 1: numNetworks activationType = activationTypes(我);开关activationType情况下“ReLU”activationLayer = reluLayer;情况下“乙状结肠”activationLayer = sigmoidLayer;结束层= [imageInputLayer (inputSize正常化=“没有”)fullyConnectedLayer (10) activationLayer fullyConnectedLayer (10) activationLayer fullyConnectedLayer (10) activationLayer fullyConnectedLayer (numClasses) softmaxLayer];%的创建一个dlnetwork对象层。网络{我}= dlnetwork(层);结束

定义模型损失函数

创建函数modelLoss上市的例子,作为输入dlnetwork输入数据与相应的标签的对象和一个mini-batch并返回损失和损失的梯度对网络中可学的参数。

指定培训选项

火车50时代mini-batch大小为128。

numEpochs = 50;miniBatchSize = 128;

火车模型

比较两个网络,追踪损失和平均梯度每个网络的每一层。每个网络包含四个可学的层次。

numIterations = numEpochs *装天花板(numObservations / miniBatchSize);numLearnableLayers = 4;损失= 0 (numIterations numNetworks);meanGradients = 0 (numIterations numNetworks numLearnableLayers);

创建一个minibatchqueue对象流程和管理mini-batches图像在训练。为每个mini-batch:

  • 使用自定义mini-batch预处理功能preprocessMiniBatch,在这个例子中,定义标签转换为一个炎热的编码的变量。

  • 格式的图像数据维度标签“SSCB”(空间、空间、通道、批)。默认情况下,minibatchqueue把数据转换为对象dlarray对象与基本类型单一。不格式添加到类的标签。

  • 火车在GPU如果一个是可用的。默认情况下,minibatchqueue将每个输出转换为对象gpuArray如果一个GPU是可用的。使用GPU需要并行计算工具箱™和支持GPU设备。金宝app支持设备的信息,请参阅金宝appGPU计算的需求(并行计算工具箱)

兆贝可= minibatchqueue (augimdsTrain,MiniBatchSize = MiniBatchSize,MiniBatchFcn = @preprocessMiniBatch,MiniBatchFormat = [“SSCB”,”“]);

遍历每一个网络。为每个网络:

  • 找到权重的指标和权重层的名称。

  • 初始化块使用支持的重量分布函数金宝appsetupGradientDistributionAxes定义在这个例子。

  • 列车网络使用自定义训练循环。

每个时代的定制培训循环,洗牌和遍历mini-batches数据的数据。为每个mini-batch:

  • 评估损失和梯度模型使用dlfevalmodelLoss功能。

  • 更新网络参数使用adamupdate函数。

  • 保存每一层的平均坡度值在每个迭代。

在每个时代,情节梯度分布的权重可学的层使用支持功能金宝appplotGradientDistributions定义在这个例子。

activationIdx = 1: numNetworks activationName = activationTypes (activationIdx);网=网络{activationIdx};%的指标体重可学的。weightIdx = ismember (net.Learnables.Parameter,“重量”);%找到层重量的名称。weightLayerNames =加入([net.Learnables.Layer (weightIdx),net.Learnables.Parameter (weightIdx)]);%准备轴显示每个时代的重量分布使用支持函数setupG金宝appradientDistributionAxes %。plotSetup = setupGradientDistributionAxes (activationName weightLayerNames numEpochs);%初始化参数亚当训练算法。averageGrad = [];averageSqGrad = [];%列车网络使用自定义训练循环。迭代= 0;开始=抽搐;%重置minibatchqueue开始的数据。重置(兆贝可);%循环时期。时代= 1:numEpochs%洗牌数据。洗牌(兆贝可);%在mini-batches循环。hasdata(兆贝可)迭代=迭代+ 1;% mini-batch读取的数据。[X, T] =下一个(兆贝可);%计算模型和梯度使用dlfeval损失% modelLoss函数。(损失,梯度)= dlfeval (@modelLoss,净,X, T);%更新使用亚当优化网络参数。[净,averageGrad averageSqGrad] = adamupdate(净、渐变averageGrad averageSqGrad,迭代);%的记录在每一个迭代。损失(迭代,activationIdx) =损失;%记录每个可学的层的平均梯度在每个迭代。gradientValues = gradients.Value (weightIdx);2 = 1:numLearnableLayers meanGradients(迭代、activationIdx ii) =意味着(gradientValues {2},“所有”);结束结束%在每个时代,权重的梯度分布每个可学的层使用支持函数的%金宝app% plotGradientDistributions。gradientValues = gradients.Value (weightIdx);plotGradientDistributions (plotSetup gradientValues时代)结束结束

梯度分布的情节显示乙状结肠网络遭受的可能性微乎其微梯度。这种效应越来越明显的梯度回流通过网络向前面的层。

比较损失

比较训练网络的损失。

图绘制(损失)包含(“迭代”)ylabel (“损失”传奇(activationTypes)

乙状结肠网络的损失减少的损失低于ReLU网络。因此,对于这个模型,使用ReLU激活层导致更快的学习。

比较平均梯度

比较每一层的平均梯度在每个迭代训练。

图tiledlayout (“流”)2 = 1:numLearnableLayers nexttile情节(meanGradients(:,:,(二))包含(“迭代”)ylabel (“平均梯度”)标题(weightLayerNames (ii)传说(activationTypes)结束

平均梯度图是一致的结果的梯度分布的情节。与乙状结肠网络层,梯度值的范围非常小,集中在0。相比之下,网络与ReLU层更大范围的梯度,减少梯度和消失的机会增加学习的速度。

金宝app支持功能

损失函数模型

modelLoss函数作为输入dlnetwork对象和mini-batch输入数据X与相应的目标T包含标签,并返回损失和损失的梯度对可学的参数。

函数(损失,梯度)= modelLoss(净,X, T) Y =前进(净,X);损失= crossentropy (Y, T);梯度= dlgradient(损失、net.Learnables);结束

小批预处理功能

preprocessMiniBatch函数进行预处理的mini-batch预测和标签使用以下步骤:

  • 使用预处理的图像preprocessMiniBatchPredictors函数。

  • 从传入单元阵列提取标签数据和连接数据分类沿着二维数组。

  • 一个炎热的分类标签编码成数字数组。编码的第一个维度产生一个相匹配的形状编码阵列网络输出。

函数[X, T] = preprocessMiniBatch(伊势亚TCell)%预处理预测。X = preprocessMiniBatchPredictors(伊势亚);%从细胞中提取标签数据和连接。猫(T = 2, TCell{1:结束});%一个炎热的编码标签。T = onehotencode (T, 1);结束

Mini-Batch预测预处理功能

preprocessMiniBatchPredictors函数进行预处理mini-batch预测因子的提取图像数据从输入单元阵列连接成一个数字数组。灰度输入,连接在第四维度添加了一个三维图像使用作为一个单通道尺寸。

函数X = preprocessMiniBatchPredictors(伊势亚)%连接。猫(X = 4,伊势亚{1:结束});结束

计算分布

gradientDistributions函数计算直方图的值并返回本中心和直方图统计。

函数(中心、数)= gradientDistributions(值)%得到的直方图统计值。(计数,边缘)= histcounts(价值观、30);% histcounts返回箱子的边缘。本中心,%计算连续边缘的元素之间的中点。中心= (1:end-1) + diff边缘(边缘)/ 2;结束

创建图轴梯度分布

setupGradientDistributionAxes函数创建轴适合绘制3 d的梯度分布的阴谋。这个函数返回一个结构数组,其中包含一个TiledChartLayout对象和一个colormap作为输入plotGradientDistributions金宝app支持功能。

函数plotSetup = setupGradientDistributionAxes (activationName weightLayerNames numEpochs) f =图;t = tiledlayout (f,“流”TileSpacing =“紧”);t.Title。字符串=“梯度分布与“+ activationName +“层”;%,以避免更新相同的价值观每一个时代,建立轴%信息之前培训循环。i = 1:元素个数(weightLayerNames) tiledAx = nexttile (t,我);%设置标签名称和标题。包含(tiledAx“梯度”);ylabel (tiledAx“时代”);zlabel (tiledAx“计数”);标题(tiledAx weightLayerNames (i));%旋转视图。视图(tiledAx(-130年,50));xlim (tiledAx [-0.5, 0.5]);ylim (tiledAx[1,正]);结束plotSetup。ColorMap = parula (numEpochs);plotSetup。TiledLayout = t;结束

情节梯度分布

plotGradientDistributions函数作为输入一个结构数组包含TiledChartLayout对象和一个colormap和数组的值(例如,层梯度)在一个特定的时代,并在三维图平滑直方图。使用支持函数金宝appsetupGradientDistributionAxes生成一个合适的结构数组输入。

函数plotGradientDistributions (plotSetup gradientValues时代)w = 1:元素个数(gradientValues) nexttile (plotSetup.TiledLayout w)颜色= plotSetup.ColorMap(时代:);值= extractdata (gradientValues {w});%的中心和分布。(中心、数)= gradientDistributions(值);%绘制x轴上的梯度值,y轴上的时代,%计算z轴。边缘的颜色设置为白色,更容易区分%之间不同的直方图。持有(“上”);fill3(中心、零(大小(数量))+时代,数量,颜色,EdgeColor =“# D9D9D9”);持有(“关闭”)drawnow结束结束

另请参阅

|||

相关的话题