次の方法で共有


デコンボリューションとアンプールを使用したイメージ オート エンコーダー

目次

まとめ

image

Image\GettingStarted\07_Deconvolution_PY.py の例は、Deconvolution と Unpooling を使用して単純なイメージ自動エンコーダーを生成する方法を示しています (07_Deconvolution_BS.cntk は対応する BrainScript バージョンです)。 これは、28x28x1 の解像度を持つ MNIST データセットを使用し、畳み込みとプーリングを使用して 7x7x1 表現にエンコードし、元の解像度にデコードします。 トレーニング基準は、ルート平均 2 乗誤差 (RMSE) です。 上の図は、MNIST テスト セットの最初の 5 つの画像に対する元のイメージ、エンコードされたイメージ、デコードされたイメージの視覚化を示しています。

セットアップ

この例を実行するには、MNIST データ セットが必要です。 フォルダーから次のコマンドを実行すると、データを Examples\Image\DataSets\MNIST 取得できます。

python install_mnist.py

例を実行する

この例はフォルダーにあります Examples\Image\GettingStarted 。 この例を実行するには、次のコマンドを使用して Python バージョンを実行します (Python CNTK環境から)。

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 のバージョンは似ています。 このモデルでは、最初に入力フィーチャに深さを cMap=1 持つ ConvolutionalLayer を適用し、続いて ReLU アクティブ化を行い、フィルターの形状とストライド (4:4)を持つ MaxPoolingLayer を使用します。 これにより、エンコードされたサイズ 7x7x1のテンソルが発生します。 次に、MaxUnpoolingLayer と DeconvLayer と対応するフィルター図形を使用して、元の解像度にデコードします。

デコーダー部分は、元 784 の(28x28)数値を 49 (7x7) 16に圧縮します。 ConvolutionalLayer の深度 1 のみを使用すると、エンコーダーの結果を意味のある方法で視覚化できるという利点があります (このページの上部にある図を参照)。 畳み込みフィルターの数を増やすことができます。たとえば cMap=3 、圧縮を減らし、できればデコード結果を向上させることができます。 この例では、トレーニングとテストの両方の RMSE が次の値に 0.196減らされます。 圧縮を減らすもう 1 つの方法は、プーリング レイヤーに小さいフィルター図形とストライドを使用することです。 プールとプール解除の両方に使用 (2:2) すると、エンコードされたサイズ 14x14x1 のテンソルが生成され、この例 0.136 の RMSE はトレーニングと 0.131 テストに縮小されます。 次の図は、3 つの設定について説明した MNIST テスト セットの最初の 5 つのイメージの元の画像とデコードされたイメージの視覚化を示しています。

image

デコンボリューションとアンプール

MaxUnpoolingLayer と DeconvLayer を少し詳しく見てみましょう。

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

MaxPoolingLayer には 2 つの入力が必要です。これは、対応するプーリング レイヤー (pool1 この場合) の出力と、対応するプーリング レイヤー (conv1 この場合) の入力です。 conv1CNTKはスイッチ変数と呼ばれる変数を格納しないため、CNTKではプール解除操作のターゲットを決定する必要があります (詳細については、こちらを参照してください)。

DeconvLayer {1, (5:5), cMap, lowerPad=(2:2:0), upperPad=(2:2:0)}

DeconvLayer の最初のパラメーターは出力ボリュームの深さ、2 つ目はカーネルシェイプ (width:height) で、3 つ目は入力ボリュームの深さです。 パディングパラメータは、出力テンソルの所望の幅と高さを達成するためにカーネル形状に従って設定する必要があります(この場合は28x28)。 DeconvLayer の詳細については、「 レイヤーリファレンス」ページを参照してください。

多層自動エンコーダー

より複雑な自動エンコーダーのために、Conv/Deconv と Pool/Unpool のレイヤーをさらに積み重ねることができます。 次の例は、使用できる各種類の 2 つのレイヤーを含む例です (ファイル内の 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

結果を視覚化するには、エンコーダー出力の07_Deconvolution_Visualizer.py正しいノード名に対処するために、実行する前に置き換えるz.pool1z.pool_B必要があります。 モデル内のすべてのノード名を調査するには、Python スクリプトでコメント print_all_node_names(model_file) を解除するだけです。