Matconvnet で Matconvnet を使用して、CNN でバイナリ分類を行っています。そして今、私は Python で Keras を使ってそれを実現しようとしています。ネットワークはまったく複雑ではなく、Matconvnet で 96% の精度を達成しました。しかし、Keras では、すべての設定が以前とまったく同じになるように最善を尽くしても、同じ結果を得ることができません。さらに悪いことに、モデルはまったく機能しません。
設定の詳細をいくつか紹介します。どんなアイデアや助けも大歓迎です!
入力
画像は20×20サイズです。トレーニング サイズは 400、テスト サイズは 100、検証サイズは 132 です。
- Matconvnet: 20*20*sample_size メソッドで保存された画像
- Keras: sample_size*20*20*1 メソッドで保存された画像
CNN 構造 (3*3)*3 conv- (2*2) maxpooling- fully connected- softmax- logloss
Matconvnet: 全結合層の代わりに畳み込み層を使用します。コードは次のとおりです。
function net = initializeCNNA() f=1/100 ; net.layers = {} ; net.layers{end+1} = struct('type', 'conv', ... 'weights', {{f*randn(3,3,1,3, 'single'), zeros(1, 3, 'single')}}, ... 'stride', 1, ... 'pad', 0) ; net.layers{end+1} = struct('type', 'pool', ... 'method', 'max', ... 'pool', [2 2], ... 'stride', 2, ... 'pad', 0) ; net.layers{end+1} = struct('type', 'conv', ... 'weights', {{f*randn(9,9,3,2, 'single'), zeros(1,2,'single')}}, ... 'stride', 1, ... 'pad', 0) ; net.layers{end+1} = struct('type', 'softmaxloss') ; net = vl_simplenn_tidy(net) ;
ケラス:
model = Sequential()
model.add(Conv2D(3, (3,3),kernel_initializer=\
keras.initializers.RandomNormal(mean=0.0, stddev=0.1, seed=None), input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2),strides=(2, 2)))
model.add(Flatten())
model.add(Dense(2,activation='softmax',\
kernel_initializer=keras.initializers.RandomNormal(mean=0.0, stddev=0.1, seed=None)))
- 損失関数
- マット変換:
softmaxloss
- ケラス:
binary_crossentropy
- マット変換:
オプティマイザ
Matconvnet: SGD
trainOpts.batchSize = 50; trainOpts.numEpochs = 20 ; trainOpts.learningRate = 0.001 ; trainOpts.weightDecay = 0.0005 ; trainOpts.momentum = 0.9 ;
ケラス: SGD
sgd = optimizers.SGD(lr=0.001, momentum=0.9, decay=0.0005) model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
- 初期化: フィルター:N(0,0.1)、バイアス: 0
- 正規化: 画像の平均値が 0 で標準値が 1 の入力中の正規化以外のバッチ正規化はありません。
上記は、正しいレプリケーションを行ったことを確認するために確認した側面です。それでも、Keras で動作しない理由がわかりません。ここにいくつかの推測があります:
- Matconvnet は、完全に接続されたレイヤーの代わりに畳み込みレイヤーを使用し、パラメーターを更新するための凝った方法を意味する場合があります。
- これらは、異なるアルゴリズムを使用して、パラメーターが異なる意味を持つ SGD を適用します。
私も他の試みをしました:
- Keras のオプティマイザを に変更し
Adadelta()
ます。改善なし。 ネットワーク構造を変更し、より深くします。できます!
しかし、Matconvnet がはるかに単純な結果でその良い結果を達成できる理由を知りたいと思っています。