win10 下 caffe 算例测试

start caffe with MNIST in win10

platform

  • win10
  • caffe
  • python27 (Anaconda2)

tutorial

  • 《深度学习轻松学》.冯超, 参见 无痛的机器学习

get data set

  • linux 平台可以直接执行 get_mnist.sh 下载数据文件, win 平台需要手动下载,点击下载 所有4个数据文件
  • 解压到本地
  • linux 平台可以直接执行 create_mnist.sh 创建数据库, win 平台可以尝试调用 create_mnist.ps1, 也可以如下手动创建:
  • 项目文件夹下打开 cmd, $Dir for caffe install \build\examples\mnist\Release\convert_mnist_data.exe train-images.idx3-ubyte train-labels.idx1-ubyte mnist_train_lmdb --backend=lmdb, 创建 mnist_train_lmdb, 然后 $Dir for caffe install \build\examples\mnist\Release\convert_mnist_data.exe t10k-images.idx3-ubyte t10k-labels.idx1-ubyte mnist_test_lmdb --backend=lmdb, 创建 mnist_test_lmdb

read lmdb database test

  • 首先 pip install lmdb
  • 测试代码
#-*- encoding=utf-8 -*-
import numpy as np
import lmdb
import caffe
import sys
import os
from skimage import io
from caffe.proto import caffe_pb2  
'''import matplotlib.pyplot as plt'''

def lmdb_process( db_path, save_dir ):
    assert os.path.exists( db_path )
    env = lmdb.open( db_path )
    datum = caffe_pb2.Datum()   # datum -> data
    item_id = 0

    if ( not os.path.exists( save_dir ) ) :
        os.makedirs( save_dir )

    with env.begin() as txn:
        cursor = txn.cursor()
        for key, value in cursor:
            datum.ParseFromString( value )
            label = datum.label
            img = caffe.io.datum_to_array( datum )
            # do something here
            item_id += 1
            save_img_jpeg( save_dir, "%07d"%item_id, img )
        print item_id
    
#    print img.shape
#    plt.imshow( img[0,:,:] )
#    plt.show()

def save_img_jpeg( save_dir, fname, img):
    
    fname = "%s.jpeg"%fname
    fname = os.path.join( save_dir, fname )
    io.imsave( fname, img[0,:,:])
    

if __name__ == "__main__":
    db_path = 'mnist_train_lmdb'
    save_dir = 'mnist_train_jpeg'
    lmdb_process( db_path, save_dir )
  • 采用数据库的方式存储数据比直接读取图像更快

网络结构和模型训练的配置

caffe 采用读入配置文件的方式进行训练,Caffe 的配置文件一般由两个组成:solver.prototxtnet.prototxt, 对应 caffe 框架中的 网络结构(net) 和 求解器(solver)。

solver.prototxt 文件

# 网络配置文件的位置
net: "net.prototxt"

# 采用 CPU 训练
solver_mode: CPU

# 训练的迭代次数共有 10000 次
max_iter: 10000

# 每500轮跑一遍,一遍100个迭代
test_iter: 100
test_interval: 500

# 每 100 轮输出一次信息
display: 100

# 基础的学习率为 0.01, 还需要定义学习率的衰减形式
base_lr: 0.01
lr_policy: "inv"
gamma: 0.0001
power: 0.75
# 动量的衰减率为 0.9, 正则项的权重为 0.0005
momentum: 0.9
weight_decay: 0.0005
# 每 5000 轮保存一次进度
snapshot: 5000
snapshot_prefix: "lenet"

net.prototxt 文件

使用最简单的 SoftMax( Wx+b ) 来判断

name: "LeNet"
layer{
    name: "data"
    type: "Data"
    top: "data"
    top: "label"
    transform_param{
        scale: 0.00390625
        mirror: false
    }
    data_param{
        source: "mnist_test_lmdb"
        batch_size: 128
        backend:LMDB
    }
}
layer{
    name: "ip"
    type: "InnerProduct"
    bottom: "data"
    top: "ip"
    inner_product_param(
        num_output: 10
        weight_filler{
            type: "xavier"
        }
        bias_filler{
            type: "constant"
        }
    )
}
layer{
    name: "loss"
    type: "SoftmaxWithLoss"
    bottom: "ip"
    bottom: "label"
    top: "loss"
}

训练

  • 运行命令 $Dir for caffe install\build\tools\Release\caffe.exe train --solver=solver.prototxt
  • 绘制 Loss 曲线


    loss曲线

测试

  • 运行命令 $Dir for caffe install\build\tools\Release\caffe.exe test --model=net.prototxt --weights=lenet_iter_10000.caffemodel
  • 此处有坑,不显示准确率。。。
I1002 11:18:47.687744 16388 caffe.cpp:314] Batch 44, loss = 0.00157361
I1002 11:18:47.743893 16388 caffe.cpp:314] Batch 45, loss = 0.000884912
I1002 11:18:47.802048 16388 caffe.cpp:314] Batch 46, loss = 0.00186016
I1002 11:18:47.849675 16388 caffe.cpp:314] Batch 47, loss = 0.000696132
I1002 11:18:47.897804 16388 caffe.cpp:314] Batch 48, loss = 0.000156863
I1002 11:18:47.946432 16388 caffe.cpp:314] Batch 49, loss = 0.000257897
I1002 11:18:47.946432 16388 caffe.cpp:319] Loss: 0.00223903
I1002 11:18:47.947937 16388 caffe.cpp:331] loss = 0.00223903 (* 1 = 0.00223903 loss)

查看中间结果

import numpy as np
import sys 
import caffe
from skimage import io

def vis_square( data ):

    data = ( data - data.min() ) / ( data.max() - data.min() )
    n = int( np.ceil( np.sqrt( data.shape[0] ) ) )
    padding = ( ((0, n**2-data.shape[0]), (0,1), (0,1)) + ( (0,0), ) * ( data.ndim -3) )
    data = np.pad( data, padding, mode='constant', constant_values = 1)

    data = data.reshape( (n,n) + data.shape[1:] ).transpose( (0,2,1,3) + tuple( range(4, data.ndim+1)) )
    data = data.reshape( ( n*data.shape[1], n*data.shape[3] ) + data.shape[4:] )
    return data 

def predict( net, transformer, img ):
    input_data = np.array( img )
    input_data = input_data.reshape(1,28,28,1)
    net.blobs['data'].data[...] = transformer.preprocess( 'data', input_data[0] )
    out = net.forward()

def process( model_path, weight_path, img_path ):
    net = caffe.Net( model_path, weight_path, caffe.TEST )
    transformer = caffe.io.Transformer( {'data': net.blobs['data'].data.shape })
    transformer.set_transpose( 'data',(2,0,1) )

    img = caffe.io.load_image( img_path, color=False )
    predict( net, transformer, img )
    for key in net.blobs:
        data = net.blobs[key].data
        if data.ndim == 4:
            vis = vis_square( data[0] )
            io.imsave( key + '.png', vis)

if __name__ == "__main__":
    # skip check parameter
    model_path = 'net.prototxt'
    weight_path = 'lenet_iter_10000.caffemodel'
    img_path = r'.\mnist_train_jpeg\0000001.jpeg'
    process( model_path, weight_path, img_path )

输出如下:


各阶段输出示意图

你可能感兴趣的:(win10 下 caffe 算例测试)