Theano 更多示例
Logistic函数


logistic函数的图,其中x在x轴上,s(x)在y轴上。
如果你想对双精度矩阵上的每个元素计算这个函数,这表示你想将这个函数应用到矩阵的每个元素上。
嗯,你是这样做的:
x=T.dmatrix('x')
s=1/(1+T.exp(-x))
logistic=theano.function([x],s)
print logistic([[1,2],[3,4]])
[[ 0.73105858 0.88079708]
[ 0.95257413 0.98201379]]
在每个元素上执行logistic的原因是因为它的所有运算 —— 除法、加法、幂和除法 —— 本身是单个元素的操作。
同时计算多个值
Theano支持多输出功能。例如,我们可以同时计算两个矩阵a和b之间每个元素的差、差的绝对值和平方差:
a,b=T.dmatrices('a','b')
diff=a-b
abs_diff=abs(a-b)
squared_diff=diff**2
f=theano.function([a,b],[diff,abs_diff,squared_diff])
注意:
dmatrices产生与你提供的名称一样多的输出。它是分配符号变量的一个快捷方式,我们将在教程中经常使用它。
当我们使用函数f,它返回三个变量。
print f([[1,1],[1,2]],[[1,1],[1,1]]) [array([[ 0., 0.],
[ 0., 1.]]), array([[ 0., 0.],
[ 0., 1.]]), array([[ 0., 0.],
[ 0., 1.]])]
为参数设置默认值
x,y=T.dscalars('x','y')
z=x+y
f=function([x,In(y,value=2)],z)
print f(2)
4.0
这里使用In类,它允许你更详细地指定你的函数的参数的属性。这里,通过创建value字段设置为1的In实例,为y赋予默认值1。
具有默认值的输入必须遵循没有默认值的输入(类似Python的函数)。可以有多个具有默认值的输入。这些参数可以按位置或名称设置,和在标准Python中一样:
x,y,w=T.dscalars('x','y','w')
z=(x+y)*w
f=function([x,In(y,value=1),In(w,value=2,name='w_by_name')],z)
print f(1)
print f(1,2)
print f(1,1,1)
print f(1,w_by_name=1,y=0)
print f(1,w_by_name=1)
4.0
6.0
2.0
1.0
2.0
In不知道作为参数传递的局部变量y和w的名称。符号变量对象具有名称属性(在上面的示例中由dscalars设置)和它们是我们构建的函数中的关键字参数的名称。这是In(y, value = 1)中工作的机制。在In(w, value=2, name='w_by_name')的情况下。我们用一个这个函数使用的名称来覆盖符号变量的name属性。
使用共享变量
还可以利用内部状态生成一个函数。例如,假设我们想要一个累加器:在开始,状态被初始化为零。然后,在每次函数调用时,状态通过函数的参数增加。
首先我们定义累加器函数。它将其参数添加到内部状态,并返回旧的状态值。
这段代码引入了一些新的概念。shared函数构造所谓的共享变量。它们是符号变量和非符号变量的混合,其值可以在多个函数之间共享。共享变量就像dmatrices(...)返回的对象一样可以在符号表达式中使用,但它们还有一个内部值,定义在所有使用这个符号变量的函数中的值。它被称为共享变量,因为它的值在许多函数之间共享。该值可以通过.get_value()和.set_value()方法访问和修改。
from theano import shared
state=shared(0)
inc=T.iscalar('inc')
accumulator=function([inc],state,updates=[(state,state+inc)])
该代码中的另一个新东西是function的updates参数。updates必须提供形式为(共享变量,新表达式)对的一个列表。它也可以是一个字典,其键是共享变量,值是新的表达式。无论哪种方式,它意味着“每当这个函数运行时,它将用相应表达式的结果替换每个共享变量的.value”。上面,我们的累加器用状态和增量总和取代state的值。
print state.get_value()
accumulator(1)
print state.get_value()
accumulator(200)
print state.get_value() 0
1
201
可以重置状态。只需使用.set_value()方法:
state.set_value(-1)
accumulator(2)
print state.get_value() 1
如上所述,你可以定义多个函数来使用相同的共享变量。这些函数都可以更新该值。
decrementor=function([inc],state,updates=[(state,state-inc)])
decrementor(2)
print state.get_value() -1
你可能想知道为什么存在更新机制。你总是可以通过返回新的表达式,并在NumPy中照常使用它们来实现类似的结果。更新机制可以是语法方便,但是它主要是为了效率。有时可以使用就地算法(例如低秩矩阵更新)更快地完成对共享变量的更新。此外,Theano对分配变量的位置和方式有更多的控制,这是在GPU上获得良好性能的重要因素之一。
可能会发生这种情况,你使用共享变量表达了某个公式,但你不想使用它的值。在这种情况下,你可以使用function的givens参数为一个特定函数替换图中的特定节点。
state=shared(0)
inc=T.iscalar('inc')
fn_of_state=state*2+inc
#foo 必须和被替换的shared变量有相同的类型
foo=T.scalar(dtype=state.dtype)
skip_shared=function([inc,foo],fn_of_state,givens=[(state,foo)])
print skip_shared(1,3)#我们使用了3作为state,而不是0
print state.get_value()#old state值不变 7
givens参数可用于替换任何符号变量,而不仅仅是共享变量。一般情况下,你可以替换常量和表达式。但要小心,不要让givens替换引入的表达式是共同依赖的,替换的顺序没有定义,所以替换必须以任何顺序工作。
在实践中,考虑givens的一个好方法是允许你用一个不同的表达式替换你的公式的任何部分,这个表达式的计算结果是一个相同形状和dtype的张量。
注意
Theano共享变量broadcast模式对于每个维度默认为False。共享变量大小可以随时间改变,所以我们不能使用形状来找到broadcastable的模式。如果你想要一个不同的模式,只要将它作为参数传递theano.shared(..., broadcastable=(True, False))
复制函数
Theano函数可以被复制,这对于创建类似的函数,但是使用不同的共享变量或更新是有用的。这是使用function对象的copy()方法完成的。复制的是原始函数的优化图,因此编译只需要执行一次。
让我们从上面定义的累加器开始:
state=shared(0)
inc=T.iscalar('inc')
accumulator=theano.function([inc],state,updates=[(state,state+inc)])
我们可以使用它像往常一样增加状态。
我们可以使用copy()创建一个类似的累加器,但使用自己的内部状态使用swap参数,它是一个要交换的共享变量的字典:
new_state=shared(0)
new_accumulator=accumulator.copy(swap={state:new_state})
new_accumulator(100)
print new_state.get_value() 100
第一个函数的状态保持不变:
print state.get_value() 0
我们现在使用delete_updates参数创建一个删除更新的副本,默认情况下,该参数设置为False:
null_accumulator=accumulator.copy(delete_updates=True)
null_accumulator(100)
print state.get_value()
如预期,共享状态不再更新。
使用随机数
因为在Theano中你首先将一切用符号表示并在之后编译这个表达式以获得函数,所以使用伪随机数字不是像在NumPy中那么直接,虽然也不太复杂。
将随机性放到Theano的计算中的考虑方式是将随机变量放在你的图中。Theano将为每个这样的变量分配一个NumPy RandomStream对象(一个随机数生成器),并根据需要绘制它。我们将这种随机数序列称为随机流。随机流的核心是它们的共享变量,因此在这里也可以对共享变量进行观察。Theanos的随机对象在RandomStreams中定义和实现,底层在RandomStreamBase中定义和实现。
简要示例
from theano.tensor.shared_randomstreams import RandomStreams
srng=RandomStreams(seed=234)
rv_u=srng.uniform((2,2))
rv_n=srng.uniform((2,2))
f=function([],rv_u)
g=function([],rv_n,no_default_updates=True)
print f()
print f()
print g()
print g() [[ 0.12672381 0.97091597]
[ 0.13989098 0.88754825]]
[[ 0.31971415 0.47584377]
[ 0.24129163 0.42046081]]
[[ 0.12309219 0.71399385]
[ 0.14249561 0.36686867]]
[[ 0.12309219 0.71399385]
[ 0.14249561 0.36686867]]
这里,’rv_u’表示来自均匀分布的2×2矩阵的随机流。同样,’rv_n’表示来自正态分布的2×2矩阵的随机流。分布的实现在RandomStreams中定义,底层在raw_random中定义。它们只在CPU上工作。
现在让我们使用这些对象。随机数发生器的内部状态是自动更新的,所以我们每次都得到不同的随机数。
当我们向function添加额外参数no_default_updates=True(如在g中)时,随机数生成器状态不受调用返回函数影响。因此,例如,多次调用g将返回相同的数字。
一个重要的提醒是,在函数的每次执行期间最多绘制一个随机变量。因此,即使rv_u随机变量在输出表达式中出现三次,almost_zeros函数保证返回大约为0(舍入误差除外)。
种子流
随机变量可以使用单独的种子或使用共同的种子。
你可以使用.rng.set_value(),通过播种或分配.rng属性来播种一个随机变量。
rng_val=rv_u.rng.get_value(borrow=True)
rng_val.seed(89234)
rv_u.rng.set_value(rng_val,borrow=True)
你也可以通过RandomStreams对象的seed方法对该对象分配的全部随机变量设置种子。该种子将用于设置临时随机数发生器的种子,这个零时随机数发生器随后将为每个随机变量生成种子。
srng.seed(89234)
函数之间共享流
与通常的共享变量一样,用于随机变量的随机数发生器在函数之间是共同的。因此,我们的nearly_zeros函数将更新函数f中使用的生成器的状态。
在Theano图之间复制随机状态
在一些使用情况下,用户可能想要将与给定的theano图(例如,具有下面的编译函数f1的g1)相关联的所有随机数发生器的“状态”转移到第二个图形(例如具有函数f2的g2)。这中情况例如,如果你试图从之前的一个序列化的模型的参数初始化模型的状态。对于和,可以通过复制state_updates参数的元素来实现。
每当从RandomStreams对象中绘制随机变量时,就会将元组添加到state_updates列表中。第一个元素是一个共享变量,它表示与此特定变量相关联的随机数生成器的状态,而第二个元素表示与随机数生成过程对应的theano图(即RandomFunction {uniform} .0)。
下面示出了如何将“随机状态”从一个theano函数传递到另一个函数的示例。
from theano.tensor.shared_randomstreams import RandomStreams
from theano.sandbox.rng_mrg import MRG_RandomStreams
class Graph():
def __init__(self,seed=123):
self.rng=RandomStreams(seed)
self.y=self.rng.uniform(size=(1,))
def copy_random_state(g1,g2):
if isinstance(g1.rng,MRG_RandomStreams):
g2.rng.rstate=g1.rng.rstate
for(su1,su2) in zip(g1.rng.state_updates,g2.rng.state_updates):
su2[0].set_value(su1[0].get_value())
g1=Graph(seed=123)
f1=theano.function([],g1.y) g2=Graph(seed=987)
f2=theano.function([],g2.y) #by default,两个函数不是同步的
print f1()
print f2() #现在复制theano随机数生成器的状态
copy_random_state(g1,g2)
print f1()
print f2() [ 0.72803009]
[ 0.55056769]
[ 0.59044123]
[ 0.59044123]
Theano 更多示例的更多相关文章
- vue mpvue 上拉加载更多示例代码
vue 上拉加载更多示例代码 可以比较简单的改为 mpvue , 去除滚动判断,直接放在 onReachBottom 周期即可. html <div id="app"> ...
- Theano at a Glance
Theano一览 Theano是一个Python库,它允许你定义.优化和求值数学表达式,特别是具有多维数组(numpy.ndarray)的数学表达式.对于涉及大量数据的问题,使用Theano可以获得与 ...
- [DeviceOne开发]-手势动画示例分享
一.简介 这是iOS下的效果,android下完全一致.通过do_GestureView组件和do_Animation组件,deviceone能很容易实现复杂的跨平台纯原生动画效果,这个示例就是通过手 ...
- Tyrion中文文档(含示例源码)
Tyrion是一个基于Python实现的支持多个WEB框架的Form表单验证组件,其完美的支持Tornado.Django.Flask.Bottle Web框架.Tyrion主要有两大重要动能: 表单 ...
- [deviceone开发]-do_GridView的简单示例
一.简介 do_GridView的高度支持-1,根据gridview里item的个数来决定gridview的高度,这样gridview自身就无法滚动了,需要放到固定高度的scrollview里才能滚动 ...
- [deviceone开发]-HeaderView和FooterView的示例
一.简介 这个是利用do_ListView组件实现下拉和上拉刷新功能的例子,除了do_ListView,其它比如do_Webview,do_ScrollView都有这个个功能.对应的BBS里的帖子详细 ...
- [DeviceOne开发]-白板的示例
一.简介 该demo通过do_Painterview这个组件实现画板的基本功能,模仿的是Appstore上的叫“白板”的应用,可以更改字体颜色,字体粗细,然后用手指进行绘制,可以回退,清屏,保存到相册 ...
- MvcPager 概述 MvcPager 分页示例 — 标准Ajax分页 对SEO进行优化的ajax分页 (支持asp.net mvc)
该示例演示如何使用MvcPager最基本的Ajax分页模式. 使用AjaxHelper的Pager扩展方法来实现Ajax分页,使用Ajax分页模式时,必须至少指定MvcAjaxOptions的Upda ...
- ListView下拉刷新、上拉载入更多之封装改进
在Android中ListView下拉刷新.上拉载入更多示例一文中,Maxwin兄给出的控件比较强大,前面有详细介绍,但是有个不足就是,里面使用了一些资源文件,包括图片,String,layout,这 ...
随机推荐
- [转载]制作QT字库文件
原文地址:http://www.cnblogs.com/liu_xf/archive/2011/07/05/2098144.htm 摘要: QT4.7.0在移植到开发板上的时候,中文支持是必不可少的, ...
- 如何在sprintf函数中输出百分号(%)等特殊符号
php中的sprinf可以格式化字符串的数据类型.今天遇到了想在其中输出%,可难倒我了. $query = sprintf("select * from books where %s li ...
- 有Bug?你的代码神兽选对了吗
传说每一个优秀的程序员都有自己专属的镇码神兽 通过 工具网址 http://www.makepic.net/Tool/Image2ascii.html 将自己喜欢的神兽图片转成文本, 可以选择不同的分 ...
- spark java api数据分析实战
1 spark关键包 <!--spark--> <dependency> <groupId>fakepath</groupId> <artifac ...
- Feeling after reading《Jane Eyre》
Yesterday I read and listened over the book named <Jane Eyre>, the book is very thoughtful, th ...
- CSPS模拟99
555我原型笔录 T1 不会线段树维护单调栈被dalao们踩爆 T2 我要实现这样一个东西: 已知a,b,c,使a=a-b,b=b-c 结果我把代码弄成这样: b=b-c;a=a-b; 然后就被dal ...
- 智和网管平台SugarNMS助力网络安全运维等保2.0建设
智和信通智和网管平台SugarNMS结合<信息安全技术 网络安全等级保护基本要求>(GB/T 22239-2019)等国家标准文件以及用户提出的网络安全管理需求进行产品设计,推出“监控+展 ...
- js的ajax请求
1 js原生get请求 <script> window.onload = function(){ var oBtn = document.getElementById('btn'); oB ...
- MongoDB自学------(1)MongoDB4.0安装
一.环境 操作系统 安装包 安装方式 Ubuntu18.04 mongodb4.0 apt安装 Ubuntu18.04 mongodb4.0 docker安装 二.apt安装 sudo apt-key ...
- Python调用函数加括号和不加括号的区别
Python调用函数加括号和不加括号的区别 # -*- coding: utf-8 -*- #!/usr/bin/env python # @Time : 2018/7/3 10:03 # @Desc ...