Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python from_logits=True和from_logits=False为UNet的tf.loss.CategoricalCrossentropy获得不同的训练结果_Python_Tensorflow_Keras_Image Segmentation_Tf.keras - Fatal编程技术网

Python from_logits=True和from_logits=False为UNet的tf.loss.CategoricalCrossentropy获得不同的训练结果

Python from_logits=True和from_logits=False为UNet的tf.loss.CategoricalCrossentropy获得不同的训练结果,python,tensorflow,keras,image-segmentation,tf.keras,Python,Tensorflow,Keras,Image Segmentation,Tf.keras,我正在使用unet进行图像语义分割工作,如果我为最后一层设置Softmax激活,如下所示: ... conv9 = Conv2D(n_classes, (3,3), padding = 'same')(conv9) conv10 = (Activation('softmax'))(conv9) model = Model(inputs, conv10) return model ... ... conv9 = Conv2D(n_classes, (3,3), padding = 'same')

我正在使用unet进行图像语义分割工作,如果我为最后一层设置
Softmax激活
,如下所示:

...
conv9 = Conv2D(n_classes, (3,3), padding = 'same')(conv9)
conv10 = (Activation('softmax'))(conv9)
model = Model(inputs, conv10)
return model
...
...
conv9 = Conv2D(n_classes, (3,3), padding = 'same')(conv9)
model = Model(inputs, conv9)
return model
...
X = []
Y = []
im = cv2.imread(impath)
X.append(im)
seg_labels = np.zeros((height, width, n_classes))
for spath in segpaths:
    mask = cv2.imread(spath, 0)
    seg_labels[:, :, c] += mask
Y.append(seg_labels.reshape(width*height, n_classes))
然后使用
loss=tf.keras.loss.Category交叉熵(from_logits=False)
即使只针对一个训练图像,训练也不会收敛

但是如果我没有像这样设置最后一层的
Softmax激活

...
conv9 = Conv2D(n_classes, (3,3), padding = 'same')(conv9)
conv10 = (Activation('softmax'))(conv9)
model = Model(inputs, conv10)
return model
...
...
conv9 = Conv2D(n_classes, (3,3), padding = 'same')(conv9)
model = Model(inputs, conv9)
return model
...
X = []
Y = []
im = cv2.imread(impath)
X.append(im)
seg_labels = np.zeros((height, width, n_classes))
for spath in segpaths:
    mask = cv2.imread(spath, 0)
    seg_labels[:, :, c] += mask
Y.append(seg_labels.reshape(width*height, n_classes))
然后使用
loss=tf.keras.loss.Category交叉熵(from_logits=True)
对于一个训练图像,训练将收敛

我的groundtruth数据集是这样生成的:

...
conv9 = Conv2D(n_classes, (3,3), padding = 'same')(conv9)
conv10 = (Activation('softmax'))(conv9)
model = Model(inputs, conv10)
return model
...
...
conv9 = Conv2D(n_classes, (3,3), padding = 'same')(conv9)
model = Model(inputs, conv9)
return model
...
X = []
Y = []
im = cv2.imread(impath)
X.append(im)
seg_labels = np.zeros((height, width, n_classes))
for spath in segpaths:
    mask = cv2.imread(spath, 0)
    seg_labels[:, :, c] += mask
Y.append(seg_labels.reshape(width*height, n_classes))
为什么??我的用法有问题吗

这是我的git实验代码:
您可以签出并运行(可以在cpu上运行)。你可以改变激活层和分类交叉熵的逻辑,看看我说了什么。

我猜问题来自softmax激活函数。查看,我发现默认情况下,sotmax应用于最后一个轴。你能看看
model.summary()
并检查这是否是你想要的吗

将“softmax”激活推进交叉熵损失层,可显著简化损失计算,并使其在数值上更加稳定。
在您的示例中,可能存在这样的情况:数值问题严重到足以使
from_logits=False
选项的培训过程无效


您可以在中找到交叉熵损失(信息增益损失的特例)的推导。此推导说明了将softmax与交叉熵损失相结合时避免的数值问题。

要使
softmax
正常工作,必须确保:

  • 您正在使用
    'channels\u last'
    作为Keras默认频道配置

    • 这意味着模型中的形状类似于
      (无、高度、宽度、通道)
    • 这似乎是您的情况,因为您将
      n_类
      放在最后一个轴中。但这也很奇怪,因为您使用的是
      Conv2D
      ,您的输出
      Y
      应该是
      (1,高度,宽度,n_类)
      ,而不是您使用的那种奇怪的形状
  • 您的
    Y
    只有0和1(不像通常发生在图像上的那样是0和255)

    • 检查
      Y.max()==1
      Y.min()==0
    • 您可能需要有
      Y=Y/255。
  • 只有一个类是正确的(您的数据没有多个值为1的路径/通道)

    • 检查
      (Y.sum(轴=-1)==1)。all()
      是否为
      True

from_logits=True
表示模型获得的损失值未标准化,基本上在我们的模型中没有任何softmax函数时使用。例如,在这个模型中,他们没有使用softmax激活函数,或者换句话说,我们可以说它有助于数值稳定性。

是的,数值稳定性很可能在这里发挥作用。源代码中也提到了这一点:
注意:使用from_logits=True可能在数值上更稳定。
。AFAIK Keras使用epsilon来处理这一点,epsilon可以关闭非常糟糕的分类点。从他的代码来看,他似乎在沿着图像通道维度堆叠二进制图像。是
CategoricalCrossEntropy
所期望的。计算两个模型中单个图像的像素输出和损失。损失应该是相同的。您是先使用
频道还是最后使用
频道?您的路径是独占的吗?(每个像素只有一条路径是正确的?
channels\u last
。是的,pathes是排他性的(地面真相是一个热点)。@Daniel Möller