Mnist caffe手写字符识别程序总结

此次试验主要通过caffe的python接口进行操作,十分方便

1,mnist.py:建立网络——建立solver——进行训练,最后还包含绘制loss和accuracy曲线的功能

# -*- coding: utf-8 -*-
import caffe
from caffe import layers as L, params as P, proto, to_proto
import numpy as np
import matplotlib.pyplot as plt

# 设定文件的路径
train_lmdb = '/home/zhaoys/myf/dataset/mnist/mnist_train_lmdb'	# 设置训练集位置
test_lmdb = '/home/zhaoys/myf/dataset/mnist/mnist_test_lmdb'	# 设置测试集位置
root = '/home/zhaoys/myf/lenet/lenet_pycaffe/'	# 根目录位置
train_proto = root + 'train.prototxt'     # 训练配置文件
test_proto = root + 'test.prototxt'       # 测试配置文件
solver_proto = root + 'solver.prototxt'   # 参数文件

def create_net(lmdb, batch_size, include_acc = False):
	# 创建第一层:数据层。向上传递两类数据:图片数据和对应的标签数据
	data, label = L.Data(source = lmdb, backend = P.Data.LMDB, batch_size = batch_size, ntop = 2,
		transform_param = dict(crop_size = 28, mirror = True, scale = 0.00390625))
	# 创建第二层:卷积层、激活函数层、池化层
	conv1 = L.Convolution(data, kernel_size = 5, stride = 1, num_output = 16, pad = 2, weight_filler = dict(type = 'xavier'))
	relu1 = L.ReLU(conv1, in_place = True)
	pool1 = L.Pooling(relu1, pool = P.Pooling.MAX, kernel_size = 3, stride = 2)
	# 创建第三层:卷积层、激活函数层、池化层
	conv2 = L.Convolution(pool1, kernel_size = 3, stride = 1, num_output = 32, pad = 1, weight_filler = dict(type = 'xavier'))
	relu2 = L.ReLU(conv2, in_place = True)
	pool2 = L.Pooling(relu2, pool = P.Pooling.MAX, kernel_size = 3, stride = 2)
	# 创建全连接层
	fc3 = L.InnerProduct(pool2, num_output = 500, weight_filler = dict(type = 'xavier'))
	relu3 = L.ReLU(fc3, in_place = True)
	# 创建dropout层
	drop3 = L.Dropout(relu3, in_place = True)
	# 创建全连接层
	fc4 = L.InnerProduct(drop3, num_output = 10, weight_filler = dict(type = 'xavier'))
	# 创建一个softmax层
	loss = L.SoftmaxWithLoss(fc4, label)
	# 在训练阶段创建accuracy层
	if include_acc:
		acc = L.Accuracy(fc4, label)
		return to_proto(loss, acc)
	else:
		return to_proto(loss)
		
def write_net():
	# 将上面的设置写入到prototxt文件里面
	with open(train_proto, 'w') as f:
		f.write(str(create_net(train_lmdb, batch_size = 64)))
		
	with open(test_proto, 'w') as f:
		f.write(str(create_net(test_lmdb, batch_size = 100, include_acc = True)))
		
def gen_solver(solver_file, train_net, test_net):
	s = proto.caffe_pb2.SolverParameter()
	s.train_net = train_net
	s.test_net.append(test_net)
	s.test_interval = 938	# 60000 / 64 = 938,训练时,经过938次迭代进行一次测试
	s.test_iter.append(100) # 10000 / 100 = 100,测试时,共进行500次迭代
	s.max_iter = 20000		# 50000 / 938 = epochs
	
	s.momentum = 0.9
	s.weight_decay = 5e-4	# 参数衰减不能太大!如此精确率可达99.2%
	
	s.base_lr = 1e-2		# 学习率相关参数
	s.lr_policy = 'inv'
	s.stepsize = 10000
	s.gamma = 1e-4
	s.power = 0.75
	
	s.display = 200
	s.snapshot = 50000
	s.snapshot_prefix = root + 'snapshot/train'
	s.type = 'SGD'
	s.solver_mode = proto.caffe_pb2.SolverParameter.GPU
	with open(solver_file, 'w') as f:
		f.write(str(s))
	
