前言

这一节将讲述如何使用Caffe2的特征进行简单的线性回归学习。主要分为以下几步:

- 生成随机数据作为模型的输入

- 用这些数据创建网络

- 自动训练模型

- 查看梯度递减的结果和学习过程中网络参数的变化

ipython notebook教程请看这里

译者注:如果图片看不清,可以保存到本地查看。

这是一个快速的例子,展示如何使用前面的基础教程进行快速的尝试用CNN进行回归。我们要解决的问题非常简单,输入是二维的x,输出是一维的y,权重w=[2.0,1.5],偏置b=0.5。所以生成ground truth的等式是y=wx+b

在这个教程中,我们将会使用Caffe2的op生成训练数据。注意,这和你日常训练工作不同:在真实的训练中,训练数据一般从外部源载入,比如Caffe的DB数据库,或者Hive表。我们将会在MNIST的例程中讲到。

这个例程中,每一个Caffe2 的op将会写得非常详细,所以会显得太多繁杂。但是在MNIST例程中,我们将使用CNN模型助手来构建CNN模型。

  1. from caffe2.python import core, cnn, net_drawer, workspace, visualize
  2. import numpy as np
  3. from IPython import display
  4. from matplotlib import pyplot

声明计算图

这里,我们声明两个图:一个用于初始化计算中将会用到的变量参数和常量,另外一个作为主图将会用于跑起梯度下降,也就是训练。(译者注:不明白为啥叫做计算图(computation graphs),其实看代码和前一个教程的一样,就是创建两个net,一个用于初始化参数,一个用于训练。)

首先,初始化网络:网络的名字不重要。我们基本上把初始化代码放在一个net中,这样,我们就可以调用RunNetOnce()函数来执行。我们分离init_net的原因是,这些操作在整个训练的过程中只需要执行一次。

  1. init_net = core.Net("init")
  2. # ground truth 参数.
  3. W_gt = init_net.GivenTensorFill( [], "W_gt", shape=[1, 2], values=[2.0, 1.5])
  4. B_gt = init_net.GivenTensorFill([], "B_gt", shape=[1], values=[0.5])
  5. # Constant value ONE is used in weighted sum when updating parameters.
  6. ONE = init_net.ConstantFill([], "ONE", shape=[1], value=1.)
  7. # ITER是迭代的次数.
  8. ITER = init_net.ConstantFill([], "ITER", shape=[1], value=0, dtype=core.DataType.INT32)
  9. # 随机初始化权重,范围在[-1,1],初始化偏置为0
  10. W = init_net.UniformFill([], "W", shape=[1, 2], min=-1., max=1.)
  11. B = init_net.ConstantFill([], "B", shape=[1], value=0.0)
  12. print('Created init net.')

上面代码创建并初始化了init_net网络。主训练网络如下,我们展示了创建的的每一步。

- 前向传播产生loss

- 通过自动微分进行后向传播

- 使用标准的SGD进行参数更新

  1. train_net = core.Net("train")
  2. # First, 生成随机的样本X和创建ground truth.
  3. X = train_net.GaussianFill([], "X", shape=[64, 2], mean=0.0, std=1.0, run_once=0)
  4. Y_gt = X.FC([W_gt, B_gt], "Y_gt")
  5. # 往ground truth添加高斯噪声
  6. noise = train_net.GaussianFill([], "noise", shape=[64, 1], mean=0.0, std=1.0, run_once=0)
  7. Y_noise = Y_gt.Add(noise, "Y_noise")
  8. #注意到不需要讲梯度信息传播到 Y_noise层,
  9. #所以使用StopGradient 函数告诉偏微分算法不需要做这一步
  10. Y_noise = Y_noise.StopGradient([], "Y_noise")
  11. # 线性回归预测
  12. Y_pred = X.FC([W, B], "Y_pred")
  13. # 使用欧拉损失并对batch进行平均
  14. dist = train_net.SquaredL2Distance([Y_noise, Y_pred], "dist")
  15. loss = dist.AveragedLoss([], ["loss"])

现在让我们看看网络是什么样子的。从下面的图可以看到,主要包含四部分。

- 随机生成X

- 使用W_gt,B_gtFC操作生成grond truth Y_gt

- 使用当前的参数W和B进行预测

- 比较输出和计算损失

  1. graph = net_drawer.GetPydotGraph(train_net.Proto().op, "train", rankdir="LR")
  2. display.Image(graph.create_png(), width=800)



现在,和其他框架相似,Caffe2允许我们自动地生成梯度操作,让我们试一下,并看看计算图有什么变化。

  1. # Get gradients for all the computations above.
  2. gradient_map = train_net.AddGradientOperators([loss])
  3. graph = net_drawer.GetPydotGraph(train_net.Proto().op, "train", rankdir="LR")
  4. display.Image(graph.create_png(), width=800)



一旦我们获得参数的梯度,我们就可以将进行SGD操作:获得当前step的学习率,更参数。在这个例子中,我们没有做任何复杂的操作,只是简单的SGD。

  1. # 迭代数增加1.
  2. train_net.Iter(ITER, ITER)
  3. # 根据迭代数计算学习率.
  4. LR = train_net.LearningRate(ITER, "LR", base_lr=-0.1, policy="step", stepsize=20, gamma=0.9)
  5. # 权重求和
  6. train_net.WeightedSum([W, ONE, gradient_map[W], LR], W)
  7. train_net.WeightedSum([B, ONE, gradient_map[B], LR], B)
  8. graph = net_drawer.GetPydotGraph(train_net.Proto().op, "train", rankdir="LR")
  9. display.Image(graph.create_png(), width=800)

再次展示计算图



既然我们创建了网络,那么跑起来

  1. workspace.RunNetOnce(init_net)
  2. workspace.CreateNet(train_net)

在我们开始训练之前,先来看看参数:

  1. print("Before training, W is: {}".format(workspace.FetchBlob("W")))
  2. print("Before training, B is: {}".format(workspace.FetchBlob("B")))

参数初始化如下

  1. Before training, W is: [[-0.77634162 -0.88467366]]
  2. Before training, B is: [ 0.]

训练:

  1. for i in range(100):
  2. workspace.RunNet(train_net.Proto().name)

迭代100次后,查看参数:

  1. print("After training, W is: {}".format(workspace.FetchBlob("W")))
  2. print("After training, B is: {}".format(workspace.FetchBlob("B")))
  3. print("Ground truth W is: {}".format(workspace.FetchBlob("W_gt")))
  4. print("Ground truth B is: {}".format(workspace.FetchBlob("B_gt")))

参数如下:

  1. After training, W is: [[ 1.95769441 1.47348857]]
  2. After training, B is: [ 0.45236012]
  3. Ground truth W is: [[ 2. 1.5]]
  4. Ground truth B is: [ 0.5]

看起来相当简单是不是?让我们再近距离看看训练过程中参数的更新过程。为此,我们重新初始化参数,看看每次迭代参数的变化。记住,我们可以在任何时候从workspace中取出我们的blobs。

  1. workspace.RunNetOnce(init_net)
  2. w_history = []
  3. b_history = []
  4. for i in range(50):
  5. workspace.RunNet(train_net.Proto().name)
  6. w_history.append(workspace.FetchBlob("W"))
  7. b_history.append(workspace.FetchBlob("B"))
  8. w_history = np.vstack(w_history)
  9. b_history = np.vstack(b_history)
  10. pyplot.plot(w_history[:, 0], w_history[:, 1], 'r')
  11. pyplot.axis('equal')
  12. pyplot.xlabel('w_0')
  13. pyplot.ylabel('w_1')
  14. pyplot.grid(True)
  15. pyplot.figure()
  16. pyplot.plot(b_history)
  17. pyplot.xlabel('iter')
  18. pyplot.ylabel('b')
  19. pyplot.grid(True)



你可以发现非常典型的批梯度下降表现:由于噪声的影响,训练过程中存在波动。在Ipython notebook中跑多几次这个案例,你将会看到不同的初始化和噪声的影响。

当然,这只是一个玩玩的例子,在MNIST例程中,我们将会看到一个更加真实的CNN训练的例子。

译者注: 转载请注明出处:http://www.jianshu.com/c/cf07b31bb5f2

