[英]Am I mislabeling my data in my neural network?
我正在 Tensorflow 中實現 EfficientNet。我的 model 過度擬合並將所有三個類預測為一個 class。經過幾個時期后,我的訓練和驗證准確度達到 99%,我的損失小於 0.5。 我在三個類別(12、8、12)之間有 32,000 張圖像。
我的假設是,它與我輸入數據的方式和對標簽進行熱編碼的方式有關。 也許是因為所有東西都被意外地標記為相同,但我不知道在哪里。
# Load Data
train_ds = tf.keras.utils.image_dataset_from_directory(
train_dir,
labels='inferred',
seed=42,
image_size=(height, width),
batch_size=batch_size
)
val_ds = tf.keras.utils.image_dataset_from_directory(
val_dir,
labels='inferred',
seed=42,
image_size=(height, width),
batch_size=batch_size
)
class_names = train_ds.class_names
num_classes = len(class_names)
print('There are ' + str(num_classes) + ' classes:\n' + str(class_names))
# Resize images
train_ds = train_ds.map(lambda image, label: (
tf.image.resize(image, (height, width)), label))
val_ds = val_ds.map(lambda image, label: (
tf.image.resize(image, (height, width)), label))
這提供了正確圖像和 class 標簽的示例:
# # Visualization of samples
# plt.figure(figsize=(10, 10))
# for images, labels in train_ds.take(1):
# for i in range(9):
# ax = plt.subplot(3, 3, i + 1)
# plt.imshow(images[i].numpy().astype("uint8"))
# plt.title(class_names[labels[i]])
# plt.axis("off")
這會導致標簽出現問題嗎?
# Prepare inputs
# One-hot / categorical encoding
def input_preprocess(image, label):
label = tf.one_hot(label, num_classes)
return image, label
train_ds = train_ds.map(input_preprocess,
num_parallel_calls=tf.data.AUTOTUNE)
train_ds = train_ds.prefetch(tf.data.AUTOTUNE)
val_ds = val_ds.map(input_preprocess)
我的網絡:
def build_model(num_classes):
inputs = Input(shape=(height, width, 3))
x = img_augmentation(inputs)
model = EfficientNetB0(
include_top=False, input_tensor=x, weights="imagenet")
# Freeze the pretrained weights
model.trainable = False
# Rebuild top
x = layers.GlobalAveragePooling2D(name="avg_pool")(model.output)
x = layers.BatchNormalization()(x)
top_dropout_rate = 0.4
x = layers.Dropout(top_dropout_rate, name="top_dropout")(x)
outputs = layers.Dense(num_classes, activation="softmax", name="pred")(x)
# Compile
model = tf.keras.Model(inputs, outputs, name="EfficientNet")
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3)
model.compile(
optimizer=optimizer, loss="categorical_crossentropy", metrics=["accuracy"]
)
return model
with strategy.scope():
model = build_model(num_classes=num_classes)
epochs = 40
hist = model.fit(train_ds, epochs=epochs, validation_data=val_ds,
workers=6, verbose=1, callbacks=callback)
plot_hist(hist)
好吧,首先你寫的代碼比你需要的多。 在 train_ds 和 val_ds 中,您沒有指定參數 label_mode。 默認情況下,它設置為“int”。 這意味着您的標簽將是整數。 如果您使用 loss=tf.keras.losses.SparseCategoricalCrossentropy 編譯您的 model,這很好。 如果你已經設置
label_mode= 'categorical' then you can use loss=tf.keras.losses.CategoricalCrossentropy
您確實將標簽轉換為單熱編碼,並且似乎已正確完成。 但是您可以通過將 label 模式設置為分類模式來避免這樣做,如前所述。 您還編寫了調整圖像大小的代碼。 這不是必需的,因為 tf.keras.utils.image_dataset_from_directory 為您調整了圖像的大小。 我無法讓您的 model 運行可能是因為我沒有 x = img_augmentation(inputs) 的代碼。 你有代碼
model = EfficientNetB0(
include_top=False, input_tensor=x, weights="imagenet")
由於您使用的是 model API 我認為這應該是
model = EfficientNetB0( include_top=False, weights="imagenet", pooling='max')(x)
注意我包括 pooliing='max' 所以 efficien.net 產生一維張量 output 因此你不需要層
x = layers.GlobalAveragePooling2D(name="avg_pool")(model.output)
我還修改了您的代碼以生成一個 test_ds,這樣我就可以測試 model 的准確性。當然我使用了不同的數據集,但結果很好。 我的完整代碼如下所示
train_dir=r'../input/beauty-detection-data-set/train'
val_dir=r'../input/beauty-detection-data-set/valid'
batch_size=32
height=224
width=224
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
train_dir,
labels='inferred',
validation_split=0.1,
subset="training",
label_mode='categorical',
seed=42,
image_size=(height, width),
batch_size=batch_size
)
test_ds = tf.keras.preprocessing.image_dataset_from_directory(
train_dir,
labels='inferred',
validation_split=0.1,
subset="validation",
label_mode='categorical',
seed=42,
image_size=(height, width),
batch_size=batch_size)
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
val_dir,
labels='inferred',
seed=42,
label_mode='categorical',
image_size=(height, width),
batch_size=batch_size
)
class_names = train_ds.class_names
num_classes = len(class_names)
print('There are ' + str(num_classes) + ' classes:\n' + str(class_names))
img_shape=(224,224,3)
base_model=tf.keras.applications.EfficientNetB3(include_top=False, weights="imagenet",input_shape=img_shape, pooling='max')
x=base_model.output
x=keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001 )(x)
x = Dense(256, kernel_regularizer = regularizers.l2(l = 0.016),activity_regularizer=regularizers.l1(0.006),
bias_regularizer=regularizers.l1(0.006) ,activation='relu')(x)
x=Dropout(rate=.45, seed=123)(x)
output=Dense(num_classes, activation='softmax')(x)
model=Model(inputs=base_model.input, outputs=output)
model.compile(Adamax(lr=.001), loss='categorical_crossentropy', metrics=['accuracy'])
epochs =5
hist = model.fit(train_ds, epochs=epochs, validation_data=val_ds,
verbose=1)
accuracy =model.evaluate(test_ds, verbose=1)[1]
print (accuracy)
```
如果您使用labels='inferred'
,您還應該指定class_names
,這將是您從中獲取圖像的三個文件夾的名稱。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.