Точность Keras не увеличивается более чем на 50% при двоичной проблеме CNN - PullRequest
0 голосов
/ 16 октября 2018

Я использую keras для обработки следующего подмножества моих данных:

5000 images of class A
5000 images of class B

С 1000 из этих изображений для каждого класса используется в качестве проверки.Масштабирование изображений до 96x96x3 каналов и нормализация в пределах 0-1.Я использую следующую модель:

model.add(Conv2D(32, (3, 3), activation="relu", input_shape=inputshape))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

И затем тренирую модель следующим образом:

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss="binary_crossentropy", optimizer=sgd, metrics=["accuracy"])

Однако точность редко (просто случайно) увеличивается с точностью до 50%:

Epoch 1/100
8000/8000 [==============================] - 23s 3ms/step - loss: 0.6939 - acc: 0.5011 - val_loss: 0.6932 - val_acc: 0.5060
Epoch 2/100
8000/8000 [==============================] - 22s 3ms/step - loss: 0.6938 - acc: 0.4941 - val_loss: 0.6941 - val_acc: 0.4940
Epoch 3/100
8000/8000 [==============================] - 22s 3ms/step - loss: 0.6937     - acc: 0.4981 - val_loss: 0.6932 - val_acc: 0.4915
Epoch 4/100
8000/8000 [==============================] - 22s 3ms/step - loss: 0.6933 - acc: 0.5056 - val_loss: 0.6931 - val_acc: 0.5060
Epoch 5/100
8000/8000 [==============================] - 22s 3ms/step - loss: 0.6935 - acc: 0.4970 - val_loss: 0.6932 - val_acc: 0.4940

Я не думаю, что проблема заключается в самих данных, так как я использовал альтернативный метод машинного обучения и получил более 94% точности с одинаковыми изображениями (за исключением использования только 5 обучающих изображений для каждогокласс, но это не относится к делу).

Любая помощь будет принята с благодарностью.

О!В случае, если это имеет значение: я использую бэкэнд CNTK.

Редактировать: вот код, который я использую для чтения изображений, который также нормализует значения пикселей в диапазоне 0-1:

import cv2
import numpy as np
from keras.preprocessing.image import img_to_array

healthy_files = sorted(os.listdir("../../uninfected/"))
healthy_imgs = [cv2.imread("../../uninfected/" + x) for x in healthy_files]
data = []
labels = []
for img in healthy_imgs[:5000]:
    resized = cv2.resize(img, (96, 96)).astype(numpy.float32) / 255.0 # normalise data to 0..1 range
    arr = img_to_array(resized) 
    data += [arr]
    labels += [0]
# The for loop above is then repeated over the other half of the dataset, with the labels line using the label [1] instead
data = np.array(data, numpy.float32)

Редактировать 2: Вот выходные данные model.summary ():

Model built:
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d_1 (Conv2D)            (None, 94, 94, 32)        896
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 92, 92, 32)        9248
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 46, 46, 32)        0
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 44, 44, 64)        18496
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 42, 42, 64)        36928
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 21, 21, 64)        0
_________________________________________________________________
flatten_1 (Flatten)          (None, 28224)             0
_________________________________________________________________
dense_1 (Dense)              (None, 256)               7225600
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 257
=================================================================
Total params: 7,291,425
Trainable params: 7,291,425
Non-trainable params: 0

Я заметил, что в этой сводке явно не было слоев активации, поэтому я изменил модель на эту:

model.add(Conv2D(32, (3, 3), input_shape=inputshape))
model.add(Activation("relu"))
model.add(Conv2D(32, (3, 3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
#model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3)))
model.add(Activation("relu"))
model.add(Conv2D(64, (3, 3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
#model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation("relu"))
#model.add(Dropout(0.5))
#model.add(Dense(10, activation="relu"))
model.add(Dense(1))
model.add(Activation("sigmoid"))

, который дал итоговый результат этого:

Model built:
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d_1 (Conv2D)            (None, 94, 94, 32)        896
_________________________________________________________________
activation_1 (Activation)    (None, 94, 94, 32)        0
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 92, 92, 32)        9248
_________________________________________________________________
activation_2 (Activation)    (None, 92, 92, 32)        0
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 46, 46, 32)        0
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 44, 44, 64)        18496
_________________________________________________________________
activation_3 (Activation)    (None, 44, 44, 64)        0
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 42, 42, 64)        36928
_________________________________________________________________
activation_4 (Activation)    (None, 42, 42, 64)        0
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 21, 21, 64)        0
_________________________________________________________________
flatten_1 (Flatten)          (None, 28224)             0
_________________________________________________________________
dense_1 (Dense)              (None, 64)                1806400
_________________________________________________________________
activation_5 (Activation)    (None, 64)                0
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 65
_________________________________________________________________
activation_6 (Activation)    (None, 1)                 0
=================================================================
Total params: 1,872,033
Trainable params: 1,872,033
Non-trainable params: 0

Излишне говорить, что результаты остаются прежними ...

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

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

В конце я сузил его до бэкэнда - я использовал CNTK на первом компьютере и Tensorflow на втором.Я попробовал CNTK на втором компьютере, и он работал отлично ... Поэтому я решил переустановить CNTK на первом компьютере.На этот раз код работал отлично.Так что я понятия не имею, что изначально было сломано, но оно имело что-то , связанное с моей установкой CNTK.Я думаю, в конце концов, весь этот Q & A на самом деле никому не поможет ... но если кто-то испытывает похожую проблему - попробуйте предложения в комментариях к вопросу - некоторые действительно хорошие советы там.И если это не сработает ... попробуйте изменить свой бэкэнд!

Cheers

0 голосов
/ 16 октября 2018

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

...