首页 > 其他分享 >Theano 中文文档 0.9 - 7.2.3 Theano中的导数

Theano 中文文档 0.9 - 7.2.3 Theano中的导数

时间:2023-05-02 15:02:00浏览次数:59  
标签:0.9 Jacobian gy 7.2 操作符 theano Theano grad


7.2.3 Theano中的导数

译者:Python 文档协作翻译小组,原文:Derivatives in Theano

本文以 CC BY-NC-SA 4.0 协议发布,转载请保留作者署名和文章出处。

Python 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。

计算梯度

现在让我们使用Theano来完成一个稍微复杂的任务:创建一个函数,该函数计算相对于其参数x的某个表达式y的导数。为此,我们将使用宏T.grad。例如,我们可以计算

相对于

的梯度。注意:。

这里是计算这个梯度的代码:

>>> import numpy
>>> import theano
>>> import theano.tensor as T
>>> from theano import pp
>>> x = T.dscalar('x')
>>> y = x ** 2
>>> gy = T.grad(y, x)
>>> pp(gy)  # print out the gradient prior to optimization
'((fill((x ** TensorConstant{2}), TensorConstant{1.0}) * TensorConstant{2}) * (x ** (TensorConstant{2} - TensorConstant{1})))'
>>> f = theano.function([x], gy)
>>> f(4)
array(8.0)
>>> numpy.allclose(f(94.2), 188.4)
True

在这个例子中,我们可以从pp(gy)看到我们正在计算正确的符号梯度。fill((x ** 2), 1.0)表示生成一个与x ** 2相同形状的矩阵并以1.0填充它。

注意

优化器简化了符号梯度表达式。你可以通过挖掘编译后的函数的内部属性来看到这一点。

pp(f.maker.fgraph.outputs[0])
'(2.0 * x)'

优化后,图中只剩下一个Apply节点,这将使输入加倍。

我们还可以计算复杂表达式的梯度,例如上面定义的logistic函数。事实证明,logistic的导数是:。

logistic函数的梯度图,其中x轴为x,y轴为


>>> x = T.dmatrix('x')
>>> s = T.sum(1 / (1 + T.exp(-x)))
>>> gs = T.grad(s, x)
>>> dlogistic = theano.function([x], gs)
>>> dlogistic([[0, 1], [-1, -2]])
array([[ 0.25      ,  0.19661193],
 [ 0.19661193,  0.10499359]])

一般来说,对于任何标量表达式sT.grad(s, w)提供Theano表达式用于计算。这样,Theano可用于对符号进行高效的微分(由于T.grad返回的表达式将在编译期间优化),即使对于具有多个输入的函数也是如此。(有关符号微分的描述,请参见自动微分)。

注意

T.grad的第二个参数可以是一个列表,在这种情况下,输出也是一个列表。两个列表中的顺序很重要:输出列表的元素iT.grad第一个参数相对于第二个参数列表中的第i元素的梯度。T.grad的第一个参数必须是标量(大小为1的张量)。有关T.grad参数的语义的更多信息以及实现的细节,请参见库的这部分。

有关微分内部工作原理的其他信息,也可以在更高级的教程扩展Theano中找到。

计算Jacobian

在Theano的用语中,术语Jacobian表示函数相对于其输入的一阶偏导数的张量。(这是对数学中所谓的Jacobian矩阵的泛化。)Theano实现theano.gradient.jacobian()宏,执行计算Jacobian所需的所有内容。以下内容说明如何手动执行。

为了手动计算某些函数y相对于某个参数x的雅可比矩阵,我们需要使用scan。我们所做的是循环y中的条目,并计算y [i]相对于x的梯度。

注意

scan是Theano中的通用操作,允许以符号方式写入各种循环方程。创建符号循环(并优化它们的性能)是一项艰巨的任务,人们正在努力提高scan的性能。我们将在本教程后面回到scan

>>> import theano
>>> import theano.tensor as T
>>> x = T.dvector('x')
>>> y = x ** 2
>>> J, updates = theano.scan(lambda i, y, x : T.grad(y[i], x), sequences=T.arange(y.shape[0]), non_sequences=[y, x])
>>> f = theano.function([x], J, updates=updates)
>>> f([4, 4])
array([[ 8.,  0.],
 [ 0.,  8.]])

我们在这段代码中使用T.arange生成从0y.shape[0]int序列。然后,我们循环该序列,并且在每个步骤,我们计算元素y[i]相对于x的梯度。 scan自动连接所有这些行,生成对应于Jacobian的矩阵。

注意

关于T.grad,有一些缺陷需要注意。其中一个是你不能重写上面的Jacobian表达式为theano.scan(lambda y_i,x: T.grad(y_i,x), sequences=y, non_sequences=x),即使从scan的文档看来是可能的。原因是y_i将不再是x的函数,而y[i]仍然是。

计算Hessian

在Theano中,术语Hessian具有通常的数学概念:它是由函数的二阶偏导数组成的矩阵,该函数的输出为标量和输入为向量。Theano实现theano.gradient.hessian()宏,完成计算Hessian所需要的所有内容。以下内容说明如何手动执行。

你可以类似于类似于的方式手动计算Hessian。现在唯一的区别是,我们计算T.grad(cost,x)的Jacobian,而不是计算某个表达式y的Jacobian,其中cost是某个标量。

>>> x = T.dvector('x')
>>> y = x ** 2
>>> cost = y.sum()
>>> gy = T.grad(cost, x)
>>> H, updates = theano.scan(lambda i, gy,x : T.grad(gy[i], x), sequences=T.arange(gy.shape[0]), non_sequences=[gy, x])
>>> f = theano.function([x], H, updates=updates)
>>> f([4, 4])
array([[ 2.,  0.],
 [ 0.,  2.]])

Jacobian乘以向量

有时我们可以用Jacobians乘以向量或向量乘以Jacobians来表达算法。与求值Jacobians然后进行相乘相比,有方法计算所需的结果同时避免对Jacobians进行真正的求值。这可以带来显着的性能提升。一个这样的算法的描述可以在这里找到:

  • Barak A. Pearlmutter,“Fast Exact Multiplication by the Hessian”,Neural Computation,1994

虽然原则上我们希望Theano为我们自动识别这些模式,但在实践中,以通用的方式实现这样的优化是非常困难的。因此,我们提供专门用于这些任务的特殊函数。

R操作符

R操作符用于求值Jacobian和向量之间的乘积,即。该公式甚至可以推广为x是一个矩阵、或者一个普通的张量,在这种情况下Jacobian变为张量并且乘积变为某种张量的积。因为在实践中,我们最终需要根据权重矩阵来计算这样的表达式,所以Theano支持这种更通用的操作形式。为了求值表达式y相对于xR操作,将Jacobian与v相乘,你需要做类似这样的事情:

>>> W = T.dmatrix('W')
>>> V = T.dmatrix('V')
>>> x = T.dvector('x')
>>> y = T.dot(x, W)
>>> JV = T.Rop(y, W, V)
>>> f = theano.function([W, V, x], JV)
>>> f([[1, 1], [1, 1]], [[2, 2], [2, 2]], [0,1])
array([ 2.,  2.])

实现Rop的操作的列表。

L操作符

类似于R操作符L操作符将计算向量乘以Jacobian。数学公式是!v \frac{\partial
f(x)}{\partial x}
L操作符也支持普通的张量(不仅仅是向量)。类似地,它可以实现如下:

>>> W = T.dmatrix('W')
>>> v = T.dvector('v')
>>> x = T.dvector('x')
>>> y = T.dot(x, W)
>>> VJ = T.Lop(y, W, v)
>>> f = theano.function([v,x], VJ)
>>> f([2, 2], [0, 1])
array([[ 0.,  0.],
 [ 2.,  2.]])

