import tensorflow as tfimport matplotlib.pyplot as pltimport cv2import osimport numpy as npfrom tensorflow.keras.preprocessing.image import ImageDataGeneratorfrom tensorflow.keras.preprocessing import imagefrom tensorflow.keras.optimizers import Nadamfrom tensorflow.keras.models import load_modeltrain = ImageDataGenerator(rescale=1 / 255)validation = ImageDataGenerator(rescale=1 / 255)train_dataset = train.flow_from_directory('raw-img/training', target_size=(200, 200), batch_size=3, class_mode='categorical')validation_dataset = train.flow_from_directory('raw-img/validation', target_size=(200, 200), batch_size=3, class_mode='categorical')model = tf.keras.models.Sequential([tf.keras.layers.Conv2D(16, (3, 3), activation='relu', input_shape=(200, 200, 3),padding='same'), tf.keras.layers.MaxPool2D(2, 2,padding='same'), # tf.keras.layers.Conv2D(32, (3, 3), activation='relu',padding='same'), tf.keras.layers.MaxPool2D(2, 2),tf.keras.layers.Dropout(rate=0.6), # tf.keras.layers.Conv2D(64, (3, 3), activation='relu',padding='same'), tf.keras.layers.MaxPool2D(2, 2),tf.keras.layers.Dropout(rate=0.6), # tf.keras.layers.Conv2D(128, (3, 3), activation='relu',padding='same'), tf.keras.layers.MaxPool2D(2, 2), # tf.keras.layers.Conv2D(128, (3, 3), activation='relu',padding='same'), tf.keras.layers.MaxPool2D(2, 2), # tf.keras.layers.Conv2D(256, (3, 3), activation='relu',padding='same'), tf.keras.layers.MaxPool2D(2, 2,), # tf.keras.layers.Flatten(), # tf.keras.layers.Dense(512, activation='relu'), tf.keras.layers.Dense(256, activation='relu'), tf.keras.layers.Dense(10, activation='sigmoid'),])print(model.summary())model.compile(loss='binary_crossentropy', optimizer=Nadam(learning_rate=0.003), metrics['accuracy'])model_fit = model.fit(train_dataset, epochs=70, batch_size=3, validation_data=validation_dataset,steps_per_epoch=len(train_dataset),validation_steps=len(validation_dataset))loss, accuracy = model.evaluate(train_dataset)print("Loss: ", loss)print("Accuracy: ", accuracy)
发现26179张图像,属于10个类别。发现8196张图像,属于10个类别。
Epoch 1/702909/2909 [==============================] - 1005s 345ms/step - loss: 0.3292 - accuracy: 0.1805 - val_loss: 0.3533 - val_accuracy: 0.0000e+00Epoch 2/702909/2909 [==============================] - 645s 222ms/step - loss: 0.3167 - accuracy: 0.1758 - val_loss: 0.3654 - val_accuracy: 0.0000e+00...Epoch 8/702909/2909 [==============================] - 445s 153ms/step - loss: 0.3160 - accuracy: 0.1835 - val_loss: 0.3666 - val_accuracy: 0.0000e+00Epoch 9/702909/2909 [==============================] - ETA: 0s - loss: 0.3146 - accuracy: 0.1867
这个代码有什么问题?准确率卡在0.1800和0.1900,损失值没有下降。
回答:
有几个问题需要注意
- 由于你的图像是200×200的,可以考虑使用更大的批次大小,比如32
- 在train = ImageDataGenerator(rescale=1 / 255)中,你可能需要考虑添加一些图像增强,比如horizontal_flip=True等。如果你添加了增强,不要在代码中对验证数据集使用train,使用validation
- 在你的模型中,你有代码tf.keras.layers.Dense(10, activation=’sigmoid’),除非你是做多标签分类,否则应该将激活函数改为”softmax”
- 你的模型可能会过拟合。我建议至少添加一个Dropout层,比如tf.keras.layers.Dropout(.3)
- 先做上述更改并查看性能。如果开始过拟合,可以增加Dropout率或减少隐藏层的节点数
- 如果你对准确率不满意,可以通过使用可调整的学习率来改进。你可以使用Keras的回调ReduceLROnPlateau。文档在这里。我建议的代码是
rlronp=tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=.5,patience=1,verbose=1)
- 我还推荐使用Keras的回调EarlyStopping。它会监控验证损失,如果在’patience’个epochs后未能减少,则停止训练。文档在这里。设置restore_best_weights=True,这样如果这个回调被激活,它会加载模型中验证损失最低的epoch的权重。我建议的代码是
es=tf.keras.callbacks.EarlyStopping(monitor="val_loss",patience=4,verbose=1, restore_best_weights=True)
- 如果使用这些回调,则在model.fit中设置callbacks=[rlronp,es]