你好,我正在尝试训练一个tensorflow卷积模型的一小部分kaggle狗对猫的数据集。
我以下列方式建立模型:
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.utils import image_dataset_from_directory
import pathlib
new_base_dir = pathlib.Path("../8/cats_vs_dogs_small")
data_augmentation = keras.Sequential(
[
layers.RandomFlip("horizontal"),
layers.RandomRotation(0.1),
layers.RandomZoom(0.2),
]
)
inputs = keras.Input(shape=(180, 180, 3))
x = data_augmentation(inputs)
x = layers.Rescaling(1./255)(x)
x = layers.Conv2D(filters=32, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=64, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=128, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=256, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=256, kernel_size=3, activation="relu")(x)
x = layers.Flatten()(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(1, activation="sigmoid")(x)
model = keras.Model(inputs=inputs, outputs=outputs)
train_dataset = image_dataset_from_directory(
new_base_dir/"train",
image_size=(180,180),
batch_size=32
)
validation_dataset = image_dataset_from_directory(
new_base_dir/"validation",
image_size=(180,180),
batch_size=32
)
test_dataset = image_dataset_from_directory(
new_base_dir/"test",
image_size=(180,180),
batch_size=32
)
我试着用两种方法编译,我希望是一样的:
model.compile(optimizer=keras.optimizers.RMSprop(),
loss=keras.losses.BinaryCrossentropy(),
metrics=[keras.metrics.Accuracy()])
和
model.compile(loss="binary_crossentropy",
optimizer="rmsprop",
metrics=["accuracy"])
然后用
history = model.fit(
train_dataset,
validation_data=validation_dataset,
epochs=5)
然而,我在两个编译中得到了不同的结果:在第一个例子中,模型似乎根本没有训练(见第一张图);而在第二个例子中,模型正在学习(见第二张图)。
这两个版本有什么不同吗?为什么?
获取数据集若要获取数据集并使用较小的版本(如果您有kaggle帐户),您可以执行以下操作
!kaggle competitions download -c dogs-vs-cats
!unzip -qq train.zip
(if从终端而不是从Jupyter笔记本删除!
),要获得较小版本的数据集,可以使用以下脚本
import os, shutil, pathlib
original_dir = pathlib.Path("./train")
new_base_dir = pathlib.Path("cats_vs_dogs_small")
def make_subset(subset_name, start_index, end_index):
for category in ("cat", "dog"):
dir = new_base_dir / subset_name / category
os.makedirs(dir)
fnames = [f"{category}.{i}.jpg" for i in range(start_index, end_index)]
for fname in fnames:
shutil.copyfile(src=original_dir / fname,
dst=dir / fname)
make_subset("train", start_index=0, end_index=1000)
make_subset("validation", start_index=1000, end_index=1500)
make_subset("test", start_index=1500, end_index=2500)
示例取自here
1条答案
按热度按时间erhoui1w1#
这是因为字符串“accuracy”被转换为
tf.keras.metrics.BinaryAccuracy()
(它将浮点数自动转换为0-1,阈值为0.5)。在第一种情况下,您使用的是tf.keras.metrics.Accuracy()
,它要求精确匹配,而您的模型只输出浮点数概率,而不是0-1。参见官方文档:
当您传递字符串'accuracy'或'acc'时,我们根据所使用的损失函数和模型输出形状将其转换为tf.keras.metrics.BinaryAccuracy、tf. keras.metrics.CategoricalAccuracy、tf.keras.metrics.SparseCategoricalAccuracy中的一个。