你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
使用反卷积和取消池的图像自动编码器
目录
总结
Image\GettingStarted\07_Deconvolution_PY.py 示例演示如何使用解码和取消池生成简单的图像自动编码器 (07_Deconvolution_BS.cntk 是相应的 BrainScript 版本) 。 它使用具有分辨率为 28x28x1 的 MNIST 数据集,使用卷积和池化并将其解码为原始分辨率,将其编码为 7x7x1 表示形式。 训练条件是根平均平方误差 (RMSE) 。 上图显示了原始图像、编码图像和 MNIST 测试集前五个图像的解码图像的可视化效果。
设置
若要运行示例,需要 MNIST 数据集。 可以通过从 Examples\Image\DataSets\MNIST
文件夹中运行以下命令来获取数据:
python install_mnist.py
运行示例
该示例位于 Examples\Image\GettingStarted
文件夹中。 若要运行此示例,请使用以下命令从 Python CNTK 环境运行 Python 版本 () :
python 07_Deconvolution_PY.py
或适用于 BrainScript 版本的此命令:
cntk configFile=07_Deconvolution_BS.cntk
用于训练和测试的 RMSE 值分别为 0.225 和 0.223。 若要可视化编码和解码的图像,请运行以下命令:
python 07_Deconvolution_Visualizer.py
为 BrainScript 模型和 False
Python 模型设置use_brain_script_model=True
。
可视化效果将存储在 Output
文件夹下 Examples\Image\GettingStarted
,以及编码器的文本表示形式和解码器输出。
技术详细信息
下面是用于完整配置文件的 BrainScript 中简单图像自动编码器的模型定义 (,请参阅 Image\GettingStarted\07_Deconvolution_BS.cntk)
cMap = 1
model = inputFeatures => {
conv1 = ConvolutionalLayer {cMap, (5:5), pad = true, activation=ReLU}(inputFeatures)
pool1 = MaxPoolingLayer {(4:4), stride=(4:4)}(conv1)
unpool1 = MaxUnpoolingLayer {(4:4), stride=(4:4)}(pool1, conv1)
deconv1 = DeconvLayer {1, (5:5), cMap, lowerPad=(2:2:0), upperPad=(2:2:0), bias=false}(unpool1)
}.deconv1
07_Deconvolution_PY.py 中的相应模型定义为
cMap = 1
conv1 = cntk.layers.Convolution ((5,5), cMap, pad=True, activation=cntk.ops.relu)(scaled_input)
pool1 = cntk.layers.MaxPooling ((4,4), (4,4))(conv1)
unpool1 = cntk.layers.MaxUnpooling ((4,4), (4,4))(pool1, conv1)
z = cntk.layers.Deconvolution((5,5), num_channels, cMap, lower_pad=(0,2,2), upper_pad=(0,2,2), bias=False, init=cntk.glorot_uniform(0.001))(unpool1)
我们在此处介绍 BrainScript 版本,Python 版本是类似的。 该模型首先应用一个 ConvolutionalLayer,其深度 cMap=1
适用于输入功能,后跟 ReLU 激活,并使用 MaxPoolingLayer 和筛选器形状和步幅 (4:4)
。 这会导致大小的 7x7x1
编码张量。 然后,它使用 MaxUnpoolingLayer 和具有相应筛选器形状的 DeconvLayer 将其解码回原始分辨率。
解码器部分将原始 784
(28x28) 数字压缩为 49
(7x7) ,这是一个因素 16
。 仅对 ConvolutionalLayer 使用深度 1
的优点是,编码器结果可以通过有意义的方式可视化, (看到此页面顶部的图表) 。 一个可以增加卷积筛选器的数量,例如 cMap=3
,要减少压缩,并希望更好的解码结果。 在此示例中,用于训练和测试的 RMSE 减少到 0.196
。 减少压缩的另一种方法是对池层使用更小的筛选器形状和步幅。 使用 (2:2)
池和取消池生成编码的张量, 14x14x1
并将此示例中的 RMSE 减少为 0.136
训练和 0.131
测试。 下图显示了三个讨论设置中 MNIST 测试集的前五张图像的原始图像和解码图像的可视化效果。
反卷积和取消池
让我们仔细查看 MaxUnpoolingLayer 和 DeconvLayer。
MaxUnpoolingLayer {(4:4), stride=(4:4)}(pool1, conv1)
MaxPoolingLayer 需要两个输入,即本例中相应的池层 (pool1
的输出,在本例中) 和相应池层 (conv1
的输入) 。 conv1
CNTK需要确定取消池操作的目标,因为CNTK不存储所谓的开关变量, (在此处查看详细信息) 。
DeconvLayer {1, (5:5), cMap, lowerPad=(2:2:0), upperPad=(2:2:0)}
DeconvLayer 的第一个参数是输出卷的深度,第二个参数是内核形状 (width:height) ,第三个是输入卷的深度。 必须根据内核形状设置填充参数,才能实现输出张量 (28x28 的所需宽度和高度,在本例中) 。 有关 DeconvLayer 的更多详细信息,请参阅 “层参考”页。
多层自动编码器
可以为更复杂的自动编码器堆叠更多的 Conv/Deconv 和 Pool/Unpool 层。 下面是一个示例,其中包含可在 (中使用的 07_Deconvolution_BS.cntk
每种类型的两个层,只需替换文件) 中的模型:
inputDim = 1
cMap1 = 5
cMap2 = 1
model = inputFeatures => {
conv_A = ConvolutionalLayer {cMap1, (5:5), pad = true, activation=ReLU}(inputFeatures)
pool_A = MaxPoolingLayer {(2:2), stride=(2:2)}(conv_A)
conv_B = ConvolutionalLayer {cMap2, (5:5), pad = true, activation=ReLU}(pool_A)
pool_B = MaxPoolingLayer {(2:2), stride=(2:2)}(conv_B)
unpool_B = MaxUnpoolingLayer {(2:2), stride=(2:2)}(pool_B, conv_B)
deconv_B = DeconvLayer {cMap1, (5:5), cMap2, lowerPad=(2:2:0), upperPad=(2:2:0)}(unpool_B)
unpool_A = MaxUnpoolingLayer {(2:2), stride=(2:2)}(deconv_B, conv_A)
deconv_A = DeconvLayer {inputDim, (5:5), cMap1, lowerPad=(2:2:0), upperPad=(2:2:0)}(unpool_A)
}.deconv_A
若要可视化需要在运行结果之前替换 z.pool1
z.pool_B
07_Deconvolution_Visualizer.py
结果,以解决编码器输出的正确节点名称。 若要调查模型中的所有节点名称,只需在 Python 脚本中取消注释 print_all_node_names(model_file)
。