tid*_*idy 6 python image-segmentation keras tensorflow tf.keras
如果我Softmax Activation
像这样设置最后一层,我正在用unet进行图像语义分割工作:
...
conv9 = Conv2D(n_classes, (3,3), padding = 'same')(conv9)
conv10 = (Activation('softmax'))(conv9)
model = Model(inputs, conv10)
return model
...
Run Code Online (Sandbox Code Playgroud)
然后使用即使只有一个训练图像loss = tf.keras.losses.CategoricalCrossentropy(from_logits=False)
,训练也不会收敛。
但是,如果我没有Softmax Activation
像这样设置最后一层:
...
conv9 = Conv2D(n_classes, (3,3), padding = 'same')(conv9)
model = Model(inputs, conv9)
return model
...
Run Code Online (Sandbox Code Playgroud)
然后使用loss = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
训练将收敛为一个训练图像。
我的groundtruth数据集是这样生成的:
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))
Run Code Online (Sandbox Code Playgroud)
为什么?我的用法有问题吗?
这是我的git实验代码:https : //github.com/honeytidy/unet 您可以检出并运行(可以在cpu上运行)。您可以更改激活层和CategoricalCrossentropy的from_logits并查看我说的内容。
默认情况下,Tensorflow 中实现的用于分类问题的所有损失函数都使用 from_logits=False。请记住,在分类问题的情况下,在预测结束时,通常希望根据概率产生输出。
\n看看下图,网络的最后一层(就在softmax函数之前)
\n\n所以序列是神经网络 \xe2\x87\x92 最后一层输出 \xe2\x87\x92 Softmax 或 Sigmoid 函数 \xe2\x87\x92 每个类的概率。
\n例如,在多类分类问题的情况下,输出可以是 y1, y2, .... yn,人们希望以某种概率产生每个输出。(参见输出层)。现在,该输出层将在交叉熵损失函数中与真实标签进行比较。
\n让我们举一个例子,我们的网络生成分类任务的输出。假设您的神经网络正在产生输出,然后使用 softmax 函数将该输出转换为概率,并使用交叉熵损失函数计算损失
\n# output produced by the last layer of NN\nnn_output_before_softmax = [3.2, 1.3, 0.2, 0.8]\n\n# converting output of last layer of NN into probabilities by applying softmax\nnn_output_after_softmax = tf.nn.softmax(nn_output_before_softmax)\n\n# output converted into softmax after appling softmax\nprint(nn_output_after_softmax.numpy())\n[0.77514964 0.11593805 0.03859243 0.07031998]\n\ny_true = [1.0, 0.0, 0.0, 0.0]\n
Run Code Online (Sandbox Code Playgroud)\n现在有两种情况:
\n一种是明确使用 softmax(或 sigmoid)函数
\n一是不单独使用softmax函数,想包含在损失函数的计算中
\n当明确使用softmax(或sigmoid)函数时,对于分类任务,TensorFlow损失函数中有一个默认选项,即from_logits=False。因此,这里 TensorFlow 假设您将输入到损失函数的任何输入都是概率,因此无需应用 softmax 函数。
\n# By default from_logits=False\nloss_taking_prob = tf.keras.losses.CategoricalCrossentropy(from_logits=False) \n\nloss_1 = loss_taking_prob(y_true, nn_output_after_softmax)\nprint(loss_1)\ntf.Tensor(0.25469932, shape=(), dtype=float32)\n
Run Code Online (Sandbox Code Playgroud)\nloss_taking_logits = tf.keras.losses.CategoricalCrossentropy(from_logits=True)\n\nloss_2 = loss_taking_logits(y_true, nn_output_before_softmax)\nprint(loss_2)\ntf.Tensor(0.2546992, shape=(), dtype=float32)\n
Run Code Online (Sandbox Code Playgroud)\n请记住,当它应该为 True 时使用 from_logits=False 会导致采用概率的 softmax 并生成错误的模型
\n小智 5
from_logits = True
表示模型获得的损失值未标准化,基本上在模型中没有任何 softmax 函数时使用。例如https://www.tensorflow.org/tutorials/generative/dcgan在这个模型中,他们没有使用 softmax 激活函数,或者换句话说,我们可以说它有助于数值稳定性。