caffe学习笔记6--训练自己的数据集
2016-04-18 11:24
627 查看
这一部分记录下如何用caffe训练自己的数据集,这里使用AlexNet的网络结构。
该结构及相应的solver文件在CAFFE/models/bvlc_alexnet目录下,使用train_val.prototxt和solver.prototxt两个文件
首先,在$CAFFE/examples/imagenet下面创建自己的文件夹,myimage,
因为原始的Imagenet数据集太大,我们这里使用自己的数据集,我从网上下载了两类数据集存放在myimage下的image文件夹下,文件结构:
-----images
|-------car
|------person
每一类存放在一个文件夹中,接下来生成txt文档,文档中包含了图片的存放路径,图片的标签,我用python来实现生成.txt文件
生成的txt文本的格式如下:
images/car/101008094025552.jpg 0
images/person/5174f5a74f4f0.jpg 1
这里需要说一下,样本标签需要从0开始,否则会出现一些问题。也可以使用控制台下的命令,这个需要自己查一下,我没有用过
还需要生成val测试文件,同样的步骤。
在生成txt文件后,需要使用imagenet下的create_imagenet.sh文件生成lmdb文件。将这个文件拷贝到你自己的文件目录下,需要修改一些目录和文件名,看一下里面的内容。
其实, 对于改变图片的大小,可以在当前目录下使用:
for name in images/*/*.jpg;do convert -resize 256x256\! $name $name; done
这条命令*为通配符,上面--resize可以不要
接下来,需要对现有图片求均值:
使用imagenet中的make_imagenet_mean.sh对训练图片数据求均值,将其拷贝到你的文件目录下,修改下路径:
在caffe根目录下运行:./examples/imagenet/myimage/make_imagenet_mean.sh
完成之后,还需要做的事情就是修改网络的训练参数和获取文件的地址:
首先,看一下train_val.prototxt.
需要修改:
对于solver.prototxt:
修改完成后,可以开始训练了:
将train_caffenet.sh放到自己的文件目录下,
在CAFFE根目录下运行:./examples/imagenet/myimage/train_caffenet.sh
这里需要注意,所有的执行语句一定是在根目录下,否则会报错,除非你在配置文件时候更改路径!
这样,训练过程就开始了,
稍微描述一下执行过程:
首先,初始化参数:输出solver.prototxt中的内容:
然后,初始化网络结构,就是train_val中的内容,这个可以在上个输出网络初始化过程中看出来。
接下来就是进入训练过程。
在我的训练过程中:
刚开始训练时:
最后要说的是,这里只是向走一遍训练的过程,但是网路的训练肯定是不充分的。
另外,我是将所有的文件都放在自己的目录下吗,也可以不放,但是要注意文件的路径。
补充记录两个问题:
1.gpu训练,运行过程中如果出现报错:
Check failed: error == cudaSuccess (2 vs. 0) out of memory这个问题很可能是你的网络结构中batch_size的值太大的原因,改小一点就没有问题
2. 迭代过程中出现 loss=-nan
这个问题可能比较多,说明学习率的值设的太大,改小一点再尝试.
该结构及相应的solver文件在CAFFE/models/bvlc_alexnet目录下,使用train_val.prototxt和solver.prototxt两个文件
首先,在$CAFFE/examples/imagenet下面创建自己的文件夹,myimage,
因为原始的Imagenet数据集太大,我们这里使用自己的数据集,我从网上下载了两类数据集存放在myimage下的image文件夹下,文件结构:
-----images
|-------car
|------person
每一类存放在一个文件夹中,接下来生成txt文档,文档中包含了图片的存放路径,图片的标签,我用python来实现生成.txt文件
import os root = os.getcwd() #获取当前路径 data = 'images' path = os.listdir(root+'/'+ data) #显示该路径下所有文件 path.sort() file = open('train.txt','w') i = 0 for line in path: str = root+'/'+ data +'/'+line for child in os.listdir(str): str1 = data+'/'+line+'/'+child; d = ' %s' %(i) t = str1 + d file.write(t +'\n') i=i+1 file.close()
生成的txt文本的格式如下:
images/car/101008094025552.jpg 0
images/person/5174f5a74f4f0.jpg 1
这里需要说一下,样本标签需要从0开始,否则会出现一些问题。也可以使用控制台下的命令,这个需要自己查一下,我没有用过
还需要生成val测试文件,同样的步骤。
在生成txt文件后,需要使用imagenet下的create_imagenet.sh文件生成lmdb文件。将这个文件拷贝到你自己的文件目录下,需要修改一些目录和文件名,看一下里面的内容。
#!/usr/bin/env sh # Create the imagenet lmdb inputs # N.B. set the path to the imagenet train + val data dirs EXAMPLE=examples/imagenet/myimage TOOLS=build/tools TRAIN_DATA_ROOT=examples/imagenet/myimage/ #训练样本的存放路径 VAL_DATA_ROOT=examples/imagenet/myimage/ #测试样本的存放路径 # Set RESIZE=true to resize the images to 256x256. Leave as false if images have # already been resized using another tool. RESIZE=false if $RESIZE; then RESIZE_HEIGHT=256 #改变图片的大小为256*256 RESIZE_WIDTH=256 else RESIZE_HEIGHT=0 RESIZE_WIDTH=0 fi # 判断路径是否正确的提示信息 if [ ! -d "$TRAIN_DATA_ROOT" ]; then echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT" echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \ "where the ImageNet training data is stored." exit 1 fi if [ ! -d "$VAL_DATA_ROOT" ]; then echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT" echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \ "where the ImageNet validation data is stored." exit 1 fi echo "Creating train lmdb..." GLOG_logtostderr=1 $TOOLS/convert_imageset \ #调用convert_imageset文件转换文件格式,后面为输入参数 --resize_height=$RESIZE_HEIGHT \ --resize_width=$RESIZE_WIDTH \ --shuffle \ $TRAIN_DATA_ROOT \ $EXAMPLE/train.txt \ $EXAMPLE/train_lmdb echo "Creating val lmdb..." GLOG_logtostderr=1 $TOOLS/convert_imageset \ --resize_height=$RESIZE_HEIGHT \ --resize_width=$RESIZE_WIDTH \ --shuffle \ $VAL_DATA_ROOT \ $EXAMPLE/val.txt \ $EXAMPLE/val_lmdb echo "Done."在caffe根目录下运行:./examples/imagenet/myimage/create_imagenet.sh,文件夹中会多出两个lmdb的文件夹
其实, 对于改变图片的大小,可以在当前目录下使用:
for name in images/*/*.jpg;do convert -resize 256x256\! $name $name; done
这条命令*为通配符,上面--resize可以不要
接下来,需要对现有图片求均值:
使用imagenet中的make_imagenet_mean.sh对训练图片数据求均值,将其拷贝到你的文件目录下,修改下路径:
#!/usr/bin/env sh # Compute the mean image from the imagenet training lmdb # N.B. this is available in data/ilsvrc12 EXAMPLE=examples/imagenet/myimage TOOLS=build/tools $TOOLS/compute_image_mean $EXAMPLE/train_lmdb \ #调用compute_iamge_mean计算均值,其cpp代码在tool目录下 $EXAMPLE/imagenet_mean.binaryproto echo "Done."
在caffe根目录下运行:./examples/imagenet/myimage/make_imagenet_mean.sh
完成之后,还需要做的事情就是修改网络的训练参数和获取文件的地址:
首先,看一下train_val.prototxt.
需要修改:
name: "AlexNet" layer { name: "data" type: "Data" top: "data" top: "label" include { phase: TRAIN } transform_param { mirror: true crop_size: 227 mean_file: "examples/imagenet/myimage/imagenet_mean.binaryproto" #均值二进制文件的存放目录 } data_param { source: "examples/imagenet/myimage/train_lmdb" #数据的存放目录 batch_size: 50 #因为我的数据规模很小,所以批处理的数据的量我改为50。 backend: LMDB } } layer { name: "data" type: "Data" top: "data" top: "label" include { phase: TEST } transform_param { mirror: false crop_size: 227 mean_file: "examples/imagenet/myimage/imagenet_mean.binaryproto" } data_param { source: "examples/imagenet/myimage/val_lmdb" batch_size: 50 backend: LMDB } }
对于solver.prototxt:
net: "examples/imagenet/myimage/train_val.prototxt" test_iter: 10 test_interval: 100 base_lr: 0.001 lr_policy: "step" gamma: 0.1 stepsize: 100 display: 20 max_iter: 400 #这里说一下最大迭代次数,原来文档中是45000,但是我的数据量很小,在几百次的时候loss已经比较小了,为了尽快的到训练结果,因此,所有的参数都相应有所修改。 momentum: 0.9 weight_decay: 0.0005 snapshot: 200 snapshot_prefix: "examples/imagenet/myimage" solver_mode: CPU #我这里使用cpu,自作的,慢的要死.关于这两个文件的解释,可以看我之前写的博客,
修改完成后,可以开始训练了:
将train_caffenet.sh放到自己的文件目录下,
#!/usr/bin/env sh ./build/tools/caffe train \ --solver=examples/imagenet/myimage/solver.prototxt
在CAFFE根目录下运行:./examples/imagenet/myimage/train_caffenet.sh
这里需要注意,所有的执行语句一定是在根目录下,否则会报错,除非你在配置文件时候更改路径!
这样,训练过程就开始了,
稍微描述一下执行过程:
首先,初始化参数:输出solver.prototxt中的内容:
然后,初始化网络结构,就是train_val中的内容,这个可以在上个输出网络初始化过程中看出来。
接下来就是进入训练过程。
在我的训练过程中:
刚开始训练时:
I0418 09:38:17.902889 504 solver.cpp:409] Test net output #0: accuracy = 0 I0418 09:38:17.902942 504 solver.cpp:409] Test net output #1: loss = 6.93296 (* 1 = 6.93296 loss)在进过一段时间的迭代后:loss减少,但是真确率提高。至于正确率,估计是我的数据的问题
I0418 10:53:33.159943 504 solver.cpp:409] Test net output #0: accuracy = 1 I0418 10:53:33.159999 504 solver.cpp:409] Test net output #1: loss = 0.0103494 (* 1 = 0.0103494 loss)还有一个要注意的是,在alexnet的训练中,lr不是固定的,在sovler中设置,这个可以观察一下控制台的输出。
最后要说的是,这里只是向走一遍训练的过程,但是网路的训练肯定是不充分的。
另外,我是将所有的文件都放在自己的目录下吗,也可以不放,但是要注意文件的路径。
补充记录两个问题:
1.gpu训练,运行过程中如果出现报错:
Check failed: error == cudaSuccess (2 vs. 0) out of memory这个问题很可能是你的网络结构中batch_size的值太大的原因,改小一点就没有问题
2. 迭代过程中出现 loss=-nan
这个问题可能比较多,说明学习率的值设的太大,改小一点再尝试.
相关文章推荐
- css中的视窗单位
- 简单易用Seajs
- CSS实现元素水平/垂直居中的方法
- JavaScript开发环境Aptana
- BoW(Bag-of-Features)特征袋对图像进行分类的理解
- 高效Web开发的10个jQuery代码片段
- 火狐和ie的代理记住
- SAP IQ: Relocate the Message Trace File to a Different Location
- logstash如何读取json格式日志,并建立json定义好的索引
- 【Bugly干货分享】一起用 HTML5 Canvas 做一个简单又骚气的粒子引擎
- Javascript模块加载框架——seajs
- jquery 对象级插件写法
- 重读“javascript高级程序设计(第三版)”--原型
- H5页面快速搭建之高级字体应用实践
- jstl简单总结
- H5页面快速搭建之高级字体应用实践
- H5页面快速搭建之高级字体应用实践
- 剑指offer(十三)之链表中倒数第k个结点
- 文本溢出解决方案---jquery-dotdotdot插件的使用方法
- jQuery Validate插件实现表单强大的验证功能