Импорт модели CNN из Matlab (Matconvnet) в Python (Keras)

Я делаю двоичную классификацию с CNN, используя Matconvnet на Matconvnet. И сейчас я пытаюсь реализовать это через Keras на Python. Сеть совсем не сложная, и я достиг 96% точности в Matconvnet. Однако с 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) ;
      
    • 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))) 
  • Функция потери
    • Matconvnet: softmaxloss
    • Keras: 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 стандартное для изображений.

Выше приведены аспекты, которые я рассмотрел, чтобы убедиться, что я сделал правильную репликацию. Но я не понимаю, почему это не работает на Керасе. Вот некоторые догадки:

  • Matconvnet использует свернутый слой вместо полностью связанного слоя и может предложить какой-то причудливый способ обновления параметров.
  • Они используют другой алгоритм для применения SGD, параметры которого имеют различное значение.

Я также сделал другие попытки:

  • Изменить оптимизатор в Keras на Adadelta(), Без улучшения.
  • Измените структуру сети и сделайте ее глубже. Оно работает!

    Но все же хочу знать, почему Matconvnet может добиться этого хорошего результата с гораздо более простым.

1 ответ

"Matconvnet использует свернутый уровень вместо полностью подключенного уровня и может предложить какой-то причудливый способ обновления параметров".

Нет. Технически не должно быть разницы между сверткой и полностью связанными слоями. Я уверен, что нет никакого причудливого способа обновить параметры.

Больше комментариев

Некоторые обсуждения в этом посте могут помочь: Не удается воспроизвести архитектуру matconvnet CNN в Keras

Другие вопросы по тегам