caffe 工具帖

来源:互联网 发布:网络设备端口流量统计 编辑:程序博客网 时间:2024/06/04 01:24

(1)第一强烈推荐使用Netscope,是一个可视化网络结构的在线工具。当写完一个网络结果文件的时候,将文本粘贴到左侧,按shift+enter就可以看到网络结构图了。

用过的都说好!没用过的赶紧Mark起来。

http://ethereon.github.io/netscope/#/editor

(2)强烈推荐使用PYTHON定义网络结构文件。

      在初期,我们可能都是使用别人写好的网络模型,觉得直接在对文本进行修改也很简单,但是!!也要学习如何使用PYTHON脚本去优雅地生成一个网络文件,不能老是重复劳动啊。

   a) 写出每一层的结构(初级选手,可以看出还是非常冗余的写法,觉得low的略过,直接看一个写法)

# -*- coding: utf-8 -*-import caffefrom caffe import layers as L,params as P,to_protopath='/home/yang/deep/Demo/Demo04/'                    #保存数据和配置文件的路径train_lmdb=path+'/lfw/lfw_train_lmdb'                #训练数据LMDB文件的位置val_lmdb=path+'lfw/lfw_val_lmdb'                     #验证数据LMDB文件的位置mean_file=path+'lfw/lfw_mean.binaryproto'         #均值文件的位置train_proto=path+'tool/lfw_alexnet_train.prototxt'         #生成的训练配置文件保存的位置val_proto=path+'tool/lfw_alexnet_val.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=227,mean_file=mean_file,mirror=True))    #创建第二屋:卷积层  conv1-5    conv1=L.Convolution(data, kernel_size=11, stride=4,num_output=96,pad=0,param=[dict(name=weight_name,lr_mult=1, decay_mult=1), dict(name=bias_name,lr_mult=2, decay_mult=0)],weight_filler=dict(type='xavier'),bias_filter=dict(type='constant'),value=0.1))    #创建BN+scale层    if include_accbn_con1=L.BatchNorm(conv1,use_global_stats=True,in_place=True)    else bn_con1=L.BatchNorm(conv1,use_global_stats=False,in_place=True)    # scale bias_term ?? true false    scale_conv1=L.Scale(conv1, scale_param=dict(bias_term=True), in_place=True)    #创建激活函数层 relu1    relu1=L.ReLU(conv1, in_place=True)    #创建池化层 pool1    pool1=L.Pooling(relu1, pool=P.Pooling.MAX, kernel_size=3, stride=2)    # conv2    conv2=L.Convolution(pool1, kernel_size=5, stride=1,num_output=256, pad=2,param=[dict(name=weight_name,lr_mult=1, decay_mult=1), dict(name=bias_name,lr_mult=2, decay_mult=0)],weight_filler=dict(type='xavier'),bias_filter=dict(type='constant'),value=0.1))     if include_accbn_con2=L.BatchNorm(conv2,use_global_stats=True,in_place=True)    else bn_con2=L.BatchNorm(conv2,use_global_stats=False,in_place=True)    # scale bias_term ?? true false    scale_conv2=L.Scale(conv2, scale_param=dict(bias_term=True), in_place=True)    relu2=L.ReLU(conv2, in_place=True)    pool2=L.Pooling(relu2, pool=P.Pooling.MAX, kernel_size=3, stride=2)        #conv3    conv3=L.Convolution(pool2, kernel_size=3, stride=1,num_output=384, pad=1,param=[dict(name=weight_name,lr_mult=1, decay_mult=1), dict(name=bias_name,lr_mult=2, decay_mult=0)],weight_filler=dict(type='xavier'),bias_filter=dict(type='constant'),value=0))    relu3=L.ReLU(conv3, in_place=True)    #conv4    conv4=L.Convolution(relu3, kernel_size=3, stride=1,num_output=384, pad=1,param=[dict(name=weight_name,lr_mult=1, decay_mult=1), dict(name=bias_name,lr_mult=2, decay_mult=0)],weight_filler=dict(type='xavier'),bias_filter=dict(type='constant'),value=0.1))    relu4=L.ReLU(conv4, in_place=True)    #conv5    conv5=L.Convolution(relu4, kernel_size=3, stride=1,num_output=256, pad=1,param=[dict(name=weight_name,lr_mult=1, decay_mult=1), dict(name=bias_name,lr_mult=2, decay_mult=0)],weight_filler=dict(type='xavier'),bias_filter=dict(type='constant'),value=0.1))    relu5=L.ReLU(conv5, in_place=True)         pool5=L.Pooling(relu5, pool=P.Pooling.MAX, kernel_size=3, stride=2)        #创建一个全连接层 fc6    fc6=L.InnerProduct(pool5, num_output=4096,param=[dict(name=weight_name,lr_mult=1, decay_mult=1), dict(name=bias_name,lr_mult=2, decay_mult=0)],weight_filler=dict(type='xavier'),bias_filter=dict(type='constant'),value=0.1))    relu6=L.ReLU(fc6, in_place=True)    #创建一个dropout层 drop6    drop6 = L.Dropout(relu6, in_place=True, dropout_param=dict(dropout_ratio=0.5))    #fc7    fc7=L.InnerProduct(drop6, num_output=4096,param=[dict(name=weight_name,lr_mult=1, decay_mult=1), dict(name=bias_name,lr_mult=2, decay_mult=0)],weight_filler=dict(type='xavier'),bias_filter=dict(type='constant'),value=0.1))    relu7=L.ReLU(fc7, in_place=True)    drop7 = L.Dropout(relu7, in_place=True, dropout_param=dict(dropout_ratio=0.5))    #fc8 ->5749    fc8 = L.InnerProduct(drop7, num_output=5749,param=[dict(name=weight_name,lr_mult=1, decay_mult=1), dict(name=bias_name,lr_mult=2, decay_mult=0)],weight_filler=dict(type='xavier'),bias_filter=dict(type='constant'),value=0))    #创建一个softmax层    loss = L.SoftmaxWithLoss(fc8, label)        if include_acc:             #在训练阶段,不需要accuracy层,但是在验证阶段,是需要的        acc = L.Accuracy(fc, 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(val_proto, 'w') as f:        f.write(str(create_net(val_lmdb,batch_size=32, include_acc=True)))        if __name__ == '__main__':    write_net()

   b)今天发现在caffe的example下面pycaffe给了一个自动生成网络文件的demo。相比于上面的写法更加简练了,有点像抽象函数的啊哈哈哈,不知道是不是这个说法.

