你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用反卷积和取消池的图像自动编码器

目录

总结

image

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 测试集的前五张图像的原始图像和解码图像的可视化效果。

image

反卷积和取消池

让我们仔细查看 MaxUnpoolingLayer 和 DeconvLayer。

MaxUnpoolingLayer {(4:4), stride=(4:4)}(pool1, conv1)

MaxPoolingLayer 需要两个输入,即本例中相应的池层 (pool1 的输出,在本例中) 和相应池层 (conv1 的输入) 。 conv1CNTK需要确定取消池操作的目标,因为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.pool1z.pool_B07_Deconvolution_Visualizer.py 结果,以解决编码器输出的正确节点名称。 若要调查模型中的所有节点名称,只需在 Python 脚本中取消注释 print_all_node_names(model_file)