培训E-net进行人类细分

时间:2018-12-13 12:31:56

标签: python tensorflow machine-learning deep-learning semantic-segmentation

我正在尝试训练一个语义分割网络( E-Net ),尤其是针对高质量的人类分割。为此,我收集了“ Supervisely Person”数据集,并使用提供的API提取了注释掩码。该数据集拥有高质量的蒙版,因此我认为与例如可可数据集。

监督-以下示例:原始图片-地面真实情况。

enter image description here

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

我对地面实况使用了S形交叉熵,对学习率使用了返回的对数,动量和指数衰减。模型实例和训练流水线如下。

    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输出

enter image description here

enter image description here

后来,我尝试对整个数据集进行训练,但是训练损失导致很多振荡。这意味着网络在某些图像中表现良好,而在另一些图像中则表现不佳。结果是经过743360次迭代(160个纪元,因为训练集包含4646个图像),我停止了训练,因为显然我所做的超参数选择存在问题。

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

enter image description here

enter image description here

enter image description here

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

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

enter image description here

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

谢谢。

1 个答案:

答案 0 :(得分:0)

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

enter image description here