您的位置:首页 > Web前端

个人中使用caffe做回归中遇到的问题和解决办法

2016-12-09 22:03 441 查看
最近在为小论文努力,要做的是一个回归任务,导师推荐使用caffe。于是,为我的电脑装上了caffe,并通过网上的一些人的经验和分享学着使用caffe。在刚刚使用caffe时,遇到了很多困难,毕竟网上的分享都是基于图片分类的,回归的还是很少的。

为了方便他人和记录自己的成长,就写下这些我遇到的一些困难和为自己的解决方案。

在使用caffe时,为遇到的第一个问题就是如何把我的数据转化成caffe构建的网络所使用的数据格式。通过查找资料,知道最常用的就是lmdb,leveldb,HDF5等格式的数据。由于个人常用python,而python把数据转成HDF5格式的比较方便,于是就选择了HDF5格式。在这里有必要说明一下,caffe自带转换图片数据格式的接口,如果你的数据是图片类型的,使用caffe的接口把图片转成lmdb格式的数据会更简单。PS:我的数据不是图片类型的

**

问题一

**

使用python生成HDF5格式的数据是非常方便的,它可以直接把numpy矩阵格式的数据写入HDF5格式的文件中。我把txt文件中的数据读入(每一行是一条数据,行尾那项是label),转化成numpy格式的矩阵,然后写入HDF5格式文件中。

import sys
import numpy
from matplotlib import pyplot
import h5py

FEATURES_SIZE = (1, 106)

filename = sys.argv[1]
setname, ext = filename.split('.')

with open(filename, 'r') as f:
lines = f.readlines()

data_lines = len(lines)
all_datas = numpy.zeros((data_lines, 1,) + FEATURES_SIZE, dtype=numpy.float32)
labels = numpy.zeros(data_lines, dtype=numpy.float32)

h5_filename = '{}.h5'.format(setname)
for i, line in enumerate(lines):
label = line.split('\n')[0].split('\t')[-1]
features = numpy.zeros((1, 106),numpy.float32)#106是我的数据特征的维度
for j in range(106):
features[0][j] = float(line.split('\n')[0].split('\t')[j])
features = features.reshape((1,) + features.shape)
all_datas[i] = features
labels[i] = float(label)
if (i+1) % 1000 == 0:
print(i+1)
h = h5py.File(h5_filename, 'w')
h.create_dataset('data', data=all_datas)
h.create_dataset('labels', data=labels)
h.close()

with open('{}_h5.txt'.format(setname), 'w') as f:
f.write(h5_filename)


运行
python *.py train.txt


这里我有必要特别说明一下,我的数据是一条向量对应一个label,向量是106维的,所以FEATURES_SIZE设置的(1,106)。数据最终处理完的格式是(data_numbers,1,1,106),label的格式就是一个data_numbers维度的向量。如果处理的不正确的话,使用训练网络时会出现shape不一致的问题。还有一点要注意的是,_h5.txt这个文件的内容,其实就是.h5文件的路径。如果你的数据跟×××.prototxt网络构建文件不在同一个文件夹下,这里的路径就要写全。不然就会出现下面这种错误

****** check fialed:_data


**

问题二

**

数据处理完毕,接下来就是网络搭建了。如果你使用HDF5格式的数据,搭建网络的.prototxt文件中的前两层就要该成下面的样子

name: "LeNet"
layer {
name: "data"
type: "HDF5Data"
top: "data"
top: "score"
include {
phase: TRAIN
}
hdf5_data_param {
source: "train_h5.txt"
batch_size: 100
}
}
layer {
name: "data"
type: "HDF5Data"
top: "data"
top: "score"
include {
phase: VAL
}
hdf5_data_param {
source: "val_h5.txt"
batch_size: 100
}
}


在搭建网络时,根据你的需求,你可以直接使用caffe的examples中样例的网络。但是有一个地方要特别注意,如果你的数据跟我的数据类似,则需要把.prototxt文件中每一个含有kernel_size的网络层作一下修改,就是把kernel_size改小点。不然就会出现下面这种错误



**

问题三

**

<
4000
p>在训练好网络之后,如何查看自己的网络到底怎么样,仅凭训练过程中的loss和精度是不行的。我们要把自己的测试数据输入训练好的网络中,然后输出测试结果和真实的label。

这时,我们需要新建一个.prototxt文件,这个文件只需要把训练网络的.prototxt文件复制过来,然后做一下简单的修改就可以了。

把最上面两层数据层删去,然后添加以下片段

input: "data"
input_shape {
dim: 1
dim: 1
dim: 1
dim: 106
}


这里的参数,根据自己的数据格式就该即可。然后把accuracy层和laoss层删去,注意一下accuracy层的bottom的输入是哪一层,。例如我的,accuracy层bottom有两个,一个是ip2,一个是label。这里label其实就是我们数据的label,为了计算accuracy的。找到名为ip2的网络层,记下它的top参数,以备后用。

接着要书写一个python脚本,代码如下:

import sys
import numpy
sys.path.append("/home/bonbon/MechineLearning/caffe/python")
import caffe

WEIGHTS_FILE = "*_iter_10000.caffemodel"
DEPLOY_FILE = '*_test.prototxt'
DATA_SIZE = (1,106)

caffe.set_mode_cpu()
net = caffe.Net(DEPLOY_FILE, WEIGHTS_FILE, caffe.TEST)
net.blobs['data'].reshape(1,1,*DATA_SIZE)

filename = sys.argv[1]

with open(filename, 'r') as f:
flag = -1
for line in f.readlines():
flag += 1

line_data = numpy.zeros((1,106),dtype = numpy.float32)
for i in range(106):
line_data[0][i] = float(line.split('\t')[i])
print line_data.shape
labels = float(line.split('\t')[-1].split('\n')[0])
net.blobs['data'].data[...] = line_data

output = net.forward()
score = output['ip2'][0][0]

print ('The predicted score is {},the true is {}'.format(score,labels))
if flag == 10:
break


运行一下:
python *.py test.txt


PS:*号代表文件的名称

恩,暂时就这些

参考链接

利用caffe做回归

caffe上使用HDF5格式数据

这里有一些关于caffe做回归的讨论

还有一些当时遇到问题,搜索的网站,太多,没记下来自己google吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  深度学习 caffe HDF5
相关文章推荐