デコンボリューション層とは何ですか?


188

私は最近、ジョナサン・ロング、エヴァン・シェルハマー、トレバー・ダレルによるセマンティックセグメンテーションのための完全畳み込みネットワークを読みました。「デコンボリューション層」が何をするのか、どのように機能するのかがわかりません。

関連する部分は

3.3。アップサンプリングは逆方向のたたみ込み畳み込みです

粗い出力を密なピクセルに接続する別の方法は、補間です。たとえば、単純な双線形補間は、入力セルと出力セルの相対位置のみに依存する線形マップによって、最も近い4つの入力から各出力計算yijします。
ある意味では、係数アップサンプリングfは、1 / fの分数入力ストライドによる畳み込みです。したがって、fが整数である限り、アップサンプリングの自然な方法は、出力ストライドを使用した逆畳み込み(逆畳み込みとも呼ばれます) fです。このような操作は、畳み込みの前後のパスを単純に逆にするため、実装するのは簡単です。
したがって、ピクセル単位の損失からのバックプロパゲーションによるエンドツーエンド学習のために、ネットワーク内でアップサンプリングが実行されます。
そのようなレイヤーのデコンボリューションフィルターは固定する必要はありませんが(たとえば、バイリニアアップサンプリングに)、学習することができます。デコンボリューションレイヤーとアクティベーション関数のスタックは、非線形アップサンプリングを学習することさえできます。
私たちの実験では、ネットワーク内のアップサンプリングは、密な予測を学習するために高速で効果的であることがわかりました。最適なセグメンテーションアーキテクチャは、これらのレイヤーを使用して、セクション4.2の洗練された予測のアップサンプリングを学習します。

たたみ込み層がどのようにトレーニングされるかを本当に理解していないと思います。

私が理解したと思うのは、カーネルサイズ畳み込み層がサイズk × kのフィルターを学習するということです。畳み込みカーネルサイズを有する層の出力K、ストライドS NNフィルタは、ディメンションである入力DIMkk×kksNn。ただし、畳み込み層の学習がどのように機能するかはわかりません。(単純なMLPが勾配降下で学習する方法を理解します(それが役立つ場合))。Input dims2n

したがって、畳み込み層の私の理解が正しい場合、これをどのように逆にすることができるのか分かりません。

誰かがデコンボリューション層を理解するのを助けてくれますか?


3
このビデオ講義では、デコンボリューション/アップサンプリングについて説明します:youtu.be/ByjaPdWXKJ4
t

6
TensorFlow(0.11)で畳み込みと転置畳み込みをどのように使用できるかを調べるノートを作成しました。実用的な例と図があれば、それらがどのように機能するかを理解するのにもう少し役立つかもしれません。
AkiRoss

1
私にとっては、このページは私に、それはまた、デコンボリューションの違いを説明し、畳み込みを移調より良い説明を与えた:towardsdatascience.com/...
T.Antoni

パラメータがないため、アップサンプリングは後方ストライド畳み込みよりも後方プーリングのようではありませんか?
ケン

注:「デコンボリューションレイヤー」という名前は、このレイヤーがデコンボリューションを実行しないため、誤解を招きます。
user76284

回答:


210

デコンボリューション層は非常に残念な名前であり、むしろ転置畳み込み層と呼ばれるべきです。

視覚的に、ストライド1でパディングなしの転置畳み込みの場合、元の入力(青のエントリ)にゼロ(白のエントリ)をパディングするだけです(図1)。

図1

ストライド2とパディングの場合、転置畳み込みは次のようになります(図2)。

図2

ここで、畳み込み算術のより多くの(素晴らしい)視覚化を見つけることができます。


16
「デコンボリューション」は畳み込みとほとんど同じですが、パディングを追加しますか?(画像の周り/ s> 1のときも各ピクセルの周り)?
マーティントーマ

17
はい、デコンボリューション層は畳み込みも実行します!それが、転置畳み込みが名前とデコンボリューションという用語が実際に誤解を招くほど優れている理由です。
デヴィッド・ダオ

11
実際に入力にゼロが埋め込まれている場合、図1で「パディングなし」と言うのはなぜですか?
Stas S

8
ところで:それはTensorFlowになりました畳み込みを転置と呼ばれている:tensorflow.org/versions/r0.10/api_docs/python/...
マーティン・トーマ

