caffe学习笔记--自定义cifar10网络参数

来源:互联网 发布:起床闹钟软件 编辑:程序博客网 时间:2024/04/25 17:53

在CIFAR-10实例中加入dropout

假如我们要在cifar-10实例中的ip1和ip2层之间加入dropout,那么我们可以定义一个drop1的层,其类型为Dropout,设置底层blob为ip1,顶层blob也为ip1(为了与原来的层匹配,也可以用其它名字,但是要保证各层之间必须能够衔接上)。然后设置dropout_ratio。至此,就为CIFAR-10实例加入了dropout。加入dropout后,重新运行程序进行训练即可。具体代码如下:

layer {  name:"drop1"  type:"Dropout"  bottom:"ip1"  top:"ip1"  dropout_param {    dropout_ratio: 0.5  }}

保存退出,开始训练。

训练后结果:

I1109 11:34:22.086735  8475 solver.cpp:310] Iteration 2000, loss = 1.08831I1109 11:34:22.086763  8475 solver.cpp:330] Iteration 2000, Testing net (#0)I1109 11:34:43.837874  8478 data_layer.cpp:73] Restarting data prefetching from start.I1109 11:34:44.743183  8475 solver.cpp:397]     Test net output #0: accuracy = 0.6436I1109 11:34:44.743232  8475 solver.cpp:397]     Test net output #1: loss = 0.991287 (* 1 = 0.991287 loss)I1109 11:34:44.743238  8475 solver.cpp:315] Optimization Done.I1109 11:34:44.743252  8475 caffe.cpp:259] Optimization Done.

从实验结果可以知道,加了Dropout层之后,虽然没有提高识别效果,但是降低了过拟合。

调整batch_size参数

首先batch_size指每次迭代训练图片的数量。
资料上说增大batch_size的好处有三点:

1)内存的利用率提高了,大矩阵乘法的并行化效率提高。
2)跑完一次epoch(全数据集)所需迭代次数减少,对于相同的数据量的处理速度进一步加快。
3)一定范围内,batchsize越大,其确定的下降方向就越准,引起训练震荡越小。

同样,盲目增大的弊端也有三点:

1)当数据集太大时,内存撑不住。
2)跑完一次epocffe-master/tools/extra/parse_log.sh caffe-master/tools/extra/extract_seconds.py和h(全数据集)所需迭代次数减少了,但要想达到相同的 精度,时间开销太大,参数的修正更加缓慢。
3)batchsize增大到一定的程度,其确定的下降方向已经基本不再变化。

实验

batch_size大小默认值是100,我增大到了200。

data_param {    source: "examples/cifar10/cifar10_train_lmdb"    batch_size: 200    backend: LMDB  }

再跑一下数据:

I1109 13:59:48.339932  9762 solver.cpp:310] Iteration 2000, loss = 0.88682I1109 13:59:48.339977  9762 solver.cpp:330] Iteration 2000, Testing net (#0)I1109 14:00:09.803097  9765 data_layer.cpp:73] Restarting data prefetching from start.I1109 14:00:10.693827  9762 solver.cpp:397]     Test net output #0: accuracy = 0.7025I1109 14:00:10.693874  9762 solver.cpp:397]     Test net output #1: loss = 0.873489 (* 1 = 0.873489 loss)I1109 14:00:10.693881  9762 solver.cpp:315] Optimization Done.I1109 14:00:10.693895  9762 caffe.cpp:259] Optimization Done.

比较和前面测试结果中的loss值,发现降低了0.1左右.

batch_normalization

简要的解释

在训练深层神经网络的过程中, 由于输入层的参数在不停的变化, 因此, 导致了当前层的分布在不停的变化, 这就导致了在训练的过程中, 要求 learning rate 要设置的非常小, 另外, 对参数的初始化的要求也很高.
Batch Normalization 的提出就是为了解决这个问题的. BN 在每一个 training mini-batch 中对每一个 feature 进行 normalize. 通过这种方法, 使得网络可以使用较大的 learning rate, 而且, BN 具有一定的 regularization 作用.

batch normalization直译过来就是批规范化。
在caffe中,可选参数定义在caffe根目录下的/src/caffe/proto/caffe.proto.

message BatchNormParameter {  // 如果为真,则使用保存的均值和方差,否则采用滑动平均计算新的均值和方差。  // 该参数缺省的时候,如果是测试阶段则等价为真,如果是训练阶段则等价为假。  optional bool use_global_stats = 1;  // 滑动平均的衰减系数,默认为0.999  optional float moving_average_fraction = 2 [default = .999];  // 分母附加值,防止除以方差时出现除0操作,默认为1e-5  optional float eps = 3 [default = 1e-5];}

实验

继续修改cifar10_quick_train_test.prototxt,添加batchnormal层。

layer {      name: "BatchNorm1"      type: "BatchNorm"     bottom: "conv1"      top: "conv1"       param {        lr_mult: 0        decay_mult: 0      }       param {        lr_mult: 0        decay_mult: 0      }      param {        lr_mult: 0        decay_mult: 0      }  }    

保存退出,进行迭代测试。

结果如下:

I1110 10:42:33.898412  7974 solver.cpp:310] Iteration 2000, loss = 1.08552I1110 10:42:33.898449  7974 solver.cpp:330] Iteration 2000, Testing net (#0)I1110 10:43:05.795646  7977 data_layer.cpp:73] Restarting data prefetching from start.I1110 10:43:07.118332  7974 solver.cpp:397]     Test net output #0: accuracy = 0.6058I1110 10:43:07.118378  7974 solver.cpp:397]     Test net output #1: loss = 1.11712 (* 1 = 1.11712 loss)I1110 10:43:07.118384  7974 solver.cpp:315] Optimization Done.I1110 10:43:07.118391  7974 caffe.cpp:259] Optimization Done.

loss下降了0.3。其实batchnormal做了两件事

1) 输入归一化 x_norm = (x-u)/std, 其中u和std是个累计计算的均值和方差。
2)y=alpha×x_norm + beta,对归一化后的x进行比例缩放和位移。其中alpha和beta是通过迭代学习的。

caffe 神经网络中的激活函数

6种激活函数的定义

1.1 ReLU / Rectified-Linear and Leaky-ReLU
ReLU是目前使用最多的激活函数,主要因为其收敛更快,并且能保持同样效果。
标准的ReLU函数为max(x, 0),当x>0时,输出x; 当x<=0时,输出0
f(x)=max(x,0)
1.2 Sigmoid
1.3 TanH / Hyperbolic Tangent
1.4 Absolute Value
f(x)=Abs(x)
1.5 Power
f(x)= (shift + scale * x) ^ power
1.6 BNLL binomial normal log likelihood的简称
f(x)=log(1 + exp(x))

如何使用这几种函数

比如我添加了sigmoid函数

layer {    name: "encode1neuron"    bottom: "encode1"    top: "encode1neuron"    type: "Sigmoid"  }  

测试结果如下:

I1110 16:36:08.785380  3022 solver.cpp:310] Iteration 2000, loss = 1.44096I1110 16:36:08.785424  3022 solver.cpp:330] Iteration 2000, Testing net (#0)I1110 16:36:34.700467  3025 data_layer.cpp:73] Restarting data prefetching from start.I1110 16:36:35.746063  3022 solver.cpp:397]     Test net output #0: accuracy = 0.4705I1110 16:36:35.746104  3022 solver.cpp:397]     Test net output #1: loss = 1.4736 (* 1 = 1.4736 loss)I1110 16:36:35.746124  3022 solver.cpp:315] Optimization Done.I1110 16:36:35.746129  3022 caffe.cpp:259] Optimization Done.

在激活层中,对输入数据进行激活操作(实际上就是一种函数变换),是逐元素进行运算的。从bottom得到一个blob数据输入,运算后,从top输入一个blob数据。在运算过程中,没有改变数据的大小,即输入和输出的数据大小是相等的。

输入:n*c*h*w
输出:n*c*h*w

阅读全文
0 0
原创粉丝点击