最近訓練了一個人臉識別模型,使用的是VGGFace2,使用了1000類來訓練,今天介紹一下訓練好的模型如何使用。
首先是deploy文件,注意這個deploy不是train.prototxt,一定是單獨的deploy.prototxt,他的開頭和結尾和train.prototxt是不一樣的。
具體在於data層,deploy的data層就是input
input: "data"
input_dim: 1
input_dim: 3
input_dim: 112
input_dim: 96
這樣就指定好了,不需要大括號,規定一下這是輸入層,以及他的維度就可以了。
然後結尾把train.prototxt裏的accuracy,還有softmaxwithloss層刪掉,加上一個softmax層
layer {
name: "prob"
type: "Softmax"
bottom: "my_fc6"
top: "prob"
}
把這個加在最後,deploy文件就算完成了。
然後開始重點,介紹python代碼部分,c++的後續我也會補上
首先不需要太多的import,一個caffe就夠了
import caffe
接着定義模型文件和權重文件的路徑
deploy = 'deploy.prototxt'
caffe_model = 'models_1000/_iter_16000.caffemodel'
接着就可以生成一個網絡的對象了
net = caffe.Net(deploy,caffe_model,caffe.TEST)
接着生成一個transformer對象,用來對輸入圖片進行各種轉換,包括尺度表換,顏色通道變換等等
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
transformer.set_transpose('data', (2,0,1))
transformer.set_channel_swap('data', (2,1,0))
第一行是轉換數據格式,把原本的h, w, c換成c, h, w,也就是把顏色通道提前,這是caffe要求的格式
第二行是把顏色通道內部順序交換,原本讀進來的是bgr通道,改成caffe需要的rgb通道
img_path = 'test.jpg'
im=(caffe.io.load_image(img_path)) * 2 - 1
然後讀取圖片,使用的是caffe自帶的io讀取,讀進來是bgr通道的,並且是浮點型0~1大小範圍的,我訓練的時候是歸一化到-1~1了,所以需要*2-1,這裏酌情縮放和減均值
net.blobs['data'].data[...] = transformer.preprocess('data',im)
這一步是把剛纔讀好的圖片餵給caffe的輸入層
out = net.forward()
然後就開始執行了,結果賦值給out變量
prob = net.blobs['prob'].data[0].flatten()
取出最後softmax概率那一層,把它拉平賦值給prob變量
print prob.argmax()
打印最大的那個概率的id,也就是猜測類別的那個對應id了
******************************************************************填坑時間**********************************************************************
這裏之前遇到了一個坑,我不知道deploy裏面要自己添加一個softmax層,看到最後一個全連接層輸出個數就是分類個數,以爲那一層就是softmax,最後打印出來的那一層的的輸出還有負數,顯然不是概率,實際的做法是最後還需要加入一個softmax層,問題就都解決了。
完整代碼:
import caffe
deploy = 'deploy.prototxt'
caffe_model = 'models_1000/_iter_16000.caffemodel'
net = caffe.Net(deploy,caffe_model,caffe.TEST)
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
transformer.set_transpose('data', (2,0,1))
transformer.set_channel_swap('data', (2,1,0))
img_path = '/data/dataset/VGGFace2/train_align/n000018/0050_02.png'
im=(caffe.io.load_image(img_path)) * 2 - 1
net.blobs['data'].data[...] = transformer.preprocess('data',im)
out = net.forward()
prob = net.blobs['prob'].data[0].flatten()
print prob.argmax()