一直在研究怎样用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. Bzoj4753/洛谷P4432 [JSOI2016]最佳团体(0/1分数规划+树形DP)

    题面 Bzoj 洛谷 题解 这种求比值最大就是\(0/1\)分数规划的一般模型. 这里用二分法来求解最大比值,接着考虑如何\(check\),这里很明显可以想到用树形背包\(check\),但是时间复 ...

  2. 设计模式-迭代器模式(Iterator Pattern)

    本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/ 迭代器模式简介 迭代器相信大部分人都不陌生,java/c++等很多编程语言的容器类都支持迭代器操 ...

  3. 【后缀自动机】poj1509 Glass Beads

    字符串最小表示 后缀自动机 O(n) 把串复制一次,链接在后面之后,建立SAM,贪心地在SAM上转移,每次贪心地选择最小的字符,转移的长度为n时停止. 输出时由于要最靠前的,所以要在endpos集合中 ...

  4. Problem F: 逆序排列

    #include<stdio.h> void sort(int *p,int n) { int i,t; ;i<n/;i++) { t=*(p+i); *(p+i)=*(p+n-i- ...

  5. iOS .a静态库的制作及使用

    一.制作.a静态库 1.创建静态库工程,工程命名为BaseSDK,生成的.a文件名变成libBaseSDK.

  6. struts2升级到2.5的配置

    之前的struts版本太低,后来用想过换个后台,但是改动太大,还是升级到最新版本的struts吧,虽然有点蛋疼的经历,最终还是解决了.下面来分享一下我的经历!!! 1.下载struts2   2.5. ...

  7. Maven命名规范收集

    一.基本命名规范: groupId:定义当前Maven项目隶属的实际项目,例如org.sonatype.nexus,此id前半部分org.sonatype代表此项目隶属的组织或公司,后部分代表项目的名 ...

  8. Matlab横坐标从特定值开始

    set(gca,'XTick',1:1:length(x)); set(gca,'XTickLabel',{'15','20','25','30','35','40','45','50','55',' ...

  9. linux图机界面机制

    1.X WindowX Window 是由麻省理工学院(MIT)推出的窗口系统,简称X,它旨在建立不依赖于特定硬件系统的图形和文字显示窗口系统的标准.1987 年9 月,MIT 推出了X 系统的11 ...

  10. HDU 4886 TIANKENG’s restaurant(Ⅱ) hash+dfs

    题意: 1.找一个字符串s使得 s不是给定母串的子串 2.且s要最短 3.s在最短情况下字典序最小 hash.,,结果t掉了...加了个姿势怪异的hash值剪枝才过.. #include <cs ...