深度学习

理解和使用深度学习网络

高级深度学习:第一部分

建立任何深度学习网络
在接下来的几篇文章中,我希望大家都能走出自己的舒适区。我将探索和介绍更高级的深度学习主题。版本19b引入了许多令人兴奋的新功能,我一直在犹豫是否要尝试这些功能,因为人们开始抛出一些术语,比如自定义训练循环、自动区分(如果你真的知道的话,甚至是“autodiff”)。但我认为是时候深入探索新概念了,不仅要理解它们,还要理解在哪里以及为什么要使用它们。
除了深度学习的基础知识,还有很多东西需要消化,所以我决定创建一系列的帖子。你现在正在阅读的这篇文章将作为基础和关键术语的温和介绍,随后是一系列着眼于单个网络类型的文章(Autoencoders, Siamese网络,GANs和注意力机制)。
高级深度学习基础知识
首先,让我们从为什么:“为什么我要麻烦地使用扩展深度学习框架?”直到现在,我都还过得去。”首先,你得到一个灵活的训练结构,它允许你在MATLAB中创建任何网络。下一篇文章中介绍的更复杂的结构需要扩展框架来解决以下功能:
  • 多输入多输出
  • 自定义损失函数
  • 体重分享
  • 自动分化
  • 训练期间的特殊可视化
我将展示一个简单的深度学习示例,然后重写它以使用扩展框架,尽管它并不需要扩展框架。为什么?因为当遇到更复杂的例子时,我们已经知道它的结构和方法了。
让我们从一个我们都知道和喜欢的简单例子开始:MNIST。这个简单的手写示例有各种派生(就像我的看图说词的例子),并且很容易用最少的代码行实现。
基本MNIST示例
每个版本(简单框架和高级框架)的步骤都是相同的:
  1. 定义网络层
  2. 指定培训项目
  3. 列车网络的
你可以跟着文档中的完整示例,它对每行代码提供了更多的描述和解释。

加载数据

[XTrain,YTrain] = digitTrain4DArrayData;[XTest, YTest] = digitTest4DArrayData;类=类别(YTrain);numClasses = nummel(类);

1.定义网络层

创建一个网络,由一系列简单的层组成。
layers = [imageInputLayer([28 28 1]) convolution2dLayer(5,20,'Padding','same') batchNormalizationLayer reluLayer maxPooling2dLayer(2,'Stride',2) fullyConnectedLayer(10) softmaxLayer classificationLayer];

2.指定培训项目

options = trainingOptions('sgdm',…“InitialLearnRate”,0.01,…“MaxEpochs”4…“阴谋”,“训练进步”);
这些都是简单的训练选择,不一定能达到最好的效果。事实上,trainingOptions只需要设置优化器,其余可以使用默认值。

3.培训网络

net = trainNetwork(XTrain,YTrain,图层,选项);
很简单!现在让我们在扩展框架中做同样的事情。
扩展框架示例
同样的例子,只是使用了扩展框架,或者“DLNetwork”,我将在后面提到这种方法。这是代码的修改版本。要跟随完整的示例,完整的代码在医生的例子

加载数据

这是完全相同的,不需要显示重复的代码。
现在,我们可以展示简单方法和DLNetwork方法之间的差异:让我们并排比较以下每个步骤,以突出显示差异。

1.定义网络层

几乎同样的:我们只需要为每个层添加名称。这在简单框架中被显式地处理,但是我们需要做更多的准备工作。
层=[…]imageInputLayer([28 28 1], 'Name',' input','Mean', Mean (Xtrain,4)) convolution2dLayer(5,20,' Name',' conv1') reluLayer('Name', 'relu1') maxPooling2dLayer(2, 'Stride', 2, 'Name',' pool1') fullyConnectedLayer(10, 'Name',' fc') softmaxLayer('Name','softmax')];
注意在层中,不再有分类层了。这将在训练循环中处理,因为这是我们想要定制的。
然后将图层转换为layerGraph,这使它们在自定义训练循环中可用。另外,指定包含网络的dlnet结构。
lgraph = layerGraph(图层);Dlnet = dlnetwork(lgraph);
dlnetwork有层和连接(可以处理Series或DAG网络)等属性,也有存储“学习类”的地方。稍后再详细介绍。

