我正在尝试训练一个语义分割网络( E-Net ),尤其是针对高质量的人类分割。为此,我收集了“ Supervisely Person”数据集,并使用提供的API提取了注释掩码。该数据集拥有高质量的蒙版,因此我认为与例如可可数据集。
监督-以下示例:原始图片-地面真实情况。
首先,我想提供一些模型细节。网络本身(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输出
后来,我尝试对整个数据集进行训练,但是训练损失导致很多振荡。这意味着网络在某些图像中表现良好,而在另一些图像中则表现不佳。结果是经过743360次迭代(160个纪元,因为训练集包含4646个图像),我停止了训练,因为显然我所做的超参数选择存在问题。
监督-以下示例:(1)损失(2)学习率(3)输入(在调整大小之前)|基本事实(调整大小之前)| 1080p输出
另一方面,在某些训练集图像实例上,网络会产生如下所示的公平(虽然不是很好)结果。
监督-下面的示例:输入(在调整大小之前)|基本事实(调整大小之前)| 1080p输出
为什么我在这些训练实例上有这些差异?我应该对模型或超参数进行任何明显的更改吗?此模型是否可能不适合此用例(例如,低网络容量)?
谢谢。