9
この非常に直感的な答えに感謝しますが、2番目のケースが「ストライド2」のケースである理由について混乱しています。
デモンエッジ

49

畳み込みの背後にある本当に基本的なレベルの直感を得る1つの方法は、入力画像上でKステンシルと考えることができるKフィルターをスライドさせ、K活性化を生成することだと思います-それぞれが特定のステンシルとの一致度を表します。その逆の操作は、K個のアクティベーションを取得し、それらを畳み込み操作のプリイメージに展開することです。したがって、逆操作の直感的な説明は、大まかに言えば、ステンシル(フィルター)とアクティベーション(各ステンシルの一致度)が与えられた画像の再構成であるため、基本的な直感的なレベルでは、ステンシルのマスクによって各アクティベーションを爆破する必要がありますそれらを合計します。

deconvを理解するためのもう1つの方法は、Caffeのデコンボリューションレイヤーの実装を調べることです。以下の関連するコードを参照してください。

DeconvolutionLayer<Dtype>::Forward_gpu
ConvolutionLayer<Dtype>::Backward_gpu
CuDNNConvolutionLayer<Dtype>::Backward_gpu
BaseConvolutionLayer<Dtype>::backward_cpu_gemm

Caffeで通常の前方畳み込み層のbackpropとして正確に実装されていることがわかります(私にとっては、cuDNN conv層でのbackpropの実装とGEMMを使用して実装されたConvolutionLayer :: Backward_gpuを比較した後、より明確になりました)。したがって、通常の畳み込みで逆伝播がどのように行われるかを理解すれば、機械的計算レベルで何が起こるかを理解できます。この計算が機能する方法は、この文言の最初の段落で説明した直感と一致します。

ただし、畳み込み層の学習がどのように機能するかはわかりません。(単純なMLPが勾配降下で学習する方法を理解します(それが役立つ場合))。

最初の質問内の他の質問に答えるために、MLPバックプロパゲーション(完全に接続された層)と畳み込みネットには2つの主な違いがあります。

1)重みの影響は局所化されているので、最初に入力画像の小さな3x3領域と畳み込まれた3x3フィルターをバックプロップする方法を見つけ、結果画像の単一ポイントにマッピングします。

2)畳み込みフィルターの重みは、空間不変性のために共有されます。これが実際に意味することは、フォワードパスでは、同じ重みを持つ同じ3x3フィルターが、フォワード計算のために同じ重みを持つ画像全体にドラッグされ、出力画像(その特定のフィルター)が生成されることです。これがバックプロップにとって意味することは、ソースパス内の各ポイントのバックプロップグラデーションが、フォワードパス中にそのフィルターをドラッグした範囲全体で合計されるということです。dLoss / dxを逆伝播する必要があるため、損失wrt x、w、バイアスのさまざまな勾配もあり、dLoss / dwは重みを更新する方法です。wとbiasは計算DAGの独立した入力であるため(事前入力はありません)、それらの逆伝播を行う必要はありません。

(my notation here assumes that convolution is y = x*w+b where '*' is the convolution operation)

7
これがこの質問に対する最良の答えだと思います。
kli_nlpr 16

8
これが最良の答えであることに同意します。一番上の答えにはかなりのアニメーションがありますが、この答えを読むまで、それらは私に任意のパディングを加えた通常の畳み込みのように見えました。ああ、人々はどのように目の保養に左右されます。
中野Re二

1
同意し、受け入れられた答えは何も説明しませんでした。これははるかに優れています。
-BjornW

すばらしい説明をありがとう。現在、バックプロップを適切に行う方法がわかりません。そのヒントを教えてください。
バスティアン

33

転置畳み込みが3x3フィルターと2のストライドで2xアップサンプリングを行う方法を説明するステップごとの数学

ここに画像の説明を入力してください

数学を検証するための最も単純なTensorFlowスニペット:

import tensorflow as tf
import numpy as np

