训练用于图像分类的堆栈自动编码器
这个例子展示了如何训练堆栈自动编码器对数字图像进行分类。
具有多个隐含层的神经网络可用于解决具有复杂数据(如图像)的分类问题。每个层都可以在不同的抽象级别学习特性。然而,训练具有多个隐含层的神经网络在实践中是很困难的。
有效训练多层神经网络的一种方法是一次训练一层。您可以通过为每个所需的隐藏层训练一种称为自动编码器的特殊类型的网络来实现这一点。
这个例子向您展示了如何训练具有两个隐藏层的神经网络来对图像中的数字进行分类。首先,使用自动编码器以无监督的方式单独训练隐藏层。然后训练最后一个softmax层,并将这些层连接在一起形成一个堆叠网络,最后以有监督的方式训练该网络。
数据集
本示例自始至终使用合成数据进行培训和测试。合成图像是通过对使用不同字体的数字图像进行随机仿射变换而生成的。
每个数字图像都是28 × 28像素,有5000个训练示例。您可以加载训练数据,并查看一些图像。
将训练数据加载到内存中[xTrainImages, tTrain] = digitTrainCellArrayData;显示一些训练图像clf为I = 1:20 subplot(4,5, I);imshow (xTrainImages{我});结束
图像的标签存储在一个10 × 5000的矩阵中,其中每一列中的一个元素都是1,表示数字所属的类别,而列中的所有其他元素都是0。需要注意的是,如果第10个元素是1,那么数字图像就是0。
训练第一个自动编码器
首先在训练数据上训练稀疏自动编码器,而不使用标签。
自动编码器是一种试图在输出处复制输入的神经网络。因此,其输入的大小将与输出的大小相同。当隐层中的神经元数量小于输入的大小时,自动编码器学习输入的压缩表示。
神经网络在训练前有随机初始化的权重。因此,每次训练的结果都是不同的。要避免这种行为,请显式设置随机数生成器种子。
rng (“默认”)
设置自动编码器隐藏层的大小。对于你要训练的自动编码器来说,让它小于输入大小是个好主意。
hiddenSize1 = 100;
您要训练的自动编码器类型是稀疏自动编码器。该自动编码器使用正则化器学习第一层的稀疏表示。您可以通过设置各种参数来控制这些正则化器的影响:
L2WeightRegularization
控制L2正则化器对网络权值(而不是偏差)的影响。这通常应该非常小。SparsityRegularization
控制稀疏性正则化器的影响,该正则化器试图对来自隐藏层的输出的稀疏性强制实施约束。注意,这与将稀疏性正则化应用于权值不同。SparsityProportion
是稀疏正则化器的一个参数。它控制隐藏层输出的稀疏性。的低值SparsityProportion
通常导致隐层中的每个神经元“专门化”,只对少量的训练样例给出高输出。例如,如果SparsityProportion
设为0.1,这相当于说隐含层中的每个神经元在训练示例中应该有0.1的平均输出。该值必须在0到1之间。理想值因问题的性质而异。
现在训练自动编码器,指定上面描述的正则化器的值。
autoenc1 = trainAutoencoder (xTrainImages hiddenSize1,...“MaxEpochs”, 400,...“L2WeightRegularization”, 0.004,...“SparsityRegularization”4...“SparsityProportion”, 0.15,...“ScaleData”、假);
您可以查看自动编码器的示意图。自动编码器由一个编码器和一个解码器组成。编码器将一个输入映射到一个隐藏的表示,而解码器试图反转这个映射来重构原始输入。
视图(autoenc1)
可视化第一个自动编码器的权重
自动编码器的编码器部分学习到的映射对于从数据中提取特征是有用的。编码器中的每个神经元都有一个与之相关的权重向量,该权重向量将根据特定的视觉特征进行调整。您可以查看这些特性的表示形式。
图()plotWeights (autoenc1);
您可以看到,自动编码器学习的特征代表了数字图像的卷曲和笔画模式。
来自自动编码器隐藏层的100维输出是输入的压缩版本,它总结了对上述可视化特征的响应。用从训练数据中提取的这些向量集合训练下一个自动编码器。首先,您必须使用经过训练的自动编码器中的编码器来生成特征。
feat1 =编码(autoenc1 xTrainImages);
训练第二个自动编码器
在训练第一个自动编码器之后,以类似的方式训练第二个自动编码器。主要的区别是使用从第一个自动编码器生成的特征作为第二个自动编码器的训练数据。另外,将隐藏表示的大小减少到50,以便第二个自动编码器中的编码器学习输入数据的更小表示。
hiddenSize2 = 50;autoenc2 = trainAutoencoder (feat1 hiddenSize2,...“MaxEpochs”, 100,...“L2WeightRegularization”, 0.002,...“SparsityRegularization”4...“SparsityProportion”, 0.1,...“ScaleData”、假);
函数可以再次查看自动编码器的图表视图
函数。
视图(autoenc2)
通过将前一组特征从第二个自动编码器传递到编码器,您可以提取第二组特征。
feat2 =编码(autoenc2 feat1);
训练数据中的原始向量有784维。在通过第一个编码器后,这被减少到100维。在使用第二个编码器后,这再次减少到50个维度。现在可以训练最后一层将这些50维向量分类为不同的数字类。
训练最后的softmax层
训练一个softmax层对50维特征向量进行分类。与自动编码器不同的是,使用训练数据的标签以有监督的方式训练softmax层。
softnet = trainSoftmaxLayer (feat2 tTrain,“MaxEpochs”, 400);
可以查看softmax层的图视图
函数。
视图(softnet)
形成一个堆叠的神经网络
你已经分别训练了一个堆叠神经网络的三个独立组件。在这一点上,看看你已经训练过的三个神经网络可能是有用的。他们是autoenc1
,autoenc2
,softnet
.
视图(autoenc1)
视图(autoenc2)
视图(softnet)
如前所述,自动编码器中的编码器已用于提取特征。您可以将自动编码器中的编码器与softmax层堆叠在一起,以形成一个堆叠网络进行分类。
stackednet =堆栈(autoenc1 autoenc2 softnet);
可以查看堆叠网络的示意图视图
函数。该网络由来自自动编码器和softmax层的编码器组成。
视图(stackednet)
形成完整的网络后,您可以在测试集中计算结果。要使用带有堆叠网络的图像,必须将测试图像重塑为一个矩阵。你可以把图像的列叠加成一个向量,然后用这些向量形成一个矩阵。
获取每个图像的像素数imageWidth = 28;imageHeight = 28;inputSize = imageWidth * imageHeight;加载测试图像(xTestImages, tt) = digitTestCellArrayData;将测试图像转换为向量,并将它们放入一个矩阵中xTest = 0 (inputSize元素个数(xTestImages));为i = 1:numel(xTestImages) xTest(:,i) = xTestImages{i}(:);结束
你可以用混淆矩阵将结果可视化。矩阵右下方框中的数字给出了总体精度。
y = stackednet (xTest);plotconfusion (tt, y);
对堆叠神经网络进行微调
通过对整个多层网络进行反向传播,可以改善堆叠神经网络的结果。这个过程通常被称为微调。
通过以一种有监督的方式对训练数据进行再训练,对网络进行微调。在您可以这样做之前,您必须将训练图像重塑为一个矩阵,就像对测试图像所做的那样。
将训练图像转化为向量,并放入矩阵中。xTrain = 0 (inputSize元素个数(xTrainImages));为i = 1:numel(xTrainImages) xTrain(:,i) = xTrainImages{i}(:);结束%执行微调stackednet =火车(stackednet xTrain tTrain);
然后使用混淆矩阵再次查看结果。
y = stackednet (xTest);plotconfusion (tt, y);
总结
这个例子展示了如何训练一个堆叠神经网络来使用自动编码器对图像中的数字进行分类。上述步骤可以应用于其他类似的问题,例如对字母图像进行分类,甚至对特定类别的物体的小图像进行分类。