我想修改Caffe中现有的softmaxloss。这个想法是为损失增加一个权重因子。例如,如果我们正在处理属于汽车类的像素,我想在损失中加上一个因子2,因为在我的情况下,汽车类的检测比狗类更重要(例如)。这是原始源代码:
__global__ void SoftmaxLossForwardGPU(const int nthreads,
const Dtype* prob_data, const Dtype* label, Dtype* loss,
const int num, const int dim, const int spatial_dim,
const bool has_ignore_label_, const int ignore_label_,
Dtype* counts) {
CUDA_KERNEL_LOOP(index, nthreads) {
const int n = index / spatial_dim;
const int s = index % spatial_dim;
const int label_value = static_cast<int>(label[n * spatial_dim + s]);
if (has_ignore_label_ && label_value == ignore_label_) {
loss[index] = 0;
counts[index] = 0;
} else {
loss[index] = -log(max(prob_data[n * dim + label_value * spatial_dim + s],
Dtype(FLT_MIN)));
counts[index] = 1;
}
}
}
您可以在https://github.com/BVLC/caffe/blob/master/src/caffe/layers/softmax_loss_layer.cu
中找到此代码在下面的代码中,您可以找到我为实现目标所做的修改:
__global__ void SoftmaxLossForwardGPU(const int nthreads,
const Dtype* prob_data, const Dtype* label, Dtype* loss,
const int num, const int dim, const int spatial_dim,
const bool has_ignore_label_, const int ignore_label_,
Dtype* counts) {
const float weights[4]={3.0, 1.0, 1.0, 0.5}
CUDA_KERNEL_LOOP(index, nthreads) {
const int n = index / spatial_dim;
const int s = index % spatial_dim;
const int label_value = static_cast<int>(label[n * spatial_dim + s]);
if (has_ignore_label_ && label_value == ignore_label_) {
loss[index] = 0;
counts[index] = 0;
} else {
loss[index] = -log(max(prob_data[n * dim + label_value * spatial_dim + s],
Dtype(FLT_MIN))) * weights[label_value];
counts[index] = 1;
}
}
}
我不确定这种修改是否正在做我想做的事情。有几个原因:
我不确定这个函数的每个值是什么意思。我想假设label_value
对应于地面实况值,但是
我不确定。
我完全不明白这一行:prob_data[n * dim + label_value * spatial_dim + s]
。估计损失在哪里?我假设损失计算正在这一行中发生,因此我将权重放在这里,但我无法在这里看到计算结果。在这里,我可以看到对矢量prob_dat
。
我知道我的代码提案不是最好的,我希望在某些时候将这些权重转换为图层的输入,但是现在我没有足够的知识去做(如果可以的话)也给了我一些提示,以实现它,那将是伟大的。)
答案 0 :(得分:2)
在caffe中实现自己的图层是一项非常好的技能,但你应该这样做是最后的手段&#34;。有很多现有的图层,你通常可以使用现有的图层实现你想要的。
您也无法在不修改forward_gpu
的情况下修改forward_cpu
实施。更重要的是,您必须修改backward
函数 - 否则更新权重的渐变不会反映您修改后的损失。
"SoftmaxWithLoss"
图层是损失"InfogainLoss"
图层的特例。如果你想拥有不同的体重&#34;对于每个班级,您只需根据权重使用"InfogainLoss"
和权重矩阵H
如果你想要空间变化的重量(不同位置的重量不同),你可以看看PR #5828, implementing "WeightedSoftmaxWithLoss"
。