机器学习-学习笔记 MNIST Fine-tuning(二)

接上回制作lmdb开始,我们把数据都分好了,现在开始制作lmdb即可。

首先制作train.txt 和 val.txt,参照教程深度学习caffe平台–制作自己.lmdb格式数据集及分类标签文件

制作数据集和标签
# coding=utf-8

def checkDir(dirName):
    import os
    if os.path.exists(dirName) == False:
        os.mkdir(dirName)

def checkFile(dirFile):
    import os
    if os.path.exists(dirFile) == True:
        os.remove(dirFile)

# copy form fileName to copyName
def copy(fileName, copyName):
    f = open(fileName, 'rb')
    checkFile(copyName)
    c = open(copyName, 'wb')
    line = f.read(8196)
    while line:
        c.write(line)
        line = f.read(8196)
    f.close()
    c.close()

n = [0 for x in range(0, 10)];

def makeTrain(numberArray):
    import random
    import os
    checkDir('mnist_test/train')

    for i in range(0, 10):
        checkDir('mnist_test/train/%d' % i)

    for i in range(0, 5000):
        number = random.choice(numberArray)
        fileName = '%d/train_%d.bmp' % (number, n[number])
        if os.path.exists('./mnist_test/%s' % fileName):
            copy('./mnist_test/%s' % fileName, './mnist_test/train/%s' % fileName)
        n[number] += 1;

def makeVal(numberArray):
    import random
    import os
    checkDir('mnist_test/val')
    for i in range(0, 10):
        checkDir('mnist_test/val/%d' % i)

    for i in range(0, 5000):
        number = random.choice(numberArray)
        fileName = '%d/train_%d.bmp' % (number, n[number])
        if os.path.exists('./mnist_test/%s' % fileName):
            copy('./mnist_test/%s' % fileName, './mnist_test/val/%s' % fileName)
        n[number] += 1;

def makeTrainTxT(numberArray):
    import os
    n = []
    for i in range(0, 10):
        n.append(os.listdir('./mnist_test/train/%d' % i))

    checkFile('./mnist_test/train.txt')
    f = open('./mnist_test/train.txt', 'wb')

    import random
    m = numberArray
    while len(m) != 0:
        number = random.choice(m)
        i = m.index(number)
        f.write('train/%d/%s %d\n' % (number, n[number][0], number))
        del n[number][0]
        if len(n[number]) == 1:
            del m[i]

    f.close()

def makeValTxT(numberArray):
    import os
    n = []
    for i in range(0, 10):
        n.append(os.listdir('./mnist_test/val/%d' % i))

    checkFile('./mnist_test/val.txt')
    f = open('./mnist_test/val.txt', 'wb')
    import random
    m = numberArray
    while len(m) != 0:
        number = random.choice(m)
        i = m.index(number)
        f.write('val/%d/%s %d\n' % (number, n[number][0], number))
        del n[number][0]
        if len(n[number]) == 1:
            del m[i]

    f.close()

m = [0, 1, 2]
makeTrain(m)
m = [0, 1, 2]
makeVal(m)
m = [0, 1, 2]
makeTrainTxT(m)
m = [0, 1, 2]
makeValTxT(m)

运行完可以使用tree看看(也可以用可视化的看)。

tree ./train

可以看到只有0, 1, 2文件夹里有图片,其他的都没有。

运行create_imagenet

接着将caffe/examples/imagenet/create_imagenet.sh移动到mnist_test目录下

cp ../examples/imagenet/create_imagenet.sh ./create_imagenet.sh

我的目录结构如下:

这里写图片描述

接着编辑create_imagenet.sh

sudo vim ./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

EXAMPLE=./ # 当前目录,就是lmdb要在哪里
DATA=./ # txt文件放在哪里
TOOLS=../caffe/build/tools

TRAIN_DATA_ROOT=./ # 就是train.txt表中的路径的根目录
VAL_DATA_ROOT=./ # 就是val.txt表中的路径的根目录

# 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..."

# 删除上一次残留的文件
rm -rf $EXAMPLE/train_lmdb 
rm -rf $EXAMPLE/val_lmdb

# 这里一定要加上-gray=true
GLOG_logtostderr=1 $TOOLS/convert_imageset -gray=true \
    --resize_height=$RESIZE_HEIGHT \
    --resize_width=$RESIZE_WIDTH \
    --shuffle \
    $TRAIN_DATA_ROOT \
    $DATA/train.txt \ # 这里是train.txt的名字
    $EXAMPLE/train_lmdb # 这里是生成的名字,根据上面删除的进行更改即可

