我的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) breakhistory = model.fit(train_generator,steps_per_epoch=steps_per_epoch, epochs=epochs, validation_data=validation_generator,validation_steps=10, callbacks=callback_list)# Testing the Modeltest_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]。
最后,我使用TensorFlow方法将模型保存为h5格式。
在另一个Python程序中,我加载这个h5文件,并希望预测网络摄像头的图像。但现在输出总是[1.0;0.0;0.0;0.0;0.0;0.0;0.0]。以下是我进行预测的代码:
import numpy as npimport cv2import tensorflow as tfmodel = 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 capturecap.release()cv2.destroyAllWindows()
如您所见,我使用OpenCV从网络摄像头读取图像。
为了解决我的问题,我尝试了以下方法:将模型简化为最小规模 –> 无效
将问题简化为二元分类 –> 无效(总是以100%的概率预测两个类别中的一个)
加载并预测单张图像 –> 无效
在测试代码之后直接加载并预测单张图像(不必保存和加载模型)–> 无效,这张图像是我的测试图像之一…通过测试,这张图像被正确分类,但作为单张图像加载并使用预测方法时,我得到了与之前相同的错误。
由于测试运行符合预期,我认为我的数据或模型没有问题。转换OpenCV的网络摄像头图像到TensorFlow模型时是否有什么问题?
您还有其他可以尝试解决我问题的想法吗?
非常感谢大家!:)
回答:
cv2.VideoCapture().read()
将返回一个值范围为(0,255)的numpy数组,但您的模型期望它们在范围(0, 1)内
您可以传递一个在预期范围内的图像,如下所示:
rezised = cv2.resize(frame, (150, 150)) / 255expandArrayImage = np.expand_dims(rezised, axis=0)# 其余代码