【问题标题】:How to design loss layer when regressing age from image using caffe使用caffe从图像中回归年龄时如何设计损失层
【发布时间】:2018-08-31 07:46:44
【问题描述】:

我正在尝试用 caffe 复制以下论文

Deep EXpectation

最后一层有 100 个输出,每一层都暗示了预测年龄的概率。最终预测年龄由以下公式计算:

所以我想使用带有标签和预测值的 EUCLIDEAN_LOSS 来亏损。

我展示了最后一个输出层和损失层的 prototxt。

layer {
    bottom: "pool5"
    top: "fc100"
    name: "fc100"
    type: "InnerProduct"
    inner_product_param {
        num_output: 100
    }
}

layer {
    bottom: "fc100"
    top: "prob"
    name: "prob"
    type: "Softmax"
}

layer {
    name: "loss"
    type: "SoftmaxWithLoss"
    bottom: "fc100"
    bottom: "label"
    top: "loss"
    loss_weight: 1
}

就目前而言,我正在尝试使用 SoftmaxWithLoss。但是,这种损失更适合分类而不是回归。在这种情况下如何设计损失层?

提前致谢。

【问题讨论】:

    标签: machine-learning neural-network deep-learning regression caffe


    【解决方案1】:

    TL;DR
    我曾经做过类似的任务,根据我的经验,训练离散标签和回归单个连续值之间几乎没有区别(在输出准确性方面)。


    有几种方法可以解决这个问题:

    1。回归单个输出

    由于您只需要预测单个标量值,因此您应该训练您的网络来做到这一点:

    layer {
        bottom: "pool5"
        top: "fc1"
        name: "fc1"
        type: "InnerProduct"
        inner_product_param {
            num_output: 1  # predict single output
        }
    }
    

    您需要确保预测值在 [0..99] 范围内:

    layer {
      bottom: "fc1"
      top: "pred01"  # map to [0..1] range
      type: "Sigmoid"
      name: "pred01"
    }
    layer {
      bottom: "pred01"
      top: "pred_age"
      type: "Scale"
      name: "pred_age"
      param { lr_mult: 0 }  # do not learn this scale - it is fixed
      scale_param {
        bias_term: false
        filler { type: "constant" value: 99 }
      }
    }
    

    pred_age 中获得预测后,您可以添加损失层

    layer {
      bottom: "pred_age"
      bottom: "true_age"
      top: "loss"
      type: "EuclideanLoss"
      name: "loss"
    }
    

    不过,我建议在这种情况下使用 "SmoothL1",因为它更健壮。

    2。回归离散预测的期望

    您可以在 caffe 中实现您的预​​测公式。为此,您需要一个 fixed 值 [0..99] 向量。有很多方法可以做到这一点,没有一个是非常直接的。这是使用net-surgery的一种方式:

    首先,定义网络

    layer {
      bottom: "prob"
      top: "pred_age"
      name: "pred_age"
      type: "Convolution"
      param { lr_mult: 0 }  # fixed layer. 
      convolution_param { 
        num_output: 1
        bias_term: false
      }
    }
    layer {
      bottom: "pred_age"
      bottom: "true_age"
      top: "loss"
      type: "EuclideanLoss"  # same comment about type of loss as before
      name: "loss"
    }
    

    你还不能使用这个网络,首先你需要将pred_age层的内核设置为0..99。

    在python中,加载新的

    net = caffe.Net('path/to/train_val.prototxt', caffe.TRAIN)
    li = list(net._layer_names).index('pred_age')  # get layer index
    net.layers[li].blobs[0].data[...] = np.arange(100, dtype=np.float32)  # set the kernel
    net.save('/path/to/init_weights.caffemodel')  # save the weights
    

    现在您可以训练您的网络了,但是确保您将从'/path/to/init_weights.caffemodel' 中保存的权重开始训练。

    【讨论】:

    • 我正在尝试第二种方法,但在从 prototxt 构建模型时出错。 “pred_age”层给出错误。该层至少需要两个参数 [num_output, kernel_size]。我使用 kernel_size 作为 100 但它也给了我错误....
    • @ilkyutonylee 我的坏 kernel_size 应该是 1
    • 我试过 filter_size: 100 和 1 但这意味着方形过滤器所以它不起作用之后我需要使用矩形过滤器所以我需要设置 [kernel_w, kernel_h]。
    • 这就是我所做的。层{底部:“prob”顶部:“prob2d”名称:“prob2d”类型:“重塑”reshape_param {形状:{暗淡:1暗淡:1暗淡:1暗淡:100}}}图层{底部:“prob2d”顶部: "pred_age" name: "pred_age" type: "Convolution" param { lr_mult: 0 } # 固定层。 convolution_param { num_output: 1 #kernel_size: 10 kernel_w: 100 kernel_h: 1 bias_term: false } } 我强行改变了概率的形状并应用了二维卷积。
    • 你的回答真的很有帮助,你驱使我解决这个问题。真的很感激!
    猜你喜欢
    • 2017-02-08
    • 2017-11-19
    • 1970-01-01
    • 2018-07-30
    • 2017-03-14
    • 2017-06-20
    • 2017-11-24
    • 1970-01-01
    • 2015-09-14
    相关资源
    最近更新 更多