Импорт модели 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:
оптимизатор
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