最近在中低端嵌入式设备上进行人脸识别移植,虽然针对模型参数尽量压缩,但模型依然有6M左右,在低端嵌入式设备上加载速度和运行速度都让人泪流满面。查阅资料后,目前针对嵌入式设备可通过float32转int8进行模型压缩和速度提升,所以本人也进行了实验,并将实验过程进行记录,分享给大家。
准备材料:
(1)测试网络的prototxt文件
(2)训练生成的caffemodel文件
(3)验证集图像文件
(4)git clone https://github.com/lyk125/caffe-int8-convert-tools.git
(5)caffe深度学习框架
以上都准备妥当了,那么就可以进行模型的转换了。
- 针对输入为三通道模型
若模型输入为三通道图像直接根据官方教程直接转换即可。
$ python caffe-int8-convert-tool.py --help
usage: caffe-int8-convert-tool.py [-h] [--proto PROTO] [--model MODEL]
[--mean MEAN MEAN MEAN] [--norm NORM]
[--images IMAGES] [--output OUTPUT]
[--gpu GPU]
find the pretrained caffe models int8 quantize scale value
optional arguments:
-h, --help show this help message and exit
--proto PROTO path to deploy prototxt.
--model MODEL path to pretrained weights
--mean MEAN value of mean
--norm NORM value of normalize
--images IMAGES path to calibration images
--output OUTPUT path to output calibration table file
--gpu GPU use gpu to forward
$ python caffe-int8-convert-tool.py --proto=squeezenet_v1.1.prototxt --model=squeezenet.caffemodel --mean 104 117 123 --images=ILSVRC2012_1k --output=squeezenet_v1.1.table --gpu=1
- 针对输入为灰度图像模型
若模型输入为灰度图将需要修改caffe-int8-convert-tool.py文件,共有两处修改:
(1)由于灰度图是没有均值的 所以如果不加任何修改,会报Mean channels incompatible with input.所以做一下修改,屏蔽均值处理。
def network_prepare(net, mean, norm):
"""
instance the prepare process param of caffe network inference
Args:
net: the instance of Caffe inference
mean: the value of mean
norm: the value of normalize
Returns:
none
"""
print("Network initial")
#img_mean = np.array(mean)
# initial transformer
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
# convert shape from RBG to BGR
#transformer.set_transpose('data', (2,0,1))
# load meanfile
#transformer.set_mean('data', img_mean)
# resize image data from [0,1] to [0,255]
transformer.set_raw_scale('data', 255)
# convert RGB -> BGR
#transformer.set_channel_swap('data', (2,1,0))
# normalize
transformer.set_input_scale('data', norm)
return transformer
(2)将需要加载图像进行灰度化处理或者resize操作,以与网络模型相对应。
def net_forward(net, image_path, transformer):
"""
network inference and statistics the cost time
Args:
net: the instance of Caffe inference
image_path: a image need to be inference
transformer:
Returns:
none
"""
# load image
image = caffe.io.load_image(image_path)
# transformer.preprocess the image
# -------add code int here to gray or resize------
img_gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
#-------------------------------------------------
net.blobs['data'].data[...] = transformer.preprocess('data',img_gray)
# net forward
start = time.clock()
output = net.forward()
end = time.clock()
print("%s forward time : %.3f s" % (image_path, end - start))
继续执行代码,即可运行输入为灰度图的模型。
python caffe-int8-convert-tool.py --proto=squeezenet_v1.1.prototxt --model=squeezenet.caffemodel --mean 104 117 123 --images=ILSVRC2012_1k --output=squeezenet_v1.1.table --gpu=1
跑完之后就可获得.table文件。
最后,通过执行
./caffe2ncnn xx.prototxt xx.caffemodel yy.param yy.bin 256 xx.table
即可获得压缩之后的模型。本人压缩后模型大小为1.6M。