用pycaffe训练图像
程序员文章站
2024-03-19 16:20:40
...
废话不多说,本文在python下调用caffe来训练,由于python下图片转lmdb比较复杂,所以就直接使用了windows下的接口。如果不会搭建caffe包的,移步这https://blog.csdn.net/zb1165048017/article/details/52980102
数据集是一个二分类的数据集,主要是人脸和非人脸,链接:https://pan.baidu.com/s/1WCErudFafJjP2V1edpV5_g 密码:q85k
要跑网络,我们要先构建自己的网络,由于数据集图片是60*60,所以我们没必要跑太复杂的网络,所以我写了个比较简单的网络,最后准确率能达到98%
import caffe
from caffe import layers as L,params as P
#定义你的网络层
def myLayer(lmdb,batch_size,is_deploy):
n=caffe.NetSpec()
#这里的source填入你的数据源lmdb
n.data,n.label=L.Data(batch_size=batch_size,backend=P.Data.LMDB,source=lmdb,
transform_param=dict(scale=1./255),ntop=2)
n.conv1 = L.Convolution(n.data, kernel_size=3,stride=2, num_output=20,
weight_filler=dict(type='xavier'))
#特征图变为 30*30
n.relu1=L.ReLU(n.conv1,in_place=True)
n.conv2 = L.Convolution(n.relu1, kernel_size=3,stride=2, num_output=60,
weight_filler=dict(type='xavier'))
#15*15
n.relu2=L.ReLU(n.conv2,in_place=True)
n.conv3 = L.Convolution(n.relu1, kernel_size=3,stride=2, num_output=90,
weight_filler=dict(type='xavier'))
n.relu3=L.ReLU(n.conv3,in_place=True)
n.score=L.InnerProduct(n.relu3,num_output=2,weight_filler=dict(type='xavier'))
n.loss=L.SoftmaxWithLoss(n.score,n.label)
return n.to_proto()
#上面的仅仅是定义,下面的是把网络写入本地的prototxt文件中
def writeLayer():
with open('train.prototxt', 'w') as f:
f.write(str(myLayer('train_lmdb', 100,0)))
with open('test.prototxt', 'w') as f:
f.write(str(myLayer('test_lmdb', 10,0)))
写完网络层,就是写solver,solver有两种方法来定义,我一开始用的第一种writeSolver(),可老是报错,报错的原因貌似是pycaffe识别不了“snapshot_prefix”这个属性,于是我后来采用了第二张写法writeSolver_2()
def writeSolver():
solverprototxt=tools.CaffeSolver(trainnet_prototxt_path='train.prototxt',
testnet_prototxt_path='test.prototxt')
#在python下,你可以没必要每个都去定义,它会自己初始化
solverprototxt.sp['base_lr']='0.001'
solverprototxt.sp['weight_decay']='0.001'
solverprototxt.sp['gamma']='0.0001'
solverprototxt.sp['power']='0.001'
solverprototxt.sp['display']='1000'
solverprototxt.sp['test_iter']='100'
solverprototxt.sp['max_iter']='5000'
solverprototxt.sp['lr_policy']="step"
solverprototxt.sp['snapshot']="1000"
#下面这个snapshot_prefix我把他去掉就能正常跑,加上就一直报错
# solverprototxt.sp['snapshot_prefix']="rr"
solverprototxt.sp['display'] = "1"
solverprototxt.sp['max_iter'] = "1000"
solverprototxt.write('solver.prototxt')
from caffe.proto import caffe_pb2
def writeSolver_2():
s=caffe_pb2.SolverParameter()
s.train_net = 'train.prototxt' # 训练配置文件
s.test_net.append('test.prototxt') # 测试配置文件
s.test_interval = 200 # 测试间隔
s.test_iter.append(1) # 测试迭代次数
s.max_iter = 78200 # 最大迭代次数
s.base_lr = 0.001 # 基础学习率
s.momentum = 0.9 # momentum系数
s.weight_decay = 5e-4 # 权值衰减系数
s.lr_policy = 'step' # 学习率衰减方法
s.stepsize=26067 # 此值仅对step方法有效
s.gamma = 0.1 # 学习率衰减指数
s.display = 782 # 屏幕日志显示间隔
s.snapshot = 2000
s.snapshot_prefix = 'shapshot'
s.type = "SGD" # 优化算法
s.solver_mode = caffe_pb2.SolverParameter.GPU
with open("solver.prototxt","w") as f:
f.write(str(s))
现在如果分别调用上面两个函数,就可以在本地生成三个文件(1个solver,另外两个分别为训练阶段和测试阶段的),如图
好,一切就绪,下面就是跑网络了,如果单纯地想让网络跑起来的话,下面两句就行了,step就是让caffe跑的步数
solver=caffe.get_solver('solver.prototxt')
solver.step(200)
下面我给的训练包括输出准确率以及可视化
def train_layer():
caffe.set_device(0)
caffe.set_mode_gpu()
solver=caffe.get_solver('solver.prototxt')
niter = 3000
x_label=[0]
y_acc=[0]
acc=0
for it in range(niter):
solver.step(1) # SGD by Caffe
solver.test_nets[0].forward()
#a为最后的score,由于测试批次是10,所以这个a是个1*10的数组,对应的b也是一个1*10的数组
a=solver.test_nets[0].blobs['score'].data.argmax(1)
b=solver.test_nets[0].blobs['label'].data
for j in range(10):
if(a[j]==b[j]):
acc+=1
if(it%40==0):
print '第',it,'次迭代,准确率为:',Decimal(float(acc)/float(10*(it+1))).quantize(Decimal('0.000'))
x_label.append(it)
y_acc.append(Decimal(float(acc)/float(10*(it+1))).quantize(Decimal('0.000')))
plt.plot(x_label, y_acc)
plt.show()
ok,下面上一段完整的代码
import caffe
from caffe import layers as L,params as P
import sys
sys.path.append('F:/caffe/caffe-master/examples/pycaffe')
import tools
def writeSolver():
solverprototxt=tools.CaffeSolver(trainnet_prototxt_path='train.prototxt',
testnet_prototxt_path='test.prototxt')
# solverprototxt.sp['base_lr']='0.001'
# solverprototxt.sp['weight_decay']='0.001'
# solverprototxt.sp['gamma']='0.0001'
# solverprototxt.sp['power']='0.001'
# solverprototxt.sp['display']='1000'
# solverprototxt.sp['test_iter']='100'
# solverprototxt.sp['max_iter']='5000'
# solverprototxt.sp['lr_policy']="step"
# solverprototxt.sp['snapshot']="1000"
## solverprototxt.sp['snapshot_prefix']="rr"
# solverprototxt.sp['display'] = "1"
# solverprototxt.sp['max_iter'] = "1000"
solverprototxt.write('solver.prototxt')
from caffe.proto import caffe_pb2
def writeSolver_2():
s=caffe_pb2.SolverParameter()
s.train_net = 'train.prototxt' # 训练配置文件
s.test_net.append('test.prototxt') # 测试配置文件
s.test_interval = 200 # 测试间隔
s.test_iter.append(1) # 测试迭代次数
s.max_iter = 78200 # 最大迭代次数
s.base_lr = 0.001 # 基础学习率
s.momentum = 0.9 # momentum系数
s.weight_decay = 5e-4 # 权值衰减系数
s.lr_policy = 'step' # 学习率衰减方法
s.stepsize=26067 # 此值仅对step方法有效
s.gamma = 0.1 # 学习率衰减指数
s.display = 782 # 屏幕日志显示间隔
s.snapshot = 2000
s.snapshot_prefix = 'shapshot'
s.type = "SGD" # 优化算法
s.solver_mode = caffe_pb2.SolverParameter.GPU
with open("solver.prototxt","w") as f:
f.write(str(s))
#original img is 60*60
def myLayer(lmdb,batch_size,is_deploy):
n=caffe.NetSpec()
n.data,n.label=L.Data(batch_size=batch_size,backend=P.Data.LMDB,source=lmdb,
transform_param=dict(scale=1./255),ntop=2)
n.conv1 = L.Convolution(n.data, kernel_size=3,stride=2, num_output=20,
weight_filler=dict(type='xavier'))
#特征图变为 30*30
n.relu1=L.ReLU(n.conv1,in_place=True)
n.conv2 = L.Convolution(n.relu1, kernel_size=3,stride=2, num_output=60,
weight_filler=dict(type='xavier'))
#15*15
n.relu2=L.ReLU(n.conv2,in_place=True)
n.conv3 = L.Convolution(n.relu1, kernel_size=3,stride=2, num_output=90,
weight_filler=dict(type='xavier'))
n.relu3=L.ReLU(n.conv3,in_place=True)
n.score=L.InnerProduct(n.relu3,num_output=2,weight_filler=dict(type='xavier'))
n.loss=L.SoftmaxWithLoss(n.score,n.label)
return n.to_proto()
def writeLayer():
with open('train.prototxt', 'w') as f:
f.write(str(myLayer('train_lmdb', 100,0)))
with open('test.prototxt', 'w') as f:
f.write(str(myLayer('test_lmdb', 10,0)))
import matplotlib.pyplot as plt
import numpy as np
from decimal import Decimal
def train_layer():
caffe.set_device(0)
caffe.set_mode_gpu()
solver=caffe.get_solver('F:/python_project/8_2/solver.prototxt')
niter = 3000
x_label=[0]
y_acc=[0]
acc=0
for it in range(niter):
solver.step(1) # SGD by Caffe
solver.test_nets[0].forward()
a=solver.test_nets[0].blobs['score'].data.argmax(1)
b=solver.test_nets[0].blobs['label'].data
for j in range(10):
if(a[j]==b[j]):
acc+=1
if(it%40==0):
print '第',it,'次迭代,准确率为:',Decimal(float(acc)/float(10*(it+1))).quantize(Decimal('0.000'))
x_label.append(it)
y_acc.append(Decimal(float(acc)/float(10*(it+1))).quantize(Decimal('0.000')))
plt.plot(x_label, y_acc)
plt.show()
writeSolver()
writeLayer()
#solver=caffe.get_solver('F:/python_project/8_2/solver.prototxt')
#solver.step(200)
train_layer()
下面是我的结果
上一篇: 轮播图 - 第一版