web-dev-qa-db-ja.com

ケラスのConv2Dからレイヤーの重みを正しく取得するにはどうすればよいですか?

私はConv2Dレイヤーを次のように定義しています:

Conv2D(96, kernel_size=(5, 5),
             activation='relu',
             input_shape=(image_rows, image_cols, 1),
             kernel_initializer=initializers.glorot_normal(seed),
             bias_initializer=initializers.glorot_uniform(seed),
             padding='same',
             name='conv_1')

これは私のネットワークの最初の層です。
入力サイズは64 x 160、画像は1チャネルです。
私はこの畳み込み層から重みを視覚化しようとしていますが、それらを取得する方法がわかりません。
これが今私がこれをやっている方法です:

1.電話

layer.get_weights()[0]

これは、形状の配列を返します(5、5、1、96)。 1は、画像が1チャネルであるためです。

2. 5 x 5フィルター

layer.get_weights()[0][:,:,:,j][:,:,0]

非常に醜いですが、これを簡単にする方法がわかりません。コメントはありがたいです。

私はこれらの5 x 5の正方形に定かではありません。それらは実際にフィルターですか?
誰もモデルからフィルタを正しく取得する方法を教えていただけませんか?

11

最初の25だけのように重みを表示しようとしました。これと同じ質問があります。これはフィルターか何かです。これは、深い信念ネットワークまたはスタックされたRBMから派生したフィルターとは異なるようです。

これは、訓練されていない視覚化された重みです: untrained weights

そしてここに訓練された重みがあります:

trained weights

不思議なことに、トレーニング後の変化はありません!それらを比較すると、それらは同一です。

そして、DBN RBMは上部のレイヤー1と下部のレイヤー2をフィルターします: DBM RBM filters

Kernel_intialization = "ones"を設定すると、見栄えの良いフィルターが得られますが、試行錯誤を繰り返しても、純損失は減少しません enter image description here

以下は、2Dコンバージョンウェイト/フィルターを表示するコードです。

  ann = Sequential()
  x = Conv2D(filters=64,kernel_size=(5,5),input_shape=(32,32,3))
  ann.add(x)
  ann.add(Activation("relu"))

...

  x1w = x.get_weights()[0][:,:,0,:]
  for i in range(1,26):
      plt.subplot(5,5,i)
      plt.imshow(x1w[:,:,i],interpolation="nearest",cmap="gray")
  plt.show()

  ann.fit(Xtrain, ytrain_indicator, epochs=5, batch_size=32)

  x1w = x.get_weights()[0][:,:,0,:]
  for i in range(1,26):
      plt.subplot(5,5,i)
      plt.imshow(x1w[:,:,i],interpolation="nearest",cmap="gray")
  plt.show()

- - - - - - - - - - - - - -更新 - - - - - - - - - - - -

そこで、1e-6ではなく0.01の学習率でもう一度試し、画像を255.0で除算して0と255ではなく0と1の間で正規化した画像を使用しました。これで畳み込みフィルターが変更され、最初の畳み込みフィルターの出力は次のようになります: Untrained Weights

気づくトレーニング済みフィルターは、妥当な学習率で(それほどではなく)変更されます: Trained Convolution Filter

これは、CIFAR-10テストセットの画像7です。 Image 7 CIFAR-10 Car

そして、これが最初の畳み込み層の出力です: Convolution Layer Output

そして、最後の畳み込み層(間に密な層がない)を取得し、トレーニングされていない分類子にフィードする場合、精度の点で生画像の分類に似ていますが、畳み込み層をトレーニングすると、最後の畳み込み層の出力が分類子(ランダムフォレスト)。

したがって、畳み込み層は実際にフィルターであり、重みでもあると結論付けます。

14
John

Layer.get_weights()[0] [:、:、:、:]では、[:、:、:、:]の寸法は、重みのx位置、重みのy位置、n番目の入力です対応する変換層(前の層から来る、最初の変換層の重みを取得しようとすると、1つの入力のみが最初の変換層に駆動されるため、この数は1である)と、対応する層のk番目のフィルターまたはカーネル、それぞれ。したがって、layer.get_weights()[0]によって返される配列形状は、1つの入力のみがレイヤーに駆動され、サイズが5x5の96個のフィルターが生成されるため、解釈できます。フィルターの1つに到達したい場合は、次のように入力できます。6番目のフィルターprint(layer.get_weights()[0] [:、:、:、6] .squeeze())としましょう。ただし、2番目のconvレイヤーのフィルターが必要な場合(下に添付されているモデル画像のリンクを参照)、32個の入力画像またはマトリックスのそれぞれに64個のフィルターがあることに注意してください。たとえば、8番目の入力画像に対して生成された4番目のフィルターの重みなど、それらのいずれかの重みを取得する場合は、print(layer.get_weights()[0] [:、:、8,4] .squeezeと入力する必要があります。 ())。 ここに画像の説明を入力

0
Cagri Kaplan