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

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

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

[python]  view plain  copy
 
  1. import theano  
  2. import theano.tensor as T  
  3. from theano import function  
  4. from theano import shared  
  5.   
  6. hottness = shared(0)  
  7. visitWeight = T.iscalar("visitWeight")  
  8. calculateHottness = function([visitWeight], hottness, updates=[(hottness, hottness + visitWeight)])  
  9. minusValue = T.iscalar("minusValue")  
  10. decreaseHottness = function([minusValue], hottness, updates=[(hottness, hottness - minusValue)])  
  11.   
  12.   
  13. visitWeight1 = 5  
  14. calculateHottness(visitWeight1)  
  15. print("hottness=%d" % hottness.get_value())  
  16. visitWeight2 = 10  
  17. calculateHottness(visitWeight2)  
  18. print("hottness=%d" % hottness.get_value())  
  19. minusValue1 = 3  
  20. decreaseHottness(minusValue1)  
  21. print("hottness=%d" % hottness.get_value())  
  22.   
  23. hottness.set_value(0)  
  24. print("hottness=%d" % hottness.get_value())  

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

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

[python]  view plain  copy
 
  1. newHottness = hottness + visitWeight  
  2. score = T.scalar(dtype=hottness.dtype)  
  3. calculateScore = function([visitWeight, score], newHottness, givens=[(hottness, score)])  
  4. print("score=%d; hottness=%d!" % (calculateScore(5100), hottness.get_value()))  
上面可以正确地计算出score的值为105,而hottness的仍为原来的值不变。

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

[python]  view plain  copy
 
  1. rateScores = shared(0)  
  2. calculateRateScores = calculateHottness.copy(swap={hottness: rateScores})  
  3. calculateRateScores(5)  
  4. print("rateScores=%d" % rateScores.get_value())  
下面来看一下在Theano中随机数的使用问题。由于Theano是先用符号化的东西来进行表达式定义,之后系统编译这些表达式为函数,最后你再调用这些函数来执行相应的功能,所以在Theano中使用随机数,是一个相对复杂的过程。对于这个问题,Theano采用RandomStream来进行解决,也就是在需要随机数的地方,定义一个RandomStream,然后在实际运行过程中,当需要随机数参与运算时,从RandomStream中读出随机数。

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

[python]  view plain  copy
 
  1. from theano.tensor.shared_randomstreams import RandomStreams  
  2. from theano import function  
  3.   
  4. randStrm = RandomStreams(seed=299)  
  5. uniformValue = randStrm.uniform((22))  
  6. normalValue = randStrm.normal((22))  
  7. getUniformValue = function([], uniformValue)  
  8. getNormalValue = function([], normalValue, no_default_updates=True)  
  9. getRandomNumber = function([], uniformValue + uniformValue - 2 * uniformValue)  
  10.   
  11. print(getUniformValue())  
  12. print(getNormalValue())  
  13. 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
 
  1. from theano import In  
  2. from theano import function  
  3. from theano import tensor as T  
  4.   
  5. x, y = T.dscalars("x""y")  
  6. z = x + y  
  7. add = function([x, In(y, value=100)], z)  
  8.   
  9. print("add=%d" % add(20))  
如上代码所示,采用In语法,可以定义y的缺省值为100。需要注意的是,与python标准语法相同,具有缺省值的参数,需要放在没有缺省值的参数后面。

你可能感兴趣的:(深度学习)