我正试图使用以下方法对狗和猫的图片进行分类 tensorflow-datasets但无论我运行多少个纪元,我的损失和准确性似乎都没有改变。
import tensorflow_datasets as tfds
import tensorflow as tf
dataset_name = 'cats_vs_dogs'
dataset, info= tfds.load(name=dataset_name, split=tfds.Split.TRAIN, with_info=True)
def preprocess(features):
print(features['image'], features['label'])
image = tf.image.resize(features['image'], [224,224])
image = tf.divide(image, 255)
print(image)
label = features['label']
print(label)
return image, label
def solution_model():
train_dataset = dataset.map(preprocess).batch(32)
model = tf.keras.Sequential(
[
tf.keras.layers.Conv2D(16, (3, 3), input_shape=(224, 224, 3), activation='relu'),
tf.keras.layers.MaxPool2D(2, 2),
tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),
tf.keras.layers.MaxPool2D(2, 2),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.MaxPool2D(2, 2),
tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
tf.keras.layers.MaxPool2D(2, 2),
tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),
tf.keras.layers.MaxPool2D(2, 2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(1024, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(1, activation='softmax')
]
)
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()
history = model.fit(train_dataset, epochs=100, verbose= 2)
return model
if __name__ == '__main__':
model = solution_model()
model.save("mymodel.h5")
无论我运行多少次,我得到的结果都是一样的。我只是得到同样的结果。
Epoch 1/100
727/727 - 51s - loss: 7.6423 - accuracy: 0.4988
Epoch 2/100
727/727 - 51s - loss: 7.6423 - accuracy: 0.4988
Epoch 3/100
727/727 - 51s - loss: 7.6423 - accuracy: 0.4988
这个问题与TensorFlow数据集的使用无关,而是与你的网络末端的softmax层的使用有关。
你的网络的输出形状是一个单一的标量(0代表猫,1代表狗)。在标量上使用softmax使得它总是去1,因此你的损失& 准确性被卡住了:无论输入什么,你总是预测1。
相反,你可能应该使用一个简单的sigmoid,这更符合你的使用情况,并保持softmax的情况下,输出形状是不是一个单一的标量(例如,对于一个热编码的目标)。
修改后的代码如下(我测试了一下,它学到了一些东西)。
import tensorflow_datasets as tfds
import tensorflow as tf
dataset_name = 'cats_vs_dogs'
dataset, info= tfds.load(name=dataset_name, split=tfds.Split.TRAIN, with_info=True)
def preprocess(features):
print(features['image'], features['label'])
image = tf.image.resize(features['image'], [224,224])
image = tf.divide(image, 255)
print(image)
label = features['label']
print(label)
return image, tf.cast(label, tf.float32)
def solution_model():
train_dataset = dataset.map(preprocess).batch(32)
model = tf.keras.Sequential(
[
tf.keras.layers.Conv2D(16, (3, 3), input_shape=(224, 224, 3), activation='relu'),
tf.keras.layers.MaxPool2D(2, 2),
tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),
tf.keras.layers.MaxPool2D(2, 2),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.MaxPool2D(2, 2),
tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
tf.keras.layers.MaxPool2D(2, 2),
tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),
tf.keras.layers.MaxPool2D(2, 2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(1024, activation='sigmoid'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(1, activation='sigmoid')
]
)
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()
history = model.fit(train_dataset, epochs=100, verbose=1)
return model
if __name__ == '__main__':
model = solution_model()
model.save("mymodel.h5")