2.指定培训项目

您将注意到显式定义了许多非可选参数:这些是您将在自定义训练循环中使用的参数。此外,我们不再有像基本框架中那样的漂亮的训练图的选择。
miniBatchSize = 128;numEpochs = 30;numObservations = numel(YTrain);numIterationsPerEpoch = floor(numObservations./miniBatchSize);initialLearnRate = 0.01;动量= 0.9;executionEnvironment = "auto";Vel = [];
现在您需要对自己的可视化负责,但这也意味着您可以在整个训练过程中创建自己的可视化,并根据自己的喜好进行定制,以显示关于网络的任何有助于理解网络训练的内容。 现在,让我们设置一个图来显示网络训练时的损失/错误。
情节=“训练进度”;if plots == "training-progress" figure lineLossTrain = animatedline;xlabel(“Total Iterations”)ylabel(“Loss”)结束

使用自定义训练循环训练网络

在进入训练循环之前,你需要了解的基本知识:
  • 一个时代是对整个数据集的一次迭代。因此,如果你有10个epoch,你将遍历所有文件10次。
  • 一个Mini-batch是数据集的较小块。数据集通常太大,无法同时容纳在内存或GPU上,因此我们批量处理数据。
因此,根据我们上面定义的参数,我们的自定义训练循环将在整个数据集中循环30次,由于我们的迷你批处理大小为128,而我们的图像总数为5000,因此将花费39次迭代来循环数据1次。
这是自定义训练循环的结构。完整的代码在医生的例子,我要提醒您的是,完整的脚本只有几行代码,但一旦您理解了整体结构,大部分代码都很简单。
for epoch = 1:numEpochs…for ii = 1:numIterationsPerEpoch% *设置:读取数据,转换为dlarray,传递给GPU...评估模型梯度和损失[gradients, loss] = dlfeval(@modelGradients, dlnet, dlX, Y);更新自定义学习速率learnRate = initialLearnRate/(1 +衰减*迭代);使用SGDM优化器更新网络参数[dlnet。Learnables, vel] = sgdmupdate(dlnet。Learnables, gradients, vel, learnRate, momentum);%更新训练图...结束结束
为了完整起见,您创建了这个函数modelGradients定义梯度和损失函数。更多细节将在下一篇文章中介绍。
function [gradients, loss] = modelGradients(dlnet, dlX, Y) dlYPred = forward(dlnet, dlX);loss = crossentropy(dlYPred, Y);gradients = dlgradient(loss, dlnet.Learnables);结束
在这个简单的例子中,是一个函数trainnetwork已扩展为一系列循环和代码。我们这样做是为了在网络需要的时候有更大的灵活性,当它过度使用时,我们可以恢复到更简单的方法。好消息是,这是非常复杂的:一旦您理解了这个结构,就需要将正确的信息放入其中!
对于那些想要可视化循环中发生的事情的人,我是这样看的:
根据上面可视化中突出显示的内容,您可能已经猜到了,本系列的下一篇文章将更详细地介绍循环的内部工作原理,以及了解损失、梯度、学习率和更新网络参数所发生的情况所需要了解的内容。
三种模型方法
要记住的最后一点是,当我使用扩展框架时DLNetwork方法,也有一个模型函数当您还希望控制初始化和显式定义网络权重和偏差时使用的方法。该示例还可以使用模型函数方法,您可以遵循此方法医生的例子了解更多。这种方法为您提供了3种方法中最好的控制,但也是最复杂的。
整个景观是这样的:
这篇文章到此结束。这是很多信息,但希望你能从中找到一些有用的东西。如果你有任何问题或澄清,请在下方留言!
|
  • 打印
  • 发送电子邮件

评论

如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。