我已经建立了一个用于图像分割的Keras模型(U-Net).然而,在我的样本中,一些错误分类(区域)并不重要,而其他错误分类是至关重要的,所以我想为它们分配更高权重的损失函数.为了使事情进一步复杂化,我希望一些错误分类(1级而不是2级)具有非常高的惩罚,而反向(2级而不是1)不应该受到如此大的惩罚.
我看到它的方式,我需要使用(在所有像素)加权分类crossentropy的总和,但我能找到的最好是这样:
def w_categorical_crossentropy(y_true, y_pred, weights):
nb_cl = len(weights)
final_mask = K.zeros_like(y_pred[:, 0])
y_pred_max = K.max(y_pred, axis=1)
y_pred_max = K.reshape(y_pred_max, (K.shape(y_pred)[0], 1))
y_pred_max_mat = K.cast(K.equal(y_pred, y_pred_max), K.floatx())
for c_p, c_t in product(range(nb_cl), range(nb_cl)):
final_mask += (weights[c_t, c_p] * y_pred_max_mat[:, c_p] * y_true[:, c_t])
return K.categorical_crossentropy(y_pred, y_true) * final_mask
Run Code Online (Sandbox Code Playgroud)
然而,这个代码只适用于单个预测,而我对Keras内部工作的知识缺乏(并且它的数学方面并没有好多少).任何人都知道如何适应它,甚至更好,是否有适合我的情况的现成的损失功能?
我会很感激一些指点.
编辑:我的问题类似于如何在Keras中逐点分类的交叉熵损失?,除了我想使用加权分类交叉熵.
我了解到,在两个类的情况下,二进制交叉熵与分类交叉熵相同。
此外,对我来说,很明显softmax是什么。
因此,我看到分类交叉熵只是惩罚了应该为1的一个分量(概率)。
但是,为什么不能或者不应该在一个热向量上使用二进制交叉熵呢?
Normal Case for 1-Label-Multiclass-Mutual-exclusivity-classification:
################
pred = [0.1 0.3 0.2 0.4]
label (one hot) = [0 1 0 0]
costfunction: categorical crossentropy
= sum(label * -log(pred)) //just consider the 1-label
= 0.523
Why not that?
################
pred = [0.1 0.3 0.2 0.4]
label (one hot) = [0 1 0 0]
costfunction: binary crossentropy
= sum(- label * log(pred) - (1 - label) * log(1 - pred))
= 1*-log(0.3)-log(1-0.1)-log(1-0.2)-log(1-0.4)
= 0.887
Run Code Online (Sandbox Code Playgroud)
我看到在二进制交叉熵中,零是目标类,并且对应于以下一键编码:
target class zero …Run Code Online (Sandbox Code Playgroud) classification machine-learning multilabel-classification cross-entropy one-hot-encoding
我处于强化学习环境中,我的环境动作空间取决于状态。因此,我在对行为动作进行采样时会经历以下过程:
(1) 为所有可能的动作生成概率对数
(2) 在这些 logits 上计算 softmax
(3) 屏蔽在这种状态下无效的动作(通过乘以一个由 0 和 1 组成的向量),这将一些概率归零
(4) 重新归一化有效动作概率
(5) 来自这个分布的样本
这对于生成动作非常有效。但是,当我需要计算策略梯度更新时遇到了问题。通常执行以下操作:
tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=A)
Run Code Online (Sandbox Code Playgroud)
其中 logits 是概率 logits,A 是采样的动作。但是,由于我在执行 softmax后执行此屏蔽/重新归一化,因此上面的代码片段在我的情况下不是正确的交叉熵。我想知道是否有一种优雅的方法来处理这种情况。我的理解是,为了数值稳定性,应该始终使用 tensorflow 的交叉熵计算,但是我不确定如何正确地合并这种掩蔽/重整化。
machine-learning reinforcement-learning tensorflow cross-entropy
我想为 Deeplab v3 添加自定义损失,它不仅适用于热编码标签,而且适用于显着性预测。因此,您在下面看到的不是 Deeplab 损失实现:
label = tf.to_int32(label > 0.2)
one_hot_labels = slim.one_hot_encoding(label, num_classes, on_value=1.0, off_value=0.0)
tf.losses.softmax_cross_entropy(one_hot_labels, logits)
Run Code Online (Sandbox Code Playgroud)
我使用了这个实现:
softmax = tf.log(tf.nn.softmax(logits))
cross_entropy = -tf.reduce_sum(label*softmax, reduction_indices=[1])
tf.losses.add_loss(tf.reduce_mean(cross_entropy))
Run Code Online (Sandbox Code Playgroud)
用 5 张图像训练了大约 1000 个 epoch 并得到了这个结果:
此外,尝试了几种学习率,但它不会改变自定义损失的结果。
我正在尝试使用 LSTM 解决一个简单的二元分类问题。我试图找出网络的正确损失函数。问题是,当我使用二元交叉熵作为损失函数时,与使用均方误差 (MSE) 函数相比,训练和测试的损失值相对较高。
经过研究,我发现二元交叉熵应该用于分类问题和 MSE 用于回归问题的理由。但是,就我而言,使用 MSE 进行二元分类时,我获得了更好的准确性和更小的损失值。
我不确定如何证明这些获得的结果是合理的。为什么不使用均方误差来解决分类问题?
我已经完成了pytorch交叉熵损失函数的自定义实现(因为我需要更多的灵活性稍后介绍)。我打算用这个训练的模型需要相当长的时间来训练,而且可用的资源不能仅仅用来测试函数是否正确实现。我已经实现了矢量化实现,因为它运行起来会更快。
以下是我的代码:
def custom_cross(my_pred,true,batch_size=BATCH_SIZE):
loss= -torch.mean(torch.sum(true.view(batch_size, -1) * torch.log(my_pred.view(batch_size, -1)), dim=1))
return loss
Run Code Online (Sandbox Code Playgroud)
如果您能建议更优化的实现,或者我在当前的实现中犯了错误,我将非常感激。该模型将使用 Nvidia Tesla K-80 进行训练。
artificial-intelligence machine-learning cross-entropy pytorch
我正在尝试用三个类来实现一个分类问题:'A'、'B' 和 'C',我想在我的模型损失函数中对不同类型的错误分类进行惩罚(有点像加权交叉熵)。类权重不适合,因为它适用于属于该类的所有数据。例如,与被错误分类为“A”相比,真实标签“B”被错误分类为“C”应该具有更高的损失。重量表如下:
A B C
A 1 1 1
B 1 1 1.2
C 1 1 1
Run Code Online (Sandbox Code Playgroud)
在当前的 categorical_crossentropy 损失中,对于真正的“B”类,如果我将预测 softmax 设为
0.5 0.4 0.1 vs 0.1 0.4 0.5
Run Code Online (Sandbox Code Playgroud)
categorical_crossentropy 将相同。'B' 是否被误分类为 A 或 C 并不重要。与第一个相比,我想增加第二个预测 softmax 的损失。
我试过https://github.com/keras-team/keras/issues/2115 但没有任何代码适用于 Keras v2。任何我可以直接将权重矩阵强制执行到 Keras 损失函数的帮助都将受到高度赞赏。
这是 tf 2.3.0。在训练期间, SparseCategoricalCrossentropy loss 和 sparse_categorical_accuracy 的报告值似乎还差得很远。我查看了我的代码,但还没有发现任何错误。这是要重现的代码:
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
x = np.random.randint(0, 255, size=(64, 224, 224, 3)).astype('float32')
y = np.random.randint(0, 3, (64, 1)).astype('int32')
ds = tf.data.Dataset.from_tensor_slices((x, y)).batch(32)
def create_model():
input_layer = tf.keras.layers.Input(shape=(224, 224, 3), name='img_input')
x = tf.keras.layers.experimental.preprocessing.Rescaling(1./255, name='rescale_1_over_255')(input_layer)
base_model = tf.keras.applications.ResNet50(input_tensor=x, weights='imagenet', include_top=False)
x = tf.keras.layers.GlobalAveragePooling2D(name='global_avg_pool_2d')(base_model.output)
output = Dense(3, activation='softmax', name='predictions')(x)
return tf.keras.models.Model(inputs=input_layer, outputs=output)
model = create_model()
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4),
loss=tf.keras.losses.SparseCategoricalCrossentropy(),
metrics=['sparse_categorical_accuracy']
)
model.fit(ds, steps_per_epoch=2, …Run Code Online (Sandbox Code Playgroud) cross-entropy ×10
keras ×4
tensorflow ×4
python ×2
pytorch ×2
cntk ×1
deeplab ×1
loss ×1
lstm ×1
softmax ×1