簡體   English   中英

我是否在 neural.network 中錯誤標記了我的數據?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM