2015-10-20 100 views
8

我想微调GoogLeNet以使用Caffe进行多标签分类。我已经将其精细调整为单标签分类,但我无法过渡到多标签。使用Caffe的多标签分类

我做的主要步骤,这是不同的:

为数据创建LMDB &地面实测

我修改代码herehere创建一个LMDB用数据和其他与地面实况。

与SigmoidCrossEntropyLoss

更换SoftmaxWithLoss更新train_val.prototxt,我取代SoftmaxWithLoss层SigmoidCrossEntropyLoss,并设置使得两个DB的加载的数据层。我按照我对单标签分类问题所做的那样设置了学习速率参数。

这个步骤似乎工作。数据流,并且可以执行solver.step(1)。为了验证数据和标签是否正确加载,我使用公式计算了损失,并得到与Caffe相同的结果。

问题

网络不收敛。运行几次迭代,不同班级的平均班级数量均为平均值。这就是说,如果类别a在人口中的0.35 1和0.65 0,则每个观察的网络将收敛到〜0.35的分类概率,而不管真实标签如何。

可能出现的错误1

我怀疑的问题是,因为我无法将图像加载到正确的朱古力的方式GoogLeNet预训练的模型可以向他们学习。我迄今为止的经验是convert_imageset,它完美地工作。现在,我使用shelhamer代码将图像保存到LMDB:

im = np.array(Image.open(os.path.join(data_dir,in_))) 
im = im[:,:,::-1] 
im = im.transpose((2,0,1)) 
im_dat = caffe.io.array_to_datum(im) 
in_txn.put('{:0>10d}'.format(in_idx), im_dat.SerializeToString()) 

我在数据层加载图像时正常化的平均值。 这看起来合适吗?还有另一种方法可以做到吗?

可能的错误2

也可能是该train_val.prototxt已经定义错误。除了切换SoftmaxWithLoss - > SigmoidCrossEntropyLoss之外,还有什么需要做的吗?

任何帮助将不胜感激! 谢谢!

+2

这似乎是你的网陷与“全1”的预测。如果你的梯度太高,可能会导致参数变成无意义的区域。你可以绘制一个训练损失与迭代次数的关系图吗?我会尝试将学习速度降低一个或两个*数量级*并重新训练,看看模型是否再次卡住。 – Shai

+1

如果你的网络不收敛,你应该检查学习速率。一般来说,对于微调,你应该有一个较低的学习速度(或高开始学习速度和快速衰减)。如果火车的损失在不同时期增加,这表明你的学习率太高。 – user3334059

+0

你见过这个问题吗? https://github.com/BVLC/caffe/issues/2407 – ginge

回答

0

在GoogLeNet输入数据应该由平均值减去:

... 
im = im.transpose((2,0,1)) 
mean = np.array((104,117,123)) 
im -= mean 
im_dat = caffe.io.array_to_datum(im) 
...