Caffe2 玩玩回归(Toy Regression)[5]的更多相关文章

  1. 机器学习总结之逻辑回归Logistic Regression

    机器学习总结之逻辑回归Logistic Regression 逻辑回归logistic regression,虽然名字是回归,但是实际上它是处理分类问题的算法.简单的说回归问题和分类问题如下: 回归问 ...

  2. 机器学习(四)--------逻辑回归(Logistic Regression)

    逻辑回归(Logistic Regression) 线性回归用来预测,逻辑回归用来分类. 线性回归是拟合函数,逻辑回归是预测函数 逻辑回归就是分类. 分类问题用线性方程是不行的   线性方程拟合的是连 ...

  3. 机器学习入门11 - 逻辑回归 (Logistic Regression)

    原文链接:https://developers.google.com/machine-learning/crash-course/logistic-regression/ 逻辑回归会生成一个介于 0 ...

  4. Coursera公开课笔记: 斯坦福大学机器学习第六课“逻辑回归(Logistic Regression)” 清晰讲解logistic-good!!!!!!

    原文:http://52opencourse.com/125/coursera%E5%85%AC%E5%BC%80%E8%AF%BE%E7%AC%94%E8%AE%B0-%E6%96%AF%E5%9D ...

  5. 岭回归(Ridge Regression)

    一.一般线性回归遇到的问题 在处理复杂的数据的回归问题时,普通的线性回归会遇到一些问题,主要表现在: 预测精度:这里要处理好这样一对为题,即样本的数量和特征的数量 时,最小二乘回归会有较小的方差 时, ...

  6. 机器学习方法(五):逻辑回归Logistic Regression,Softmax Regression

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术.应用感兴趣的同学加入. 前面介绍过线性回归的基本知识, ...

  7. 机器学习 (三) 逻辑回归 Logistic Regression

    文章内容均来自斯坦福大学的Andrew Ng教授讲解的Machine Learning课程,本文是针对该课程的个人学习笔记,如有疏漏,请以原课程所讲述内容为准.感谢博主Rachel Zhang 的个人 ...

  8. ML 逻辑回归 Logistic Regression

    逻辑回归 Logistic Regression 1 分类 Classification 首先我们来看看使用线性回归来解决分类会出现的问题.下图中,我们加入了一个训练集,产生的新的假设函数使得我们进行 ...

  9. 【机器学习实战】第8章 预测数值型数据:回归(Regression)

    第8章 预测数值型数据:回归 <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/ ...

随机推荐

  1. layui+ajax+select

    1.看效果 2.前端代码 <div class="layui-form-item"> <label class="layui-form-label&qu ...

  2. 洛谷 P1494 [国家集训队]小Z的袜子(莫队)

    题目链接:https://www.luogu.com.cn/problem/P1494 一道很经典的莫队模板题,然而每道莫队题的大体轮廓都差不多. 首先莫队是一种基于分块的算法,它的显著特点就是: 能 ...

  3. 每日扫盲(三):id_rsa、id_rsa.pub 、authorized_keys

    一.authorized_keys 1.就是为了让两个linux机器之间使用ssh不需要用户名和密码.采用了数字签名RSA或者DSA来完成这个操作 2.模型分析 假设 A (192.168.20.59 ...

  4. RocketMq-粪发涂墙1.0

    角色 说明 Producer 生产者,用于将消息发送到RocketMQ,生产者本身既可以是生成消息,也可以对外提供接口,由外部来调用接口,再由生产者将受到的消息发送给MQ. Consumer 消费者, ...

  5. Spring整合JDBC和Druid连接池

    我的博客名为黑客之谜,喜欢我的,或者喜欢未来的大神,点一波关注吧!顺便说一下,双十二快到了,祝大家双十二快乐,尽情的买买买~ 如果转载我的文章请标明出处和著名,谢谢配合. 我的博客地址为: https ...

  6. Java中正负数的存储方式-正码 反码和补码

    Java中正负数的存储方式-正码 反码和补码 正码 我们以int 为例,一个int占用4个byte,32bits 0 存在内存上为 00000000 00000000 00000000 0000000 ...

  7. python pylab.plot() 方法使用

    Python 中用pylab模块, pylab.plot() 函数,绘制折线统计图 import pylab as pl x = [, , , ] y = [, , , ] ''' plot参数说明: ...

  8. [Python] Tkinter的食用方法_01_简单界面

    #开始 放假之后感觉整个人已经放飞自我了,完全不知道自己一天天在干什么,明明有很多的事情需要做,但是实际上每天啥都没做,,,虚度光阴... 晚上突然心烦意乱,开始思考今天一天都做了什么,感觉很有负罪感 ...

  9. Jmeter_请求原件之参数化CSV

    1.用途:注册10个账户 2.用CSV 制造数据相对比TEXT更方便 3.创建CSV 文件,注册账户和密码如下 4.Jmeter设置如下 因为是注册10个账户,要运行10次 5.线程组->添加- ...

  10. LVS、Tomcat、Nginx、PHP优化项

    一.LVS 性能调优的方法最佳实践1.最小化安装编译系统内核2.优化持久服务超时时间:    1)显示超时时间    #ipvsadm -Ln --timeout    #Timeout (tcp t ...