我有一个产生4D输出张量的网络,其中空间维度(〜像素)中每个位置的值将被解释为该位置的类概率。换句话说,输出为(num_batches, height, width, num_classes)
。我有相同大小的标签,其中真实类被编码为一热。我想用此计算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)
高度*宽度时间并平均结果?
答案 0 :(得分:3)
将输出展平为尺寸为(num_batches, height * width * num_classes)
的2D张量。您可以使用Flatten
图层执行此操作。确保y
以相同的方式展平(通常调用y = y.reshape((num_batches, height * width * num_classes))
就足够了。)
对于第二个问题,对所有width*height
预测使用分类交叉熵与对每个width*height
预测的分类交叉熵平均(通过分类交叉熵的定义)基本相同。
答案 1 :(得分:3)
找到this issue来证实我的直觉。
简而言之:softmax将采用2D或3D输入。如果它们是3D keras将采用这样的形状(样本,时间尺度,数字)并在最后一个上应用softmax。出于一些奇怪的原因,它不适用于4D张量。
解决方案:将输出重塑为像素序列
reshaped_output = Reshape((height*width, num_classes))(output_tensor)
然后应用softmax
new_output = Activation('softmax')(reshaped_output)
然后要么将目标张量重塑为2D,要么将最后一层重塑为(width,height,num_classes)。
否则,如果我现在不在手机上,我会尝试使用时间分配(激活(' softmax'))。但不知道这是否会奏效......稍后再尝试
我希望这会有所帮助:-)
答案 2 :(得分:2)
你也可能reshape
无法自行定义softmax
和loss
。这是softmax
,它应用于最后一个输入维度(如tf
后端):
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))
不需要进一步改造。
答案 3 :(得分: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.softmax
和keras.backend.categorical_crossentropy
文档)。
PS。我使用keras
中的tensorflow.keras
(tensorflow 2)
更新:我已经对真实数据集进行了训练,并且它也可以正常工作。