简体   繁体   English

为什么 tensorflow 模型总是预测同一类?

[英]Why is tensorflow model always predicting same class?

my TensorFlow model is always predicting the same class with a confidant of 100%.我的 TensorFlow 模型总是用 100% 的知己预测同一类。

First a short description of my setting: Task is to do image classification with 7 classes and reading images from the webcam.首先简要描述我的设置:任务是使用 7 个类进行图像分类并从网络摄像头读取图像。 For training, validation, and testing of the model, I'm using TensorFlow with data generators.为了训练、验证和测试模型,我将 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'])

Just for information this is my model.仅供参考,这是我的模型。 Training, validation and testing is done with this code:使用以下代码完成训练、验证和测试:

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) 

I'm reaching a correct classification rate up to 90%.我达到了高达 90% 的正确分类率。 My loss function is down to something around 0,3.我的损失函数下降到 0.3 左右。 Debugging the testing and watching the predictions get expected values like [0.08;0.06;0.56;0.04;0.10;0.09;0.07].调试测试并观察预测会得到预期值,如 [0.08;0.06;0.56;0.04;0.10;0.09;0.07]。

In the end, I'm saving my model as an h5 with the TensorFlow method.最后,我使用 TensorFlow 方法将我的模型保存为 h5。

In another python program, I'm loading this h5 and want to predict the webcam image.在另一个 python 程序中,我正在加载这个 h5 并想预测网络摄像头图像。 But now the output is always [1.0;0.0;0.0;0.0;0.0;0.0;0.0].但现在输出总是 [1.0;0.0;0.0;0.0;0.0;0.0;0.0]。 Here is my code how I'm doing this:这是我的代码,我是如何做到这一点的:

 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()

As you can see, I'm using OpenCV to read from a webcam.如您所见,我正在使用 OpenCV 从网络摄像头读取数据。

To solve my problem I have tried the following: Reduce my model to a minimum --> no effect为了解决我的问题,我尝试了以下方法:将我的模型减少到最小 --> 没有效果

Reduce my problem to a binary classification --> no effect (always predicting one of the two classes with 100%)将我的问题简化为二元分类 --> 没有影响(总是以 100% 预测两个类别之一)

Load and predict a single image --> no effect加载和预测单个图像 --> 没有效果

Load and predict a single image directly after the code for testing (don't have to save and load the model) --> no effect, the image was one of my test images...By testing this image was classified correctly, loading it as a single image and use the predict method I've got the same error as bevor.测试代码后直接加载预测单张图片(不必保存和加载模型) --> 没有效果,图片是我的测试图片之一...通过测试这张图片分类正确,加载它作为单个图像并使用预测方法我得到了与 bevor 相同的错误。

So because of testing is running as expected, I don't think I've got a problem with my data or model.因此,由于测试按预期运行,我认为我的数据或模型没有问题。 Is there anything wrong with transforming the webcam image from OpenCV to the TensorFlow model?将网络摄像头图像从 OpenCV 转换为 TensorFlow 模型有什么问题吗?

Do you have any other ideas I can try to fix my problem?您还有其他想法可以尝试解决我的问题吗?

Many thanks at all!非常感谢! :) :)

cv2.VideoCapture().read() will return a numpy array with values ranging in (0,255) but your model expects them to be in range (0, 1) cv2.VideoCapture().read()将返回一个数值在 (0,255) 范围内的 numpy 数组,但您的模型希望它们在 (0, 1) 范围内

you can pass an image within the expected range like:您可以在预期范围内传递图像,例如:

rezised = cv2.resize(frame, (150, 150)) / 255
expandArrayImage = np.expand_dims(rezised, axis=0)
# rest of the code

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM