前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >caffe详解之Python接口

caffe详解之Python接口

作者头像
AI异构
发布2020-07-29 11:03:05
7970
发布2020-07-29 11:03:05
举报
文章被收录于专栏:AI异构AI异构

从零开始,一步一步学习caffe的使用,期间贯穿深度学习和调参的相关知识!

生成net文件

代码语言:javascript
复制
from caffe import layers as L, params as P

def lenet(lmdb, batch_size):
    # 以Lenet-5网络搭建为例
    n = caffe.NetSpec() # 继承自NetSpec
    # 创建数据层。数据层类型选用LMDB文件,向上传递两类数据(ntop=2):图片数据和对应的标签,并归一化到[0,1]
    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=5, num_output=20,  weight_filler=dict(type='xavier'))
    #创建池化层
    n.pool1 = L.Pooling(n.conv1, kernel_size=2, stride=2, pool=P.Pooling.MAX)
    n.conv2 = L.Convolution(n.pool1, kernel_size=5, num_output=50, weight_filler=dict(type='xavier'))
    n.pool2 = L.Pooling(n.conv2, kernel_size=2, stride=2, pool=P.Pooling.MAX)
    #创建全连接层
    n.fc1 =   L.InnerProduct(n.pool2, num_output=500, weight_filler=dict(type='xavier'))
    #创建激活函数层
    n.relu1 = L.ReLU(n.fc1, in_place=True)
    n.score = L.InnerProduct(n.relu1, num_output=10, weight_filler=dict(type='xavier'))
    #创建loss函数
    n.loss =  L.SoftmaxWithLoss(n.score, n.label)

    return n.to_proto()

with open('mnist/lenet_auto_train.prototxt', 'w') as f:
    f.write(str(lenet('mnist/mnist_train_lmdb', 64)))

with open('mnist/lenet_auto_test.prototxt', 'w') as f:
    f.write(str(lenet('mnist/mnist_test_lmdb', 100)))

生成solver文件

代码语言:javascript
复制
from caffe.proto import caffe_pb2
def gen_solver(solver_file, net_file, test_net_file=None):

    s = caffe_pb2.SolverParameter() #继承自SolverParameter

    s.train_net = net_file
    if not test_net_file:
        s.test_net.append(net_file)
    else:
        s.test_net.append(test_net_file)

    s.test_interval = 500       # 每训练500次,执行一次测试
    s.test_iter.append(100)     # 测试迭代次数,假设测试数据有8000个,那batch size=80
    s.max_iter = 20000          # 最大迭代次数

    s.base_lr = 0.001           # 基础学习率
    s.momentum = 0.9            # momentum系数
    s.weight_decay = 5e-4       # 正则化权值衰减因子,防止过拟合

    s.lr_policy = 'step'        # 学习率衰减方法
    s.stepsize=1000             # 只对step方法有效, base_lr*gamma^floor(iter/stepsize)
    s.gamma = 0.1
    s.display = 500             # 输出日志间隔迭代次数
    s.snapshot = 10000          # 在指定迭代次数时保存模型
    s.snapshot_prefix = 'shapshot'
    s.type = 'SGD'              # 迭代算法类型, ADADELTA, ADAM, ADAGRAD, RMSPROP, NESTEROV
    s.solver_mode = caffe_pb2.SolverParameter.GPU #采用GPU训练 或单独设置

    with open(solver_file, 'w') as f:
        f.write(str(s))

    solver = caffe.SGDSolver(solver_file)
    return solver

训练 && 测试

solver.net.forward()

solver.net.forward()是将batch_size个图片送到网络中去,只有前向传播(Forward Propagation,FP),作用于训练集

代码语言:javascript
复制
#训练数据作为输入,进行一次前向传播:
solver.net.forward()

#假如有300个数据,我们的batch_size的大小为100,那么:
solver.net.forward()    #数据为1-100;
solver.net.forward()    #数据为101-200
solver.net.forward()    #数据为201-300
solver.net.forward()    #数据为1-100
#另外,我们可以设置forward开始的地方,如下面所示:
solver.net.forward(start ='conv1')  #表示从conv1开始,这样的话,data层这不用传用新的数据了。
solver.test_nets[i].forward()

solver.test_nets[i].forward()也是将batch_size个图片送到网络中去,只有前向传播(Forward Propagation,FP),作用于测试集。其中i表示第几个测试网络,从0开始。例如,我们就一个测试网络的话,我们就写为:solver.test_nets[0].forward()

代码语言:javascript
复制
# 测试数据作为输入,进行一次前向传播:
solver.test_nets[0].forward() #第一个测试网络
solver.test_nets[1].forward() #第二个测试网络

