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.prototxt
和net.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 )
输出如下:
网友评论