10

我有一个产生 4D 输出张量的网络,其中空间维度(〜像素)中每个位置的值将被解释为该位置的类概率。换句话说,输出是(num_batches, height, width, num_classes)。我有相同大小的标签,其中真正的类被编码为 one-hot。我想categorical-crossentropy用这个来计算损失。

问题 #1:函数K.softmax需要一个2D张量(num_batches, num_classes)

问题#2:我不确定每个位置的损失应该如何组合。reshape张量到(num_batches * height * width, num_classes)然后调用它是否正确K.categorical_crossentropy?或者更确切地说,调用K.categorical_crossentropy(num_batches, num_classes)height*width 次并平均结果?

4

4 回答 4

8

发现这个问题来证实我的直觉。

简而言之:softmax 将采用 2D 或 3D 输入。如果它们是 3D keras 将采用这样的形状(样本、时间维度、numclasses)并在最后一个上应用 softmax。由于一些奇怪的原因,它不会为 4D 张量做到这一点。

解决方案:将输出重塑为一系列像素

reshaped_output = Reshape((height*width, num_classes))(output_tensor)

然后应用你的softmax

new_output = Activation('softmax')(reshaped_output) 

然后要么将目标张量重塑为 2D,要么将最后一层重塑为(宽度、高度、num_classes)。

否则,如果我现在不在手机上,我会尝试使用TimeDistributed(Activation('softmax')). 但不知道这是否可行……稍后再试

我希望这有帮助 :-)

于 2017-04-01T07:01:43.523 回答
2

您也可以什么都不做,而是自己reshape定义。这是应用于最后一个输入维度的(如在后端):softmaxlosssoftmaxtf

def image_softmax(input):
    label_dim = -1
    d = K.exp(input - K.max(input, axis=label_dim, keepdims=True))
    return d / K.sum(d, axis=label_dim, keepdims=True)

在这里你有loss(没有必要重塑任何东西):

__EPS = 1e-5
def image_categorical_crossentropy(y_true, y_pred):
    y_pred = K.clip(y_pred, __EPS, 1 - __EPS)
    return -K.mean(y_true * K.log(y_pred) + (1 - y_true) * K.log(1 - y_pred))

无需进一步重塑。

于 2017-04-03T22:15:40.330 回答
2

只需将输出展平为 size 的 2D 张量(num_batches, height * width * num_classes)。您可以对Flatten图层执行此操作。确保您y以相同的方式展平(通常调用y = y.reshape((num_batches, height * width * num_classes))就足够了)。

对于第二个问题,对所有width*height预测使用分类交叉熵与对每个预测的分类交叉熵求平均值基本相同width*height(通过分类交叉熵的定义)。

于 2017-03-27T04:55:15.917 回答
1

似乎现在您可以简单地softmax在最后一层进行激活Conv2D,然后指定categorical_crossentropy损失并在图像上进行训练,而无需任何重塑技巧或任何新的损失函数。我尝试过使用虚拟数据集进行过度拟合,效果很好。试试看~!

inp = keras.Input(...)
# define your model here
out = keras.layers.Conv2D(classes, (1, 1), activation='softmax') (...)
model = keras.Model(inputs=[inp], outputs=[out], name='unet')
model.compile(loss='categorical_crossentropy',
                      optimizer='adam',
                      metrics=['accuracy'])
model.fit(tensor4d, tensor4d)

您还可以使用形状进行编译sparse_categorical_crossentropy,然后使用形状输出进行训练,其中输出中的(samples, height, width)每个像素对应一个类标签:model.fit(tensor4d, tensor3d)

这个想法是,softmax并将categorical_crossentropy应用于最后一个轴(您可以检查keras.backend.softmaxkeras.backend.categorical_crossentropy文档)。

PS。我kerastensorflow.keras(张量流2)使用

更新:我已经对我的真实数据集进行了培训,并且它也可以正常工作。

于 2019-12-14T12:54:09.013 回答