修改lenet网络进行训练(一)
2015-12-23 23:37
435 查看
本文主要是在已有的lenet框架基础上对网络进行修改,然后训练。
四部分内容
1.protobuf的了解
2.xvaier算法了解
3.caffe中对网络定义文件
4.参考薛开宇学习笔记(四)写的两个代码文件
先介绍几个基本知识
(一)protobuf
首先,protobuf是一个开源 项 目,而且是后台很硬的开源项目。网上现有的大部分(至少80%)开源项目,要么是某人单干、要么是几个闲杂人等合伙搞。而protobuf则不然,它是 鼎鼎大名的Google公司开发出来,并且在Google内部久经考验的一个东东。由此可见,它的作者绝非一般闲杂人等可比。
简单地说,这个东东干的事儿其实和XML 差不多,也就是把某种数据结构的信息,以某种格式保存起来。主要用于数据存储、传输协议格式等场合。
话说到了去年(大约是08年7月),Google突然大发慈悲,把这个好东西贡献给了开源社区。
protobuf有啥特色
◇性能好/效率高
时间开销:XML格式化(序列化)的开销倒还好;但是XML解析(反序列化)的开销就不敢恭维啦。俺之前经常碰到一些时间性能很敏感的场合,由于不堪忍受XML解析的速度,弃之如敝履。
空间开销:熟悉XML语法的同学应该知道,XML格式为了有较好的可读性,引入了一些冗余的文本信息。所以空间开销也不是太好(不过这点缺点,俺不常碰到)。
由于Google公司赖以吹嘘的就是它的海量数据和海量处理能力。对于几十万、上百万机器的集群,动不动就是PB级的数据量,哪怕性能稍微提高 0.1% 也是相当可观滴。所以Google自然无法容忍XML在性能上的明显缺点。再加上Google从来就不缺造轮子的牛人,所以protobuf也就应运而生 了。
◇代码 生成机制
除了性能好,代码生成机制是主要吸引俺的地方。为了说明这个代码生成机制,俺举个例子。
比如有个电子商务的系统(假设用C++实现),其中的模块A需要发送大量的订单信息给模块B,通讯的方式使用socket。
假设订单包括如下属性:
--------------------------------
时间:time(用整数表示)
客户id:userid(用整数表示)
交易金额:price(用浮点数表示)
交易的描述:desc(用字符串表示)
--------------------------------
如果使用protobuf实现,首先要写一个proto文件(不妨叫Order.proto),在该文件中添加一个名为"Order"的message结构,用来描述通讯协议中的结构化数据。该文件的内容大致如下:
--------------------------------
message Order
{
required int32 time = 1;
required int32 userid = 2;
required float price = 3;
optional string desc = 4;
}
--------------------------------
然后,使用protobuf内置的编译器编译 该proto。由于本例子的模块是C++,你可以通过protobuf编译器的命令行参数(看“这里 ”),让它生成C++语言的“订单包装类”。(一般来说,一个message结构会生成一个包装类)
然后你使用类似下面的代码来序列化/解析该订单包装类:
--------------------------------
// 发送方
Order order;
order.set_time(XXXX);
order.set_userid(123);
order.set_price(100.0f);
order.set_desc("a test order");
string sOrder;
order.SerailzeToString(&sOrder);
// 然后调用某种socket的通讯库把序列化之后的字符串发送出去
// ......
--------------------------------
// 接收方
string sOrder;
// 先通过网络通讯库接收到数据,存放到某字符串sOrder
// ......
Order order;
if(order.ParseFromString(sOrder)) // 解析该字符串
{
cout << "userid:" << order.userid() << endl
<< "desc:" << order.desc() << endl;
}
else
{
cerr << "parse error!" << endl;
}
--------------------------------
有了这种代码生成机制,开发人员再也不用吭哧吭哧地编写那些协议解析的代码了万一将来需求发生变更,要求给订单再增加一个“状态”的属性,那只需要在Order.proto文件中增加一行代码。对于发送方(模块A),只要增加一行设置状态的代码;对于接收方(模块B)只要增加一行读取状态的代码。哇塞,简直太轻松了!
另外,如果通讯双方使用不同的编程语言来实现,使用这种机制可以有效确保两边的模块对于协议的处理是一致的。
(二) xvaier 算法
在caffe中用xvaier算法进行网络权值的初始化;从网上拔了一些资料,有了个基本的概念
find the
right docstring and then read the referenced paper, Xavier Glorot & Yoshua Bengio’s Understanding
the difficulty of training deep feedforward neural networks.
更多细节可以从上面的文档中学习
(三)caffe中网络结构的定义和初始化在两个文件中,后缀都为.prototxt;文件名中带有solver为网络结构的参数的定义。具体的参数代表的意义后面的文章会进一步解释
(四)下面是按照薛开宇学习笔记四进行编写的两个文件 但是因为这是2014年的笔记,现在caffe应该是有更新,数据使用的lmdb不是leverdb,估计直接用这个跑是跑不同的。还没来及修改,先放着儿做参考吧
lenet_train.ptototxt
lenet_solver.protptxt
四部分内容
1.protobuf的了解
2.xvaier算法了解
3.caffe中对网络定义文件
4.参考薛开宇学习笔记(四)写的两个代码文件
先介绍几个基本知识
(一)protobuf
首先,protobuf是一个开源 项 目,而且是后台很硬的开源项目。网上现有的大部分(至少80%)开源项目,要么是某人单干、要么是几个闲杂人等合伙搞。而protobuf则不然,它是 鼎鼎大名的Google公司开发出来,并且在Google内部久经考验的一个东东。由此可见,它的作者绝非一般闲杂人等可比。
简单地说,这个东东干的事儿其实和XML 差不多,也就是把某种数据结构的信息,以某种格式保存起来。主要用于数据存储、传输协议格式等场合。
话说到了去年(大约是08年7月),Google突然大发慈悲,把这个好东西贡献给了开源社区。
protobuf有啥特色
◇性能好/效率高
时间开销:XML格式化(序列化)的开销倒还好;但是XML解析(反序列化)的开销就不敢恭维啦。俺之前经常碰到一些时间性能很敏感的场合,由于不堪忍受XML解析的速度,弃之如敝履。
空间开销:熟悉XML语法的同学应该知道,XML格式为了有较好的可读性,引入了一些冗余的文本信息。所以空间开销也不是太好(不过这点缺点,俺不常碰到)。
由于Google公司赖以吹嘘的就是它的海量数据和海量处理能力。对于几十万、上百万机器的集群,动不动就是PB级的数据量,哪怕性能稍微提高 0.1% 也是相当可观滴。所以Google自然无法容忍XML在性能上的明显缺点。再加上Google从来就不缺造轮子的牛人,所以protobuf也就应运而生 了。
◇代码 生成机制
除了性能好,代码生成机制是主要吸引俺的地方。为了说明这个代码生成机制,俺举个例子。
比如有个电子商务的系统(假设用C++实现),其中的模块A需要发送大量的订单信息给模块B,通讯的方式使用socket。
假设订单包括如下属性:
--------------------------------
时间:time(用整数表示)
客户id:userid(用整数表示)
交易金额:price(用浮点数表示)
交易的描述:desc(用字符串表示)
--------------------------------
如果使用protobuf实现,首先要写一个proto文件(不妨叫Order.proto),在该文件中添加一个名为"Order"的message结构,用来描述通讯协议中的结构化数据。该文件的内容大致如下:
--------------------------------
message Order
{
required int32 time = 1;
required int32 userid = 2;
required float price = 3;
optional string desc = 4;
}
--------------------------------
然后,使用protobuf内置的编译器编译 该proto。由于本例子的模块是C++,你可以通过protobuf编译器的命令行参数(看“这里 ”),让它生成C++语言的“订单包装类”。(一般来说,一个message结构会生成一个包装类)
然后你使用类似下面的代码来序列化/解析该订单包装类:
--------------------------------
// 发送方
Order order;
order.set_time(XXXX);
order.set_userid(123);
order.set_price(100.0f);
order.set_desc("a test order");
string sOrder;
order.SerailzeToString(&sOrder);
// 然后调用某种socket的通讯库把序列化之后的字符串发送出去
// ......
--------------------------------
// 接收方
string sOrder;
// 先通过网络通讯库接收到数据,存放到某字符串sOrder
// ......
Order order;
if(order.ParseFromString(sOrder)) // 解析该字符串
{
cout << "userid:" << order.userid() << endl
<< "desc:" << order.desc() << endl;
}
else
{
cerr << "parse error!" << endl;
}
--------------------------------
有了这种代码生成机制,开发人员再也不用吭哧吭哧地编写那些协议解析的代码了万一将来需求发生变更,要求给订单再增加一个“状态”的属性,那只需要在Order.proto文件中增加一行代码。对于发送方(模块A),只要增加一行设置状态的代码;对于接收方(模块B)只要增加一行读取状态的代码。哇塞,简直太轻松了!
另外,如果通讯双方使用不同的编程语言来实现,使用这种机制可以有效确保两边的模块对于协议的处理是一致的。
(二) xvaier 算法
在caffe中用xvaier算法进行网络权值的初始化;从网上拔了一些资料,有了个基本的概念
find the
right docstring and then read the referenced paper, Xavier Glorot & Yoshua Bengio’s Understanding
the difficulty of training deep feedforward neural networks.
更多细节可以从上面的文档中学习
(三)caffe中网络结构的定义和初始化在两个文件中,后缀都为.prototxt;文件名中带有solver为网络结构的参数的定义。具体的参数代表的意义后面的文章会进一步解释
(四)下面是按照薛开宇学习笔记四进行编写的两个文件 但是因为这是2014年的笔记,现在caffe应该是有更新,数据使用的lmdb不是leverdb,估计直接用这个跑是跑不同的。还没来及修改,先放着儿做参考吧
lenet_train.ptototxt
name: "LeNet" #define data_layer layers{ # input the layers name name:"mnist" # input type type:DATA # input parameter data_param{ #read data from mnist-train-lmdb source:"example/mnist/mnist_train_lmdb" # batchsize define batch_size:64 # data normalization [0,1],1/256=0.00390625 scale:0.00390625 } #data and label blob space top:"data" top:"label" } #define conv1_layer layers{ name:"conv1" type:CONVOLUTION bottom:data top:"conv1" blobs_lr:1 blobs_lr:2 convolution_param{ num_output:20 kernel_size:5 stride:1 weight_filler{ type:"xavier" } bias_filler{ type:"constant" } } } #define pooling_layer layers{ name:"pool1" type:POOLING bottom:"conv1" top:"pool1" pooling_param{ pool:MAX kernel_size:2 stride:2 } } #define conv2_layer layers{ name:conv2 type:CONVOLUTION bottom:"pooling1" top:"conv2" blobs_lr:1 blobs_lr:2 convolution_param{ num_output:50 kernel_size:5 stride:1 weight_filler{ type:"xavier" } bias_filler{ type:"constant" } } } #define pool2 layers{ name:"pool2" type:POOLING bottom:"conv2" top:"pool2" pooling_param{ pool:MAX kernel_size:2 stride:2 } } #define MLF layers{ name:"ip1" type:INNER_PRODUCT blobs_lr:1 blobs_lr:2 inner_produce_param{ num_output:500 weight_filler{ type:"xvaier" } bias_filler{ type:"constant" } } bottom:"pool2" top:"ip1" } # define ReLU_layer layers{ name:"relu1" type:RELU bottom:"ip1" top:"ip1" } # define MLF layers{ name:"ip2" type:INNER_PRODUCT blobs_lr:1 blobs_lr:2 inner_product_param{ num_output:10 weight_filler{ type:"xavier" } bias_filler{ type:"constant" } } bottom:"ip1" top:"ip2" } #define loss_layer layers{ name:"loss" type:SOFTMAX_LOSS bottom:"ip2" bottom:"laber" }
lenet_solver.protptxt
train_net:"lenet_train.prototxt" test_net:"lenet_test.prototxt" test_iter:100 test_interval:500 base_lr:0.01 momentum:0.9 weight_decay:0.0005 lr_policy:"inv" gamma:0.0001 power:0.75 display:100 max_iter:10000 snapshot:5000 snapshot_prefix:"lenet" solver_mode:1
相关文章推荐
- 待完成任务(一) 利用自己的数据集 利用lenet网络进行训练
- http请求
- 机器学习公开课笔记(4):神经网络(Neural Network)——表示
- 机器学习公开课笔记(4):神经网络(Neural Network)——表示
- 《SDN: Software Defined Networks》笔记--SDN控制器,网络可编程
- JSP提示"The superclass “javax.servlet.http.HttpServlet” was not found on the Java Build Path"
- iOS开发——使用Charles进行https网络抓包详解
- Apache HttpClient
- LA 3902 网络
- 测试类 模拟http请求 运用Jodd包
- Android之实时监控网络状态
- 网络请求456
- http://www.w3school.com.cn/
- 利用caffe 用自己的数据集在imagenet网络中实践
- iOS开发——使用Charles进行http网络抓包详解
- Xcode模拟器上,网络正常,高德地图只显示方格,这是为什么呢?本人遇到的是如下情况.....
- Python网络爬虫中的网页中文正则表达式匹配小心得
- 12-Angular的http与location
- 什么是HTTP?Ping命令是什么?
- 基于http在互联网传输敏感数据的消息摘要、签名与加密方案