Caffe学习笔记2:LeNet拒绝官方脚本!从数据准备到训练再到预测

作为深度学习界的“hello world!”,学习起来真没那么容易。
接触深度学习,第一个接触的就是mnist。但是初次接触就只跑了三个脚本

get_mnist.sh
create_mnist.sh
train_lenet.sh

然后就结束了,对此我蒙逼了许久。因为对于caffe的整体框架不熟悉,对CNN不深入,因此感觉举步维艰。经过1个多月的沉淀终于能完整的走一遍MNIST。
对于初学者,深度学习分为三步:1.数据准备 2.训练 3.预测
一.数据准备
官方例程推荐的数据集为

t10k-images-idx3-ubyte
t10k-labels-idx1-ubyte
train-images-idx3-ubyte
train-labels-idx1-ubyte

相信许多人和我一样会问:这是什么啊,打开还是一推二进制数。确实,官方的数据集可视化不好,但是可以借助matlab或者python解析出来。但是,对于普通人拿到的数据往往都是图片格式,而且是很多。

Paste_Image.png

这该进行怎么加载训练呢。
先粗略的看下,官方的数据集。可以看出images对应一个labels,所以我们准备的数据包括图片和标签。
1)基础准备
在data文件夹下创建如下文件夹,准备训练集,验证集和测试集


Paste_Image.png

创建 train test文件夹和对应的txt将你的训练集放到train中,将验证集放到test中。(这里应该多建一个valid文件夹,里面存放的是验证集,而test中放测试集,这里偷工减料了)
接着要制作标签,如果量少可以考虑手敲,但是大数据就只能借助代码了。
创建make_list.py

#coding=utf-8
#caffe and opencv test mnist
#test by yuzefan
import os
from os.path import join, isdir

def gen_listfile(dir):
    cwd=os.getcwd() # 获取当前目录
    os.chdir(dir)   # 改变当前的目录
    sd=[d for d in os.listdir('.') if isdir(d)] # 列出当前目录下的所有文件和目录名,os.listdir可以列出文件和目录
    sd.sort()
    class_id=0
    with open(join(dir,'listfile.txt'),'w') as f :  #join():connect string,"with...as"is used for safety,without it,you must write by"file = open("/tmp/foo.txt") file.close()
        for d in sd :
            fs=[join(d,x) for x in os.listdir(d)]
            for img in fs:
                f.write(img + ' '+str(class_id)+'\n')
            class_id+=1
    os.chdir(cwd)

if __name__ == "__main__":
    root_dir = raw_input('image root dir: ')
    while not isdir(root_dir):
        raw_input('not exist, re-input please: ')
    gen_listfile(root_dir)

运行后可以得到标签,如下:

Paste_Image.png

list已经准备好了,接着要把数据转成lmdb。caffe之所以速度快,得益于lmdb数据格式。
创建creat_lmdb.sh脚本

#coding=utf-8
#!/usr/bin/env sh 
#指定脚本的解释程序
#by yuzefan
set -e #如果任何语句的执行结果不是true则应该退出
# CAFFEIMAGEPATH is the txt file path
# DATA is the txt file path

CAFFEDATAPATH=mytest/chinese/data
DATA=mytest/chinese/data/mnist
TOOLS=~/caffe-master/build/tools

# TRAIN_DATA_PATH & VAL_DATA_ROOT is root path of your images path, so your train.txt file must do not contain
# this line again!!
TRAIN_DATA_ROOT=/home/ubuntu/caffe-master/mytest/chinese/data/mnist/train/
VAL_DATA_ROOT=/home/ubuntu/caffe-master/mytest/chinese/data/mnist/test/
# Set RESIZE=true to resize the images to 28x28. Leave as false if images have
# already been resized using another tool.
RESIZE=true
if $RESIZE;then
    RESIZE_HEIGHT=28
    RESIZE_WIDTH=28
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 \
    --gray=true\
    $TRAIN_DATA_ROOT \
    $DATA/train.txt \
    $CAFFEDATAPATH/caffe_train_lmdb

