zhimingluo / NLDF

Other
59 stars 19 forks source link

loss变为NAN #2

Open i4yyds opened 6 years ago

i4yyds commented 6 years ago

您好!我将您代码中的网络结构简化为以下代码: self.pool5_conv1 = self.Conv2d(vgg.pool5, [3, 3, 512, 128], 0.01, padding='SAME', name='c1') self.contrast_1 = self.Contrast_Layer(self.pool5_conv1, 3) self.pool5_conv2 = self.Conv_2d(tf.concat([self.pool5_conv1, self.contrast1], axis=3), [3, 3, 256, 256], 0.01, padding='SAME', name='c2') self.pool5_conv3 = self.Conv_2d(self.pool5conv2, [1, 1, 256, 2], 0.01, padding='SAME', name='c3') self.Score = tf.nn.conv2d_transpose(self.pool5_conv3, self.bilinear_upsample_weights(16, 2), output_shape=[1, 176, 176, 2], strides=[1, 16, 16, 1]) 然后loss下降到0.32左右时,Loss就会变为NAN。(loss是边缘损失和交叉熵的和) 但是我运行你的网络结构时并不会出现NAN的问题,loss能降到很低。降低学习率我已经试了,然而并不行。 请问我应该如何解决这个问题呢?

asgq123 commented 5 years ago

你好,请问你用的是MSRA-B数据集吗?我训练时遇到了nan的情况 @SoulCoderCN

zhimingluo commented 5 years ago

你好,请问你用的是MSRA-B数据集吗?我训练时遇到了nan的情况 @SoulCoderCN

你好,我这几天比较忙没有时间去检查具体是什么原因导致的NaN,需要过几天才能告诉你具体的原因。

asgq123 commented 5 years ago

我没有怎么接触过显著性检测,之前用其他模型的时候,由于Batchsize过大,loss会变为NAN,这边可以设置批处理吗 @zhimingluo

zhimingluo commented 5 years ago

应该不是batch的问题,不太确定是不是loss的具体实现是否有Bug

asgq123 commented 5 years ago

你训练的时候有遇到这样的情况吗? @zhimingluo

zhimingluo commented 5 years ago

你训练的时候有遇到这样的情况吗? @zhimingluo

我训练的时候,好像没怎么遇到NaN的情况

asgq123 commented 5 years ago

emmm,如果你方便的话,可以分享下你用的数据集吗?MSRA-B?

zhimingluo commented 5 years ago

应该就是MSRA-B数据集,不知道现在还能不能找到下载的链接

AlphaNext commented 5 years ago

Hello, @zhimingluo 有几个问题想请教一下,下面的程序片段摘自NLDF.py中:

# 73~84行
#Get the contour term
self.Prob_C = tf.reshape(self.Prob, [1, 176, 176, 2])
self.Prob_Grad = tf.tanh(self.im_gradient(self.Prob_C))
self.Prob_Grad = tf.tanh(tf.reduce_sum(self.im_gradient(self.Prob_C), reduction_indices=3, keep_dims=True))

self.label_C = tf.reshape(self.label_holder, [1, 176, 176, 2])
self.label_Grad = tf.cast(tf.greater(self.im_gradient(self.label_C), self.contour_th), tf.float32)
self.label_Grad = tf.cast(tf.greater(tf.reduce_sum(self.im_gradient(self.label_C),
                                                           reduction_indices=3, keep_dims=True),
                                             self.contour_th), tf.float32)

self.C_IoU_LOSS = self.Loss_IoU(self.Prob_Grad, self.label_Grad)

# 152~158行
def Loss_IoU(self, pred, gt):     
        inter = tf.reduce_sum(tf.multiply(pred, gt))     
        union = tf.add(tf.reduce_sum(tf.square(pred)), tf.reduce_sum(tf.square(gt)))     
        if inter == 0:     
            return 0     
        else:      
            return 1 - (2*(inter+1)/(union + 1))
ZhangXG001 commented 4 years ago

@AlphaNext @SoulCoderCN label读取并resize之后应该是0或者1的二值图,但是在经过self.im_gradient函数后取值范围应该是(0, ]也就是大于零,1.5这个取值应该是凭经验取吧。还有就是loss会出现nan的问题,总的损失包括了iou损失和交叉熵损失,我把他们单独拿出来测试,发现问题出现在iou损失,当iou损失降低到一定值时就会出现nan,根据iou损失的定义,把问题定位到了im_gradient函数,返回值使用了tf.sqrt,这个函数会有结果为nan的现象出现,我把代码修改为tf.sqrt(tf.add(tf.square(gx)+1e-8,tf.square(gy)+1e-8)+1e-8)解决了这个问题。