我在Matconvnet上使用Matconvnet对CNN进行二进制分类。现在,我试图通过Python上的Keras实现它。网络根本不复杂,我在Matconvnet上达到了96%的准确率。然而对于Keras来说,即使我尽力确保每个设置与以前完全相同,我也无法得到相同的结果。或者更糟糕的是,该模型根本不起作用。
以下是有关设置的一些详细信息。任何想法或帮助表示赞赏!
输入
图像尺寸为20 * 20。培训规模为400,测试规模为100,验证规模为132。
CNN结构 (3 * 3)* 3 conv-(2 * 2)maxpooling-完全连接 - 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) ;
Keras:
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 ;
Keras:SGD
sgd = optimizers.SGD(lr=0.001, momentum=0.9, decay=0.0005)
model.compile(loss='binary_crossentropy',
optimizer=sgd,
metrics=['accuracy'])
以上是我审核的方面,以确保我做了正确的复制。但我不明白为什么它不适用于Keras。以下是一些猜测:
我也做过其他尝试:
Adadelta()
。没有改善。更改网络结构并使其更深入。它有效!
但是仍然想知道为什么Matconvnet可以用更简单的方法取得好成绩。
答案 0 :(得分:0)
" Matconvnet使用卷积层而不是完全连接的层,可能意味着更新参数的一些奇特方式。"
没有。从技术上讲,卷积和完全连接的层之间应该没有区别。我非常确定没有花哨的方法来更新参数。
更多评论即将来临......
这篇文章中的一些讨论可能会有所帮助: Can't replicate a matconvnet CNN architecture in Keras