Tensorflow快餐教程(7) - 梯度下降

摘要: 梯度下降

梯度下降

学习完基础知识和矩阵运算之后,我们再回头看下第一节讲的线性回归的代码:

import tensorflow as tf
import numpy as nptrX = np.linspace(-1, 1, 101)
trY = 2 * trX + np.random.randn(*trX.shape) * 0.33 # 创建一些线性值附近的随机值X = tf.placeholder("float") 
Y = tf.placeholder("float")def model(X, w):return tf.multiply(X, w) # X*w线性求值,非常简单w = tf.Variable(0.0, name="weights") 
y_model = model(X, w)cost = tf.square(Y - y_model) # 用平方误差做为优化目标train_op = tf.train.GradientDescentOptimizer(0.01).minimize(cost) # 梯度下降优化# 开始创建Session干活!
with tf.Session() as sess:# 首先需要初始化全局变量,这是Tensorflow的要求tf.global_variables_initializer().run()for i in range(100):for (x, y) in zip(trX, trY):sess.run(train_op, feed_dict={X: x, Y: y})print(sess.run(w)) 

除了这一句

train_op = tf.train.GradientDescentOptimizer(0.01).minimize(cost)

应该都可以看懂了。
我们这一节就来讲看不懂的这一行,梯度下降优化函数。

从画函数图形说起

所谓梯度下降,其实没有什么神秘的,就是求个函数极值问题而己。
函数比矩阵强的一点是可以画图啊。

所以我们先学习一下如何画函数的图形:

import matplotlib.pyplot as plt
import numpy as npx = np.linspace(-10,10,1000)
y = x ** 2 - 2 * x+ 1
plt.plot(x, y)
plt.title("matplotlib")
plt.xlabel("height")
plt.ylabel("width")
# 设置图例
plt.legend(["X","Y"], loc="upper right")
plt.grid(True)
plt.show()

上面我们用np.linspace来生成若干点组成的向量,然后取y=x22x+1y=x2−2x+1的值。
画出的图像是这样的:

求函数的最小值

现在我们想要求这条曲线上的最小值点。因为这个函数的定义域是无限的,我们不可能从负无穷到正无穷挨个试那个最小。
但是,我们可以随便找一个点为起点,然后比较一下它左边相邻一点的点和右边和它相邻一点的点看看哪个更小。然后取较小的那个点,继续这个过程。

假设我们从x=-5这个坐标开始,y=(-5)(-5)-2(-5)+1=36。所以这个点是(-5,36). 
我们取0.1为步长,看看-5.1和-4.9的y值是多少,发现同(-5.1, 37.21)和(-4.9,34.81)。-4.9的值更小,于是-4.9就成为新一轮迭代的值。然后从(-4.9,34.81)到(-4.8,33.64),以此类推。一直到(1.0, 0)达到最小值,左右都比它大,这个极值就找到了。
求极值的这个函数我们称为损失函数loss function,或代价函数cost function,或者误差函数error function。这几个名称可以互换使用。
求得的极小值,我们称为x=argminf(x)x∗=argminf(x)

这种方法可以解决问题。但是它的问题在于慢。在函数下降速度很快的时候可以多移动一点加快速度,下降速度变慢了之后少移一点防止跑过了。

那么这个下降速度如何度量呢?我们都学过,用导数-derivative,也就是切线的斜率。有了导数之后,我们可以沿着导数的反方向,也就是切换下降的方向去寻找即可。
这种沿着x的导数的反方向移动一小步来减少f(x)值的技术,就被称为梯度下降 - gradient descent.
第n+1的值为第n次的值减去导数乘以一个可以调整的系数。
也就是
xn+1=xnηdf(x)dxxn+1=xn−ηdf(x)dx
其中,这个可调整的系数ηη,我们称为学习率。学习率越大下降速度越快,但是也可能错过最小值而产生振荡。
选择学习率的方法一般是取一个小的常数。也可以通过计算导数消失的步长。还可以多取几个学习率值,然后取效果最好的一个。

f(x)=x22x+1f(x)=x2−2x+1的导函数为f(x)=2x2f′(x)=2x−2
我们还是选择从(-5,36)这个点为起点,学习率我们取0.1。
则下一个点$x_2=-5 - 0.1 (2(-5)-2)= -3.8$
则第2个点下降到(-3.8,23.04)。比起第一种算法我们右移0.1,这次一下子就右移了1.2,效率提升12倍。

晋阶三维世界

我们看下我们在做线性回归时使用的损失函数:

cost = tf.square(Y - y_model)

这是个平方函数fLoss=Σni=1(yi(wxi+b))2fLoss=Σi=1n(yi−(wxi+b))2
其中yiyi是已知的标注好的结果,xixi是已知的输入值。未知数只有两个,w和b。
所以下一步求梯度下降的问题变成求二元二次函数极小值的问题。

我们还是先看图,二元二次函数的图是什么样子的。我们取个f(x,y)=x2+y2+x+y+1f(x,y)=x2+y2+x+y+1为例吧。

先学画图:

from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt# 创建 3D 图形对象
fig = plt.figure()
ax = Axes3D(fig)X3 = np.linspace(-10,10,100)
Y3 = np.linspace(-10,10,100)
X3, Y3 = np.meshgrid(X3, Y3)
Z3 = X3*X3 + Y3*Y3 + X3 + Y3 + 1
ax.plot_surface(X3, Y3, Z3, cmap=plt.cm.winter)# 显示图
plt.show()

图绘制出来是这样子的:

从一条曲线变成了一个碗一样的曲面。但是仍然是有最小值点的。

现在不只是有x一个方向,而是有x和y两个方向。两个方向也好办,x方向和y方向分别找梯度就是了。分别取x和y方向的偏微分。
xn+1=xnηf(x,y)x,yn+1=ynηf(x,y)yxn+1=xn−η∂f(x,y)∂x,yn+1=yn−η∂f(x,y)∂y

偏导数虽然从dd换成了,但是求微分的公式还是一样的。只不过在求x的时候把y当成常数就是了。

我们可以用梯度符号来简单表示=(f(x,y)x,f(x,y)y)∇=(∂f(x,y)∂x,∂f(x,y)∂y),这个倒三角符号读作nabla.

在Tensorflow里,梯度下降这样基本的操作自然是不需要我们操心的,我们只需要调用tf.train.GradientDescentOptimizer就好。

例子我们在前面已经看过了,我们复习一下:

cost = tf.square(Y - y_model) # 用平方误差做为优化目标train_op = tf.train.GradientDescentOptimizer(0.01).minimize(cost) # 梯度下降优化

赋给GradientDescentOptimizer的0.01就是我们的ηη,学习率。

自适应梯度演化史

如果您的逻辑思维比较强的话,一定会发现从二维导数升级到三维梯度时,有一个参数我们没有跟着一起扩容,那就是学习率ηη.

我们还是看一个图,将上面的方程变成f(x,y)=8x2+y2+x+y+1f(x,y)=8x2+y2+x+y+1

Z3 = 8*X3*X3 + Y3*Y3 + X3 + Y3 + 1

图像变成下面这样子:

大家可以直观地感受到,f(x,y)x∂f(x,y)∂xf(x,y)y∂f(x,y)∂y方向的下降速度是明显不一样的。
如果对于更高维的情况,问题可能更严重,众口难调。

最简单的方法可能是对于每个维度都用一个专门的学习率。不过这样也太麻烦了,这时Adaptive Gradient自适应梯度下降就被当时在UC伯克利读博士的John C. Duchi提出了,简写为AdaGrad. 
在Tensorflow中,我们可以通过tf.train.AdagradOptimizer来使用AdaGrad.

AdaGrad的公式为(xt+1)i=(xt)iηΣtτ=1(f(xτ))2i(f(xt))i(xt+1)i=(xt)i−ηΣτ=1t(∇f(xτ))i2(∇f(xt))i

但是,AdaGrad也有自己的问题。虽然初始指定一个ηη值之后可以自适应,但是如果这个ηη太大的话仍然会导致优化不稳定。但是如果太小了,随着优化,这个学习率会越来越小,可能就到不了极小值就停下来了。

于是当时在Google做实习生的Mathew Zeiler做出了两点改进:一是引入时间窗口概念,二是不用手动指定学习率。改进之后的算法叫做AdaDelta. 
公式中用到的RMS是指Root Mean Square,均方根. 
AdaDelta的公式为(xi)i=(RMS[Δx]t1)i(RMS[g]t)i(f(xi))i(∇xi)i=−(RMS[Δx]t−1)i(RMS[g]t)i(∇f(xi))i
具体过程请看Zeiler同学写的paper: http://arxiv.org/pdf/1212.5701v1.pdf

在Tensorflow中,我们只要使用tf.train.AdadeltaOptimizer这个封装就好。

