hans

hans

【Python】【Caffe】一、生成prototxt文件《python調用caffe模塊》


GitHub 代碼地址: https://github.com/HansRen1024/Use-Python-to-call-Caffe-module

前言#

寫這一系列博文前真的想了好久,有種無從下手的感覺。還是功力太淺,越是這樣越要硬著頭皮寫。加油!

我先將各個函數單獨放出來,最後再放出完整代碼。各個函數中單獨用到的模塊,我在函數中單獨加載,這樣方便將代碼獨立出來單獨運行。

import caffe 是全局通用模塊,我就不在每個函數中單獨加載了。

一、加載 caffe 模塊#

為了以後方便使用,把 caffe 模塊放到 python 默認路徑下,這樣在任意目錄下就都能加載 caffe 模塊了。

caffe 編譯通過後運行:

make pycaffe
sudo cp -r python/caffe/ /usr/local/lib/python/dist-packages #有些朋友路徑是site-packages,這個因人而異。

這個時候運行 python,import caffe,會提示找不到 caffe 的動態庫。

可以將 $CAFFE_ROOT/.build_release/lib/ 加到環境變量中去,

也可以將該動態庫複製到 /usr/lib/ 或者 /usr/local/lib 目錄下。

此時,應該就可以在任意目錄下運行 python,import caffe 了。

二、生成訓練和測試 prototxt 文件#

生成網絡結構文件我找到了兩種方法,下面這種通過定義一個 NetSpec () 實例 n 的方法是比較好的,所以我先寫的這個方法。這種方法生成的文件內,各個層的名字和輸出 blob 的名字就是等號前面定義的 n 的方法。

def lenet(lmdb, batch_size, include_acc=False):
    from caffe import layers as L
    from caffe import params as P
    n = caffe.NetSpec()
    # 具體每個層內的參數,可以對照現有的prototxt文件。我這裡寫的並不全。
    n.data, n.label = L.Data(batch_size=batch_size, backend=P.Data.LMDB, source=lmdb,
                             transform_param=dict(scale=1./255), ntop=2)              # ntop表示兩個輸出
    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.ip1 = L.InnerProduct(n.pool2, num_output=500, weight_filler=dict(type='xavier'))
    n.relu1 = L.ReLU(n.ip1, in_place=True)
    n.ip2 = L.InnerProduct(n.relu1, num_output=10, weight_filler=dict(type='xavier'))
    n.loss = L.SoftmaxWithLoss(n.ip2, n.label)
    if include_acc: # 生成測試文件時,需要有計算準確率的層。
        n.acc = L.Accuracy(n.ip2, n.label)
    return n.to_proto() # 注意這裡的to_proto()不用帶參數。

def write_lenet():
    with open('./doc/train_lenet.prototxt','w') as f:
        f.write(str(lenet('./doc/mnist_train_lmdb', 64)))
    
    with open('./doc/test_lenet.prototxt', 'w') as f:
        f.write(str(lenet('./doc/mnist_test_lmdb', 100, True)))

三、生成 deploy 文件#

這裡我放出生成網絡結構文件的第二種方法,雖然我並不推薦使用這個方法。其實 deploy 直接拿上面生成好的文件改就行,很簡單。

def deploy():
    from caffe import layers as L
    from caffe import params as P
    from caffe import to_proto
    # deploy文件沒有數據層
    conv1 = L.Convolution(bottom='data', kernel_size=5, num_output=20, weight_filler=dict(type='xavier'))
    pool1 = L.Pooling(conv1, kernel_size=2, stride=2, pool=P.Pooling.MAX)
    conv2 = L.Convolution(pool1, kernel_size=5, num_output=50, weight_filler=dict(type='xavier'))
    pool2 = L.Pooling(conv2, kernel_size=2, stride=2, pool=P.Pooling.MAX)
    ip1 = L.InnerProduct(pool2, num_output=500, weight_filler=dict(type='xavier'))
    relu1 = L.ReLU(ip1, in_place=True)
    ip2 = L.InnerProduct(relu1, num_output=10, weight_filler=dict(type='xavier')) 
    prob = L.Softmax(ip2) # 最後一層不用計算loss,輸出概率。
    return to_proto(prob) # 這裡需要帶參數

def write_deploy():
    with open('doc/deploy_lenet.prototxt', 'w') as f:
        f.write('name: "Lenet"\n')
        f.write('input: "data"\n')
        f.write('input_dim: 1\n')
        f.write('input_dim: 3\n')
        f.write('input_dim: 28\n')
        f.write('input_dim: 28\n')
        f.write(str(deploy()))

四、生成 solver 文件#

方法一是用字典生成:

def solver_dict():
    solver_file='doc/solver_lenet.prototxt'
    sp={}
    sp['train_net']='"doc/train_lenet.prototxt"'
    sp['test_net']='"doc/test_lenet.prototxt"'
    sp['test_iter']='100'
    sp['test_interval']='500'
    sp['display']='100'
    sp['max_iter']='10000'
    sp['base_lr']='0.01'
    sp['lr_policy']='"inv"'
    sp['gamma']='0.0001'
    sp['power']='0.75'
    sp['momentum']='0.9'
    sp['weight_decay']='0.0005'
    sp['snapshot']='5000'
    sp['snapshot_prefix']='"models/lenet"'
    sp['solver_mode']='GPU'
    sp['solver_type']='SGD'
    sp['device_id']='0'
    
    with open(solver_file, 'w') as f:
        for key, value in sp.items():
            if not(type(value) is str):
                raise TypeError('All solver parameters must be string')
            f.write('%s: %s\n' %(key, value))