把不同类型层的操作封装在不同的函数里面了。很好!可以根据需要自已扩充一些层的写法,比如BN层。

https://github.com/BVLC/caffe/blob/master/examples/pycaffe/caffenet.py

from __future__ import print_functionfrom caffe import layers as L, params as P, to_protofrom caffe.proto import caffe_pb2# helper function for common structuresdef conv_relu(bottom, ks, nout, stride=1, pad=0, group=1):    conv = L.Convolution(bottom, kernel_size=ks, stride=stride,                                num_output=nout, pad=pad, group=group)    return conv, L.ReLU(conv, in_place=True)def fc_relu(bottom, nout):    fc = L.InnerProduct(bottom, num_output=nout)    return fc, L.ReLU(fc, in_place=True)def max_pool(bottom, ks, stride=1):    return L.Pooling(bottom, pool=P.Pooling.MAX, kernel_size=ks, stride=stride)def caffenet(lmdb, batch_size=256, include_acc=False):    data, label = L.Data(source=lmdb, backend=P.Data.LMDB, batch_size=batch_size, ntop=2,        transform_param=dict(crop_size=227, mean_value=[104, 117, 123], mirror=True))    # the net itself    conv1, relu1 = conv_relu(data, 11, 96, stride=4)    pool1 = max_pool(relu1, 3, stride=2)    norm1 = L.LRN(pool1, local_size=5, alpha=1e-4, beta=0.75)    conv2, relu2 = conv_relu(norm1, 5, 256, pad=2, group=2)    pool2 = max_pool(relu2, 3, stride=2)    norm2 = L.LRN(pool2, local_size=5, alpha=1e-4, beta=0.75)    conv3, relu3 = conv_relu(norm2, 3, 384, pad=1)    conv4, relu4 = conv_relu(relu3, 3, 384, pad=1, group=2)    conv5, relu5 = conv_relu(relu4, 3, 256, pad=1, group=2)    pool5 = max_pool(relu5, 3, stride=2)    fc6, relu6 = fc_relu(pool5, 4096)    drop6 = L.Dropout(relu6, in_place=True)    fc7, relu7 = fc_relu(drop6, 4096)    drop7 = L.Dropout(relu7, in_place=True)    fc8 = L.InnerProduct(drop7, num_output=1000)    loss = L.SoftmaxWithLoss(fc8, label)    if include_acc:        acc = L.Accuracy(fc8, label)        return to_proto(loss, acc)    else:        return to_proto(loss)def make_net():    with open('train.prototxt', 'w') as f:        print(caffenet('/path/to/caffe-train-lmdb'), file=f)    with open('test.prototxt', 'w') as f:        print(caffenet('/path/to/caffe-val-lmdb', batch_size=50, include_acc=True), file=f)if __name__ == '__main__':    make_net()

(3)使用caffe 训练模型,生成训练日志后,绘制精度和损失。

     1.在训练脚本前面加上:

  1. GLOG_logtostderr=0 GLOG_log_dir=path/to/your/Log/  \ 

     2.

 ./parse_log.sh caffe.CYang.yang.log  #以log结尾的日志文件

        #得到类似train和test的文件如下:

     

     

 ./plot_training_log.py.example 0  test_acc.png  caffe.CYang.yang.log      #关于测试精度
./plot_training_log.py.example 2  test_loss.png  caffe.CYang.yang.log    #关于测试损失
./plot_training_log.py.example 6  train_loss.png  caffe.CYang.yang.log  #关于训练损失

下面这个渣渣的训练情况大家忽略,因为我的网络还有很多问题。


(4)每次都面对小黑框,是不是视觉疲劳了。连隔壁的小伙伴都看不下去了。

      强烈推荐第3波。Anaconda和spyder

      便捷的PYTHON工具。说明,不用修改caffe的任何配置。

      安装anaconda后,在Terminal输入Spyder就会出现下面的界面,左边是编辑界面,右边是命令窗口。


      下面给了一个安装Anaconda的脚本,一键解决。

链接: https://pan.baidu.com/s/1nuAiYpz 密码: r3q4