注意

v求值的关键点,其在L操作R操作中不同。对于L操作符,这个求值的关键点需要具有与输出相同的形状,而对于R操作符,该点应具有与输入相同的形状参数。此外,这两个操作的结果不同。L操作符的结果与输入参数具有相同的形状,而R操作符的结果具有与输出相似的形状。

支持R操作的操作的列表。

R操作符

R操作符用于求值Jacobian和向量之间的乘积,即。该公式甚至可以推广为x是一个矩阵、或者一个普通的张量,在这种情况下Jacobian变为张量并且乘积变为某种张量的积。因为在实践中,我们最终需要根据权重矩阵来计算这样的表达式,所以Theano支持这种更通用的操作形式。为了求值表达式y相对于xR操作,将Jacobian与v相乘,你需要做类似这样的事情:

>>> W = T.dmatrix('W')
>>> V = T.dmatrix('V')
>>> x = T.dvector('x')
>>> y = T.dot(x, W)
>>> JV = T.Rop(y, W, V)
>>> f = theano.function([W, V, x], JV)
>>> f([[1, 1], [1, 1]], [[2, 2], [2, 2]], [0,1])
array([ 2.,  2.])

实现Rop的操作的列表。

L操作符

类似于R操作符L操作符将计算向量乘以Jacobian。数学公式是!v \frac{\partial
f(x)}{\partial x}
L操作符也支持普通的张量(不仅仅是向量)。类似地,它可以实现如下:

>>> W = T.dmatrix('W')
>>> v = T.dvector('v')
>>> x = T.dvector('x')
>>> y = T.dot(x, W)
>>> VJ = T.Lop(y, W, v)
>>> f = theano.function([v,x], VJ)
>>> f([2, 2], [0, 1])
array([[ 0.,  0.],
 [ 2.,  2.]])

注意

v求值的关键点,其在L操作R操作中不同。对于L操作符,这个求值的关键点需要具有与输出相同的形状,而对于R操作符,该点应具有与输入相同的形状参数。此外,这两个操作的结果不同。L操作符的结果与输入参数具有相同的形状,而R操作符的结果具有与输出相似的形状。

支持R操作的操作的列表。

Hessian乘以向量

如果你需要计算Hessian乘一个向量,你可以利用上面定义的操作符,它比实际计算精确的Hessian然后执行乘积更有效率。由于Hessian矩阵的对称性,你有两个选择将给你相同的结果,虽然这些选择可能表现出不同的性能。因此,我们建议在使用以下两种方法之前分析它们:

>>> x = T.dvector('x')
>>> v = T.dvector('v')
>>> y = T.sum(x ** 2)
>>> gy = T.grad(y, x)
>>> vH = T.grad(T.sum(gy * v), x)
>>> f = theano.function([x, v], vH)
>>> f([4, 4], [2, 2])
array([ 4.,  4.])

或使用R操作符

>>> x = T.dvector('x')
>>> v = T.dvector('v')
>>> y = T.sum(x ** 2)
>>> gy = T.grad(y, x)
>>> Hv = T.Rop(gy, x, v)
>>> f = theano.function([x, v], Hv)
>>> f([4, 4], [2, 2])
array([ 4.,  4.])

最后的要点

  • grad函数以符号的方式工作:它接收并返回Theano变量。
  • grad可以与宏进行比较,因为它可以重复应用。
  • 标量costs只能由grad直接处理。数组通过重复应用来处理。
  • 内置函数使得高效地计算向量乘以Jacobian向量乘以Hessian
  • 优化工作还在进行中,包括有效计算完全Jacobian和Hessian矩阵以及Jacobian乘以向量


标签:0.9,Jacobian,gy,7.2,操作符,theano,Theano,grad
From: https://blog.51cto.com/wizardforcel/6239976