AdaDelta并不是唯一的改进方案,类似的方案还有RMSProp, Adam等。我们可以使用tf.train.RMSPropOptimizer和tf.train.AdamOptimizer来调用就好了。

还记得第1节中我们讲卷积神经网络的例子吗?我们用的不再是梯度下降,而是RMSProp:

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=py_x, labels=Y))
train_op = tf.train.RMSPropOptimizer(0.001, 0.9).minimize(cost)
predict_op = tf.argmax(py_x, 1)

物理学的启示

虽然各种自适应梯度下降方法洋洋大观,但是复杂的未必就是最好的。导数的物理意义可以认为是速度。速度的变化我们可以参考物理学的动量的概念,同时引入惯性的概念。如果遇到坑,靠动量比较容易冲出去,而其它方法就要迭代很久。
在Tensorflow中,可以通过tf.train.MomentumOptimizer来使用动量方法。

我们可以看一下Mathew Zeiler的论文中对于几种方法的对比:

从中可以看到,虽然在前期,动量方法上窜下跳不像AdaGrad稳定,但是后期效果仍然是最好的。


作者:lusing

原文链接

本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/521796.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

腾讯物联网操作系统正式开源,最小体积仅1.8 KB

9月18日,腾讯宣布将开源自主研发的轻量级物联网实时操作系统TencentOS tiny。相比市场上其它系统,腾讯TencentOS tiny在资源占用、设备成本、功耗管理以及安全稳定等层面极具竞争力。该系统的开源可大幅降低物联网应用开发成本,提升开发效率&…

云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍

摘要: 本文带大家简单理解阿里巴巴Java开发手册中的规约内容以及P3C项目,可以帮助开发者扫描出所有潜在的代码隐患。在中间也聊了一些对于不同语言设计的理解,如何去看待语言的设计,其实是我们去学习一个语言的核心。演讲嘉宾简介…

你的数据安全么?Hadoop再曝安全漏洞| 黑客利用Hadoop Yarn资源管理系统未授权访问漏洞进行攻击

摘要: 4月30日,阿里云发现,俄罗斯黑客利用Hadoop Yarn资源管理系统REST API未授权访问漏洞进行攻击。 Hadoop是一款由Apache基金会推出的分布式系统框架,它通过著名的 MapReduce 算法进行分布式处理,Yarn是Hadoop集群的…

博文强识|进阶企业大咖

出品 | CSDN云计算 每个周三周五,和小编共同分享优秀博文,一起遨游在知识的海洋。 你需要知道的那些 redis 数据结构(前篇) redis 对于团队中的同学们来说是非常熟悉的存在了,我们常用它来做缓存、或是实现分布式锁等…

php 类似微信下拉菜单,微信小程序模拟下拉菜单开发实例

本文主要和大家分享微信小程序模拟下拉菜单开发实例,希望能帮助到大家。一.知识点1.实现动态显示和隐藏某个控件列表1data:{open:false},showitem:function(){this.setData({open:!this.data.open})},.display_show{display: block;}.display_none{display: none;}2…

算法导论 pdf_学习数据结构和算法最好的书是什么?

-----------通知:如果本站对你学习算法有帮助,请收藏网址,并推荐给你的朋友。由于 labuladong 的算法套路太火,很多人直接拿我的 GitHub 文章去开付费专栏,价格还不便宜。我这免费写给你看,多宣传原创作者是…

Tensorflow快餐教程(8) - 深度学习简史

摘要: 深度学习简史深度学习简史从机器学习流派说起如果要给机器学习划分流派的话,初步划分可以分为『归纳学习』和『统计学习』两大类。所谓『归纳学习』,就跟我们平时学习所用的归纳法差不多,也叫『从样例中学习』。归纳学习又分…

usb设备驱动程序(一)

代码&#xff1a; #include <linux/atomic.h> #include <linux/kernel.h> #include <linux/list.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/usb.h> #include <linux/videodev2.h> #include <linux…

Tensorflow快餐教程(9) - 卷积

摘要&#xff1a; 卷积的计算方法卷积卷积就是滑动中提取特征的过程在数学中&#xff0c;卷积convolution是一种函数的定义。它是通过两个函数f和g生成第三个函数的一种数学算子&#xff0c;表征函数f与g经过翻转和平移的重叠部分的面积。其定义为&#xff1a;h(x)f(x)∗g(x)∫…

商家笑了 设计师哭了,京东+英特尔的AI这招太绝

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 刘丹出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;在如今“无促销不电商”的大环境熏陶下&#xff0c;商家需要榨干了脑浆想尽各种奇招&#xff0c;玩法虽多&#xff0c;但万变不离其宗。面对上万、甚至…