echo "Creating val lmdb..."

GLOG_logtostderr=1 $TOOLS/convert_imageset \
    --resize_height=$RESIZE_HEIGHT \
    --resize_width=$RESIZE_WIDTH \
    --shuffle \
    --gray=true\
    $VAL_DATA_ROOT \
    $DATA/test.txt \
    $CAFFEDATAPATH/caffe_val_lmdb

echo "Done."

运行完后在data目录下出现

caffe_train_lmdb
caffe_val_lmdb

这里使用了caffe的tools中的convert_imageset。使用方法:

convert_imageset [FLAGS] ROOTFOLDER/ LISTFILE DB_NAME 
其中 
参数:ROOTFOLDER 表示输入的文件夹 
参数:LISTFILE 表示输入文件列表,其每一行为:类似 subfolder1/file1.JPEG 7 
可选参数:[FLAGS] 可以指示是否使用shuffle,颜色空间,编码等。
--gray=true  \-------------------------------------------->如果灰度图的话加上即可
还调用了opencv,对输入图像进行尺寸变换,满足网络的要求。

注意:

TRAIN_DATA_PATH & VAL_DATA_ROOT is root path of your images path, so your train.txt file must do not contain

到此,数据准备就结束了。
二.训练
训练需要模型描述文件和模型求解文件。

lenet_train_test.prototxt
lenet_solver.prototxt

对于lenet_train_test.prototxt,需要改的地方只有数据层

name: "LeNet"
layer {
  name: "mnist"  #名字随便
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TRAIN
  }
  transform_param {
    scale: 0.00390625
  }
  data_param {
    source: "mytest/chinese/data/caffe_train_lmdb"  #这里是上一步生成的lmdb
    batch_size: 64#一次压入网络的数量
    backend: LMDB
  }
}
layer {
  name: "mnist"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TEST
  }
  transform_param {
    scale: 0.00390625
  }
  data_param {
    source: "mytest/chinese/data/caffe_val_lmdb"
    batch_size: 100 
    backend: LMDB
  }
}

对于lenet_solver.prototxt

# The train/test net protocol buffer definition
net: "mytest/chinese/lenet_train_test.prototxt"#这里可以把训练和验证放到一起,实际可以分开
# test_iter specifies how many forward passes the test should carry out.
# In the case of MNIST, we have test batch size 100 and 100 test iterations,
# covering the full 10,000 testing images.
test_iter: 100 #test_iter * batch_size= 10000(test集的大小)
# Carry out testing every 500 training iterations.
test_interval: 500 
# The base learning rate, momentum and the weight decay of the network.
base_lr: 0.01
momentum: 0.9
weight_decay: 0.0005
# The learning rate policy
lr_policy: "inv"
gamma: 0.0001
power: 0.75
# Display every 100 iterations
display: 20
# The maximum number of iterations
max_iter: 10000
# snapshot intermediate results
snapshot: 5000
snapshot_prefix: "mytest/chinese/lenet"
# solver mode: CPU or GPU
solver_mode: GPU

训练可以执行train_lenet.sh,实际上还是调用了tools

#!/usr/bin/env sh
set -e

./build/tools/caffe train --solver=mytest/chinese/lenet_solver.prototxt $@

没有意外的话就能正常开始训练了。
三.预测
预测可以参考我之前写的

Caffe学习笔记1:用训练好的mnist模型进行预测(两种方法)
http://www.jianshu.com/p/6fcdefbacf5b

小笔记:均值计算
减均值预处理能提高训练和预测的速度,利用tools

二进制格式的均值计算
build/tools/compute_image_mean examples/mnist/mnist_train_lmdb examples/mnist/mean.binaryproto
带两个参数:
第一个参数:examples/mnist/mnist_train_lmdb, 表示需要计算均值的数据,格式为lmdb的训练数据。
第二个参数:examples/mnist/mean.binaryproto, 计算出来的结果保存文件。

接下来的计划:现在说白了是个10类的分类器,接下来增强网络使其能够训练并预测出0~9 and ‘a’~‘z’

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容