方法二是調用 caffe 模塊生成,這種方法生成的文件內,小數部分會有很小的損失。處女座強迫症犯了!

def solver_caffe():
    from caffe.proto import caffe_pb2
    s = caffe_pb2.SolverParameter()
    solver_file='doc/solver_lenet.prototxt'
    
    s.train_net = 'doc/train_lenet.prototxt'
    s.test_net.append('doc/test_lenet.prototxt')
    s.test_interval = 500
    s.test_iter.append(100)
    s.display = 100
    s.max_iter = 10000
    s.base_lr = 0.01
    s.lr_policy = "inv"
    s.gamma = 0.0001
    s.power = 0.75
    s.momentum = 0.9
    s.weight_decay = 0.0005
    s.snapshot = 5000
    s.snapshot_prefix = "models/lenet"
    s.type = "SGD"
    s.solver_mode = caffe_pb2.SolverParameter.GPU
    
    with open(solver_file, 'w') as f:
        f.write(str(s))

五、完整代碼:#

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Sat Jul 29 11:16:29 2017

@author: hans
"""

import caffe

def lenet(lmdb, batch_size, include_acc=False):
    from caffe import layers as L
    from caffe import params as P

    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=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.ip1 = L.InnerProduct(n.pool2, num_output=500, weight_filler=dict(type='xavier'))
    n.relu1 = L.ReLU(n.ip1, in_place=True)
    n.ip2 = L.InnerProduct(n.relu1, num_output=10, weight_filler=dict(type='xavier'))
    n.loss = L.SoftmaxWithLoss(n.ip2, n.label)
    if include_acc:
        n.acc = L.Accuracy(n.ip2, n.label)
    return n.to_proto()

def write_lenet():
    with open('./doc/train_lenet.prototxt','w') as f:
        f.write(str(lenet('./doc/mnist_train_lmdb', 64)))
    
    with open('./doc/test_lenet.prototxt', 'w') as f:
        f.write(str(lenet('./doc/mnist_test_lmdb', 100, True)))

def deploy():
    from caffe import layers as L
    from caffe import params as P
    from caffe import to_proto

    conv1 = L.Convolution(bottom='data', kernel_size=5, num_output=20, weight_filler=dict(type='xavier'))
    pool1 = L.Pooling(conv1, kernel_size=2, stride=2, pool=P.Pooling.MAX)
    conv2 = L.Convolution(pool1, kernel_size=5, num_output=50, weight_filler=dict(type='xavier'))
    pool2 = L.Pooling(conv2, kernel_size=2, stride=2, pool=P.Pooling.MAX)
    ip1 = L.InnerProduct(pool2, num_output=500, weight_filler=dict(type='xavier'))
    relu1 = L.ReLU(ip1, in_place=True)
    ip2 = L.InnerProduct(relu1, num_output=10, weight_filler=dict(type='xavier'))
    prob = L.Softmax(ip2)
    return to_proto(prob)

def write_deploy():
    with open('doc/deploy_lenet.prototxt', 'w') as f:
        f.write('name: "Lenet"\n')
        f.write('input: "data"\n')
        f.write('input_dim: 1\n')
        f.write('input_dim: 3\n')
        f.write('input_dim: 28\n')
        f.write('input_dim: 28\n')
        f.write(str(deploy()))
    
def solver_dict():
    solver_file='doc/solver_lenet.prototxt'
    sp={}
    sp['train_net']='"doc/train_lenet.prototxt"'
    sp['test_net']='"doc/test_lenet.prototxt"'
    sp['test_iter']='100'
    sp['test_interval']='500'
    sp['display']='100'
    sp['max_iter']='10000'
    sp['base_lr']='0.01'
    sp['lr_policy']='"inv"'
    sp['gamma']='0.0001'
    sp['power']='0.75'
    sp['momentum']='0.9'
    sp['weight_decay']='0.0005'
    sp['snapshot']='5000'
    sp['snapshot_prefix']='"models/lenet"'
    sp['solver_mode']='GPU'
    sp['solver_type']='SGD'
    sp['device_id']='0'
    
    with open(solver_file, 'w') as f:
        for key, value in sp.items():
            if not(type(value) is str):
                raise TypeError('All solver parameters must be string')
            f.write('%s: %s\n' %(key, value))
            
def solver_caffe():
    from caffe.proto import caffe_pb2

    s = caffe_pb2.SolverParameter()
    solver_file='doc/solver_lenet.prototxt'
    
    s.train_net = 'doc/train_lenet.prototxt'
    s.test_net.append('doc/test_lenet.prototxt')
    s.test_interval = 500
    s.test_iter.append(100)
    s.display = 100
    s.max_iter = 10000
    s.base_lr = 0.01
    s.lr_policy = "inv"
    s.gamma = 0.0001
    s.power = 0.75
    s.momentum = 0.9
    s.weight_decay = 0.0005
    s.snapshot = 5000
    s.snapshot_prefix = "models/lenet"
    s.type = "SGD"
    s.solver_mode = caffe_pb2.SolverParameter.GPU
    
    with open(solver_file, 'w') as f:
        f.write(str(s))

def train():
    caffe.set_device(0)
    caffe.set_mode_gpu()
    solver = caffe.SGDSolver('doc/solver_lenet.prototxt')
    solver.solve()

if __name__ == '__main__':
    write_lenet()
#    write_deploy()
#    solver_dict()
#    solver_caffe()
#    train()
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。