我是否在神经网络中错误地标记了我的数据?



我正在Tensorflow中实现高效网络。我的模型是过拟合的,并且预测这三个类别只是一个类别。经过几个epoch,我的训练和验证准确率在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))

这提供了正确的图像和类标签的示例:

# # 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编译你的模型,这是很好的。如果你设置了

label_mode= 'categorical' then you can use loss=tf.keras.losses.CategoricalCrossentropy 

您确实将标签转换为单热编码,并且似乎已正确完成。但是您可以通过如上所述将标签模式设置为categorical来避免这样做。您还编写了代码来调整图像的大小。这是不必要的,因为tf.keras.utils。Image_dataset_from_directory为您调整了图像的大小。我有麻烦让你的模型运行可能是因为我没有x = img_augmentation(输入)的代码。你的代码

model = EfficientNetB0(
include_top=False, input_tensor=x, weights="imagenet")

由于您正在使用模型API,我认为这应该是

model = EfficientNetB0( include_top=False, weights="imagenet", pooling='max')(x)

我包含了poolpooling ='max',所以effentnet产生一个一维张量输出,因此你不需要层

x = layers.GlobalAveragePooling2D(name="avg_pool")(model.output)

我还修改了您的代码以生成test_ds,以便我可以测试模型的准确性。当然,我使用了不同的数据集,但结果很好。我的完整代码如下所示

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,这将是您从中获取图像的三个文件夹的名称。

最新更新