【theano-windows】学习笔记三——theano中的导数

前言

就一个NN而言,包含梯度、偏置、参数更新,而前面第一篇博客学习了theano中符号变量的定义, 第二篇博客学习了变量的随机初始化, 变量之间的互相操作(类似于sigmoid(wx+b)), 但是参数更新还应涉及到损失函数的偏导计算,这一章节就是看看theano的梯度计算函数`tensor.grad(). 此外还有雅可比式(一阶导),海森矩阵(二阶导),雅克比乘以向量,海森矩阵乘以向量的操作

梯度计算

目前感觉这个函数没什么需要注意的, 使用方法直接就是 T.grad(y,x), 意思就是y对x求导,而且我们还能用function.marker.fgraph.outputs[0]把得到的导数公式输出出来,先导入模块,没什么好说的

import theano
import theano.tensor as T
from theano import pp#用于输出表达式
  • y=x^2+x^3+x^4试水

    x=T.dscalar('x')#定义一个变量
    y=x**2+x**3+x**4#定义一个操作
    gy=T.grad(y,x)#将y对x求导
    f=theano.function([x],gy)# 执行这个求导函数
    pp(f.maker.fgraph.outputs[0])

    输出是

    Elemwise{Composite{((i0 * i1) + (i2 * sqr(i1)) + (i3 * Composite{(sqr(i0) * i0)}(i1)))}}(TensorConstant{2.0}, x, TensorConstant{3.0}, TensorConstant{4.0})

    然后怎么依据这个输出把导数表达式写出来呢?这里我们把i0,i1,i2,i3分别用2,x,3,4替换(TensorConstant{2.0}意思就是常数张量2.0,’sqr’代表平方),然后带入到前面的Composite{((i0 * i1) + (i2 * sqr(i1)) + (i3 * Composite{(sqr(i0) * i0)}(i1)))}中, 注意遇到Composite{xxx}(xxx), 就用()中的xxx去替换{}中的xxx,然后我来分析一波

    这里写图片描述

    这样就能得到一个结果2*x+3*x^2+4*(x^2)*x,刚好就是y=x2+x3+x4x的偏导结果

  • 同样的例子套入到对率函数中去

    y1=1/(1+T.exp(-x))
    gy1=T.grad(y1,x)
    f2=theano.function([x],gy1)# pp(gy1)pp(f2.maker.fgraph.outputs[0])

    输出是

    Elemwise{Composite{(scalar_sigmoid((-i0)) * scalar_sigmoid(i0))}}(x)

    按照上面的图画一下,然后可以写出来结果是sigmoid(-x)*sigmoid(x),其实也就是

    yyx=sigmoid(x)=11+ex=sigmoid(x)sigmoid(x)=11+ex11+ex=y(1y)

注意, T.grad()的第二个参数可以是一个列表,那么输出也就是列表了,意思应该就是损失函数可以对权重和偏置在一个函数中求导

计算雅克比矩阵

theano中雅克比就是计算一个函数的输出相对于每个输入的一阶偏导数。theano中有两种方法去实现

  • 间接(人工)方法
    由于这需要使用到循环(对每个输入都要计算偏导数), 因而提前接触到了theano中用于创建循环的函数scan(), 如果想提前了解scan(), 可以去看这位博主的五个例子掌握theano.scan函数

    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.]])
    ​```

    这里稍微说一下用到的scan内容:

    • 第一个参数默认就是定义的函数了,这里用了个lambda表达式lambda i,y,x : T.grad(y[i],x)意思是我们要计算这个梯度, 而这i,y,x的来源就是后面的几个参数,赋值顺序一般是sequences中的变量outputs_info的变量,non_sequences中的变量 , 这个顺序要记住
    • 参数sequences表示我们需要遍历的量,一般都是T.arange()创建的列表,把它丢给了i
    • 参数non_sequences是其他两个输入量[y,x],把它丢给了lambda函数中的y,x
    • 返回值J是输出变量列表,updates是字典,表示每个输出变量列表的更新规则
  • 直接方法
    theano中直接提供了一个函数来实现Jacobian矩阵的计算theano.gradient.jacobian(expression, wrt, consider_constant=None, disconnected_inputs='raise')

    
    #直接计算hessian矩阵x=T.dvector('x')
    y=T.dvector('y')
    input=[x,y]
    s=T.sum(x**2+y**2)
    f=theano.gradient.jacobian(expression=s,wrt=input)
    h=theano.function(input,f)
    x=[1,2]
    y=[1,2]
    h(x,y)
    '''
    [array([ 2.,  4.]), array([ 2.,  4.])]
    '''

    看样子计算的就是损失函数expression关于input中变量的偏导数

