zoukankan      html  css  js  c++  java
  • Ubuntu17.10 下配置caffe 仅CPU i386可以直接apt install caffe-cpu,但是怎么运行mnist代码我懵逼了

    Ubuntu16.04下配置caffe(仅CPU)

     参考:http://blog.csdn.net/zt_1995/article/details/56283249
     

    第二次配置caffe环境,依旧把之前犯过的错误重新走了一遍,不会配置的地方还是忘了,所以打算通过博客记录下来,方便以后学习使用。

    1.安装依赖包

    $ sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-serial-dev protobuf-compiler
    $ sudo apt-get install --no-install-recommends libboost-all-dev
    $ sudo apt-get install libopenblas-dev liblapack-dev libatlas-base-dev
    $ sudo apt-get install libgflags-dev libgoogle-glog-dev liblmdb-dev

    注:如果提示”安装无法定位软件包”,可以尝试sudo apt-get update命令

    2.安装caffe

    $ cd ~
    $ git clone git://github.com/BVLC/caffe.git

    3.编译caffe

    $ cd caffe
    $ cp Makefile.config.example Makefile.config (复制一份Makefile.config文件)

    在Makefile.config文件中把CPU_ONLY := 1的注释给去掉,就是去掉前面的#号

    接下来在caffe根目录下执行下面命令

    $ make all

    在这个命令后,我遇到了一个报错信息,

    ./include/caffe/util/hdf5.hpp:6:18: fatal error: hdf5.h: No such file or directory

    这是hdf5路径问题造成的,可以通过下面命令来获得hdf5的路径,

    $ sudo find / -name hdf5.h 

    我找到的hdf5.h的路径为:/usr/include/hdf5/serial/hdf5.h,于是在makefile.config文件中,把文件改成下面所示:

    再执行一遍上述命令,继续报错,这次是/usr/bin/ld: cannot find -lhdf5
    于是同上面一个处理 去找libhdf5.so
    配置文件改为:

    LIBRARY_DIRS := $(PYTHON_LIB) /usr/lib/x86_64-linux-gnu/hdf5/serial 
                /usr/local/lib /usr/lib
    INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/include/hdf5/serial 
                /usr/local/include
    /usr/bin/ld: cannot find -lcblas
    /usr/bin/ld: cannot find -latlas

    解决

    sudo apt-get install libatlas-base-dev

    其他问题:
    CXX/LD -o .build_release/tools/convert_imageset.bin
    .build_release/lib/libcaffe.so: undefined reference to cv::imread(cv::String const&, int)' .build_release/lib/libcaffe.so: undefined reference tocv::imencode(cv::String const&, cv::_InputArray const&, std::vector >&, std::vector > const&)'
    .build_release/lib/libcaffe.so: undefined reference to `cv::imdecode(cv::_InputArray const&, int)'
    collect2: error: ld returned 1 exit status
    make: *** [.build_release/tools/convert_imageset.bin] Error 1

    solution:

    add "opencv_imgcodecs" in Makefile.(LIBRARIES += glog gflags protobuf leveldb snappy
    lmdb boost_system hdf5_hl hdf5 m
    opencv_core opencv_highgui opencv_imgproc opencv_imgcodecs)
    将上面黄色部分放在:# PYTHON_LIBRARIES := boost_python3 python3.5m 这行前。

    If you input "make all",the problem is the same again.But if you delete all the file in build(rm -rf ./build/*) before "make all"(I use make clean ),you will success.I just success

    github 讨论帖:https://github.com/BVLC/caffe/issues/2348

    接着执行下面命令:

    make test
    我这里还是会报上面错 undefined reference to cv::imread(,。。。奇怪的是后面make runtest过了。

    最后,

    $ make runtest


    mnist测试:
    参考:http://www.cnblogs.com/bigdata01/p/6886151.html

    第一部分 下载mnist数据集
    在data/mnist目录下执行:
    ./get_mnist.sh
     这样下载完成了4个文件:
        t10k-images-idx3-ubyte
        t10k-labels-idx1-ubyte
        train-images-idx3-ubyte
        train-labels-idx1-ubyte
    但下载的是二进制文件,需要转换为LEVELDB或LMDB才能被Caffe识别。

     

    第二部分 数据处理
    在Caffe根目录下执行:
    ./examples/mnist/create_mnist.sh
    这样在/examples/mnist/目录下生成了两个文件夹
    mnist_test_lmdb
    mnist_train_lmdb
    每个文件夹里面各有两个文件。

    第三部分 训练(LeNet-5模型)
    首选将 lenet_solver.prototxt 文件中的
    # solver mode: CPU or GPU
    solver_mode: GPU
    改为
    # solver mode: CPU or GPU
    solver_mode: CPU
    然后执行
    ./examples/mnist/train_lenet.sh
    进行训练。训练结束后会生成 lenet_iter_10000.caffemodel 权值文件。

     

    第四部分 测试

    执行:
    ./build/tools/caffe.bin test
    -model examples/mnist/lenet_train_test.prototxt
    -weights examples/mnist/lenet_iter_10000.caffemodel
    -iterations 100
    查看预测结果。

    最终结果:
    I0520 19:50:40.672024  3989 caffe.cpp:318] Loss: 0.0273101
    I0520 19:50:40.672076  3989 caffe.cpp:330] accuracy = 0.9918
    I0520 19:50:40.672130  3989 caffe.cpp:330] loss = 0.0273101 (* 1 = 0.0273101 loss)

    OK 完成。

     

    4.编译python接口

    安装pip

    $ sudo apt-get install python-pip

    执行安装依赖
    根据caffe/python目录下的requirements.txt中列出的清单安装即可。
    fortran编译器(gfortran)使为了安装scipy,否则会报错。

    cd ~/caffe
    sudo apt-get install gfortran
    cd ./python
    for req in $(cat requirements.txt); do pip install $req; done

    回到caffe根目录

    sudo pip install -r python/requirements.txt

    编译pycaffe接口

    make pycaffe -j8

    此时报错

    python/caffe/_caffe.cpp:10:31: fatal error: numpy/arrayobject.h: 没有那个文件或目录
    

    于是,输入如下命令即可

    sudo apt-get install python-numpy

    最后:
    ----------------------进入caffe /python 才可以执行其中的python脚本--------------------
    
    zz@zz-Inspiron-5520:~$ cd caffe
    zz@zz-Inspiron-5520:~/caffe$ cd python
    zz@zz-Inspiron-5520:~/caffe/python$ python
    >>> import caffe

    应该没有任何错误。设置下环境变量即可成功安装pycaffe了。



     export PYTHONPATH=/path/to/caffe/python:$PYTHONPATH
     

    在配置过程中会遇到各种问题,各种报错,最有效的办法就是百度啦。感谢以下博客
    参考博客:
    http://blog.csdn.net/striker_v/article/details/51615197
    http://blog.csdn.net/u011762313/article/details/47262549
    http://www.cnblogs.com/xuanxufeng/p/6016945.html

    附:caffe入门说明,对各个文件的解释。

    参考:http://blog.csdn.net/cham_3/article/details/72141753

    Caffe的几个重要文件

    用了这么久Caffe都没好好写过一篇新手入门的博客,最近应实验室小师妹要求,打算写一篇简单、快熟入门的科普文。
    利用Caffe进行深度神经网络训练第一步需要搞懂几个重要文件:

    1. solver.prototxt
    2. train_val.prototxt
    3. train.sh

    接下来我们按顺序一个个说明。

    solver.prototxt

    solver这个文件主要存放模型训练所用到的一些超参数:

    • net := 指定待训练模型结构文件,即train_val.prototxt
    • test_interval := 测试间隔,即每隔多少次迭代进行一次测试
    • test_initialization := 指定是否进行初始测试,即模型未进行训练时的测试
    • test_iteration := 指定测试时进行的迭代次数
    • base_lr := 指定基本学习率
    • lr_policy := 学习率变更策略,这里有介绍,可供参考
    • gamma := 学习率变更策略需要用到的参数
    • power := 同上
    • stepsize := 学习率变更策略Step的变更步长(固定步长)
    • stepvalue := 学习率变更策略Multistep的变更步长(可变步长)
    • max_iter := 模型训练的最大迭代次数
    • momentum := 动量,这是优化策略(Adam, SGD, … )用到的参数
    • momentum2 := 优化策略Adam用到的参数
    • weight_decay := 权重衰减率
    • clip_gradients := 固定梯度范围
    • display := 每隔几次迭代显示一次结果
    • snapshot := 快照,每隔几次保存一次模型参数
    • snapshot_prefix := 保存模型文件的前缀,可以是路径
    • type := solver优化策略,即SGD、Adam、AdaGRAD、RMSProp、NESTROVE、ADADELTA等
    • solver_mode := 指定训练模式,即GPU/CPU
    • debug_info := 指定是否打印调试信息,这里有对启用该功能的输出作介绍
    • device_id := 指定设备号(使用GPU模式),默认为0

    用户根据自己的情况进行相应设置,黑体参数为必须指定的,其余参数为可选(根据情况选择)。

    train_val.prototxt

    train_val文件是用来存放模型结构的地方,模型的结构主要以layer为单位来构建。下面我们以LeNet为例介绍网络层的基本组成:

    name: "LeNet"
    layer {
      name: "mnist"                                #网络层名称
      type: "Data"                                 #网络层类型,数据层
      top: "data"                                  #这一层的输出,数据
      top: "label"                                 #这一层的输出,标签
      include {    phase: TRAIN  }                 #TRAIN:=用于训练,TEST:=用于测试
      transform_param {    scale: 0.00390625  }    #对数据进行scale
      data_param {                                 #数据层配置 
        source: "examples/mnist/mnist_train_lmdb"  #数据存放路径
        batch_size: 64                             #指定batch大小
        backend: LMDB                              #指定数据库格式,LMDB/LevelDB
      }
    }
    layer {
      name: "mnist"
      type: "Data"
      top: "data"
      top: "label"
      include {    phase: TEST  }
      transform_param {    scale: 0.00390625  }
      data_param {
        source: "examples/mnist/mnist_test_lmdb"
        batch_size: 100
        backend: LMDB
      }
    }
    layer{
        name:"conv1"       
        type:"Convolution" #卷积层
        bottom:"data"      #上一层的输出作为输入
        top:"conv1"        
        param{name:"conv1_w" lr_mult:1 decay_mult:1} #卷积层参数w的名称,学习率和衰减率(相对于base_lr和weight_decay的倍数)
        param{name:"conv1_b" lr_mult:2 decay_mult:0} #卷积层参数b的名称,学习率和衰减率
        convolution_param{
            num_output:20         #卷积层输出的feature map数量 
            kernel_size:5         #卷积层的大小
            pad:0                 #卷积层的填充大小
            stride:1              #进行卷积的步长
            weight_filler{type:"xavier" }      #参数w的初始话策略
            weight_filler{type:"constant" value:0.1}     #参数b的初始化策略
        }
    }
    layer {        #BatchNorm层,对feature map进行批规范化处理
        name:"bn1"
        type:"BatchNorm"
        bottom:"conv1"
        top:"conv1"
        batch_norm_param{ use_global_stats:false} #训练时为false,测试时为true
    }
    layer {           #池化层,即下采样层
      name: "pool1"
      type: "Pooling"
      bottom: "conv1"
      top: "pool1"
      pooling_param {
        pool: MAX   #最大值池化,还有AVE均值池化
        kernel_size: 2
        stride: 2
      }
    }
    layer {
      name: "conv2"
      type: "Convolution"
      bottom: "pool1"
      top: "conv2"
      param {    lr_mult: 1  }
      param {    lr_mult: 2  }
      convolution_param {
        num_output: 50
        kernel_size: 5
        stride: 1
        weight_filler {      type: "xavier"    }
        bias_filler {      type: "constant"    }
      }
    }
    layer {
        name:"bn2"
        type:"BatchNorm"
        bottom:"conv2"
        top:"conv2"
        batch_norm_param{ use_global_stats:false}
    }
    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  }  
      param {    lr_mult: 2  }
      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  }
      param {    lr_mult: 2  }
      inner_product_param {
        num_output: 10
        weight_filler {      type: "xavier"    }
        bias_filler {      type: "constant"    }
      }
    }
    layer {                             #损失函数层
      name: "prob"
      type: "SoftmaxWithLoss"
      bottom: "ip2"
      bottom: "label"
      top: "prob"
    }
    

    参数初始化策略可参考这里, 激活函数可参考这里

    网络结构和超参数都设计完了,接下来就可以进行模型训练了。这里我介绍最常用的模型训练脚本,也是Caffe官方文档给的例子。

    train.sh

    这个脚本文件可写,可不写。每次运行需要写一样的命令,所以建议写一下。

    TOOLS=/path/to/your/caffe/build/tools
    GLOG_logtostderr=0 GLOG_log_dir=log/  #该行用于调用glog进行训练日志保存,使用时请把该行注释删除,否则会出错
    $TOOLS/caffe train --solver=/path/to/your/solver.prototxt #--snapshot=/path/to/your/snapshot or --weights=/path/to/your/caffemodel ,snapshot和weights两者只是选一,两个参数都可以用来继续训练,区别在于是否保存solver状态
    • 1
    • 2
    • 3

    数据准备

    这里我们举个简单的例子,改代码是Caffe官方文档提供的,但只能用于单标签的任务,多标签得对源码进行修改。该脚本是对图片数据生成对应的lmdb文件,博主一般使用原图,即数据层类型用ImageData。

    #!/usr/bin/env sh
    # Create the imagenet lmdb inputs
    # N.B. set the path to the imagenet train + val data dirs
    set -e
    
    EXAMPLE=""                            #存储路径
    DATA=""                               #数据路径
    TOOLS=/path/to/your/caffe/build/tools #caffe所在目录
    
    TRAIN_DATA_ROOT=""                   #训练数据根目录
    VAL_DATA_ROOT=""                     #测试数据根目录
    # 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/mnist_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/mnist_test_lmdb
    
    echo "Done."

    这样,我们就可以愉快的开始训练啦。

  • 相关阅读:
    抓住六个点,谈唯品会的峰值系统应对实践
    从服务端架构设计角度,深入理解大型APP架构升级
    腾讯微信技术总监周颢:一亿用户增长背后的架构秘密
    App服务端架构变迁
    微服务、SOA 和 API对比与分析
    QPS从0到4000请求每秒,谈达达后台架构演化之路
    重构心法——打造高质量代码
    [转]使用 C++11 编写 Linux 多线程程序
    [转]编译防火墙——C++的Pimpl惯用法解析
    [转]C++ 取代switch的三种方法
  • 原文地址:https://www.cnblogs.com/bonelee/p/8442127.html
Copyright © 2011-2022 走看看