def test_conv2d_transpose():
    # input batch shape = (1, 2, 2, 1) -> (batch_size, height, width, channels) - 2x2x1 image in batch of 1
    x = tf.constant(np.array([[
        [[1], [2]], 
        [[3], [4]]
    ]]), tf.float32)

    # shape = (3, 3, 1, 1) -> (height, width, input_channels, output_channels) - 3x3x1 filter
    f = tf.constant(np.array([
        [[[1]], [[1]], [[1]]], 
        [[[1]], [[1]], [[1]]], 
        [[[1]], [[1]], [[1]]]
    ]), tf.float32)

    conv = tf.nn.conv2d_transpose(x, f, output_shape=(1, 4, 4, 1), strides=[1, 2, 2, 1], padding='SAME')

    with tf.Session() as session:
        result = session.run(conv)

    assert (np.array([[
        [[1.0], [1.0],  [3.0], [2.0]],
        [[1.0], [1.0],  [3.0], [2.0]],
        [[4.0], [4.0], [10.0], [6.0]],
        [[3.0], [3.0],  [7.0], [4.0]]]]) == result).all()

ここで計算が間違っていると思います。中間出力は3+ 2 * 2 = 7である必要があり、3x3カーネルの場合、最終出力は7-3 + 1 = 5x5である必要があります
Alex

@Alex、申し訳ありませんが、中間出力が7である理由を理解できません。詳しく説明してください。
-andriys

2
@andriys表示した画像で、最終結果がトリミングされるのはなぜですか?
ジェームズボンド

28

スタンフォードCSクラスCS231nを伴うノート視覚認識のための畳み込みニューラルネットワーク、アンドレイKarpathyによって、畳み込みニューラルネットワークを説明するの優れた仕事をします。

このホワイトペーパーを読むと、次のような大まかなアイデアが得られます。

これらのスライドは、デコンボリューショナルネットワークに最適です。


29
それらのリンクのいずれかのコンテンツを短いパラグラフで要約することは可能ですか?リンクはさらなる調査に役立つかもしれませんが、理想的には、スタック交換の回答には、サイトを離れることなく基本的な質問に対処するのに十分なテキストが含まれている必要があります。
ニールスレーター

申し訳ありませんが、これらのページの内容は大きすぎて短い段落に要約できません。
アズラエル

12
完全な要約は必要ではなく、見出しだけです。たとえば、「デコンボリューショナルニューラルネットワークはCNNに似ていますが、任意の隠れ層の機能を使用して前の層を再構築できるように訓練されます入力を出力から再構築できます。これにより、問題のあるドメインで一般的な高レベルの機能を学習するために、教師なしでトレーニングすることができます-通常は画像処理」(注:自分の答え)。
ニールスレーター

6
リンクは良好ですが、自分の言葉でモデルの簡単な要約をした方が良いでしょう。
SmallChess

11

このトピックに関するtheaonのWebサイトから素晴らしい記事を見つけました[1]:

転置畳み込みの必要性は、通常、通常の畳み込みとは逆方向の変換を使用して、フィーチャマップをより高次元の空間に投影するという要望から生じます。[...]つまり、畳み込みの接続パターンを維持しながら、4次元空間から16次元空間にマップします。

転置畳み込み -分数ストライド畳み込みとも呼ばれる-は、畳み込みの前後のパスを入れ替えることで機能します。カーネルが畳み込みを定義することに注意するのが1つの方法ですが、それが直接畳み込みであるか転置畳み込みであるかは、フォワードパスとバックワードパスの計算方法によって決まります。

転置畳み込み演算は、入力に対する畳み込みの勾配と考えることができます。これは通常、転置畳み込みが実際にどのように実装されるかです。

最後に、直接畳み込みで転置畳み込みを実装することが常に可能であることに注意してください。欠点は、通常、入力に多くのゼロの列と行を追加する必要があるため、実装の効率が大幅に低下することです。

簡単に言えば、「転置畳み込み」は行列を使用した数学的演算(畳み込みと同様)ですが、畳み込み値から元の(反対方向)に戻る場合の通常の畳み込み演算よりも効率的です。これが、実装で逆方向を計算するときに畳み込みが好ましい理由です(つまり、入力のパディングに起因するスパース行列に起因する多くの不要な0乗算を回避するため)。

Image ---> convolution ---> Result

Result ---> transposed convolution ---> "originalish Image"

たまに、畳み込みパスに沿っていくつかの値を保存し、「戻る」ときにその情報を再利用することがあります。

Result ---> transposed convolution ---> Image

それがおそらく「デコンボリューション」と間違って呼ばれる理由です。ただし、畳み込みの行列転置(C ^ T)と関係があるため、より適切な名前は「転置畳み込み」です。

