欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用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,另外两个分别为训练阶段和测试阶段的),如图

用pycaffe训练图像

好,一切就绪,下面就是跑网络了,如果单纯地想让网络跑起来的话,下面两句就行了,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()

下面是我的结果

用pycaffe训练图像