美文网首页机器学习TF/coffeCAFFE
caffe将各种原始图片数据集转换为lmdb格式并训练网络

caffe将各种原始图片数据集转换为lmdb格式并训练网络

作者: Ericzhang922 | 来源:发表于2017-04-25 15:48 被阅读4434次

    1.Caltech-UCSD Birds200 鸟类图像数据

    Caltech-UCSD Birds200 是一个鸟类图片数据集,包含 200 不同种鸟类,共计 11788 张图片
    此处下载该数据集Caltech-UCSD Birds200 鸟类图像数据

    文件夹images内包含200个文件夹,其中每一个文件夹包含一个分类.(由于都是一一对应的关系,所以我们可以直接利用word中表格栏选项中的文本转换为表格的方法,将其暂时转换为表格形式,然后再copy到excel中做进一步处理)

    • README.txt是该数据集的解释文件
    • images.txt是该数据集内images内图片的目录文件 每一行代表一个子文件夹内的一个图片文件
    id content
    1 001.Black_footed_Albatross/Black_Footed_Albatross_0046_18.jpg
    2 001.Black_footed_Albatross/Black_Footed_Albatross_0009_34.jpg
    3 001.Black_footed_Albatross/Black_Footed_Albatross_0002_55.jpg
    4 001.Black_footed_Albatross/Black_Footed_Albatross_0074_59.jpg
    5 001.Black_footed_Albatross/Black_Footed_Albatross_0014_89.jpg
    6 001.Black_footed_Albatross/Black_Footed_Albatross_0085_92.jpg
    7 001.Black_footed_Albatross/Black_Footed_Albatross_0031_100.jpg
    .... ....
    • classes.txt是标签文件 代表200个种类的200个标签
    id label
    1 001.Black_footed_Albatross
    2 002.Laysan_Albatross
    3 003.Sooty_Albatross
    4 004.Groove_billed_Ani
    5 005.Crested_Auklet
    6 006.Least_Auklet
    7 007.Parakeet_Auklet
    .... ....
    • image_class_labels.txt对应于images.txt文件 表示每一个图片的标签
    id label
    1 1
    2 1
    3 1
    4 1
    5 1
    6 1
    7 1
    .... ....
    • train_test_split.txt对应于images.txt中分割train和test图片,其中1表示train图片而0表示test图片
    id train/test
    1 0
    2 1
    3 0
    4 1
    5 1
    6 0
    7 1
    .... ....

    通过以上的简单转换就可以变成excel表格形式,然后将其全部copy到一个excel文件中,再做简单的处理将重复的id栏去掉,可以得到如下表格:

    id image lable train/test
    1 001.Black_footed_Albatross/Black_Footed_Albatross_0046_18.jpg 1 0
    2 001.Black_footed_Albatross/Black_Footed_Albatross_0009_34.jpg 1 1
    3 001.Black_footed_Albatross/Black_Footed_Albatross_0002_55.jpg 1 0
    4 001.Black_footed_Albatross/Black_Footed_Albatross_0074_59.jpg 1 1
    5 001.Black_footed_Albatross/Black_Footed_Albatross_0014_89.jpg 1 1
    6 001.Black_footed_Albatross/Black_Footed_Albatross_0085_92.jpg 1 0
    7 001.Black_footed_Albatross/Black_Footed_Albatross_0031_100.jpg 1 1
    8 001.Black_footed_Albatross/Black_Footed_Albatross_0051_796103.jpg 1 1
    9 001.Black_footed_Albatross/Black_Footed_Albatross_0010_796097.jpg 1 1
    10 001.Black_footed_Albatross/Black_Footed_Albatross_0025_796057.jpg 1 0
    .... .... .... ....

    所以通过train/test的选择,我们就可以将其分成训练集和测试集。再将其copy回word文档,就可以产生两个需要用到的文件train.txt和val.txt。这就是参考文档中的filelist文件,所以可以跳过参考文档中的做法。

    • train.txt
      001.Black_footed_Albatross/Black_Footed_Albatross_0009_34.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0074_59.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0014_89.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0031_100.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0051_796103.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0010_796097.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0023_796059.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0040_796066.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0089_796069.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0067_170.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0060_796076.jpg 1
      ....
    • val.txt
      001.Black_footed_Albatross/Black_Footed_Albatross_0046_18.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0002_55.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0085_92.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0025_796057.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0086_796062.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0049_796063.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0006_796065.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0016_796067.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0065_796068.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0042_796071.jpg 1
      001.Black_footed_Albatross/Black_Footed_Albatross_0090_796077.jpg 1
      ....

    接下来我们将图片和用到的文件放到一个文件夹mydata下

    train.txt
    val.txt
    images

    在caffe中,作者为我们提供了这样一个文件:convert_imageset.cpp,存放在根目录下的tools文件夹下。编译之后,生成对应的可执行文件放在 $cafferoot/tools/ 下面,这个文件的作用就是用于将图片文件转换成caffe框架中能直接使用的db文件。
    error:

    ./include/caffe/util/cudnn.hpp:8:34: fatal error: caffe/proto/caffe.pb.h: No such file or directory
    #include "caffe/proto/caffe.pb.h"
    

    解决方法:fatal error: caffe/proto/caffe.pb.h: No such file or directory

    $ protoc src/caffe/proto/caffe.proto --cpp_out=.
    $ mkdir include/caffe/proto
    $ mv src/caffe/proto/caffe.pb.h include/caffe/proto
    $ cp -r include/caffe/proto ./
    

    执行下面的命令,编译convert_imageset.cpp文件,执行不成功,显示proto的错误,此时我们改变方法,利用自带的example/imagenet下的文件来生成所需的文件。由于image的大小不一样,所以最好在开始的时候就将所有图片转换成为同样大小,利用以下命令转换:

    find ./ -name '*.jpg' -exec convert -resize 600x480 {} {} \;
    

    在image文件夹的目录内执行此命令后就将所有的图片都转换成为320x240大小的图片了。copy example/imagenet下的文件到mydata文件夹下,修改create_imagenet.sh文件(该文件内也有resize的选项)
    在运行create_imagenet.sh时出现E0425 14:24:29.828167 5561 io.cpp:80] Could not open or find file /home/hypervision/work/caffe/mydata/images/val//home/hypervision/work/caffe/mydata/images/val/001.Black_footed_Albatross/Black_Footed_Albatross_0006_796065.jpg 找不到图片的现象是因为txt文件中image和对应的label之间只能有一个空格(只能是英文输入环境下的空格!!!),这用excel转word的时候会在这里产生中文环境下的空格而产生错误!!!caffe训练自己的模型步骤 要改正此错误也很好改:

    #用查找和替换方式
    .jpg (中文输入环境下的空格)
    .jpg (英文输入环境下的空格)
    

    这时运行该文件就可以生成在次数据集上的lmdb格式的数据文件了。create_imagenet.sh文件为:

    #!/usr/bin/env sh
    # Create the imagenet lmdb inputs
    # N.B. set the path to the imagenet train + val data dirs
    set -e
    #全部的文件(包含数据)都放在/caffe/mydata文件夹内
    EXAMPLE=../mydata   #存放输出lmdb文件的文件夹
    DATA=../mydata      #存放train.txt和val.txt文件的文件夹
    TOOLS=../build/tools #调用convert_imageset程序
    
    TRAIN_DATA_ROOT=/home/hypervision/work/caffe/mydata/images/train/  #train数据存放目录(可包含子文件夹)
    VAL_DATA_ROOT=/home/hypervision/work/caffe/mydata/images/val/      #val数据存放目录(可包含子文件夹)
    
    
    # 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
      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 \
        --resize_height=$RESIZE_HEIGHT \
        --resize_width=$RESIZE_WIDTH \
        --shuffle \
        $TRAIN_DATA_ROOT \
        $DATA/train.txt \
        $EXAMPLE/ilsvrc12_train_lmdb
    
    echo "Creating val lmdb..."
    
    GLOG_logtostderr=1 $TOOLS/convert_imageset \
        --resize_height=$RESIZE_HEIGHT \
        --resize_width=$RESIZE_WIDTH \
        --shuffle \
        $VAL_DATA_ROOT \
        $DATA/val.txt \
        $EXAMPLE/ilsvrc12_val_lmdb
    
    echo "Done."
    

    在当前目录开启terminal,执行create_imagenet.sh:

    hypervision@hypervision-700:~/work/caffe/mydata$ ./create_imagenet.sh 
    Creating train lmdb...
    I0425 14:33:11.755530  5941 convert_imageset.cpp:86] Shuffling data
    I0425 14:33:11.995342  5941 convert_imageset.cpp:89] A total of 5994 images.
    I0425 14:33:11.995568  5941 db_lmdb.cpp:35] Opened lmdb ../mydata/ilsvrc12_train_lmdb
    I0425 14:33:16.814551  5941 convert_imageset.cpp:147] Processed 1000 files.
    I0425 14:33:21.675709  5941 convert_imageset.cpp:147] Processed 2000 files.
    I0425 14:33:26.373101  5941 convert_imageset.cpp:147] Processed 3000 files.
    I0425 14:33:31.185261  5941 convert_imageset.cpp:147] Processed 4000 files.
    I0425 14:33:36.626116  5941 convert_imageset.cpp:147] Processed 5000 files.
    I0425 14:33:41.590888  5941 convert_imageset.cpp:153] Processed 5994 files.
    Creating val lmdb...
    I0425 14:33:42.242558  5971 convert_imageset.cpp:86] Shuffling data
    I0425 14:33:42.513573  5971 convert_imageset.cpp:89] A total of 5794 images.
    I0425 14:33:42.513809  5971 db_lmdb.cpp:35] Opened lmdb ../mydata/ilsvrc12_val_lmdb
    I0425 14:33:47.492820  5971 convert_imageset.cpp:147] Processed 1000 files.
    I0425 14:33:58.676864  5971 convert_imageset.cpp:147] Processed 2000 files.
    I0425 14:34:16.156783  5971 convert_imageset.cpp:147] Processed 3000 files.
    I0425 14:34:36.846071  5971 convert_imageset.cpp:147] Processed 4000 files.
    I0425 14:34:56.638617  5971 convert_imageset.cpp:147] Processed 5000 files.
    I0425 14:35:11.903795  5971 convert_imageset.cpp:153] Processed 5794 files.
    Done.
    

    在当前目录可以看到生成了两个文件夹ilsvrc12_train_lmdb和ilsvrc12_val_lmdb分别存放训练和验证所需的数据。
    然后利用 make_imagenet_mean.sh 生成所需要的 mean file,和create_imagenet.sh同样的设置:

    #!/usr/bin/env sh
    # Compute the mean image from the imagenet training lmdb
    # N.B. this is available in data/ilsvrc12
    
    EXAMPLE=../mydata
    DATA=../mydata
    TOOLS=../build/tools
    
    $TOOLS/compute_image_mean $EXAMPLE/ilsvrc12_train_lmdb \
      $DATA/imagenet_mean.binaryproto
    
    echo "Done."
    

    在运行过程中如果出现如下错误:

    I0425 14:46:16.075706  6398 db_lmdb.cpp:35] Opened lmdb ../mydata/ilsvrc12_train_lmdb
    I0425 14:46:16.076617  6398 compute_image_mean.cpp:70] Starting iteration
    F0425 14:46:16.076819  6398 compute_image_mean.cpp:79] Check failed: size_in_datum == data_size (230400 vs. 144720) Incorrect data field size 230400
    *** Check failure stack trace: ***
        @     0x7fb05aca25cd  google::LogMessage::Fail()
        @     0x7fb05aca4433  google::LogMessage::SendToLog()
        @     0x7fb05aca215b  google::LogMessage::Flush()
        @     0x7fb05aca4e1e  google::LogMessageFatal::~LogMessageFatal()
        @           0x4025d8  main
        @     0x7fb059c13830  __libc_start_main
        @           0x402bb9  _start
        @              (nil)  (unknown)
    Aborted (core dumped)
    Done.
    

    检查图片大小在之前的resize过程中是否都设置一样了,如果存在不一样则会出现上诉错误,利用create_imagenet.sh中的resize再次生成一下lmdb文件,并再次运行此mean文件就可以得到imagenet_mean.binaryproto文件:

    hypervision@hypervision-700:~/work/caffe/mydata$ sh ./make_imagenet_mean.sh 
    I0425 14:51:12.212188  6553 db_lmdb.cpp:35] Opened lmdb ../mydata/ilsvrc12_train_lmdb
    I0425 14:51:12.213258  6553 compute_image_mean.cpp:70] Starting iteration
    I0425 14:51:13.346879  6553 compute_image_mean.cpp:101] Processed 5994 files.
    I0425 14:51:13.347925  6553 compute_image_mean.cpp:108] Write to ../mydata/imagenet_mean.binaryproto
    I0425 14:51:13.349079  6553 compute_image_mean.cpp:114] Number of channels: 3
    I0425 14:51:13.349189  6553 compute_image_mean.cpp:119] mean_value channel [0]: 110.145
    I0425 14:51:13.349315  6553 compute_image_mean.cpp:119] mean_value channel [1]: 127.242
    I0425 14:51:13.349419  6553 compute_image_mean.cpp:119] mean_value channel [2]: 123.707
    Done.
    

    我们利用caffe官方给出的文本定义网络结构和solver文件来训练一个神经网络,选择/caffe/models/bvlc_alexnet,查看solver.prototxt,可以不用修改该文件:

    net: "../models/bvlc_alexnet/train_val.prototxt"
    test_iter: 1000
    test_interval: 1000
    base_lr: 0.01
    lr_policy: "step"
    gamma: 0.1
    stepsize: 100000
    display: 20
    max_iter: 450000
    momentum: 0.9
    weight_decay: 0.0005
    snapshot: 10000
    snapshot_prefix: "../models/bvlc_alexnet/caffe_alexnet_train"
    solver_mode: GPU
    

    查看train_val.prototxt文件,我们需要修改的是输入端的各种数据及mean file,如下:

    name: "AlexNet"
    layer {
      name: "data"
      type: "Data"
      top: "data"
      top: "label"
      include {
        phase: TRAIN
      }
      transform_param {
        mirror: true
        crop_size: 227
        mean_file: "../mydata/imagenet_mean.binaryproto"  #此处需要修改
      }
      data_param {
        source: "../mydata/ilsvrc12_train_lmdb"           #此处需要修改    
        batch_size: 256
        backend: LMDB
      }
    }
    layer {
      name: "data"
      type: "Data"
      top: "data"
      top: "label"
      include {
        phase: TEST
      }
      transform_param {
        mirror: false
        crop_size: 227
        mean_file: "../mydata/imagenet_mean.binaryproto" #此处需要修改  
      }
      data_param {
        source: "../mydata/ilsvrc12_val_lmdb"            #此处需要修改
        batch_size: 50
        backend: LMDB
      }
    }
    

    接着由于我们copy的是imagenet内的训练文件,里面对应的是models/bvlc_reference_caffenet内的文件,而我们需要训练的是bvlc_alexnet内的文件,所以还需要修改/mydata目录下的train_caffenet.sh:

    #!/usr/bin/env sh
    set -e
    
    ../build/tools/caffe train \
        --solver=../models/bvlc_alexnet/solver.prototxt $@
    

    和resume_training.sh:

    #!/usr/bin/env sh
    set -e
    
    ../build/tools/caffe train \
        --solver=../models/bvlc_alexnet/solver.prototxt \
        --snapshot=../models/bvlc_alexnet/caffenet_train_10000.solverstate.h5 \
        $@
    

    好了,准备工作已经全部完成,只需要执行train_caffenet.sh即可。(注意以上各种文件的路径是否加载正确,要以当前目录为准,不要单纯的安装文件的形式去修改,否则会找不到需要加载的各种文件而报错!!!)

    训练过程中如果出现Check failed: error == cudaSuccess (2 vs. 0) out of memory的问题证明在train_val.prototxt文件中train和val的batch_size太大了,一次性读入的图片超出了显存,所以适当的修改batch_size的值。
    caffe跑试验遇到错误:Check failed: error == cudaSuccess (2 vs. 0) out of memory

    相关文章

      网友评论

        本文标题:caffe将各种原始图片数据集转换为lmdb格式并训练网络

        本文链接:https://www.haomeiwen.com/subject/bhvvzttx.html