一直在研究怎样用caffe做行人检測问题。然而參考那些经典结构比方faster-rcnn等,都是自己定义的caffe层来完毕的检測任务。

这些都要求对caffe框架有一定程度的了解。近期看到了怎样用caffe完毕回归的任务,就想把检測问题当成回归问题来解决。

我们把行人检測问题当成回归来看待,就须要限制检出目标的个数,由于我们的输出个数是固定的。所以,这里我假定每张图片最多检出的目标个数为2。即每一个目标用4个值来表示其位置信息(中心位置坐标x,y。

BBox的宽和高)。则网络的最后输出是8个值。

制作HDF5数据

这里我们使用HDF5格式的数据来完毕我们的回归任务,那么首先我们须要的是制作h5格式的数据。

这里以VOC数据集为例。以下是制作HDF5格式数据的python代码。

import h5py
import caffe
import os
import xml.etree.ElementTree as ET
import cv2
import time
import math
from os.path import join, exists
import numpy as np def convert(size, box):
dw = 1./size[0]
dh = 1./size[1]
x = (box[0] + box[1])/2.0
y = (box[2] + box[3])/2.0
w = box[1] - box[0]
h = box[3] - box[2]
x = x*dw
w = w*dw
y = y*dh
h = h*dh
return (x,y,w,h) def shuffle_in_unison_scary(a, b):
rng_state = np.random.get_state()
np.random.shuffle(a)
np.random.set_state(rng_state)
np.random.shuffle(b) def processImage(imgs):
imgs = imgs.astype(np.float32)
for i, img in enumerate(imgs):
m = img.mean()
s = img.std()
imgs[i] = (img - m) / s
return imgs TrainImgDir = 'F:/GenerateHDF5/trainImage'
TrainLabelDir = 'F:/GenerateHDF5/trainLabels'
TestImgDir = 'F:/GenerateHDF5/testImg'
TestLabelDir = 'F:/GenerateHDF5/testLabels' InImg = []
InBBox = [] for rootDir,dirs,files in os.walk(TestLabelDir): #####
for file in files:
file_name = file.split('.')[0]
full_file_name = '%s%s'%(file_name,'.jpg')
full_file_dir = '%s/%s'%(TestImgDir,full_file_name) #####
Img = cv2.imread(full_file_dir,cv2.CV_LOAD_IMAGE_GRAYSCALE)
xml_file = open("%s/%s"%(rootDir,file))
tree = ET.parse(xml_file)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text) landmark = np.zeros(8)
count = 0
for obj in root.iter('object'):
count = count + 1
if count == 3:
break
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
bb = convert((w,h), b)
landmark[(count-1)*4+0]=bb[0]
landmark[(count-1)*4+1]=bb[1]
landmark[(count-1)*4+2]=bb[2]
landmark[(count-1)*4+3]=bb[3] InBBox.append(landmark.reshape(8))
Img = cv2.resize(Img,(h,w))
InImg.append(Img.reshape((1,h,w))) InImg, InBBox = np.asarray(InImg), np.asarray(InBBox)
InImg = processImage(InImg)
shuffle_in_unison_scary(InImg, InBBox) outputDir = 'hdf5/'
HDF5_file_name = 'hdf5_test.h5' #####
if not os.path.exists(outputDir):
os.makedirs(outputDir) output = join(outputDir,HDF5_file_name)
with h5py.File(output, 'w') as h5:
h5['data'] = InImg.astype(np.float32)
h5['labels'] = InBBox.astype(np.float32)
h5.close()

这里注意一点,全部的BBox数据都要做归一化操作,即全部坐标要除以图片相应的宽高。据说,这样做能使最后得到的结果更好。

制作好了HDF5数据后。注意每一个H5文件大小不能超过2G(这是caffe的规定,假设一个文件超过2G。请分开制作多个)。

然后建立一个TXT文件,文件中写上全部H5文件的绝对路径。比方我这里建立的文件是list_train.txt。

然后我仅仅有一个H5文件,即hdf5_train.h5。所以我的list_train.txt文件中的内容就是/home/XXX/caffe/model/hdf5/hdf5_train.h5

配置solver文件

接下来是caffe的solver文件。这个文件没有什么差别,

test_iter: 20
test_interval: 70
base_lr: 0.0000000005
display: 9
max_iter: 210000
lr_policy: "step"
gamma: 0.1
momentum: 0.9
weight_decay: 0.0001
stepsize: 700
snapshot: 500
snapshot_prefix: "snapshot"
solver_mode: GPU
net: "train_val.prototxt"
solver_type: SGD

配置train_val.prototxt文件

接下来是网络的train_val.prototxt文件。这是caffe的网络结构文件,我们这里以LeNet网络为例。我这里是这种:

