Caffe:尽可能简单地从快照预测图像

Caffe: Predict an image from snapshot as simple as possible

有什么方法可以轻松地使用 Caffe 快照来预测新图像吗?

"EASILY" 我的意思是:

  1. 不要手动将 train.prototxt 更改为 deploy.prototxt 并仔细考虑。
  2. 不将文件转换为 LMDB(或类似的其他格式),只使用简单的图像文件(没有任何文件名列表或其他内容)
  3. 仅使用 python 代码(不使用 CLI)

我已经基于 Caffe MNIST 示例训练了一个二元分类网络。我将 MNIST 更改为用于分类 2 类,它训练得非常好。但是现在我已经完成了网络训练并生成了快照(包含 'snapshot.caffemodel' 和 'solver.caffemodel'),我一直在研究如何使用这个快照来预测只有一个图像而没有所有麻烦......

我当前的代码是(如果我能像这样简单地进行预测,我真的更喜欢):

#I'M NOT SURE IF I SHOULD USE 'caffe.Net(...)' OR 'caffe.Classifier(...)'
net = caffe.Classifier('Data/train.prototxt',
                       'Data/Snapshot_iter_1000.caffemodel',
                       mean=convertBinaryProtoToNPY('Data/mean_image.binaryproto'),
                       image_dims=(100, 100),
                       raw_scale=255)

score = net.predict([caffe.io.load_image('/Data/Images/1.jpg')])
print score

我收到这个错误:

File "C:\Anaconda2\lib\site-packages\caffe\classifier.py", line 29, in __init__ in_ = self.inputs[0]
IndexError: list index out of range

搜索后我发现我不应该使用 'train.prototxt' 而是 'deploy.prototxt'.

Caffe 当前的处理方式有时似乎过于复杂,尤其是对于使用快照预测图像等琐碎的任务... 也许我做事的方式不对...

您确实需要手动将您的train_val.prototxt更改为deploy.protoxt
然而,这种改变比你想象的要容易。

train_val.prototxt复制到新的deploy.prototxt并按照以下步骤编辑deploy.prototxt

第一个变化:输入。

而不是使用 training/validation 数据集(通常表示为 "Data"/"HDF5Data"/"Imagedata" 层),您需要告诉 caffe 为图像分配内存您稍后将手动提供。
为此,您需要删除现有的输入层(对于 TRAIN 和 TEST 阶段),并将它们替换为:

layer {
  name: "input"
  type: "Input"
  top: "data"  # or whatever was the name of the "top" of the training input. no need for "label" top - you do not have ground truth labels in test.
  input_param { shape: { dim: 1 dim: 3 dim: 100 dim: 100 } } # give caffe the expected dimensions of your input for memory allocation
}

第二个变化:网络的输出。

在训练期间,您的净输出是损失,而不是预测。
因此,首先删除 all 损失层(特别是,任何期望得到 "label" 为 "bottom" 的层)。这包括"SoftmaxWithLoss"/"Accuracy"/"SigmoidCrossEntropyLoss"
您需要用适当的预测层替换损失层。例如,"SoftmaxWithLoss" 层应替换为简单的 "Softmax" 层,"SigmoidCrossEntropy" 层应替换为 "Sigmoid" 层,依此类推。
因此,如果你有类似

layer {
  type: "SoftmaxWithLoss"
  name: "loss"
  bottom: "fc8"  # we need this name !
  bottom: "label"
  ...
}

替换为:

layer {
  name: "prob"
  type: "Softmax"
  bottom: "fc8" # the SAME as the train loss layer!
  top: "prob"
}

保存您的更改,现在您有一个合适的 deploy.prototxt

有关详细信息,请参阅 this post。