相关文章

  • Theano 中文文档 0.9 - 7. 教程
    7.教程译者:Python文档协作翻译小组,原文:Tutorial。本文以CCBY-NC-SA4.0协议发布,转载请保留作者署名和文章出处。Python文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。让我们开始一个交互式会话(例如使用python或ipython)并导入Theano。>>>......
  • Theano 中文文档 0.9 - 7.2.1 起手式 —— 代数
    7.2.1起手式——代数译者:Python文档协作翻译小组,原文:BabySteps-Algebra。本文以CCBY-NC-SA4.0协议发布,转载请保留作者署名和文章出处。Python文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。两个标量相加为了让我们开始使用Theano并......
  • Theano 中文文档 0.9 - 6. 更新Theano
    6.更新Theano译者:Python文档协作翻译小组,原文:UpdatingTheano。本文以CCBY-NC-SA4.0协议发布,转载请保留作者署名和文章出处。Python文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。根据你如何安装Theano,选择下面三个部分中的一个。你应该......
  • Visual AssistX Version 10.9.2488 Cracked
    任何问题请反馈至邮箱:[email protected](随缘查看邮件)Anyporbs->[email protected]再次声明:本破解补丁仅供交流学习和研究使用,不可用于商业。如果您喜欢该程序和内容,请支持正版,购买注册,得到更好的正版服务。Notice:thispatcherisforcommunication,lear......
  • Visual AssistX Version 10.9.2488 Cracked
    任何问题请反馈至邮箱:[email protected](随缘查看邮件)Anyporbs->[email protected]再次声明:本破解补丁仅供交流学习和研究使用,不可用于商业。如果您喜欢该程序和内容,请支持正版,购买注册,得到更好的正版服务。Notice:thispatcherisforcommunication,lear......
  • centos7 安装MySql 安装5.7.28
    1、先执行查询:rpm-qa|grepmariadb执行结果如:mariadb-libs-5.5.64-1.el7.x86_642、先执行删除:rpm-e--nodepsmariadb-libs3、下载MySQL数据库:这里使用的是mysql-5.7.28版本4、将下载好的MySQL安装包上传到服务器5、到目录中解压文件:tar-xvfmysql-5.7.28-1.el7.x86_6......
  • [Unity脚本运行时更新]C#7.2新特性
    洪流学堂微信公众号。本文是该系列《Unity脚本运行时更新带来了什么?》的第7篇。洪流学堂公众号回复runtime,获取本系列所有文章。Unity2017-2018.2中的4.x运行时已经支持到C#6,之前的文章已经介绍完毕。Unity2018.3将支持到C#7.3,今天我们来看看C#7.2新特性能给代码带来什么吧,不过这......
  • Day 27 27.2 JS进阶之window对象
    JS-Function对象之window对象window是客户端浏览器对象模型的基类,window对象是客户端JavaScript的全局对象。一个window对象实际上就是一个独立的窗口,对于框架页面来说,浏览器窗口每个框架都包含一个window对象。(1)全局作用域在客户端浏览器中,window对象是访问BOM......
  • iis搭建discuz7.2 的曲折经历 y以及各种报错的处理
    环境windowsserver 2008R2  mysql 5.1.73 iis6 php5.6安装PHP解压PHP,我给的路径是C:\Users\Administrator\Desktop\php,大伙儿随意把php.ini-production改名为php.ini(用于开发环境的话,就改那个development)修改扩展路径extension_dir="./ext"启用MySQL扩展(即去......
  • kubeadm部署k8s 1.20.9
    3台CentOS7系统,k8s-masterip172.31.0.140、k8s-node1ip172.31.0.141、k8s-node2ip172.31.0.142在3台主机的hosts文件里添加记录:172.31.0.140   cluster-endpoint配置yum源yuminstall-yyum-utilsyum-config-manager\--add-repo\http://mirrors.aliyun.com/docker-ce......