使用caffe从图像回归年龄时如何设计损失层
How to design loss layer when regressing age from image using caffe
我正在尝试用 caffe 重现以下论文
最后一层有100个输出,每一层都隐含着预测年龄的概率。最终预测年龄由以下等式计算:
所以我想使用带有标签和预测值的 EUCLIDEAN_LOSS 进行亏损。
我展示了最后一个输出层和损失层的原型文本。
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。然而,这种损失更适合于分类而不是回归。在这种情况下,我该如何设计损失层?
提前致谢。
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] 向量。有很多方法可以做到这一点,none 非常 straight-forward。这是使用 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'
中保存的权重开始训练的。
我正在尝试用 caffe 重现以下论文
最后一层有100个输出,每一层都隐含着预测年龄的概率。最终预测年龄由以下等式计算:
所以我想使用带有标签和预测值的 EUCLIDEAN_LOSS 进行亏损。
我展示了最后一个输出层和损失层的原型文本。
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。然而,这种损失更适合于分类而不是回归。在这种情况下,我该如何设计损失层?
提前致谢。
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] 向量。有很多方法可以做到这一点,none 非常 straight-forward。这是使用 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'
中保存的权重开始训练的。