明显调用的表达式前的括号必须具有指针函数类型_每天三分钟带你搞懂C++基础Day5 处理类型 typedef、auto、decltype...

类型别名(type alias)一个名字&#xff0c;是某种类型的同义词。使用类型名有很多好处&#xff0c;能让复杂的类型名字变得简单明了&#xff0c;易于理解和使用。有两种方法可用于定义类型别名。传统的方法是使用关键字typedef :typedef double wages; //wages是double的同义词…

基于OGG Datahub插件将Oracle数据同步上云

摘要&#xff1a;随着数据规模的不断扩大&#xff0c;传统的RDBMS难以满足OLAP的需求&#xff0c;本文将介绍如何将Oracle的数据实时同步到阿里云的大数据处理平台当中&#xff0c;并利用大数据工具对数据进行分析。一、背景介绍随着数据规模的不断扩大&#xff0c;传统的RDBMS…

那些阿里的年轻人

摘要&#xff1a; 今天是年轻人的节日 十九年前&#xff0c;杭州城西一间狭小简陋的民房里 有一群年轻人 他们衣着朴素、口袋里也没什么钱 但每个人的眼神是坚定的、热烈的 他们每天挂在嘴边的 是梦想要做一件改变世界的事儿 1999年&#xff0c;一群杭州的年轻人离开北京&#…

php的添加语句怎么写,php修改语句怎么写

php修改语句是“update student set 字段1新值1,…where id $id”,…;”&#xff0c;其中update语句就是用于修改数据库表中的数据。推荐&#xff1a;《PHP视频教程》PHP sql修改语句语法&#xff1a;$sql “update student set 字段1新值1,…where id $id”,…;注意&#xff…

招人!入职阿里仅1年,我和做AI的程序员薪资翻了2倍!

最近在知乎上&#xff0c;关于AI的这个话题又被顶起来&#xff0c;其中&#xff0c;这条回答让人印象深刻&#xff1a;在这短短的一条信息里&#xff0c;无疑显示出&#xff1a;AI行业缺人&#xff0c;高端岗位80万年薪恐怕也招不来&#xff01;小编上周在一个AI群里&#xff0…

使用Unoconv和LibreOffice进行格式转换实现在线预览 doc,doxc,xls,xlsx,ppt,pptx 文件

此项目根据企业真实需求制作而成&#xff0c;希望能帮助大家解决在线预览的问题&#xff01; 此项目已开源&#xff0c;欢迎大家来STAR 软件版本SpringBoot2.2.2.RELEASELibreOffice6.3.2unoconv0.6文章目录一、配置管理① pom② yml③ controller④ 文件格式转换工具类FileFor…

关于CNN图像分类的一份综合设计指南

摘要&#xff1a; 本文是一篇关于使用CNN完成图像分类的综合设计指南&#xff0c;涵盖了一些模型设计、模型优化以及数据处理经验&#xff0c;是一份适合图像分类方向研究者参考的综合设计指南。对于计算机视觉任务而言&#xff0c;图像分类是其中的主要任务之一&#xff0c;比…

从GitHub中整理出来的15个最受欢迎的Python开源框架,你喜欢哪个

摘要&#xff1a; 从GitHub中整理出的15个最受欢迎的Python开源框架。这些框架包括事件I/O&#xff0c;OLAP&#xff0c;Web开发&#xff0c;高性能网络通信&#xff0c;测试&#xff0c;爬虫等。 Django: Python Web应用开发框架 Django 应该是最出名的Python框架&#xff0c;…

greenplum配置高可用_高可用hadoop集群配置就收藏这一篇,动手搭建Hadoop(5)

01 ssh免密安装02 jdk安装03 hadoop伪分布式安装04 hadoop全分布式完成了前面四步&#xff0c;现在做hadoop的高可用。其实和之前的lvs的高可用差不多的。如果我们有两个namenode节点&#xff0c;分别是node01和node02。假设node01是主节点&#xff0c;node02是从节点&#xff…

聊聊我是如何在面试别人Spring事务时“套路”对方的

戳蓝字“CSDN云计算”关注我们哦&#xff01;“中国最好面试官”我希望把面试当作是一次交流&#xff0c;像朋友那样&#xff0c;而不是像一场Q & A。但也有人觉得&#xff0c;我对应聘者“太好了”&#xff0c;这完全没必要&#xff0c;反正最后他也不会来。好吧&#xff…