训练堆叠自编码器图像分类
这个例子展示了如何训练堆叠自编码器来分类数字图像。
具有多个隐藏层的神经网络可以用于解决具有复杂数据的分类问题,例如图像。每一层都可以在不同的抽象级别上学习特性。然而,训练具有多个隐藏层的神经网络在实践中可能很困难。
有效训练多层神经网络的一种方法是一次训练一层。您可以通过为每个所需的隐藏层训练一种称为自动编码器的特殊类型的网络来实现这一点。
这个例子向你展示了如何训练带有两个隐藏层的神经网络来分类图像中的数字。首先,使用自动编码器以无监督的方式单独训练隐藏层。然后训练一个最终的softmax层,并将这些层连接在一起形成一个堆叠的网络,以监督的方式最后一次训练这个网络。
数据集
本例自始至终使用合成数据进行训练和测试。合成图像是通过对使用不同字体创建的数字图像应用随机仿射变换生成的。
每个数字图像是28乘28像素,有5000个训练示例。您可以加载训练数据,并查看一些图像。
将训练数据装入内存[xTrainImages,tTrain] = digitTrainCellArrayData;显示一些训练图片clf为I = 1:20 subplot(4,5, I);imshow (xTrainImages{我});结束
图像的标签存储在一个10 × 5000的矩阵中,其中每列中有一个元素为1,表示该数字所属的类别,列中所有其他元素为0。需要注意的是,如果第10个元素是1,那么数字图像就是零。
训练第一个自动编码器
首先在训练数据上训练一个稀疏自动编码器,而不使用标签。
自动编码器是一种试图在输出时复制其输入的神经网络。因此,其输入的大小将与输出的大小相同。当隐藏层中的神经元数量小于输入的大小时,自动编码器学习输入的压缩表示。
神经网络在训练前随机初始化权重。因此,每次训练的结果都不一样。要避免这种行为,请显式地设置随机数生成器种子。
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 = encode(autoenc1,xTrainImages);
训练第二个自动编码器
在训练了第一个自动编码器之后,以类似的方式训练第二个自动编码器。主要的区别是,您使用从第一个自动编码器生成的特征作为第二个自动编码器的训练数据。此外,您还将隐藏表示的大小减小到50,以便第二个自动编码器中的编码器学习到输入数据的更小表示。
hiddenSize2 = 50;autoenc2 = trainAutoencoder(feat1,hiddenSize2,...“MaxEpochs”, 100,...“L2WeightRegularization”, 0.002,...“SparsityRegularization”4...“SparsityProportion”, 0.1,...“ScaleData”、假);
属性可以再次查看自动编码器的图表视图
函数。
视图(autoenc2)
您可以通过将前一组特征从第二个自动编码器传递给编码器来提取第二组特征。
Feat2 = encode(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层一起堆叠,以形成用于分类的堆叠网络。
stackkednet = stack(autoenc1,autoenc2,softnet);
命令可以查看堆叠网络示意图视图
函数。该网络由自编码器和软最大层编码器组成。
视图(stackednet)
形成完整的网络后,您可以在测试集中计算结果。要使用带有堆叠网络的图像,必须将测试图像重新塑造成一个矩阵。你可以这样做:将图像的列堆叠起来形成一个向量,然后用这些向量形成一个矩阵。
获取每个图像中的像素数imageWidth = 28;imageHeight = 28;inputSize = imageWidth*imageHeight;加载测试映像[xTestImages,tTest] = digitTestCellArrayData;将测试图像转换为向量,并将它们放入一个矩阵中。xTest = 0 (inputSize,numel(xTestImages));为i = 1:numel(xTestImages) xTest(:,i) = xTestImages{i}(:);结束
你可以用混淆矩阵将结果可视化。矩阵右下角的数字给出了整体精度。
y = stackednet(xTest);plotconfusion (tt, y);
对堆叠神经网络进行微调
通过对整个多层网络进行反向传播,可以改善堆叠神经网络的结果。这个过程通常被称为微调。
你可以通过以一种有监督的方式在训练数据上重新训练网络来微调网络。在此之前,您必须将训练图像重塑为一个矩阵,就像对测试图像所做的那样。
将训练图像转换成向量,并将它们放入一个矩阵中。xTrain = 0 (inputSize,numel(xTrainImages));为i = 1:numel(xTrainImages) xTrain(:,i) = xTrainImages{i}(:);结束%执行微调stackednet = train(stackednet,xTrain,tTrain);
然后使用混淆矩阵再次查看结果。
y = stackednet(xTest);plotconfusion (tt, y);
总结
这个例子展示了如何训练一个堆叠的神经网络来使用自编码器对图像中的数字进行分类。上面介绍的步骤也可以应用到其他类似的问题上,比如对字母图像进行分类,甚至对特定类别的物体的小图像进行分类。