计算海森矩阵

普遍接受的关于海森矩阵的数学说法是: 它是具有标量输出和向量输入的二阶偏导函数的矩阵。同样有间接和直接两种计算方法

  • 间接(人工)计算方法
    与间接计算Jacobian矩阵不同的是我们不是计算某个表达式的雅克比式,而是计算关于导数T.grad(cost,x)的雅可比式

    
    #间接计算Hessian矩阵x=T.dvector('x')
    y=x**2
    cost=y.sum()
    gy=T.grad(cost,x)#先计算损失关于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.]])
    '''

    依旧是theano.scan()的应用, 第一个参数是计算梯度的函数, 后面的先把sequences的列表丢给i, 然后将non_sequence中的gy,x分别丢给lambda表达式中的gyx

  • 直接计算方法
    theano中直接提供了一个函数来实现Hessian矩阵的计算:theano.gradient.hessian(cost, wrt, consider_constant=None, disconnected_inputs='raise')

    x=T.dvector('x')
    y=T.dvector('y')
    input=[x,y]
    s=T.sum(x**2+y**2)
    f=theano.gradient.hessian(cost=s,wrt=input)
    h=theano.function(input,f)
    x=[1,2]
    y=[1,2]
    h(x,y)
    '''
    [array([[ 2.,  0.],[ 0.,  2.]]), array([[ 2.,  0.],[ 0.,  2.]])]
    '''

    看样子计算的就是损失函数cost关于input中变量的偏导数

雅可比式与向量乘积

R-操作(右乘)

计算目标

f(x)xv

其中 x可以是矩阵或者是张量,主要还是因为我们需要依据权重矩阵做一些表达式的计算

#雅可比式*向量
W=T.dmatrix('W')
V=T.dmatrix('V')
x=T.dvector('x')
y=T.dot(x,W)
JV=T.Rop(y,W,V)#这里直接调用的就是Rop函数对应右乘操作
f=theano.function([W,V,x],JV)
w=[[1, 1], [1, 1]]
v=[[2, 2], [2, 2]]
x=[0,1]
f(w,v,x)
'''
array([ 2.,  2.])
'''

这干了一件什么事情呢?数学表达式如下:

yyWV=Wx=xV

L-操作(左乘)

#向量*雅可比式
W = T.dmatrix('W')
V = T.dvector('V')
x = T.dvector('x')
y = T.dot(x, W)
VJ = T.Lop(y, W, V)#这里直接调用的就是Rop函数对应右乘操作
f = theano.function([V,x], VJ)
f([2, 2], [0, 1])
'''
array([[ 0.,  0.],[ 2.,  2.]])
'''

yVyW=Wx=Vx

左乘和右乘的差别

其实从矩阵的乘法规则就能发现他们的不同:

左乘中的v与输出有相同的shape, 右乘中的v与输入有相同的shape

左乘的结果与输入有相同shape, 右乘的结果与输出有相似的shape

海森矩阵与向量乘积

由于Hessian矩阵具有对成型, 所以有两种操作可以得到相同的结果,但是性能可能稍有不同。所以theano建议大家在使用两个方法时先分析一下

方法一:

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.])
'''

方法二:

x=T.dvector('x')
v=T.dvector('v')
y=T.sum(x**2)#定义操作
gy=T.grad(y,x)#一阶导
Hv=T.Rop(gy,x,v)#利用Jacobian矩阵的右乘操作
f=theano.function([x,v],Hv)
f([4,4],[2,2])
'''
array([ 4.,  4.])
'''

