您的位置:首页 > 其它

深度学习算法实践4---Theano常用技巧

2016-09-21 14:28 405 查看
在上一篇文章中介绍了神经网感知器模型中用到的一些算法,在这篇文章中,将继续介绍这些常用的算法,首先是随机数的生成,因为感知器模型必须用随机数来初始化连接权值,其次是求导数,因为感知器学习算法是,会用到梯度下降算法,涉及到求导问题。

在讨论随机数生成算法之前,我们先来讨论一下共享变量,这很像C语言中的静态变量,假设我们要对网站的内容的热度进行统计分析,我们用hottness来表示热度,用visitWeight来表示访问的权重,每次用户访问该内容时,该内容对应的hottness就增加visitWeight,使用Theano可以用下面的代码来实现:

[python] view
plain copy

 





import theano  

import theano.tensor as T  

from theano import function  

from theano import shared  

  

hottness = shared(0)  

visitWeight = T.iscalar("visitWeight")  

calculateHottness = function([visitWeight], hottness, updates=[(hottness, hottness + visitWeight)])  

minusValue = T.iscalar("minusValue")  

decreaseHottness = function([minusValue], hottness, updates=[(hottness, hottness - minusValue)])  

  

  

visitWeight1 = 5  

calculateHottness(visitWeight1)  

print("hottness=%d" % hottness.get_value())  

visitWeight2 = 10  

calculateHottness(visitWeight2)  

print("hottness=%d" % hottness.get_value())  

minusValue1 = 3  

decreaseHottness(minusValue1)  

print("hottness=%d" % hottness.get_value())  

  

hottness.set_value(0)  

print("hottness=%d" % hottness.get_value())  

运行上面的代码,可以得到5和15两个值,表明我们的共享变量是起作用的。如果我们想重复热度值时,如一个统计周期结束时,只需调用hottness.set_value(0)即可实现,同时,如果我们系统踩的功能,假设每获得一个踩,热度降低一定值,我们可以定义一个新的decreaseHottness函数,两个函数可以共享同一个hottness变量。

假设有一些内容,我们采用了用户打分系统,分为1~5分,用户每次评分,在热度加上用户的评分值,为重用上述逻辑,只需要将用到hottness的地方,换成一个新的变量例如score就可以了,代码如下所示:

[python] view
plain copy

 





newHottness = hottness + visitWeight  

score = T.scalar(dtype=hottness.dtype)  

calculateScore = function([visitWeight, score], newHottness, givens=[(hottness, score)])  

print("score=%d; hottness=%d!" % (calculateScore(5, 100), hottness.get_value()))  

上面可以正确地计算出score的值为105,而hottness的仍为原来的值不变。

显然,如果我们要统计某个项目用户打分的总分情况,更好的方法是利用Theano的函数拷贝机制,将hottness替换为新的rateScores,而此时visitWeight就对应于用户的评分值,下面代码将实现这一目的:

[python] view
plain copy

 





rateScores = shared(0)  

calculateRateScores = calculateHottness.copy(swap={hottness: rateScores})  

calculateRateScores(5)  

print("rateScores=%d" % rateScores.get_value())  

下面来看一下在Theano中随机数的使用问题。由于Theano是先用符号化的东西来进行表达式定义,之后系统编译这些表达式为函数,最后你再调用这些函数来执行相应的功能,所以在Theano中使用随机数,是一个相对复杂的过程。对于这个问题,Theano采用RandomStream来进行解决,也就是在需要随机数的地方,定义一个RandomStream,然后在实际运行过程中,当需要随机数参与运算时,从RandomStream中读出随机数。

随机数在神经网络中,主要用于权值中,因此我们会初始化一个权值矩阵,在Theano中,我们可以使用uniform分布来获得这些在0~1的随机权值,代码如下所示:

[python] view
plain copy

 





from theano.tensor.shared_randomstreams import RandomStreams  

from theano import function  

  

randStrm = RandomStreams(seed=299)  

uniformValue = randStrm.uniform((2, 2))  

normalValue = randStrm.normal((2, 2))  

getUniformValue = function([], uniformValue)  

getNormalValue = function([], normalValue, no_default_updates=True)  

getRandomNumber = function([], uniformValue + uniformValue - 2 * uniformValue)  

  

print(getUniformValue())  

print(getNormalValue())  

print(getRandomNumber())  

上面代码会生成2*2的随机权值矩阵,上述代码还可以用来获得normal分布的随机数权值矩阵,而且我们通过使用no_default_updates=True,使我们每次获得的随机数是相等的,最后一个函数是获得接近于零的随机数。

需要注意的是,上述代码只能在CPU上运行,如果想让代码在CPU和GPU上均可运行,则只需将上面代码的第一句修改为:from theano.sandbox.rng_mrg import MRG_RandomStreams as RandomStreams即可。

在Theano中,函数的缺省参数的处理也不同于python的标准方法。代码如下所示:

[python] view
plain copy

 





from theano import In  

from theano import function  

from theano import tensor as T  

  

x, y = T.dscalars("x", "y")  

z = x + y  

add = function([x, In(y, value=100)], z)  

  

print("add=%d" % add(20))  

如上代码所示,采用In语法,可以定义y的缺省值为100。需要注意的是,与python标准语法相同,具有缺省值的参数,需要放在没有缺省值的参数后面。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: