caffe入门

模型配置文件

http://ethereon.github.io/netscope/#/editor   在线可视化模型结构,shift+enter

写模型结构代码的时候可以直接使用这个功能来所见即所得

xx.prototxt

除了第一行设置该模型的名字,其余全是layer的设置

layer应该时没有顺序的,因为layer中要设置bottom和top,分别表示输入端和输出端,但是编写代码按模型顺序写会更加易读

layer中的不同type需要不同的参数

http://caffe.berkeleyvision.org/tutorial/layers.html    可以看到所有不同的type

type: Python 时需要增加

python_param {

  module: ''"   python文件名

  layer: ''     python中class的名字

  param_str: "{'xx':,..... }"

  include {

    phase: TRAIN/TEST

  }

Caffe can be told to include or exclude a layer when running a network in a particular phase

一般也就是输入会有这个设定了,对于TRAIN或者TEST对应不同的输入层

注意一般layer中param会定义两个用以定义lr和decay,不是覆盖的关系,虽然名字都一样,但是对应的表示不一样,一般第一个描述filter,第二个描述bias,如下:

 1 layer {
 2     name: "conv1"
 3     type: "Convolution"
 4     bottom: "data"
 5     top: "conv1"
 6     # learning rate and decay multipliers for the filters
 7     param { lr_mult: 1 decay_mult: 1 }
 8     # learning rate and decay multipliers for the biases
 9     param { lr_mult: 2 decay_mult: 0 }
10     convolution_param {
11       num_output: 96     # learn 96 filters
12       kernel_size: 11    # each filter is 11x11
13       stride: 4          # step 4 pixels between each filter application
14       weight_filler {
15         type: "gaussian" # initialize the filters from a Gaussian
16         std: 0.01        # distribution with stdev 0.01 (default mean: 0)
17       }
18       bias_filler {
19         type: "constant" # initialize the biases to zero (0)
20         value: 0
21       }
22     }
23   }

 

 可视化

在可视化模型结构的过程中,只有layer中的name代表的层可视化出来了,其他的top,bottom取的名字其实代表着数据流,也就是blob,具体指代的图中的边

如果输入输出的边相同,说明这两个结点可以合成

注意对于单个结点,一般都是top名和layer名一样

 

参考: http://blog.leanote.com/post/braveapple/Caffe-%E4%BD%BF%E7%94%A8%E6%8A%80%E5%B7%A7

运行

caffe的运行提供三种接口: C++接口(命令行), Python接口, 和Matlab接口

C++接口(命令行);

./build/tools/caffe train --solver=xx.prototxt

caffe <command> <args>

 

 图像数据格式转换

caffe中自带程序可对图像数据转换成db(leveldb/lmdb)文件

./build/tools/convert_imageset   [FLAGS]     ROOTFOLDER/LISTFILE     DB_NAME

FLAGS: 图片参数组,后面详细介绍

 

ROOTFOLDER/: 图片存放的绝对路径,从linux系统根目录开始

LISTFILE: 图片文件列表清单,一般为一个txt文件,一行一张图片

DB_NAME: 最终生成的db文件存放目录

如果我们本地有训练数据集,.jpg格式,那我们需要自己创建一个图片列表清单,自己写脚本

 

python接口使用方法;

https://blog.csdn.net/l691899397/article/details/76202178

训练的方式

提取特征的方式

使用输入图片到deploy

 

计算图片数据的均值

怎么计算均值文件

1. 二进制格式的均值计算

caffe中使用的均值数据格式时binaryproto,caffe自带计算均值代码

./build/tools/compute_image_mean examples/mnist/mnist_train_lmdb examples/mnist/mean.binaryproto

 

 第一个参数,是需要计算均值的数据,格式为lmdb的训练数据,第二个参数,计算出来的结果保存文件

2. python格式的均值计算

我们先按1计算出二进制格式的均值,然后转换成python格式的均值。

 1 #!/usr/bin/env python
 2 import numpy as np
 3 import sys,caffe
 4 if len(sys.argv)!=3:
 5     print "Usage: python convert_mean.py mean.binaryproto mean.npy"
 6     sys.exit()
 7 blob = caffe.proto.caffe_pb2.BlobProto()
 8 bin_mean = open( sys.argv[1] , 'rb' ).read()
 9 blob.ParseFromString(bin_mean)
10 arr = np.array( caffe.io.blobproto_to_array(blob) )
11 npy_mean = arr[0]
12 np.save( sys.argv[2] , npy_mean )

 

保存为convert_mean.py

运行: Python convert_mean.py mean.binaryproto mean.npy

 

caffemodel可视化

*.caffemodel文件里面存放的就是各层的参数,即net.params,里面没有数据net.blobs.   *.solverstate时用来恢复训练的,防止意外终止而保存的快照

我们可以提出caffemodel里面保存的参数进行可视化

参考链接: http://blog.leanote.com/post/braveapple/Caffe-%E4%BD%BF%E7%94%A8%E6%8A%80%E5%B7%A7

 

绘制网络模型

python/draw_net.py可以将网络模型由prototxt变成一张图片

sudo apt-get install GraphViz

sudo pip install pydot

 

 

绘制loss和accuracy曲线

采用的也是jupyter notebook进行曲线绘制

如果不需要绘制曲线,只需要训练出一个 caffemodel,直接调用 solver.solve() 就可以了。如果要绘制曲线,就需要把迭代过程中的值保存下来,因此不能直接调用 solver.solve(), 需要迭代。在迭代过程中,每迭代200次测试一次

同样代码参考链接

 

 

用训练好的caffemodel来进行分类

下载caffemodel文件和均值文件

在测试阶段,需要把测试数据减去均值

synset_words.txt文件

分类方法: 

c++方式  

./build/examples/cpp_classification/classification.bin \
  models/bvlc_reference_caffenet/deploy.prototxt \
  models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel \
  data/ilsvrc12/imagenet_mean.binaryproto \
  data/ilsvrc12/synset_words.txt \
  examples/images/cat.jpg

 

python接口

参考链接

 

 

如何将别人训练好的model用到自己数据集上/Pretrain

使用别人训练好的参数,此处有一个大坑,那就是必须和别人用同一个 network ,因为参数是根据 network 而来的。当然,最后一层,我们是可以修改的,因为我们的数据可能并没有1000类,而只有几类。我们把最后一层的输出类别改一下,然后把层的名称改一下就可以了。最后用别人的参数、修改后的 network 和我们自己的数据,再进行训练,使得参数适应我们的数据,这样一个过程,通常称之为微调 (fine tuning)。

修改data层:

把均值文件(mean_file)、数据源文件 (source)、批次大小 (batch_size)和数据源格式 (backend) 这四项作相应的修改。

修改最后一个全连接层:

只需要修改两个地方,一个name,一个时num_output,看自己的分类任务时多少类

 

测试网络的中间层输出

我们可以看下模型的一些参数和一些中间输出

看下如何读取网络的结构:

对于每一层,其结构构成为:(batch_size, channel_dim, height, width)

# 对于每一层,显示输出类型。
    for layer_name, blob in net.blobs.iteritems():
        print layer_name + '\t' + str(blob.data.shape)

    data    (50, 3, 227, 227)
    conv1   (50, 96, 55, 55)
    pool1   (50, 96, 27, 27)
    norm1   (50, 96, 27, 27)
    conv2   (50, 256, 27, 27)
    pool2   (50, 256, 13, 13)
    norm2   (50, 256, 13, 13)
    conv3   (50, 384, 13, 13)
    conv4   (50, 384, 13, 13)
    conv5   (50, 256, 13, 13)
    pool5   (50, 256, 6, 6)
    fc6 (50, 4096)
    fc7 (50, 4096)
    fc8 (50, 1000)
    prob    (50, 1000)

看下参数的形状: net.params索引[0]表示weights, [1]表示为biases

参数形状为(output_channels, input_channels, filter_height,filter_width) 时weights

(output_channels,)为biases

for layer_name, param in net.params.iteritems():
        print layer_name + '\t' + str(param[0].data.shape), str(param[1].data.shape)

    conv1   (96, 3, 11, 11) (96,)
    conv2   (256, 48, 5, 5) (256,)
    conv3   (384, 256, 3, 3) (384,)
    conv4   (384, 192, 3, 3) (384,)
    conv5   (256, 192, 3, 3) (256,)
    fc6 (4096, 9216) (4096,)
    fc7 (4096, 4096) (4096,)
    fc8 (1000, 4096) (1000,)

可以定义一个函数来帮助可视化特征

 

def vis_square(data):
        """输入一个形如:(n, height, width) or (n, height, width, 3)的数组,并对每一个形如(height,width)的特征进行可视化sqrt(n) by sqrt(n)"""

        # 正则化数据
        data = (data - data.min()) / (data.max() - data.min())

        # 将滤波器的核转变为正方形
        n = int(np.ceil(np.sqrt(data.shape[0])))
        padding = (((0, n ** 2 - data.shape[0]),
                   (0, 1), (0, 1))                 # 在相邻的滤波器之间加入空白 
                   + ((0, 0),) * (data.ndim - 3))  # 不扩展最后一维
        data = np.pad(data, padding, mode='constant', constant_values=1)  # 扩展一个像素(白色)

        # tile the filters into an image
        data = data.reshape((n, n) + data.shape[1:]).transpose((0, 2, 1, 3) + tuple(range(4, data.ndim + 1)))
        data = data.reshape((n * data.shape[1], n * data.shape[3]) + data.shape[4:])

        plt.imshow(data)
        plt.axis('off')
        plt.show()

 

 看下第一个卷积层的输出特征

# 参数为一个[weights, biases]的列表
    filters = net.params['conv1'][0].data
    vis_square(filters.transpose(0, 2, 3, 1))

接着参考链接: https://blog.csdn.net/jnulzl/article/details/52077915

 

 

 

转载于:https://www.cnblogs.com/lainey/p/8669381.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值