我试图用caffe重现以下论文
深刻的期望
最后一层有100个输出,每一层都暗示预测年龄的概率。最终预测年龄由……计算
的 TL; DR 强> 我曾经历过类似的任务,根据我的经验,训练离散标签和回归单个连续值之间几乎没有差异(就输出精度而言)。
有几种方法可以解决这个问题:
由于您只需要预测单个标量值,因此您应该训练您的网络:
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 你可以添加一个损失层
pred_age
layer { bottom: "pred_age" bottom: "true_age" top: "loss" type: "EuclideanLoss" name: "loss" }
虽然,我建议使用 "SmoothL1" 在这种情况下,因为它更健壮。
"SmoothL1"
您可以在caffe中实现预测公式。你需要一个 的 固定 强> 值的向量[0..99]。有很多方法可以做到这一点,没有一个是非常简单的。这是使用的一种方式 净手术 :
首先,定义网络
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' 。
'/path/to/init_weights.caffemodel'