したがって、コンピューティングコストを検討する際には非常に理にかなっています。転置畳み込みを使用しない場合、Amazon gpusにもっと多く支払うことになります。

ここのアニメーションを注意深く読んで見てください:http : //deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html#no-zero-padding-unit-strides-transposed

その他の関連資料:

フィルターの転置(または、より一般的には、エルミート転置または共役転置)は、単純に一致フィルターです[3]。これは、カーネルを時間反転し、すべての値の共役を取ることで検出されます[2]。

私もこれに不慣れであり、フィードバックや修正に感謝します。

[1] http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html

[2] http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html#transposed-convolution-arithmetic

[3] https://en.wikipedia.org/wiki/Matched_filter


1
Nit picking、しかしリンクは次のようになります:deeplearning.net/software/theano_versions/dev/tutorial/…–
Herbert

1
これがベストアンサーだと思います!!!
kli_nlpr

10

たとえば、PCAを使用できます。

convを使用する場合、フォワードパスは入力画像から主成分の係数を抽出し、バックワードパス(入力を更新する)は係数(の勾配)を使用して新しい入力画像を再構築するため、新しい入力画像には、目的の係数によりよく一致するPC係数があります。

deconvを使用すると、フォワードパスとバックワードパスが逆になります。フォワードパスは、PC係数から画像を再構築しようとし、バックワードパスは、指定された(勾配の)画像のPC係数を更新します。

deconvフォワードパスは、この投稿で指定されたconv勾配計算を正確に行います:http ://andrew.gibiansky.com/blog/machine-learning/convolutional-neural-networks/

そのため、deconvのcaffe実装(Andrei Pokrovskyの回答を参照)では、deconvの前方パスがbackward_cpu_gemm()を呼び出し、後方パスがforward_cpu_gemm()を呼び出します。


6

デビッド・ダオの答えに加えて、逆のことを考えることもできます。1つの出力ピクセルを生成するために使用される(低解像度)入力ピクセルに焦点を合わせる代わりに、どの個々の入力ピクセルが出力ピクセルのどの領域に寄与するかに焦点を合わせることができます。

これは、一連の非常に直感的でインタラクティブな視覚化を含むこの蒸留出版物で行われます。この方向で考えることの利点の1つは、チェッカーボードアーティファクトの説明が簡単になることです。


5

DSPの観点からの畳み込み

私はこれに少し遅れていますが、それでも私の視点と洞察を共有したいと思います。私の背景は理論物理学とデジタル信号処理です。特に、私はウェーブレットを研究し、畳み込みはほとんど私のバックボーンにあります;)

ディープラーニングコミュニティの人々が畳み込みについて話す方法も、私を混乱させました。私の観点からは、不足していると思われるのは、懸念の適切な分離です。いくつかのDSPツールを使用して、ディープラーニングコンボリューションについて説明します。

免責事項

主要なポイントを理解するために、私の説明は少し手で波打っており、数学的に厳密ではありません。


定義

xn={xn}n=={,x1,x0,x1,}

ynバツn

yバツn=k=ynkバツk

q=q0q1q2バツ=バツ0バツ1バツ2バツ3T

qバツ=q1q000q2q1q000q2q1q000q2q1バツ0バツ1バツ2バツ3

kN

kバツn=バツnk

kk1

