【问题标题】:UNet COCO 2017 Model has terrible loss and accuracyUNet COCO 2017 模型具有可怕的损失和准确性
【发布时间】:2020-09-05 23:17:14
【问题描述】:

我目前正在使用 COCO 2017 数据集和使用 keras 和 tensorflow 的 UNet 架构练习图像分割,但我遇到了可怕的准确性和损失值。

我编写了一个函数,该函数通过数据集过滤选择某些类的特定图像,并将它们传递到一个类似于注释文件的列表变量中,其中包含图像文件名和图像 ID。然后将这些数据输入到生成器中,生成器的输出是生成器变量,然后我将其输入到我的 model.fit 函数中。

我目前有 3 个课程,[背景、电视、笔记本电脑]。

以下代码是我的模型:

IMG_WIDTH = 224
IMG_HEIGHT = 224
IMG_CHANNELS = 3
epochs = 25
validation_steps = val_size
steps_per_epoch = train_size

##Creating the model

initializer = "he_normal"

###Building U-Net Model

##Input Layer
inputs = Input((IMG_WIDTH, IMG_HEIGHT, IMG_CHANNELS))

##Converting inputs to float
s = tf.keras.layers.Lambda(lambda x: x / 255)(inputs)

##Contraction
c1 = 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)

##Expansion
u6 = 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 Layer
outputs = tf.keras.layers.Conv2D(1, (1,1), activation="softmax")(c9)

##Defining Model
model = tf.keras.Model(inputs=[inputs], outputs=[outputs])

##Compiling Model
model.compile(optimizer="adam", loss="categorical_crossentropy", metrics=['accuracy'])


##Training the model
results = model.fit(x = train_gen, 
                    validation_data = val_gen, 
                    steps_per_epoch = steps_per_epoch, 
                    validation_steps = validation_steps, 
                    epochs = epochs, 
                    verbose = True)

当我开始训练时,这些是准确率和损失参数:

Epoch 1/25
  32/7069 [..............................] - ETA: 16:01:30 - loss: 2.2134e-08 - accuracy: 0.0472

这与我之前使用 Unet 进行细胞核分割的经验不同。我的问题是:这正常吗?如果不是,我如何提高模型的准确性和损失?我对机器学习非常陌生,所以我能阅读的任何建议或参考资料将不胜感激。

【问题讨论】:

    标签: python tensorflow machine-learning keras deep-learning


    【解决方案1】:

    问题就在这里:

    outputs = tf.keras.layers.Conv2D(1, (1,1), activation="softmax")(c9)
    

    如果你有三个类,你应该在大小为 3 的输出上激活 softmax,对吗?我会在最后使用 DENSE 层,例如:

    outputs = model.add(Dense(3, activation='softmax'))(c9)
    

    你应该很好。

    【讨论】:

    • 天哪,我不敢相信我没有注意到这一点!感谢您指出这一点!我现在正在处理更现实的数字,损失从 0.60 开始,准确度从 0.55 开始。这些正常数字是否可以通过进一步的培训来解决?最后,为什么密集层更适合输出?非常感谢!
    • @HomerBacanto 更现实,但接近 0.5 的准确度实际上意味着您有很大的改进空间(因为随机选择收敛到 0.5)。对于 DENSE 层,实际上是您选择使用什么。这是DL中的经典设计。唯一重要的是在输出中包含尽可能多的班级编号。
    • 谢谢@MikhailStepanov!奇怪的是,Dense 层开始时的准确率/损失比比 Conv2D 层更好。训练后 Conv2D 会比 Dense 层更好吗?再次感谢
    • @alift 这些改进需要什么?您是指添加层、更改层中的神经元数量还是调整选择不同的优化器?
    • @HomerBacanto 那是我的错。如果Dense 层应用于 4D 张量,如Conv2D 输出,它将返回 4D 张量。它的输出将被正确地softmaxed,即沿着通道轴(最后,-1)。我错了Conv2D 与 softmax。我没有检查它,但我猜softmax应用于整个输出。但是分割需要沿着-1轴的softmax,正如Dense实际上所做的那样。
    猜你喜欢
    • 2018-09-16
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    • 2016-07-18
    • 2018-01-03
    • 2021-07-23
    • 1970-01-01
    • 2020-08-08
    相关资源
    最近更新 更多