Снижение требований к памяти для сверточной нейронной сети - PullRequest
0 голосов
/ 23 сентября 2018

Я пытаюсь создать сверточную нейронную сеть для изображений.В настоящее время у меня есть около 136 изображений (еще много будет добавлено позже) для 17 классов.

Каждое изображение имеет форму numpy.array формы (330, 330, 3).

Я используюследующий код для сети:

batch_size = 64
nb_classes = 17
nb_epoch = 2
img_rows = 330
img_cols = 330
nb_filters = 16
nb_conv = 3  # convolution kernel size
nb_pool = 2

model = Sequential()
# 1st conv layer: 
model.add(Convolution2D(
         nb_filters, (nb_conv, nb_conv),
         padding="valid",
         input_shape=(img_rows, img_cols, 3),
         data_format='channels_last',  )) 
model.add(Activation('relu'))

# 2nd conv layer: 
model.add(Convolution2D(nb_filters, (nb_conv, nb_conv), data_format='channels_last')) 
model.add(Activation('relu'))

# maxpooling layer: 
model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool), data_format="channels_last")) 
model.add(Dropout(0.25))

# 2 FC layers: 
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))

model.add(Dropout(0.5))
model.add(Dense(nb_classes))
model.add(Activation('softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adadelta')

model.summary()

model.fit(X_train, y_train, batch_size=batch_size, epochs=nb_epoch,  verbose=1  )

Однако, он выдает сообщение, что «> 10% системной памяти используется» очень скоро после начала самой первой эпохи.Это перестает отвечать на запросы, и я должен перезагрузить его.

Какие шаги я могу предпринять или внести изменения в код, чтобы уменьшить требования к памяти?

Ответы [ 3 ]

0 голосов
/ 23 сентября 2018

«Вам нужно идти глубже» (c) =)

После 2 слоев свертки / объединения у вас остается изображение 80x80, которое становится грандиозным плотным слоем 6400 после выравнивания.Если у вас есть только 17 классов, вам нужно пойти глубже, добавить больше свертки и объединения, чтобы ваше изображение стало примерно размером 20x20 (еще 2 дополнительных извлечения / maxpool), тогда ваша сеть будет работать лучше и потребовать меньше памяти для плотных слоев.

0 голосов
/ 23 сентября 2018

Посмотрев на вывод model.summary(), вы узнаете, что вызывает эту проблему (т. Е. Какие слои имеют слишком много параметров):

Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_189 (Conv2D)          (None, 328, 328, 16)      448       
_________________________________________________________________
activation_189 (Activation)  (None, 328, 328, 16)      0         
_________________________________________________________________
conv2d_190 (Conv2D)          (None, 326, 326, 16)      2320      
_________________________________________________________________
activation_190 (Activation)  (None, 326, 326, 16)      0         
_________________________________________________________________
max_pooling2d_9 (MaxPooling2 (None, 163, 163, 16)      0         
_________________________________________________________________
dropout_3 (Dropout)          (None, 163, 163, 16)      0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 425104)            0         
_________________________________________________________________
dense_5 (Dense)              (None, 128)               54413440  
_________________________________________________________________
activation_191 (Activation)  (None, 128)               0         
_________________________________________________________________
dropout_4 (Dropout)          (None, 128)               0         
_________________________________________________________________
dense_6 (Dense)              (None, 17)                2193      
_________________________________________________________________
activation_192 (Activation)  (None, 17)                0         
=================================================================
Total params: 54,418,401
Trainable params: 54,418,401
Non-trainable params: 0
_________________________________________________________________

Как видите, с момента вывода *Слой 1005 * настолько велик, что слой Dense будет иметь слишком много параметров: 425104 * 128 + 128 = 54413440, то есть 54 миллиона параметров только для одного слоя (а это почти 99% всех параметров в модели).Итак, как уменьшить это число?Вам нужно уменьшить выходной размер слоев свертки, используя аргумент stride (который я не рекомендую) или объединяя слои (желательно после каждого слоя свертки).Давайте добавим еще два пула слоев и еще один слой конвоя (я даже увеличил количество фильтров в слоях конвоя, поскольку мы углубляемся, так как это обычно полезно):

# 1st conv + pooling layer: 
model.add(Convolution2D(
         nb_filters, (nb_conv, nb_conv),
         padding="valid",
         input_shape=(img_rows, img_cols, 3),
         data_format='channels_last',  )) 
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool), data_format="channels_last"))

# 2nd conv + pooling layer: 
model.add(Convolution2D(nb_filters*2, (nb_conv, nb_conv), data_format='channels_last')) 
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool), data_format="channels_last")) 

# 3rd conv + pooling layer:
model.add(Convolution2D(nb_filters*2, (nb_conv, nb_conv), data_format='channels_last')) 
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool), data_format="channels_last")) 

# the rest is the same...

Вывод сводной модели:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_197 (Conv2D)          (None, 328, 328, 16)      448       
_________________________________________________________________
activation_203 (Activation)  (None, 328, 328, 16)      0         
_________________________________________________________________
max_pooling2d_16 (MaxPooling (None, 164, 164, 16)      0         
_________________________________________________________________
conv2d_198 (Conv2D)          (None, 162, 162, 32)      4640      
_________________________________________________________________
activation_204 (Activation)  (None, 162, 162, 32)      0         
_________________________________________________________________
max_pooling2d_17 (MaxPooling (None, 81, 81, 32)        0         
_________________________________________________________________
conv2d_199 (Conv2D)          (None, 79, 79, 32)        9248      
_________________________________________________________________
activation_205 (Activation)  (None, 79, 79, 32)        0         
_________________________________________________________________
max_pooling2d_18 (MaxPooling (None, 39, 39, 32)        0         
_________________________________________________________________
dropout_9 (Dropout)          (None, 39, 39, 32)        0         
_________________________________________________________________
flatten_4 (Flatten)          (None, 48672)             0         
_________________________________________________________________
dense_11 (Dense)             (None, 128)               6230144   
_________________________________________________________________
activation_206 (Activation)  (None, 128)               0         
_________________________________________________________________
dropout_10 (Dropout)         (None, 128)               0         
_________________________________________________________________
dense_12 (Dense)             (None, 17)                2193      
_________________________________________________________________
activation_207 (Activation)  (None, 17)                0         
=================================================================
Total params: 6,246,673
Trainable params: 6,246,673
Non-trainable params: 0
_________________________________________________________________

Как видите, теперь он имеет менее 6,5 миллионов параметров, что составляет почти одну девятую часть количества параметров в предыдущей модели.Вы даже можете добавить еще один слой пула, чтобы еще больше сократить количество параметров.Однако имейте в виду, что по мере того, как ваша модель становится глубже (т. Е. Имеет все больше и больше слоев), вам, возможно, придется позаботиться о таких проблемах, как исчезающий градиент и перенастройка .

0 голосов
/ 23 сентября 2018

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...