kバツn={バツn/kn/kZ0そうでなければ

k=3

3{バツ0バツ1バツ2バツ3バツ4バツ5バツ6}={バツ0バツ3バツ6}
3{バツ0バツ1バツ2}={バツ000バツ100バツ200}

k=2

2x=(x0x2)=(10000010)(x0x1x2x3)

そして

2x=(x00x10)=(10000100)(x0x1)

k=kT


部品ごとの深層学習畳み込み

qx

  • kk(qx)
  • k(kq)x
  • kq(kx)

q(kx)=q(kTx)=(k(q)T)Tx

(q)q

q(kx)=(q1q000q2q1q000q2q1q000q2q1)(10000100)(x0x1)=(q1q200q0q1q200q0q1q200q0q1)T(10000010)T(x0x1)=((10000010)(q1q200q0q1q200q0q1q200q0q1))T(x0x1)=(k(q)T)Tx

わかるように、転置操作、つまり名前です。

最近傍アップサンプリングへの接続

畳み込みネットワークで見られる別の一般的なアプローチは、組み込みの補間形式を使用したアップサンプリングです。単純な繰り返し補間を使用して、係数2によるアップサンプリングを行ってみましょう。これはと書くことができます2(11)xq2(11)qxq=(q0q1q2)

(11)q=(q0q0+q1q1+q2q2),

つまり、繰り返しアップサンプラーを係数2で、サイズ3のカーネルのたたみ込みを、カーネルサイズ4の転置たたみ込みで置き換えることができます。


結論と最後の発言

深層学習で見られる一般的な畳み込みを、基本的な操作で分解することで少し明確にしたいと思います。

ここではプーリングを取り上げませんでした。しかし、これは単なるノンリニアダウンサンプラーであり、この表記法の中で扱うこともできます。


素晴らしい答え。数学的/記号的な観点をとることで、しばしば物事が明確になります。この文脈における「デコンボリューション」という用語は既存の用語と衝突すると考えるのは正しいですか?
user76284

それは実際には衝突せず、意味をなさないだけです。デコンボリューションは、アップサンプル演算子によるたたみ込みのみです。デコンボリューションという用語は、何らかの形の逆演算のように聞こえます。ここで逆関数について話すことは、行列演算のコンテキストでのみ意味があります。畳み込みの逆演算ではなく、逆行列で乗算します(除算と乗算など)。
アンドレ・ベルグナー

zθバツ=zzθz=バツ

(最小ノルム)デコンボリューション、畳み込み行列の逆数(より正確には、その擬似逆数)を乗算すること同等です。あれは、θz=バツ もし z=θ+バツ。これは実際のデコンボリューションが実際に何に対応するかを明確にするので、あなたの答えに良い追加をするかもしれません。
user76284

つまり、OPのいわゆる「デコンボリューション層」は実際にはデコンボリューションを行っていません。それは何か他のことをしている(あなたが答えで説明したこと)。
user76284

4

このブログ投稿に出くわすまで、論文で正確に何が起こったかを理解するのに苦労しました:http : //warmspringwinds.github.io/tensorflow/tf-slim/2016/11/22/upsampling-and-image-segmentation -with-tensorflow-and-tf-slim /

2倍のアップサンプリングで何が起きているのかを理解する方法の概要を次に示します。

紙からの情報

  • アップサンプリングとは何ですか?
    • 「係数fによるアップサンプリングは、1 / fの分数入力ストライドによる畳み込みです」
    • →部分ストライド畳み込みは、http: //deeplearning.net/software/theano/tutorial/conv_arithmetic.htmlによると、転置畳み込みとしても知られています。
  • その畳み込みのパラメーターは何ですか?
  • 重みは固定されていますか、またはトレーニング可能ですか?
    • 論文は、「2倍アップサンプリングを双線形補間に初期化しますが、パラメーターを学習できるようにします[...]」と述べています。
    • ただし、対応するgithubページは、「元の実験では補間レイヤーが双線形カーネルに初期化されてから学習されました。フォローアップ実験およびこのリファレンス実装では、双線形カーネルが固定されています」
    • →固定重量

簡単な例

  1. 次の入力画像を想像してください:

入力画像

  1. フラクショナルストライドコンボリューションは、これらの値の間にfactor-1 = 2-1 = 1ゼロを挿入し、その後stride = 1を仮定することにより機能します。したがって、次の6x6の埋め込み画像を受け取ります

パディング画像

  1. バイリニア4x4フィルターは次のようになります。その値は、使用される重み(=ゼロが挿入されていないすべての重み)の合計が1になるように選択されます。その3つの一意の値は0.56、0.19、および0.06です。さらに、フィルターの中心は、慣例に従って3行3列目のピクセルです。

フィルタ

  1. パディング画像に4x4フィルターを適用すると(padding = 'same'およびstride = 1を使用)、次の6x6アップサンプリング画像が生成されます。

拡大画像

  1. この種のアップサンプリングは、各チャネルに対して個別に実行されます(https://github.com/shelhamer/fcn.berkeleyvision.org/blob/master/surgery.pyの行59を参照)。最後に、2倍のアップサンプリングは、バイリニア補間と境界の処理方法に関する規則を使用した、非常に単純なサイズ変更です。16倍または32倍のアップサンプリングは、ほぼ同じように機能します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.