2

我正在使用 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-全连接-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))) 
  • 损失函数
    • Matconvnet:softmaxloss
    • 喀拉斯:binary_crossentropy
  • 优化器

    • Matconvnet:新元

      trainOpts.batchSize = 50;
      trainOpts.numEpochs = 20 ;
      trainOpts.learningRate = 0.001 ;
      trainOpts.weightDecay = 0.0005 ;
      trainOpts.momentum = 0.9 ;
      
    • Keras:新元

      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 可以用一个更简单的方法来达到那么好的结果。

4

1 回答 1

0

“Matconvnet 使用卷积层而不是全连接层,这可能意味着更新参数的一些奇特方式。”

不。从技术上讲,卷积层和全连接层之间应该没有区别。我很确定没有花哨的方法来更新参数。

更多评论来了。。

这篇文章中的一些讨论可能会有所帮助: 无法在 Keras 中复制 matconvnet CNN 架构

于 2017-07-17T09:17:20.303 回答