name: "LeNet"
layer {
name: "data"
type: "HDF5Data"
top: "data"
top: "labels"
include {
phase: TRAIN
}
hdf5_data_param {
source: "list_train.txt"
batch_size: 50
}
}
layer {
name: "data"
type: "HDF5Data"
top: "data"
top: "labels"
include {
phase: TEST
}
hdf5_data_param {
source: "list_test.txt"
batch_size: 50
}
}
layer {
name: "conv1"
type: "Convolution"
bottom: "scaled"
top: "conv1"
param {
lr_mult: 1.0
}
param {
lr_mult: 2.0
}
convolution_param {
num_output: 20
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
param {
lr_mult: 1.0
}
param {
lr_mult: 2.0
}
convolution_param {
num_output: 50
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool2"
top: "ip1"
param {
lr_mult: 1.0
}
param {
lr_mult: 2.0
}
inner_product_param {
num_output: 500
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "ip1"
top: "ip1"
}
layer {
name: "ip2"
type: "InnerProduct"
bottom: "ip1"
top: "ip2"
param {
lr_mult: 1.0
}
param {
lr_mult: 2.0
}
inner_product_param {
num_output: 8
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "error"
type: "EuclideanLoss"
bottom: "ip2"
bottom: "labels"
top: "error"
include {
phase: TEST
}
}
layer {
name: "loss"
type: "EuclideanLoss"
bottom: "ip2"
bottom: "labels"
top: "loss"
include {
phase: TRAIN
}
}

这里注意的是。最后的一层全连接层,输出的num_output应该是你label的维度,我这里是8。然后最后的loss计算,我使用的是欧氏距离的loss,也能够试着用其它类型的loss。

開始训练

依照以上步骤配置好了,最后就是训练了。

在控制台中输入下面指令来训练我们的数据:

./cafferoot/caffe/tools/caffe train --solver=solver.prototxt

可能是我数据源的问题,我的loss一開始很大。然后一直降不下来。也有可能是LeNet本身网络性能就不好。

关于网络的性能还须要另外再想办法提升。

使用caffe的HDF5数据完毕回归任务的更多相关文章

  1. 【机器学习实战】第8章 预测数值型数据:回归(Regression)

    第8章 预测数值型数据:回归 <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/ ...

  2. caffe添加python数据层

    caffe添加python数据层(ImageData) 在caffe中添加自定义层时,必须要实现这四个函数,在C++中是(LayerSetUp,Reshape,Forward_cpu,Backward ...

  3. caffe中关于数据进行预处理的方式

    caffe的数据层layer中再载入数据时,会先要对数据进行预处理.一般处理的方式有两种: 1. 使用均值处理 transform_param { mirror: true crop_size: me ...

  4. 总结一下用caffe跑图片数据的研究流程

    近期在用caffe玩一些数据集,这些数据集是从淘宝爬下来的图片.主要是想研究一下对女性衣服的分类. 以下是一些详细的操作流程,这里总结一下. 1 爬取数据.写爬虫从淘宝爬取自己须要的数据. 2 数据预 ...

  5. caffe 中 python 数据层

    caffe中大多数层用C++写成. 但是对于自己数据的输入要写对应的输入层,比如你要去图像中的一部分,不能用LMDB,或者你的label 需要特殊的标记. 这时候就需要用python 写一个输入层. ...

  6. 【撸码caffe 五】数据层搭建

    caffe.cpp中的train函数内声明了一个类型为Solver类的智能指针solver: // Train / Finetune a model. int train() { -- shared_ ...

  7. 在caffe-ssd安装编译环境运行make all时候报错:Makefile:572: recipe for target '.build_release/src/caffe/util/hdf5.o' failed make: *** [.build_release/src/caffe/util/hdf5.o] Error 1

    解决办法: 修改:Makefile.config INCLUDE_DIRS /usr/include/hdf5/serial/ 修改:Makefile LIBRARIES hdf5_hl and hd ...

  8. 在caffe中使用hdf5的数据

    caffe默认使用的数据格式为lmdb文件格式,它提供了把图片转为lmdb文件格式的小程序,但是呢,我的数据为一维的数据,我也要分类啊,那我怎么办?肯定有办法可以转为lmdb文件格式的,我也看了一些源 ...

  9. Windows下用Caffe跑自己的数据(遥感影像)

    1 前言 Caffe对于像我这样的初学者来说是一款非常容易上手的深度学习框架.关于用Caffe跑自己的数据这样的博客已经非常多,感谢前辈们为我们提供的这么好的学习资源.这里我主要结合我所在的行业,说下 ...

随机推荐

  1. Elasticsearch match_phrase用法

    目前有用到的用法如下: post /index_name/_search { "query" : { "match_phrase": { "nickn ...

  2. 常见OJ提交结果对照表

    Waiting:你的程序刚刚提交,正在等待OJ评测你的程序.   Compiling:OJ正在编译你的程序.   Accepted:OK!你的程序是正确的 ^_^.   Wrong Answer:你的 ...

  3. BZOJ 2286 [Sdoi2011]消耗战(虚树+树形DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2286 [题目大意] 出一棵边权树,每次给出一些关键点,求最小边割集, 使得1点与各个关 ...

  4. BZOJ 1221 [HNOI2001] 软件开发(费用流)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1221 [题目大意] 每天对毛巾都有一定的需求ni,每天可以花f价值每条购买毛巾, 当天 ...

  5. [NOIp2016提高组]换教室

    题目大意: 有n节课,第i节课在c[i]上课,同时d[i]也有一节课d[i]. 你有权利向教务处发出m次申请把自己的教室改到d[i],相应的批准概率是k[i]. 教室是图上的一些点,其中每条边都有边权 ...

  6. insert失败自动执行update(duplicate先insert)

    例如:有一张表 字段有  id主键自增,或者唯一索引:datetime时间  name名字 INSERT INTO TABLE (id,datetime) VALUES (1,1440000000), ...

  7. 关于JS的This指针

    下面讨论一个执行上下文的最后一个属性——this指针的概念. This指针 A this value is a special object which is related with the exe ...

  8. JS对象和数组

    /* 数组和对象 [JavaScript 权威指南 第五版] */ /* 对象: 是一个无序属性集合, 每个属性都有自己的名字和值 */ /* 创建对象简单方法, 对象直接量 */ var obj = ...

  9. VC知识库

    VC知识库http://www.vckbase.com/index.php/code

  10. spring的@Async异步使用

    pring的@Async功能,用的时候一定要注意: 1.异步方法和调用类不要在同一个类中. 2.xml里需要加入这一行 <task:annotation-driven/> 下面的可以直接粘 ...