#假如有300个数据,我们的batch_size的大小为100,那么:
solver.test_nets[0].forward()    #数据为1-100;
solver.test_nets[0].forward()    #数据为101-200
solver.test_nets[0].forward()    #数据为201-300
solver.test_nets[0].forward()    #数据为1-100
solver.net.backward()

solver.net.backward()是将batch_size个图片送到网络中去,只有反向传播(Back Propagation,BP),作用于训练集

代码语言:javascript
复制
#训练数据作为输入,进行一次反向传播:
solver.net.backward()
solver.step(n)

solver.step(1) 也是将batch_size个图片送到网络中去,不过solver.step(1)不仅有正向传播FP,而且还有反向传播!这样就可以更新整个网络的权值与偏置,同时得到该batchloss

代码语言:javascript
复制
#训练网络进行一次正向与反向传播,并进行更新权值与偏置;
sover.step(1)#表示进行1次训练。

sover.step(n)#表示进行n次训练。
solver.solve()

根据solver文件中设置进行完整model训练。

代码语言:javascript
复制
# 根据solver文件中设置进行完整model训练
solver.solve()

训练设置

训练过程中选择使用GPUCPU,若有多块GPU可以指定使用哪一块。

代码语言:javascript
复制
# 使用GPU
caffe.set_device(gpu_id) # 若不设置,默认为0
caffe.set_mode_gpu()
# 使用CPU
caffe.set_mode_cpu()

数据与参数的保存及调用

Blob
代码语言:javascript
复制
#solver.net.blobs为一个字典的数据类型,里面的key值为各个layer的名字,value为caffe的blob块;

solver.net.blobs
#输出:
rderedDict([('data', <caffe._caffe.Blob at 0x7f7bde968398>),
            ('label', <caffe._caffe.Blob at 0x7f7bde968488>),
            ('conv1', <caffe._caffe.Blob at 0x7f7bde968578>),
            ('pool1', <caffe._caffe.Blob at 0x7f7bde968e60>),
            ('conv2', <caffe._caffe.Blob at 0x7f7bde9686e0>),
            ('pool2', <caffe._caffe.Blob at 0x7f7bde968cf8>),
            ('ip1', <caffe._caffe.Blob at 0x7f7bde968c80>),
            ('ip2', <caffe._caffe.Blob at 0x7f7bde968c08>),
            ('loss', <caffe._caffe.Blob at 0x7f7bde968b90>)])

#我们可以访问Blob块里的内容了,通过看Blob块的源码你会发现里面有data, diff,count等内容的。
#我们以conv1层为例子,我们访问conv1的输出的数据,可以通过下面的语句:
solver.net.blobs['conv1'].data
solver.net.blobs['conv1'].diff
#如果想看它们的数据结构,可以通过下面的语句得到:
solver.net.blobs['conv1'].data.shape
solver.net.blobs['conv1'].diff.shape
#另外,还可以通过reshape()transpose()等操作对它们变形,应该是对数组的操作之类的吧。
Params
代码语言:javascript
复制
#solver.net.params为一个字典的数据类型,key值为layer的名字,value为caffe的blob块的容器;
solver.net.params()
#输出为:
solver.net.params
orderedDict([ ('conv1', <caffe._caffe.BlobVec at 0x7f7bffd68578>),
            ('conv2', <caffe._caffe.BlobVec at 0x7f7bde9ff6e0>),
            ('ip1', <caffe._caffe.BlobVec at 0x7f7bde968f80>),
            ('ip2', <caffe._caffe.BlobVec at 0x7f7bde968408>)])

#下面,我们可以访问params块里的内容了。我们以conv1层为例子,具体如下:

#sover.net.params['conv1'][0]里面放是与连接权值相关的数据、梯度;可以通过下面方式访问:
solver.net.params['conv1'][0].data  #数据值
solver.net.params['conv1'][0].diff  #梯度值
#solver.net.params['conv1'][1]里面放的是与偏置相关的的数据、梯度;可以通过下面方式访问:
solver.net.params['conv1'][1].data  #数据值
solver.net.params['conv1'][1].diff  #梯度值

#同样,我们可以还可以通过它们进行 shape()、reshape()、transpose()等操作

参考

caffe中python接口的使用(https://www.cnblogs.com/yinheyi/p/6062488.html)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-02-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI异构 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 生成net文件
  • 生成solver文件
  • 训练 && 测试
    • solver.net.forward()
      • solver.test_nets[i].forward()
        • solver.net.backward()
          • solver.step(n)
            • solver.solve()
            • 训练设置
            • 数据与参数的保存及调用
              • Blob
                • Params
                • 参考
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档