多くの場所で、通常は完全な畳み込みネットワーク、オートエンコーダーなどで人々がこのようなものを使用していることに気付きました。
model.add(UpSampling2D(size=(2,2)))
model.add(Conv2DTranspose(kernel_size=k, padding='same', strides=(1,1))
私はそれと単純に何が違うのだろうと思っています:
model.add(Conv2DTranspose(kernel_size=k, padding='same', strides=(2,2))
この違いを説明する論文へのリンクは歓迎です。
Here および here転置畳み込みがどのように機能するかについての本当に素晴らしい説明を見つけることができます。これらのアプローチの両方を要約するには:
最初のアプローチでは、まず機能マップをアップサンプリングします。
[[1, 2], [3, 4]] -> [[1, 1, 2, 2], [1, 1, 2, 2], [3, 3, 4, 4], [3, 3, 4, 4]]
そして、古典的な畳み込みを適用します(Conv2DTranspose
とstride=1
およびpadding='same'
はConv2D
と同等です)。
2番目のアプローチでは、フィーチャマップを最初にun(max)poolingします:
[[1, 2], [3, 4]] -> [[1, 0, 2, 0], [0, 0, 0, 0], [3, 0, 4, 0], [0, 0, 0, 0]]
そして、filter_size
、filtersなどで古典的な畳み込みを適用します。
楽しい事実は、これらのアプローチは異なりますが、共通点があることです。転置畳み込みは畳み込みの勾配の近似であるため、最初のアプローチはsum pooling
を近似し、2番目のmax pooling
勾配を近似します。これにより、最初の結果がわずかに滑らかな結果になります。
最初のアプローチが表示される他の理由は次のとおりです。
Conv2DTranspose
(およびそれに相当するもの)はkeras
で比較的新しいため、学習可能なアップサンプリングを実行する唯一の方法はUpsample2D
を使用することでした。keras
の著者-Francois Cholletは、チュートリアルの one でこのアプローチを使用しました。keras
の不整合により、API
で畳み込みがひどく機能するように思われました。