#keras #deep-learning #conv-neural-network #feature-extraction #vgg-net
#keras #глубокое обучение #conv-нейронная сеть #извлечение объектов #vgg-net
Вопрос:
Я работал над проблемой распознавания изображений. После точной настройки VGG19 и добавления нескольких слоев и обучения модели. После достижения наилучшей точности тестирования я сохранил модель, удалил последние 6 слоев и извлек активации последнего полностью подключенного слоя, используя следующий код.
ROWS,COLS = 669,1026
input_shape = (ROWS, COLS, 3)
# train_data_dir = '/home/spectrograms/train'
validation_data_dir = '/home/spectrograms/test'
nb_train_samples = 791
nb_validation_samples = 198
# epochs = 200
batch_size = 10
if K.image_data_format() == 'channels_first':
input_shape = (3, ROWS, COLS)
else:
input_shape = (ROWS, COLS,3)
test_datagen = ImageDataGenerator(rescale=1. / 255)
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(ROWS, COLS),
batch_size=batch_size,
class_mode='binary')
model = Model(inputs=model.inputs, outputs=model.layers[-6].output)
predict = model.predict_generator(validation_generator,steps = 10)
print(predict[10])
print(predict[10].shape)
Но в выходном векторе много нулей.
[5.77765644e-01 2.44531885e-01 0.00000000e 00 0.00000000e 00
0.00000000e 00 0.00000000e 00 0.00000000e 00 0.00000000e 00
2.99371660e-01 8.27999532e-01 2.34099194e-01 2.67183155e-01
0.00000000e 00 1.95847541e-01 4.49438214e-01 1.00336084e-02
0.00000000e 00 0.00000000e 00 4.63756740e-01 0.00000000e 00
0.00000000e 00 1.15372933e-01 0.00000000e 00 0.00000000e 00
1.13927014e-01 6.74777776e-02 7.49553144e-01 0.00000000e 00
6.73675537e-02 2.85279214e-01 0.00000000e 00 0.00000000e 00
1.84553280e-01 4.57495511e-01 0.00000000e 00 0.00000000e 00
5.35506964e-01 0.00000000e 00 0.00000000e 00 0.00000000e 00
2.92950690e-01 0.00000000e 00 5.27026653e-01 0.00000000e 00
0.00000000e 00 0.00000000e 00 3.94881278e-01 0.00000000e 00
5.37508354e-02 6.67039156e-02 1.16688050e-01 6.52413011e-01
3.44565332e-01 0.00000000e 00 0.00000000e 00 0.00000000e 00
0.00000000e 00 0.00000000e 00 1.10359691e-01 3.63592118e-01
9.89193693e-02 1.15959466e-01 0.00000000e 00 1.57176346e-01
0.00000000e 00 0.00000000e 00 0.00000000e 00 2.90686011e-01
0.00000000e 00 6.03572190e-01 1.97682872e-01 1.57113865e-01
0.00000000e 00 2.84446061e-01 1.26254544e-01 0.00000000e 00
0.00000000e 00 5.51187336e-01 0.00000000e 00 0.00000000e 00
0.00000000e 00 0.00000000e 00 0.00000000e 00 0.00000000e 00
1.11384936e-01 1.67153805e-01 2.63090044e-01 0.00000000e 00
9.35753658e-02 9.16089058e-01 1.90610379e-01 0.00000000e 00
0.00000000e 00 0.00000000e 00 3.04680824e-01 2.47930676e-01
0.00000000e 00 0.00000000e 00 0.00000000e 00 0.00000000e 00
1.50975913e-01 3.60320956e-02 0.00000000e 00 3.47187579e-01
0.00000000e 00 0.00000000e 00 0.00000000e 00 0.00000000e 00
3.01374853e-01 0.00000000e 00 2.38310188e-01 0.00000000e 00
0.00000000e 00 0.00000000e 00 3.16582739e-01 0.00000000e 00
0.00000000e 00 0.00000000e 00 0.00000000e 00 8.17666354e-04
2.30050087e-01 4.66496646e-01 0.00000000e 00 0.00000000e 00
1.05043598e-01 0.00000000e 00 6.77903090e-03 3.72976154e-01]
Это нормально? Или я делаю что-то не так?
Ответ №1:
Мне кажется, все в порядке. Положительные ненулевые значения, которые вы получили в своем выходном векторе, — это активированные нейроны. Поскольку активация, используемая в VGGNet, в основном ReLU (за исключением выходного уровня), поэтому выходное значение любого уровня ограничено между 0 или некоторым положительным значением.
Если вы помните, функции relu — это что-то вроде-
def relu(z):
return max(0, z)
Итак, как вы видите, он сводит все отрицательные значения к нулю и пропускает только положительные значения.
Следовательно, вполне естественно, что все эти значения равны нулю (жаргон: в терминах relu они называются мертвыми нейронами, что является большой проблемой в RNN, а не в CNN)