def training(solver_proto):
	caffe.set_device(0)
	caffe.set_mode_gpu()
	solver = caffe.SGDSolver(solver_proto)
	solver.solve()
	
	'''
	# 绘制loss曲线并保存 通过VNC显示
	max_iter = 20000
	display = 200
	test_interval = 938
	loss = np.zeros(max_iter // display)
	accuracy = np.zeros(max_iter // test_interval + 1)
	train_loss = 0
	test_accuracy = 0
	
	for iter in range(max_iter):
		solver.step(1)
		train_loss += solver.net.blobs['SoftmaxWithLoss1'].data
		if iter % display == 0:
			loss[iter // display] = train_loss / display
			train_loss = 0
		if iter % test_interval == 0:
			for test_iter in range(test_interval):
				solver.test_nets[0].forward()
				test_accuracy += solver.test_nets[0].blobs['Accuracy1'].data
			accuracy[iter // test_interval] = test_accuracy / test_interval
			test_accuracy = 0
	
	plt.title('mnist loss & accuracy')
	plt.xlabel(u'Iters',fontproperties='SimHei',fontsize=14)
	plt.ylabel(u'loss & accuracy',fontproperties='SimHei',fontsize=14)
	plt.plot(loss, 'g')
	plt.plot(accuracy, 'r')
	plt.savefig(root + 'loss_accuracy.png')
	plt.show()
	'''
	
if __name__ == '__main__':
	# write_net()
	gen_solver(solver_proto, train_proto, test_proto)
	training(solver_proto)
	
	

 

2,制作infer.python文件,labels.txt,deploy.prototxt。最后包含查看net和blob的图。源码如下:

# -*- coding: utf-8 -*-
import os
import caffe
import numpy as np
import cv2
import sys
import matplotlib.pyplot as plt

# 文件路径设置
root = '/home/zhaoys/myf/lenet/lenet_pycaffe/'	#根目录
deploy = root + 'deploy.prototxt'
caffe_model = root + 'snapshot/train_iter_50000.caffemodel'
labels = root + 'labels.txt'

# 生成网络
net = caffe.Net(deploy, caffe_model, caffe.TEST)

# 格式转换
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})

# 添加类别信息
name = []
with open(labels, 'r+') as f:
	for l in f.readlines():
		name.append(l)
		
# 依次测试前5张图
for i in range(0, 5):
	img = root + 'demo/test_{}.jpg'.format(i)
	input_image = cv2.imread(img, cv2.IMREAD_GRAYSCALE).astype(np.float32)
	net.blobs['data'].data[...] = transformer.preprocess('data', input_image)

	out = net.forward()	# 进行一次前向传播
	
	prob = net.blobs['prob'].data[0].flatten()	# softmax层每个类别的概率
	print 'prob:' + str(prob)
	maxprob = prob.argsort()[-1]
	print 'class:' + str(name[maxprob])

# 查看net的参数和blob的数据
'''
for k, v in net.params.items():	# 查看各层的w参数值
	print k
	print v[0].data
for k, v in net.params.items():	# 查看各层的b参数值
	print k
	print v[1].data

for k, v in net.params.items():	# 查看各层的w参数值的维度
	print k
	print v[0].data.shape
for k, v in net.params.items():	# 查看各层的b参数值的维度
	print k
	print v[1].data.shape
w1 = net.params['Convolution1'][0].data	# 查看Convolution1层的w参数值
print w1
b1 = net.params['Convolution1'][1].data # 查看Convolution1层的b参数值
print b1

for k, v in net.blobs.items():	# 查看各层的数据
	print k
	print v.data
for k, v in net.blobs.items():	# 查看各层的数据维度
	print k
	print v.data.shape
	
fea = net.blobs['Convolution2'].data[0, 0]	# 查看第一个全连接的特征
cv2.imwrite('/home/zhaoys/myf/lenet/lenet_pycaffe/featuremap/fea.png', fea)
'''