echo "Creating val lmdb..."

# 这里一定要加上-gray=true
GLOG_logtostderr=1 $TOOLS/convert_imageset -gray=true \
    --resize_height=$RESIZE_HEIGHT \
    --resize_width=$RESIZE_WIDTH \
    --shuffle \
    $VAL_DATA_ROOT \
    $DATA/val.txt \ # 这里是val.txt的名字
    $EXAMPLE/val_lmdb # 这里是生成的名字,根据上面删除的进行更改即可

echo "Done."

保存后运行

./create_imagenet.sh

使用caffe的convert_imageset生成lmdb文件

训练

首先,我们需要把训练用的网格(lenet_train_test.prototxt)、运行参数(lenet_solver.prototxt)、运行脚本(train_lenet.sh)复制过来。

具体复制过程就不讲了,很简单。

主要我们需要改这三个文件的内容,与我们训练的数据集进行配对。

lenet_train_test.prototxt,只需要更改Data就行。

layer {
  name: "mnist"
  type: "Data" # 数据
  top: "data"
  top: "label"
  include {
    phase: TRAIN # 用于Train阶段
  }
  transform_param {
    scale: 0.00390625
  }
  data_param {
    source: "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: "val_lmdb" # 这里需要些lmdb文件夹路径,在哪里运行就怎么写
    batch_size: 64 # 一次用多少个
    backend: LMDB # 什么格式的数据(后缀)
  }
}

lenet_solver.prototxt

# The train/test net protocol buffer definition
net: "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: 30 # 测试阶段迭代次数
# 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.001 # 学习速率
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: 100 # 每次迭代100次输出信息
# The maximum number of iterations
max_iter: 200 # 迭代多少次
# snapshot intermediate results
snapshot: 5000 # 迭代5000次弄一次快照
snapshot_prefix: "lenet" # 结果出来的路径和名字
# solver mode: CPU or GPU
solver_mode: CPU

train_lenet.sh

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

../caffe/build/tools/caffe train --solver=./lenet_solver.prototxt $@
# 这里只需要找到caffe路径即可。

运行即可。

./train_lenet.sh

这里写图片描述

测试一下

../caffe/build/tools/caffe test -model ./lenet_train_test.prototxt -weights ./lenet_iter_200.caffemodel -iterations 10

这里写图片描述

ok, 成功了,记住这个数据集里没有3,我们拿具体图片进行测试一下。

# coding=utf-8


def getNumber(IMAGE_FILE, flag):
    import os
    import sys
    import Image
    import numpy as np
    from scipy.misc import imread, imresize
    import matplotlib.pyplot as plt
    caffe_root = './caffe/'
    sys.path.insert(0, caffe_root + "python")
    import caffe
    MODEL_FILE = './mnist_test/lenet.prototxt'  # 网络信息
    PRETRAINED = './mnist_test/lenet_iter_200.caffemodel'  # 训练后的结果
    input_image = caffe.io.load_image(IMAGE_FILE, color=False)
    net = caffe.Classifier(MODEL_FILE, PRETRAINED, raw_scale=255, image_dims=(28, 28))  # 载入分类器
    prediction = net.predict([input_image])  # 对图片进行预测,分类
    caffe.set_mode_cpu()  # 使用CPU模式
    if (flag):
        img = imread(IMAGE_FILE)
        plt.imshow(img)
        plt.title(prediction[0].argmax())
        plt.show()
    return prediction[0].argmax()

print(getNumber('./mnist_test/2/train_1.bmp', True))

这里写图片描述

试试看数字3,即没有学习的数字

这里写图片描述

接下来进行Fine-tuning,加入3试试看。

利用上面的,制作0, 1, 2, 3的lmdb。

m = [0, 1, 2, 3]
makeTrain(m)
m = [0, 1, 2, 3]
makeVal(m)
m = [0, 1, 2, 3]
makeTrainTxT(m)
m = [0, 1, 2, 3]
makeValTxT(m)

接着执行,也可以修稿lenet_solver.prototxt的相关属性,我这里之前那个是迭代500次,这次是迭代200次

sudo ./create_imagenet.sh 
sudo ../caffe/build/tools/caffe train --solver ./lenet_solver.prototxt --weights ./lenet_iter_500.caffemodel 

测试函数跟上面的一样,只需要改点东西即可。

这里写图片描述

这里写图片描述

Caffe学习系列(7):solver及其配置

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值