您好,我正在嘗試在 kaggle dogs-vs-cats 資料集的一小部分上訓練 tensorflow 卷積模型。
我正在通過以下方式構建模型:
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
(如果從終端而不是從 Jupyter notebook 洗掉!)并獲得較小版本的資料集,您可以使用以下腳本
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)
該示例取自此處
uj5u.com熱心網友回復:
這是因為字串“accuracy”在幕后被轉換為tf.keras.metrics.BinaryAccuracy()(以 0.5 作為閾值自動將浮點數轉換為 0-1)。在第一種情況下,您使用tf.keras.metrics.Accuracy()的是需要精確匹配的模型,而您的模型僅輸出浮點數概率而不是 0-1。
參見官方檔案:
當您傳遞字串 'accuracy' 或 'acc' 時,我們會根據使用的損失函式和模型輸出形狀。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/534014.html
