我目前使用的是从Kaggle入门代码中获取的Unet模型,并修改了一些参数,以便在TACO数据集上训练用于垃圾分类的模型。现在,我不知道如何继续优化我的模型。我遇到了极高的损失和极低的准确率,我不太确定哪些参数能改善我的模型的准确率和损失。TACO数据集有60个类别(包括背景在内是61个)。我是不是做错了什么?我对这个领域还比较新,所以任何可以阅读的参考资料或建议都将非常受欢迎。
这是我的模型代码:
IMG_WIDTH = 224IMG_HEIGHT = 224IMG_CHANNELS = 3epochs = 25validation_steps = val_sizesteps_per_epoch = train_size##Creating the modelinitializer = "he_normal"###Building U-Net Model##Input Layerinputs = Input((IMG_WIDTH, IMG_HEIGHT, IMG_CHANNELS))##Converting inputs to floats = tf.keras.layers.Lambda(lambda x: x / 255)(inputs)##Contractionc1 = tf.keras.layers.Conv2D(16, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(s)c1 = tf.keras.layers.Dropout(0.1)(c1)c1 = tf.keras.layers.Conv2D(16, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(c1)p1 = tf.keras.layers.MaxPooling2D((2,2))(c1)c2 = tf.keras.layers.Conv2D(32, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(p1)c2 = tf.keras.layers.Dropout(0.1)(c2)c2 = tf.keras.layers.Conv2D(32, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(c2)p2 = tf.keras.layers.MaxPooling2D((2,2))(c2)c3 = tf.keras.layers.Conv2D(64, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(p2)c3 = tf.keras.layers.Dropout(0.2)(c3)c3 = tf.keras.layers.Conv2D(64, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(c3)p3 = tf.keras.layers.MaxPooling2D((2,2))(c3)c4 = tf.keras.layers.Conv2D(128, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(p3)c4 = tf.keras.layers.Dropout(0.2)(c4)c4 = tf.keras.layers.Conv2D(128, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(c4)p4 = tf.keras.layers.MaxPooling2D((2,2))(c4)c5 = tf.keras.layers.Conv2D(256, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(p4)c5 = tf.keras.layers.Dropout(0.3)(c5)c5 = tf.keras.layers.Conv2D(256, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(c5)##Expansionu6 = tf.keras.layers.Conv2DTranspose(128, (2,2), strides=(2,2), padding="same")(c5)u6 = tf.keras.layers.concatenate([u6, c4])c6 = tf.keras.layers.Conv2D(128, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(u6)c6 = tf.keras.layers.Dropout(0.2)(c6)c6 = tf.keras.layers.Conv2D(128, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(c6)u7 = tf.keras.layers.Conv2DTranspose(64, (2,2), strides=(2,2), padding="same")(c6)u7 = tf.keras.layers.concatenate([u7, c3])c7 = tf.keras.layers.Conv2D(64, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(u7)c7 = tf.keras.layers.Dropout(0.2)(c7)c7 = tf.keras.layers.Conv2D(64, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(c7)u8 = tf.keras.layers.Conv2DTranspose(32, (2,2), strides=(2,2), padding="same")(c7)u8 = tf.keras.layers.concatenate([u8, c2])c8 = tf.keras.layers.Conv2D(32, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(u8)c8 = tf.keras.layers.Dropout(0.1)(c8)c8 = tf.keras.layers.Conv2D(32, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(c8)u9 = tf.keras.layers.Conv2DTranspose(16, (2,2), strides=(2,2), padding="same")(c8)u9 = tf.keras.layers.concatenate([u9, c1], axis=3)c9 = tf.keras.layers.Conv2D(16, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(u9)c9 = tf.keras.layers.Dropout(0.1)(c9)c9 = tf.keras.layers.Conv2D(16, (3,3), activation="relu", kernel_initializer=initializer, padding="same")(c9)##Output Layeroutputs = tf.keras.layers.Dense(61, activation="softmax")(c9)##Defining Modelmodel = tf.keras.Model(inputs=[inputs], outputs=[outputs])##Compiling Modelmodel.compile(optimizer="adam", loss="categorical_crossentropy", metrics=['accuracy'])##Training the modelresults = model.fit(x = train_gen, validation_data = val_gen, steps_per_epoch = steps_per_epoch, validation_steps = validation_steps, epochs = epochs, verbose = True)
这是第一轮epoch的准确率和损失情况:
Epoch 1/25 185/1200 [===>..........................] - ETA: 3:30:04 - loss: 388.0077 - accuracy: 9.0721e-04
我目前使用TensorBoard、ModelCheckpoint和EarlyStopping作为回调函数,但遗憾的是我不知道这些如何帮助优化我的模型。增加每层的神经元数量会有效吗?
回答:
我猜,你对训练速度不满意:ETA 3:30:04
。通常模型需要训练几轮才能显著降低损失。但是每轮等待4小时可不好,对吗?你可以做几件事:
- 确保你在GPU上训练模型,因为CPU和GPU训练之间的差异是巨大的
- 你可以尝试简化你的模型
- 或者,如果你想要复杂的模型,但没有太多时间训练,可以使用迁移学习
在迁移学习中,你可以使用预训练模型,添加自己的层,然后重新训练。以下是一个示例:
from tensorflow.keras.applications import MobileNetV2from tensorflow.keras.layers import *base_model = MobileNetV2( include_top=False, input_shape=(IMG_WIDTH, IMG_HEIGHT, IMG_CHANNELS))base_model.trainable = Falselayer = Dense(256, activation='relu')(base_model.output)layer = BatchNormalization()(layer)out = Dense(61, activation='softmax')(layer)model = Model(inputs=base_model.input, outputs=out)