【问题标题】:Doubts when changing the SoftMaxWithLoss layer of caffe framework更改caffe框架的SoftMaxWithLoss层时的疑惑
【发布时间】:2018-02-05 14:14:22
【问题描述】:

我想修改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;
    }
  }
}

我不确定这个修改是否在做我想做的事。有几个原因:

  1. 我不确定这个函数的每个值是什么意思。例如,我假设label_value 对应于真实值,但是 我不确定。

  2. 我完全不明白这一行:prob_data[n * dim + label_value * spatial_dim + s]。这里估计的损失在哪里?我假设损失计算发生在这条线上,因此我把我的权重放在这里,但我看不到这里的计算。在这里我可以看到对向量prob_dat的特定位置的访问。

我知道我的代码提案不是最好的,我想在某个时候将这些权重转换为层的输入,但现在我没有足够的知识来做到这一点(如果你也可以给给我一些提示以实现它,那会很棒)。

【问题讨论】:

  • 请记住,请求站外资源(例如文章)在 Stack Overflow 上是题外话。建议您删除或改写第 1 点。

标签: machine-learning neural-network deep-learning caffe image-segmentation


【解决方案1】:
  1. 在 caffe 中实现您自己的层是一项非常好的技能,但您应该将此作为“最后的手段”。有很多现有的层,您通常可以使用现有的层来实现您想要的。

  2. 如果不修改 forward_cpu,则无法修改 forward_gpu 实现。更重要的是,您也必须修改 backward 函数 - 否则更新权重的梯度不会反映您修改后的损失。

  3. "SoftmaxWithLoss" 层是损失"InfogainLoss" 层的特例。如果您想为每个班级设置不同的“权重”,您可以根据自己的权重简单地使用"InfogainLoss" 和权重矩阵H
    如果您想在空间上具有不同的权重(不同位置的权重不同),您可以查看PR #5828, implementing "WeightedSoftmaxWithLoss"

【讨论】:

  • 嗨,Shai,再次感谢您的回答。问题是:每个班级的权重只是我实验的第一步。出于这个原因,我决定基于 SoftMaxWithLoss 做我自己的网络。与 InfogainLoss 相关的是 softmaxwithloss 中使用的相同损失公式,对吧?我在哪里可以找到对此的理论解释?我需要知道的第一件事是如何处理 SoftMaxWithLoss 中实现的损失。我在某些地方读到这种损失与交叉熵相同。但我不确定这个事实。
  • 我的另一个问题是关于向后函数的修改。为什么梯度更新我的权重不会反映当前的损失?
  • @Dhorka 请参阅 this thread 了解有关 softmax 损失和 infogain 损失之间联系的更多信息
猜你喜欢
  • 2018-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-24
  • 2016-11-17
  • 1970-01-01
  • 2020-11-02
相关资源
最近更新 更多