数据集较小
发现1836张属于2个类别的图像。发现986张属于2个类别的图像。
模型的标准架构
image_generator = ImageDataGenerator( rescale=1./255, validation_split=0.35 ) train_data_gen = image_generator.flow_from_directory( directory=directory, target_size=(IMG_SHAPE, IMG_SHAPE), subset='training', ) val_data_gen = image_generator.flow_from_directory( directory=directory, target_size=(IMG_SHAPE, IMG_SHAPE), subset='validation', )---model = tf.keras.models.Sequential([ tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(IMG_SHAPE, IMG_SHAPE, 3)), tf.keras.layers.MaxPooling2D(2, 2), tf.keras.layers.Conv2D(64, (3, 3), activation='relu'), tf.keras.layers.MaxPooling2D(2, 2), tf.keras.layers.Conv2D(128, (3, 3), activation='relu'), tf.keras.layers.MaxPooling2D(2, 2), tf.keras.layers.Conv2D(128, (3, 3), activation='relu'), tf.keras.layers.MaxPooling2D(2, 2), tf.keras.layers.Flatten(), tf.keras.layers.Dense(512, activation='relu'), tf.keras.layers.Dense(2, activation='softmax'), ]) model.compile( optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'] ) BATCH_SIZE = 128 EPOCHS = 7 total_train, total_val = train_data_gen.samples, val_data_gen.samples steps_per_epoch = int(np.ceil(total_train / float(BATCH_SIZE))) validation_freq = int(np.ceil(total_val / float(BATCH_SIZE))) history = model.fit( train_data_gen, epochs=EPOCHS, steps_per_epoch=steps_per_epoch, validation_data=val_data_gen, validation_freq=validation_freq )
获得完美的指标
Epoch 1/715/15 [==============================] - 66s 4s/step - loss: 1.0809 - accuracy: 0.4917Epoch 2/715/15 [==============================] - 56s 4s/step - loss: 0.3475 - accuracy: 0.8729Epoch 3/715/15 [==============================] - 60s 4s/step - loss: 0.1113 - accuracy: 0.9583Epoch 4/715/15 [==============================] - 58s 4s/step - loss: 0.1987 - accuracy: 0.9109Epoch 5/715/15 [==============================] - 59s 4s/step - loss: 0.1127 - accuracy: 0.9438Epoch 6/715/15 [==============================] - 60s 4s/step - loss: 0.0429 - accuracy: 0.9854Epoch 7/715/15 [==============================] - 49s 3s/step - loss: 0.0542 - accuracy: 0.9812
但是在我评估它之后,结果完全偏向第一个类别
只有在一轮运行时它才有效,但准确率不足
评估代码
def make_pred(model, labled_dataset, IMG_SHAPE, img_path) -> LabelName: def make_image(img_path): # img = img_path.resize((IMG_SHAPE, IMG_SHAPE), Image.ANTIALIAS) img = image.load_img(img_path, target_size=(IMG_SHAPE, IMG_SHAPE)) img = image.img_to_array(img) return np.expand_dims(img, axis=0) pred_id: List[List] = np.argmax(model.predict(make_image(img_path)), axis=1) all_labels = list(labled_dataset.class_indices.keys()) return all_labels[int(pred_id)]
哪里出了问题?
在评估之前我应该缩小源图像吗?
回答:
-
问题出在
validation_freq
上,它应该是validation_steps
,之后我们终于得到了val_accuracy
,这样训练开始以正确的方式进行验证 -
除此之外,
IMG_SHAPE
在ImageDataGenerator
和模型内部的input_shape=(IMG_SHAPE, IMG_SHAPE, 3))
中并不相同 -
使用PIL进行预测可能也有帮助,它的结果与
keras.preprocessing.image
略有不同
def make_pred_PIL(model, labled_dataset, IMG_SHAPE, img_path) -> LabelName: img = cv2.imread(img_path) img = cv2.resize(img, (IMG_SHAPE, IMG_SHAPE)) img = np.array(img, dtype=np.float32) img = np.reshape(img, (-1, IMG_SHAPE, IMG_SHAPE, 3)) pred_id: List[List] = np.argmax(model.predict(img), axis=1) all_labels = list(labled_dataset.class_indices.keys()) return all_labels[int(pred_id)]