注意事项

  • grad函数是符号运算: 接受和返回Theano变量
  • grad可以被重复使用
  • grad操作中, 标量损失可以直接用grad处理, 但是数组类型的需要用循环处理,比如计算Jacobian矩阵中需要对向量中每个值进行梯度的循环计算
  • 内置函数能够高效计算向量*雅可比式、向量*海森矩阵

代码地址:链接: https://pan.baidu.com/s/1eSAIZOu 密码: wu27

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

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

相关文章

【theano-windows】学习笔记五——theano中张量部分函数

前言 至此感觉应该可以写出一个logistic回归程序了,但是为了达到对theano中张量的更灵活的使用, 还是先看一下thenao.tensor对变量都提供了哪些操作,最全的文档戳这里或者这里, 这里就稍微摘取一点自我感觉以后可能用得多的函数 基本张量函数 创建张量…

【theano-windows】学习笔记六——theano中的循环函数scan

前言 Scan是Theano中最基础的循环函数, 官方教程主要是通过大量的例子来说明用法. 不过在学习的时候我比较习惯先看看用途, 然后是参数说明, 最后再是研究实例. 国际惯例, 参考网址 官网关于Scan的11个例子 官网更全面的介绍 简介 用途 递归的一般形式, 可以被用于循环s…

【theano-windows】学习笔记九——softmax手写数字分类

前言 上一篇博客折腾了数据集的预备知识, 接下来按照官方的Deep learning 0.1 documentation一步步走, 先折腾softmax, 关于softmax和logistic回归分类的联系, 我在之前写过一个小博客 国际惯例, 参考博客走一波: Classifying MNIST digits using Logistic Regression soft…

【theano-windows】学习笔记十——多层感知机手写数字分类

