Почему модель тензорного потока всегда предсказывает один и тот же класс? - PullRequest
2 голосов
/ 20 февраля 2020

моя модель TensorFlow всегда предсказывает один и тот же класс с доверенным лицом 100%.

Сначала краткое описание моей настройки: Задача состоит в том, чтобы классифицировать изображения с помощью 7 классов и считывать изображения с веб-камеры. Для обучения, проверки и тестирования модели я использую TensorFlow с генераторами данных.

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv2D(32,(3,3), activation='elu',input_shape=(image_heigth,image_width,3)))
model.add(tf.keras.layers.Conv2D(64,(3,3), activation='elu'))
model.add(tf.keras.layers.MaxPooling2D((2,2)))
model.add(tf.keras.layers.Conv2D(128,(3,3), activation='elu'))
model.add(tf.keras.layers.MaxPooling2D((2,2)))
model.add(tf.keras.layers.Conv2D(256,(3,3), activation='elu'))
model.add(tf.keras.layers.Conv2D(256,(3,3), activation='elu'))
model.add(tf.keras.layers.MaxPooling2D((2,2)))
model.add(tf.keras.layers.Conv2D(512,(3,3), activation='elu'))
model.add(tf.keras.layers.MaxPooling2D((2,2)))
model.add(tf.keras.layers.Dropout(0.3))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(512, activation='elu'))
model.add(tf.keras.layers.Dense(7, activation='softmax'))

model.summary()

model.compile(loss='categorical_crossentropy', optimizer=tf.keras.optimizers.RMSprop(lr=1e-4), metrics=['acc'])

Просто для информации это моя модель. Обучение, проверка и тестирование выполняются с помощью этого кода:

train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255, rotation_range=40, shear_range=0.2,zoom_range=0.2, horizontal_flip=True)
validation_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255)
test_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(train_dir, target_size=(image_heigth,image_width),batch_size=batch_size, class_mode='categorical', shuffle=True)
validation_generator = validation_datagen.flow_from_directory(validation_dir, target_size=(image_heigth,image_width), batch_size=5, class_mode='categorical')

for data_batch, labels_batch in train_generator:
    print('Shape des Datenstapels:', data_batch.shape)
    print('Shape des Klassenbzeichnungsstabels:', labels_batch.shape)
    break

history = model.fit(train_generator,steps_per_epoch=steps_per_epoch, epochs=epochs, validation_data=validation_generator,validation_steps=10, callbacks=callback_list)

# Testing the Model
test_generator = test_datagen.flow_from_directory(test_dir, target_size=(image_heigth,image_width), batch_size=5, class_mode='categorical')
test_loss, test_acc = model.evaluate(test_generator, steps=5)
predictions = model.predict(test_generator)
image_batch, label_batch = next (test_generator) 

Я достигаю правильного уровня классификации до 90%. Моя функция потери составляет около 0,3. Отладка тестирования и просмотр прогнозов получают ожидаемые значения, такие как [0,08; 0,06; 0,56; 0,04; 0,10; 0,09; 0,07].

В конце я сохраняю свою модель как h5 с помощью метода TensorFlow.

В другой программе python я загружаю этот h5 и хочу предсказать изображение с веб-камеры. , Но теперь выход всегда равен [1,0; 0,0; 0,0; 0,0; 0,0; 0,0; 0,0]. Вот мой код, как я это делаю:

 import numpy as np
import cv2
import tensorflow as tf

model = tf.keras.models.load_model('/home/poppe/Dokumente/Models/Proto2.h5')

classes = ['One', 'two', 'three', 'four', 'five', 'six', 'seven']

model.summary()

cap = cv2.VideoCapture(0)

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()
    # Our operations on the frame come here
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    rezised = cv2.resize(frame, (150, 150))
    expandArrayImage = np.expand_dims(rezised, axis=0)


    prediction = model.predict(expandArrayImage)

    print (np.max(prediction))
    print(classes[np.argmax(prediction)])

    # Display the resulting frame
    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything is done, release the capture
cap.release()
cv2.destroyAllWindows()

Как видите, я использую OpenCV для чтения с веб-камеры.

Чтобы решить мою проблему, я попытался сделать следующее: Сократить мою модель до минимума -> без эффекта

Сократить мою проблему до бинарной классификации -> без эффекта (всегда предсказывая одно из два класса со 100%)

Загрузка и прогнозирование одного изображения -> без эффекта

Загрузка и прогнозирование одного изображения непосредственно после кода для тестирования (не нужно сохранять и загрузить модель) -> безрезультатно, изображение было одним из моих тестовых изображений ... При тестировании это изображение было классифицировано правильно, загрузив его как одно изображение и используя метод прогнозирования, я получил ту же ошибку, что и bevor.

Так что из-за того, что тестирование работает, как и ожидалось, я не думаю, что у меня есть проблема с моими данными или моделью. Что-то не так с преобразованием изображения с веб-камеры из OpenCV в модель TensorFlow?

Есть ли у вас какие-либо другие идеи, которые я могу попытаться решить, моя проблема?

Большое спасибо! :)

1 Ответ

1 голос
/ 20 февраля 2020

cv2.VideoCapture().read() вернет массив numpy со значениями в диапазоне (0,255), но ваша модель ожидает, что они находятся в диапазоне (0, 1)

, вы можете передать изображение в ожидаемом диапазоне, например :

rezised = cv2.resize(frame, (150, 150)) / 255
expandArrayImage = np.expand_dims(rezised, axis=0)
# rest of the code
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...