在之前的博客里我已经写过 CaffeModel的文件了,这个就是我们训练的网络结果。
现在既然已经有了训练好的模型,就要开始通过这个网络进行自己的分类了。
准备内容
- 首先找到训练好的
.caffemodel
文件。 - 然后准备网络模型的
deploy.prototxt
- 准备训练时候使用的均值文件
imagenet_mean.binaryproto
- 新建一个
label.txt
文件里面写上你的各个类的名字(注意顺序) - 要分类的文件:
1.jpg
解释一下 deploy.prototxt
文件并不是你训练的时候使用的 train_val.prototxt
文件,因为是分类所以deploy.prototxt
把训练的内容部分全部给删除了。所以如果没有deploy.prototxt
的话,请自己写一份,仿照其他网络的样例。
其次binaryproto
文件是训练时候使用的均值文件,不是分类生成的。
然后就是label.txt
就是标签文件,里面每行是一个内容,我的标签文件里面是:
down
sitdown
standup
handup
1
2
3
.
.
.
996
我这里面一共有4类,但是有1000行,是因为我训练的时候忘了修改train_val.prototxt
里面的输出向量的大小了。所以用数字替补了。如果你训练的时候修改过train_val.prototxt
的 inner_product_param
的num_output
的值,那么对应的你这个标签文件里也写多少行就可以了。然后deploy.prototxt
也要一样。
分类
Caffe可以通过 C++方法也可以通过 Python方法或者直接命令行方法来分类,我自己只测试了使用 C++的方法
C++方法分类
在 caffe下面有写好的 C++文件:
caffe/build/examples/cpp_classification/classification.bin
这个是编译好的 classification.bin
的可执行文件,其源代码在:
caffe/examples/cpp_classification/classification.cpp
如果要修改,在这里修改之后编译。
然后在caffe
根目录下新建一个classification_test.sh
文件,里面的内容如下:
#!/bin/bash
./build/examples/cpp_classification/classification.bin \
examples/imgsnet/bvlc_alexnet/deploy.prototxt \
examples/imgsnet/bvlc_alexnet/caffe_alexnet_train_iter_1000.caffemodel \
examples/imgs/data/imagenet_mean.binaryproto \
examples/imgs/data/label.txt \
examples/imgs/data/val/down/1.jpg
这里的文件位置,请自行指定,我这个文件里面的位置都是我网络的。
然后会输出类似的内容:
---------- Prediction for examples/imgs/data/val/down/20170309_163509_down.jpg ----------
0.9756 - "down"
0.0229 - "sitdown"
0.0016 - "standup"
0.0000 - "handup"
0.0000 - "59"
前面是概率,后面是对应的 label,输出的 top 5的预测。
错误解决
问题1:
F0329 12:55:18.108248 8610 classification.cpp:82] Check failed: labels_.size() == output_layer->channels() (4 vs. 1000) Number of labels is different from the output layer dimension.
说明你label.txt
的内容长度和 deploy.prototxt
的长度不一致,说lebel.txt
的长度是4而deploy.prototxt
里的 output_num
的内容长度是1000. 这里的解决办法是,其中一个改成一样的长度就行了。
问题2:
F0329 15:48:14.703812 9905 net.cpp:757] Cannot copy param 0 weights from layer 'fc8'; shape mismatch. Source param shape is 1000 4096 (4096000); target param shape is 4 4096 (16384). To learn this layer's parameters from scratch rather than copying from a saved net, rename the layer.
这个问题说的是你网络训练的文件train_val.prototxt
里的output_num
和deploy.prototxt
的output_num
长度不一致。
所以我最后的解决办法就是,把所有长度以train_val.prototxt
的写的输出向量长度为准。