使用caffe的HDF5数据完毕回归任务
一直在研究怎样用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数据完毕回归任务的更多相关文章
- 【机器学习实战】第8章 预测数值型数据:回归(Regression)
第8章 预测数值型数据:回归 <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/ ...
- caffe添加python数据层
caffe添加python数据层(ImageData) 在caffe中添加自定义层时,必须要实现这四个函数,在C++中是(LayerSetUp,Reshape,Forward_cpu,Backward ...
- caffe中关于数据进行预处理的方式
caffe的数据层layer中再载入数据时,会先要对数据进行预处理.一般处理的方式有两种: 1. 使用均值处理 transform_param { mirror: true crop_size: me ...
- 总结一下用caffe跑图片数据的研究流程
近期在用caffe玩一些数据集,这些数据集是从淘宝爬下来的图片.主要是想研究一下对女性衣服的分类. 以下是一些详细的操作流程,这里总结一下. 1 爬取数据.写爬虫从淘宝爬取自己须要的数据. 2 数据预 ...
- caffe 中 python 数据层
caffe中大多数层用C++写成. 但是对于自己数据的输入要写对应的输入层,比如你要去图像中的一部分,不能用LMDB,或者你的label 需要特殊的标记. 这时候就需要用python 写一个输入层. ...
- 【撸码caffe 五】数据层搭建
caffe.cpp中的train函数内声明了一个类型为Solver类的智能指针solver: // Train / Finetune a model. int train() { -- shared_ ...
- 在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 ...
- 在caffe中使用hdf5的数据
caffe默认使用的数据格式为lmdb文件格式,它提供了把图片转为lmdb文件格式的小程序,但是呢,我的数据为一维的数据,我也要分类啊,那我怎么办?肯定有办法可以转为lmdb文件格式的,我也看了一些源 ...
- Windows下用Caffe跑自己的数据(遥感影像)
1 前言 Caffe对于像我这样的初学者来说是一款非常容易上手的深度学习框架.关于用Caffe跑自己的数据这样的博客已经非常多,感谢前辈们为我们提供的这么好的学习资源.这里我主要结合我所在的行业,说下 ...
随机推荐
- HDU 5861 Road(线段树 区间修改 单点查询)
Road Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- Xamarin中打开别人项目找不到android.jar文件
Xamarin中打开别人项目找不到android.jar文件 错误信息:Could not find android.jar for API Level 23.打开非本机创建的Xamarin项目,编译 ...
- hdu 5692 Snacks(dfs时间戳+线段树)
Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- [bzoj1009](HNOI2008)GT考试 (kmp+矩阵快速幂加速递推)
Description 阿 申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学 A1A2...Am(0&l ...
- Java源代码编译过程
编译其本质是将一种语言规范转换成另一种语言规范,即将Java语言规范转换为JVM虚拟机语言规范.结果就是.java文件到.class文件. 对于C/C++编译直接将高级语言转换为机器语言,Java ...
- [转载]c++常用字符串操作函数
原文地址:c++常用字符串操作函数作者:Valsun 函数名: stpcpy 功 能: 拷贝一个字符串到另一个 用 法: char *stpcpy(char *destin, char *source ...
- mysql服务常用命令
一.查出当前mysql正在执行的sql命令mysql> show full processlist; 然后找出要终止的语句的idmysql> kill id号 未登录的情况下>mys ...
- 【JSP JSTL】<c:if>多个判断条件 + <c:foreach>满足条件跳出循环
有一个需求,将所拥有的权限存放于session中,现在JSP页面判断这些如果在所有权限中有某一个或者某几个,就显示相对应的页面内容 举一个例子,实现以上的逻辑,<c:if>多个判断条件 + ...
- 统计中的t检验
1.什么情况下,应用t检验 1. 已知总体的均值m,或者我们假设了一个总体均值m: 2. 我们知道样本的个数n,样本的的方差var,样本的均值m: 3. 我们假设总体,或者样本都是服从正太分布的. 2 ...
- IOS开发博客学习
M了个J :http://www.cnblogs.com/mjios/tag/objective-c/ http://www.cnblogs.com/tianjian/p/3358602.html ...