1

我正在尝试训练一个语义分割网络(E-Net),特别是用于高质量的人体分割。为此,我收集了“监督人员”数据集,并使用提供的 API 提取了注释掩码。该数据集包含高质量的掩码,因此我认为与例如 COCO 数据集相比,它将提供更好的结果。

监督 - 下面的例子:原始图像 - 基本事实。

在此处输入图像描述

首先,我想给出模型的一些细节。网络本身 ( Enet_arch) 从最后一个卷积层返回 logits 和通过 产生的概率tf.nn.sigmoid(logits,name='logits_to_softmax')

我在地面实况上使用 sigmoid 交叉熵,在学习率上使用返回的 logits、动量和指数衰减。模型实例和训练管道如下。

    self.global_step = tf.Variable(0, name='global_step', trainable=False)
    self.momentum = tf.Variable(0.9, trainable=False)

    # introducing weight decay
    #with slim.arg_scope(ENet_arg_scope(weight_decay=2e-4)):
    self.logits, self.probabilities  = Enet_arch(inputs=self.input_data, num_classes=self.num_classes, batch_size=self.batch_size) # returns logits (2d), probabilities (2d)

    #self.gt is int32 with values 0 or 1 (coming from read_tfrecords.Read_TFRecords annotation images + placeholder defined to int)
    self.gt = self.input_masks

    # self.probabilities is output of sigmoid, pixel-wise between probablities [0, 1].
    # self.predictions is filtered probabilities > 0.5 = 1 else 0
    self.predictions = tf.to_int32(self.probabilities > 0.5)

    # capture segmentation accuracy
    self.accuracy, self.accuracy_update = tf.metrics.accuracy(labels=self.gt, predictions=self.predictions)

    # losses and updates
    # calculate cross entropy loss on logits
    loss = tf.losses.sigmoid_cross_entropy(multi_class_labels=self.gt, logits=self.logits)

    # add the loss to total loss and average (?)
    self.total_loss = tf.losses.get_total_loss()

    # decay_steps = depend on the number of epochs
    self.learning_rate = tf.train.exponential_decay(self.starter_learning_rate, global_step=self.global_step, decay_steps=123893, decay_rate=0.96, staircase=True)

    #Now we can define the optimizer
    #optimizer = tf.train.AdamOptimizer(learning_rate=self.learning_rate, epsilon=1e-8)
    optimizer = tf.train.MomentumOptimizer(self.learning_rate, self.momentum)

    #Create the train_op.
    self.train_op = optimizer.minimize(loss, global_step=self.global_step)

我首先尝试在单个图像上过度拟合模型,以识别该网络可以捕获的细节深度。为了提高输出质量,我将所有图像的大小调整为1080p,然后再将它们输入网络。在这个试验中,我对网络进行了 10K 次迭代训练,总误差达到了 ~30%(从 捕获tf.losses.get_total_loss())。

如下所示,在单个图像上训练的结果非常好。

监督 - 下面的示例:(1)损失(2)输入(调整大小之前)| 基本事实(调整大小之前)| 1080p 输出

在此处输入图像描述

在此处输入图像描述

后来,我尝试在整个数据集上进行训练,但训练损失会产生很多波动。这意味着在某些图像中网络表现良好,而在另一些图像中则不然。作为 743360 次迭代(即 160 个 epoch,因为训练集包含 4646 张图像)后的结果,我停止了训练,因为我所做的超参数选择显然有问题。

监督 - 下面的示例:(1)损失(2)学习率(3)输入(调整大小之前)| 基本事实(调整大小之前)| 1080p 输出

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

另一方面,在训练集图像的某些实例上,网络会产生如下所示的公平(虽然不是很好)结果。

监督 - 下面的示例:输入(调整大小之前)| 基本事实(调整大小之前)| 1080p 输出

在此处输入图像描述

为什么我在这些训练实例上有这些差异?我应该对模型或超参数进行任何明显的更改吗?这个模型是否可能不适合这个用例(例如低网络容量)?

提前致谢。

4

1 回答 1

0

事实证明,这里的问题确实是 E-net 架构。我用 DeepLabV3 改变了架构,发现损失行为和性能有很大的不同……即使是小分辨率!

在此处输入图像描述

于 2018-12-20T09:22:45.233 回答