之前读了一下ghostnet的文章,然后搭建了一下ghost-yolo-2layer的结构,这里主要是记录一下ghost-yolo转caffe的流程~
论文笔记:https://blog.csdn.net/weixin_38715903/article/details/105285570
darknet:https://github.com/AlexeyAB/darknet/
darknet to caffe:https://github.com/marvis/pytorch-caffe-darknet-convert
caffe-yolo:https://github.com/ChenYingpeng/caffe-yolov3
需要用到的文件:https://github.com/hualuluu/ghost-yolo
目录
1.关于darknet
2.关于darknet to caffe
1).logistic激活函数是包含在conv的整体结构中:
2).scale_channels:
3).均值池化
3.具体操作
3.1.训练
3.2.darknet to caffe
3.3. caffe-yolo
ghostnet用的darknet不是官方的,是这个https://github.com/AlexeyAB/darknet/,后面Alexey大神自己维护的,所以添加了一些原有darknet不支持的层。
用到的是这个https://github.com/marvis/pytorch-caffe-darknet-convert ,这里面大大好几年前提交的,所以有一些层已经不支持了
针对这跟问题,ghostnet中有logistic激活函数、scale_channels、avg pooling都要做一些改变和添加,不然转出就有问题。
if block['activation'] == 'logistic':
sigmoid_layer = OrderedDict()
sigmoid_layer['bottom'] = bottom
sigmoid_layer['top'] = bottom
if block.has_key('name'):
sigmoid_layer['name'] = '%s-act' % block['name']
else:
sigmoid_layer['name'] = 'layer%d-act' % layer_id
sigmoid_layer['type'] = 'Sigmoid'
layers.append(sigmoid_layer)
#上面是添加代码
elif block['activation'] != 'linear':
relu_layer = OrderedDict()
relu_layer['bottom'] = bottom
relu_layer['top'] = bottom
if block.has_key('name'):
relu_layer['name'] = '%s-act' % block['name']
else:
relu_layer['name'] = 'layer%d-act' % layer_id
relu_layer['type'] = 'ReLU'
if block['activation'] == 'leaky':
relu_param = OrderedDict()
relu_param['negative_slope'] = '0.1'
relu_layer['relu_param'] = relu_param
layers.append(relu_layer)
topnames[layer_id] = bottom
layer_id = layer_id+1
这个层主要是包括两个操作,包括了reshape和scale两种操作
elif block['type'] == 'scale_channels':
reshape_layer= OrderedDict()
scale_layer = OrderedDict()
layer_name = str(block['from'])
if(int(block['from'])>0):
prev_layer_id1=int(block['from'])+1
else:
prev_layer_id1 = layer_id + int(block['from'])
reshape_bottom=topnames[layer_id-1]
reshape_layer['bottom'] = reshape_bottom
reshape_param = OrderedDict()
reshape_param['shape']=OrderedDict()
reshape_param['shape']['dim']=['0']
reshape_param['shape']['dim'].append('0')
reshape_layer['reshape_param']=reshape_param
reshape_layer['type']='Reshape'
reshape_layer['name']='layer%d-reshape' % layer_id
reshape_layer['top']='layer%d-reshape' % layer_id
layers.append(reshape_layer)
print('~~~~~~~~~~')
bottom1 = topnames[prev_layer_id1]
bottom2 = reshape_layer['name']
scale_layer['bottom'] = [bottom1, bottom2]
if block.has_key('name'):
scale_layer['top'] = block['name']
scale_layer['name'] = block['name']
else:
scale_layer['top'] = 'layer%d-scale' % layer_id
scale_layer['name'] = 'layer%d-scale' % layer_id
scale_param = OrderedDict()
filler=OrderedDict()
bias_filler=OrderedDict()
filler['value']='1.0'
bias_filler['value']='0'
scale_param['axis']='0'
scale_param['bias_term']='false'
#scale_param['filler']=filler
#scale_param['bias_filler']=bias_filler
scale_layer['type'] = 'Scale'
scale_layer['scale_param']=scale_param
layers.append(scale_layer)
bottom = scale_layer['top']
print(layer_id)
topnames[layer_id] = bottom
layer_id = layer_id + 1
darknet中的均值池化不需要设定参数,默认输出的feature map的大小为1*1,但是caffe里需要有池化核的size,就是输入特征feature map的长宽(input_w,input_h),所以转caffe的时候要注意。
从https://github.com/hualuluu/ghost-yolo中下载cfg和darknet2caffe.py文件
训练过程就pass了【不会的看这里-https://blog.csdn.net/weixin_38715903/article/details/103695844】,下载cfg文件,按照darknet的步骤训练就行了;
这一步会得到ghostnet-yolo.weights
git clone https://github.com/marvis/pytorch-caffe-darknet-convert
然后下载darknet2caffe.py,替换原有的darknet2caffe.py
注意!!下载的darknet2caffe.py中有一些路径需要改成自己的,比如说你的caffe路径【需要一些caffe头文件】
你需要把训练的cfg文件copy到pytorch-caffe-darknet-convert/cfg文件中,并且根据avg pooling的输入特征尺寸,修改卷积核尺寸参数:
[avgpool]
改为:这里34,60是因为输入的feature map尺寸是这个我们需要通过均值池化得到1*1的尺寸
[avgpool]
size_h=34
size_w=60
再运行:
sudo python2.7 darknet2caffe.py cfg/ghostnet-yolo.cfg ghostnet-yolo.weights ghostnet-yolo.prototxt ghostnet-yolo.caffemodel
这一步会得到ghostnet-yolo.prototxt和ghostnet-yolo.caffemodal
git clone https://github.com/ChenYingpeng/caffe-yolov3
cd caffe-yolov3
"""全部都要改成自己的caffe路径"""
# build C/C++ interface
include_directories(${PROJECT_INCLUDE_DIR} ${GIE_PATH}/include)
include_directories(${PROJECT_INCLUDE_DIR}
/home/ubuntu247/liliang/caffe-ssd/include
/home/ubuntu247/liliang/caffe-ssd/build/include
)
file(GLOB inferenceSources *.cpp *.cu )
file(GLOB inferenceIncludes *.h )
cuda_add_library(yolov3-plugin SHARED ${inferenceSources})
target_link_libraries(yolov3-plugin
/home/ubuntu247/liliang/caffe-ssd/build/lib/libcaffe.so
/usr/lib/x86_64-linux-gnu/libglog.so
/usr/lib/x86_64-linux-gnu/libgflags.so.2
/usr/lib/x86_64-linux-gnu/libboost_system.so
/usr/lib/x86_64-linux-gnu/libGLEW.so.1.13
)
/*
* Company: Synthesis
* Author: Chen
* Date: 2018/06/04
*/
#include "yolo_layer.h"
#include "blas.h"
#include "cuda.h"
#include "activations.h"
#include "box.h"
#include
#include
//yolov3
//float biases[18] = {10,13,16,30,33,23,30,61,62,45,59,119,116,90,156,198,373,326};
float biases[18] = {7, 15, 16, 18, 22, 32, 9, 40, 20, 71, 37, 39, 52, 65, 70, 110, 105, 208};
/*
* Company: Synthesis
* Author: Chen
* Date: 2018/06/04
*/
#ifndef __YOLO_LAYER_H_
#define __YOLO_LAYER_H_
#include
#include
#include
using namespace caffe;
const int classes = 3;
const float thresh = 0.5;
const float hier_thresh = 0.5;
const float nms_thresh = 0.5;
const int num_bboxes = 3;
const int relative = 1;
mkdir build
cd build
cmake ..
make -j12
./x86_64/bin/detectnet ../prototxt/ghost-yolo.prototxt ../caffemodel/host-yolo.caffemodel ../images/bicycle.jpg