前言 上一篇学习了softmax, 然后更进一步就是学习一下基本的多层感知机(MLP)了. 其实多层感知机同时就是w*xb用某个激活函数激活一下, 得到的结果作为下一层神经元的输入x, 类似于 output⋯f3(f2(f1(x∗w1b2)∗w2b2)∗w3b3)⋯output=\cdots f^3(f^2(f^1(x*w^1+b^2)*w^2+b^2)*…

【theano-windows】学习笔记十一——theano中与神经网络相关函数

前言 经过softmax和MLP的学习, 我们发现thenao.tensor中除了之前的博客【theano-windows】学习笔记五——theano中张量部分函数提到的张量的定义和基本运算外, 还有一个方法称为nnet, 如果自己实现过前面两篇博客中的代码就会发现用到了theano.tensor.nnet.sigmoid和thenao.te…

【caffe-windows】全卷积网络特征图分析

前言 突然就想分析一下全卷积网络的转置卷积部分了, 就是这么猝不及防的想法, 而且这个网络对图片的输入大小无要求,这么神奇的网络是时候分析一波了,我个人的学习方法调试代码,然后对照论文看理论 本次分析主要针对每层的权重大小和特征图…

【theano-windows】学习笔记十二——卷积神经网络

前言 按照进度, 学习theano中的卷积操作 国际惯例, 来一波参考网址 Convolutional Neural Networks (LeNet) 卷积神经网络如何应用在彩色图像上? 卷积小知识 三大特性:局部感知(稀疏连接), 权值共享, 池化 上图很重要, 描述的是前一个隐层m-1具有四…

【theano-windows】学习笔记十三——去噪自编码器

前言 上一章节学习了卷积的写法,主要注意的是其实现在theano.tensor.nnet和theano.sandbox.cuda.dnn中都有对应函数实现, 这一节就进入到无监督或者称为半监督的网络构建中. 首先是自编码器(Autoencoders)和降噪自编码器(denoising Autoencoders) 国际惯例, 参考网址: Denoi…

【theano-windows】学习笔记十四——堆叠去噪自编码器

前言 前面已经学习了softmax,多层感知器,CNN,AE,dAE,接下来可以仿照多层感知器的方法去堆叠自编码器 国际惯例,参考文献: Stacked Denoising Autoencoders (SdA) Greedy Layer-Wise Training of Deep Networks 理…

【theano-windows】学习笔记十五——受限玻尔兹曼机

前言 终于到了最喜欢的模型: 受限玻尔兹曼机(RBM)了, 发现关于RBM是如何从能量模型发展过来的介绍非常不错, 而关于详细理论证明, 可以去看我前面的受限玻尔兹曼机的一系列博客. 国际惯例, 参考博客,超级强推第二个博客, 证明过程很给力: Restricted Boltzmann Machines (R…

【Ogre-windows】环境配置

前言 由于工程原因, 学习一下Ogre面向对象图形渲染开源引擎, 慢慢爬坑吧。首先还是环境的配置问题哎. 其实最重要的是要预先编译三方库, 虽然官方说可以自动编译, 但是在自己电脑上还是出现了无法解析外部符号之类的问题, 正常情况下我就认为是三方库的lib出现了问题, 最后额外…

【theano-windows】学习笔记十六——深度信念网络DBN

前言 前面学习了受限玻尔兹曼机(RBM)的理论和搭建方法, 如果稍微了解过的人, 肯定知道利用RBM可以堆叠构成深度信念网络(deep belief network, DBN)和深度玻尔兹曼机(deep Boltzmann machine), 这里就先学习一下DBN. 国际惯例, 参考博文: Deep Belief Networks A fast lear…

【Ogre-windows】实例配置

前言 折腾了好久才搞定教程实例, 主要是因为上一篇博客安装的具体版本是Ogre1.10.9, 而官方的Ogre Wiki Tutorial Framework没有指定具体版本, 如果单纯下载Ogre Wiki Tutorial Framework 1.10 - (Windows line endings, updated 2015-10-15) 运行, 基本会血崩. 所以, 在经过仔…

【Ogre-windows】旋转矩阵及位置解析

前言 这篇博客主要针对三种问题 如何创建动画帧如何获取全局位置如何计算全局旋转矩阵 仿真环境为VS2013Ogre1.10.9与matlab验证 创建动画帧 这里只做一个简单的实验: 将自带的人物模型Jaiqua的run运动给新创建的运动myrun中并播放,直接贴代码了 void JaiQua:…

BP推导——续

前言 之前有证明过一次人工神经网络——【BP】反向传播算法证明 ,但是回头看的时候,有很多地方非常不严谨,特此拿出来再单独证明一次BP,并严格保证其严谨性。如果想看看粗略的证明,可以去看我之前的博客,毕…

matlab学习——强连通分量

前言 最近motion graph相关实验,发现实现运动过渡需要构建运动图,而为了避免运动过渡陷入死胡同,需要对图结构进行裁剪,方法就是计算图模型的极大强联通分量,但是自己懒得去实现,所以就去搜了一下matlab中…

【音频处理】离散傅里叶变换

前言 最近复现音乐驱动舞蹈的文章《Dancing-to-Music Character Animation》,用到了与傅里叶变换很相似的称为常Q变换的方法去分割音乐,所以对傅里叶变换做了一个小了解,本文不深入各种乱糟糟的理论,比如什么蝶形算法啥的&#x…

【音频处理】短时傅里叶变换

前言 上一篇博客讲了离散傅里叶变换,里面的实例是对整个信号进行计算,虽然理论上有N点傅里叶变换(本博客就不区分FFT和DFT了,因为它俩就是一个东东,只不过复杂度不同),但是我个人理解是这个N点是信号前面连续的N个数值…

【theano-windows】学习笔记十九——循环神经网络

前言 前面已经介绍了RBM和CNN了,就剩最后一个RNN了,抽了一天时间简单看了一下原理,但是没细推RNN的参数更新算法BPTT,全名是Backpropagation Through Time。 【注】严谨来说RNN有两个称呼:①结构上递归的recursive n…

【theano-windows】学习笔记二十——LSTM理论及实现

前言 上一篇学习了RNN,也知道了在沿着时间线对上下文权重求梯度的时候,可能会导致梯度消失或者梯度爆炸,然后我们就得学习一波比较常见的优化方法之LSTM 国际惯例,参考网址: LSTM Networks for Sentiment Analysis …