在学习和参加相关深度学习比赛的时候,一般情况下都是在准备好的情况下展开,而在实际的工作项目中。因为每一个公司的业务场景不同,需要我们自己去标记图片数据(参看深度学习标记工具汇总),并且在标记好的图片集中制作 caffe 框架的数据格式(lmdb文件),即本文所讲内容。
制作自己的 caffe 训练数据集的整个过程分为:1. 准备自己的数据集;2. 生成 .txt 文件; 3.转化为 db 文件;4. 计算均值。之后开始训练。
这里从网上下载整理一些图片,分为两类,其中 bird 60张和 cat 60张,其中 50张 bird 和 50张 cat 作为训练集,1其余0张作为验证集。在 .../caffe/data 文件夹下新建文件夹 myself,然后在 myself 文件夹下新建两个子文件夹, train 和 val,即训练集和测试集。然后在 train 文件夹下新建两个文件夹 bird 和 cat,分别存放 50 张 bird 图片和 50 张 cat 图片,在 val 文件夹下放 10张bird 和 10张 cat 图片。至此,我们准备好了原始的数据集。
在 .../caffe/examples 新建一个 myself 文件夹,用于存放配置文件和 脚本文件。
cd ~/caffe/
sudo mkdir examples/myself
# 在 caffe 根目录下进行操作,这是默认的,也是良好的习惯
sudo gedit examples/myself/create_filelist.sh
编辑 create_filelist.sh 脚本文件,输入以下内容:
DATA=data/myself
MY=examples/myself
echo "Create train.txt..."
rm -rf $DATA/train.txt
find $DATA/train/bird -name birdt*.jpg | cut -d '/' -f5 | sed "s:^:bird/:" | sed "s/$/ 1/">>$MY/train.txt
find $DATA/train/cat -name catt*.jpg | cut -d '/' -f5 | sed "s:^:cat/:" | sed "s/$/ 2/">>$MY/train.txt
echo "Create val.txt..."
rm -rf $DATA/val.txt
find $DATA/val -name birdv*.jpg | cut -d '/' -f4 | sed "s/$/ 1/">>$MY/val.txt
find $DATA/val -name catv*.jpg | cut -d '/' -f4 | sed "s/$/ 2/">>$MY/val.txt
echo "All done"
代码解释:
rm -rf $DATA/train.txt 表示清除该路径下的train.txt文件
find $DATA/train/bird -name birdt*.jpg 此处为find指令的用法。
$DATA/train/bird 表示具体的图片路径
birdt*.jpg 表示在以图片名字以birdt开始的jpg图片
cut -d '/' -f5
此处为cut指令的用法,具体表示请百度,此处表示以’/’为分隔符,由于该指令在caffe-master目录下执行,
之后路径为/data/myself/train/bird/然后是图片名字,所以要采取的图片的名字为第5个,所以为-f5,下
面val集的图片路径为/data/myself/val/然后是图片名字,为第4个,所以为-f4
sed "s:^:bird/:" 此处表示给图片名字加前缀’bird/’,表示一种路径
由于train文件夹下又分了两个文件夹,所以此处加前缀,表示路径
val文件夹下直接就是图片,所以不需要前缀。
sed "s/$/ 1/" 加后缀’ 1’,也就是标签
$MY/train.txt 表示在/examples/myself/路径下产生train.txt,以上内容全部保存到此。
上述的验证集文件夹 bird 图片和 cat 图片没有分开,是依靠图片名字的字符串作为区分标准。但在大数据集的情况下,建议以文件夹作为区分标准(细节之处不同,实际工作可以提高效率)。另一种实现方法实现 create_filelist.txt 文件:
准备工作:
原始数据:train文件夹下的bird图片和cat图片分别在各自的文件夹下,即train文件夹下有两个文件夹,bird和cat。
但是val文件夹目录下并没有再分开bird和cat,而是将验证集10张bird和10张cat一起放到了val文件夹下。
这是上述方法的图片数据的存储格式。
变更之处:此处需要将val文件夹下新建两个文件夹,bird和cat1 (因为在代码中需要使用该文件夹名称,
而cat是Ubuntu中的一个指令,冲突)。
同时将train文件夹下的cat文件夹重命名为cat1,将10张bird图片放到bird文件夹下,10张cat文件夹放到cat_1文件夹下,即可!
其他步骤都一样,只是将create_filelist.sh代码部分换成下列代码:
代码:
DATA=data/myself
MY=examples/myself
echo "Create train.txt..."
rm -rf $DATA/train.txt
ls $DATA/train/bird | sed "s:^:bird/:" | sed "s/$/ 1/">>$MY/train.txt
ls $DATA/train/cat1 | sed "s:^:cat1/:" | sed "s/$/ 2/">>$MY/train.txt
echo "Create val.txt..."
rm -rf $DATA/val.txt
ls $DATA/val/bird | sed "s:^:bird/:" | sed "s/$/ 1/">>$MY/val.txt
ls $DATA/val/cat1 | sed "s:^:cat1/:" | sed "s/$/ 2/">>$MY/val.txt
echo "All done"
代码解释:
此处代码和上面代码的改变之处就是将find和cut命令替换为了ls命令,ls表示列举,具体含义可以百度。
依据文件区分不同类别的数据图片,而不是图片名称中的字符串。
然后在 caffe 根目录下执行此 sh 文件,生成 .txt 文件:
cd ~/caffe/
sudo sh examples/myself/create_filelist.sh
新建转化 db 文件的脚本文件 create_lmdb.sh
cd ~/caffe/
sudo gedit examples/myself/create_lmdb.sh
编辑 create_lmdb.sh 文件:
MY=examples/myself
echo "Create train lmdb.."
rm -rf $MY/train_lmdb
build/tools/convert_imageset --shuffle --resize_height=256 --resize_width=256 /home/felix/caffe/data/myself/train/ $MY/train.txt $MY/train_lmdb
echo "Create val lmdb.."
rm -rf $MY/val_lmdb
build/tools/convert_imageset --shuffle --resize_width=256 --resize_height=256 /home/felix/caffe/data/myself/val/ $MY/val.txt $MY/val_lmdb
echo "All Done.."
保存退出,执行 create_lmdb.sh 文件:
cd ~/caffe/
sudo sh examples/myself/create_lmdb.sh
计算均值的原因是保证所有特征都在0附近,在大多数情况下,我们并不关心所输入图像的整体明亮程度,比如对象识别任务中,图像的整体明亮程度,并不会影响图像中存在的是什么物体,我们对图像的平均亮度感兴趣,所以可以减去这个值来进行均值规整化。
新建 create_meanfile.sh 文件:
EXAMPLE=examples/myself
DATA=examples/myself/
TOOLS=build/tools
$TOOLS/compute_image_mean $EXAMPLE/train_lmdb $DATA/mean.binaryproto
echo "Done."
得到均值文件 mean.binaryproto 文件便完成了图像的前期处理。接下来就可以进行相关的训练。
snapshot_prefix:用于存放生成的model的路径(最好写绝对路径)
net:是我们要调用的网络,所以我们需要修改成我们要调用的网络的路径
接下来就要打开我们调用的网络trainval.prototxt文件,修改source路径,并根据需要修改全连接层的num_output参数等。
cd caffe
./build/tools/caffe train -solver=/XXX/XXX/…/sovler.prototxt
运行结束以后会在snapshot文件夹下生成caffemodel和solverstate文件,一个是模型文件,一个是中间状态文件。当训练过程中断,想要继续训练数据,此时只需要调用solverstate文件即可。命令如下:
cd caffe
./build/tools/caffe train -solver=/XXX/XXX/…/sovler.prototxt -snapshot=/XXX/XXX/…/XX.solverstate
当需要用已经训练好的model对某次训练做 finetune,可以使用caffemodel,命令如下:
cd caffe
./build/tools/caffe train -solver=/XXX/XXX/…/sovler.prototxt -weights=/XXX/XXX/…/XX.caffemodel
参考链接1 参考链接2