# 显示模型参数函数
'''
def show_feature(data, padsize = 1, padval = 0):
    data -= data.min()
    data /= data.max()
    
    # force the number of filters to be square
    n = int(np.ceil(np.sqrt(data.shape[0])))
    padding = ((0, n ** 2 - data.shape[0]), (0, padsize), (0, padsize)) + ((0, 0),) * (data.ndim - 3)
    data = np.pad(data, padding, mode='constant', constant_values=(padval, padval))
    
    # tile the filters into an image
    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
	
plt.rcParams['figure.figsize'] = (8, 8)
plt.rcParams['image.interpolation'] = 'nearest'
# plt.rcParams['image.cmap'] = 'gray'


for k, v in net.params.items():	# 查看各层的w参数值的维度
	print k
	print v[0].data.shape
	
weight = net.params["Convolution1"][0].data
net_conv1 = show_feature(weight.reshape(16, 5, 5))
plt.imshow(net_conv1)
plt.savefig('/home/zhaoys/myf/lenet/lenet_pycaffe/featuremap/net_conv1.png')

weight = net.params["Convolution2"][0].data
net_conv2 = show_feature(weight.reshape(32 * 16, 3, 3))
plt.imshow(net_conv2)
plt.savefig('/home/zhaoys/myf/lenet/lenet_pycaffe/featuremap/net_conv2.png')


for k, v in net.blobs.items():	# 查看各层的数据维度
	print k
	print v.data.shape
	
data = show_feature(net.blobs["data"].data[0])
plt.imshow(data)
plt.savefig('/home/zhaoys/myf/lenet/lenet_pycaffe/featuremap/blob_data.png')

blob_conv1 = show_feature(net.blobs["Convolution1"].data[0])
plt.imshow(blob_conv1)
plt.savefig('/home/zhaoys/myf/lenet/lenet_pycaffe/featuremap/blob_conv1.png')

blob_pool1 = show_feature(net.blobs["Pooling1"].data[0])
plt.imshow(blob_pool1)
plt.savefig('/home/zhaoys/myf/lenet/lenet_pycaffe/featuremap/blob_pool1.png')

blob_conv2 = show_feature(net.blobs["Convolution2"].data[0])
plt.imshow(blob_conv2)
plt.savefig('/home/zhaoys/myf/lenet/lenet_pycaffe/featuremap/blob_conv2.png')

blob_pool2 = show_feature(net.blobs["Pooling2"].data[0])
plt.imshow(blob_pool2)
plt.savefig('/home/zhaoys/myf/lenet/lenet_pycaffe/featuremap/blob_pool2.png')
'''

 

num0
num1
num2
num3
num4
num5
num6
num7
num8
num9
layer {
  name: "data"
  type: "Input"
  top: "data"
  input_param {
    shape { dim: 1 dim: 1 dim: 28 dim: 28 }
  }
}
layer {
  name: "Convolution1"
  type: "Convolution"
  bottom: "data"
  top: "Convolution1"
  convolution_param {
    num_output: 16
    pad: 2
    kernel_size: 5
    stride: 1
    weight_filler {
      type: "xavier"
    }
  }
}
layer {
  name: "ReLU1"
  type: "ReLU"
  bottom: "Convolution1"
  top: "Convolution1"
}
layer {
  name: "Pooling1"
  type: "Pooling"
  bottom: "Convolution1"
  top: "Pooling1"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "Convolution2"
  type: "Convolution"
  bottom: "Pooling1"
  top: "Convolution2"
  convolution_param {
    num_output: 32
    pad: 1
    kernel_size: 3
    stride: 1
    weight_filler {
      type: "xavier"
    }
  }
}
layer {
  name: "ReLU2"
  type: "ReLU"
  bottom: "Convolution2"
  top: "Convolution2"
}
layer {
  name: "Pooling2"
  type: "Pooling"
  bottom: "Convolution2"
  top: "Pooling2"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "InnerProduct1"
  type: "InnerProduct"
  bottom: "Pooling2"
  top: "InnerProduct1"
  inner_product_param {
    num_output: 500
    weight_filler {
      type: "xavier"
    }
  }
}
layer {
  name: "ReLU3"
  type: "ReLU"
  bottom: "InnerProduct1"
  top: "InnerProduct1"
}
layer {
  name: "Dropout1"
  type: "Dropout"
  bottom: "InnerProduct1"
  top: "InnerProduct1"
}
layer {
  name: "InnerProduct2"
  type: "InnerProduct"
  bottom: "InnerProduct1"
  top: "InnerProduct2"
  inner_product_param {
    num_output: 10
    weight_filler {
      type: "xavier"
    }
  }
}
layer {
  name: "prob"
  type: "Softmax"
  bottom: "InnerProduct2"
  top: "prob"
}

3,caffe学习总结

组成:Blob/layer/Net/Solver

层:SoftmaxWithLoss/Softmax/InnerProduct/Accuracy/Reshape/Dropout/
    Activiation Layers:Sigmoid/ReLU/TanH/AbsVal/Power/BNLL/
    Vision layers:Convolution/Pooling/LRN/im2col/
    Data Layers:Data/MemoryData/HDF5Data/ImageData/WindowData/
    
优化方法:SGD/AdaDelta/AdaGrad/Adam/Nesterov/RMSProp/

参数设置:layer(...) solver(...)

caffe命令:caffe <command> <args> 例:sudo sh ./build/tools/caffe train --solver=examples/mnist/train_lenet.sh
    command:train/test/device_query/time/
    args:solver/gpu/snapshot/weights/iteration/model/sighup_effect/sigint_effect/

开发过程:
dataset->LMDB/jpg,png/
net->train.prototxt/test.prototxt/            -> caffemodel    -> infer->deploy.prototxt/
solver->solver.prototxt/

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值