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支持多输出功能。例如,我们可以同时计算两个矩阵ab之间每个元素的差、差的绝对值和平方差:

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不知道作为参数传递的局部变量yw的名称。符号变量对象具有名称属性(在上面的示例中由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)])

该代码中的另一个新东西是functionupdates参数。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上获得良好性能的重要因素之一。

可能会发生这种情况,你使用共享变量表达了某个公式,但你不想使用它的值。在这种情况下,你可以使用functiongivens参数为一个特定函数替换图中的特定节点。

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
0

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.rstatefor(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]

 

转载于:https://www.cnblogs.com/qniguoym/p/7662459.html

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

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

相关文章

SensorKernel层框架分析

接上文安卓9.0Sensor框架前言前面我们已经讲解了sensor框架中的framework到vendor层,这篇文章我们将会讲解kernel层的内容。不过不同的芯片平台,kernel层中的sensor框架是不同的,这里针对的是mt8167s平台。不过这里提醒一下,MTK平…

【习题 5-8 UVA - 230】Borrowers

【链接】 我是链接,点我呀:) 【题意】 在这里输入题意 【题解】 用mapset写个模拟就好。 3个区域 书架、桌子、别人的手上。 其中前两个区域的书都能借出去。 【代码】 #include <bits/stdc.h> using namespace std;set <pair<string, string> > mset1,mse…

java requestparams_java – 如何验证@RequestParams不为空?

我有一个计算器服务,从用户获取操作类型num1和num2.我需要验证用户是否实际输入了这些值,而不是将其留空.RequestMapping(value "/calculate")ResponseBodypublic CalculationResult calculate(RequestParam(name "op") String operation, RequestParam(…

Linux内核LED子系统、请务必看

前言LED子系统你要是说很难嘛&#xff0c;但是它就是控制一些简单的GPIO口&#xff0c;但是你要是说它很简单嘛&#xff0c;但是我也不见得一个初学者很快就能掌握&#xff0c;你如果是刚入门这部分的话&#xff0c;我觉得你还是要去仔细研究下这些驱动。前两天在网上看到一句话…

UVALive 4394 String painter

题目大意&#xff1a;有两个字符串A,B&#xff0c;一次刷可以把A串一段刷成同一个字母&#xff0c;问至少要刷几次才能把A串变成B串。串长≤100。 本来以为是个很简单的区间DP&#xff0c;后来发现直接区间DP是不行的&#xff0c;这玩意有后效性&#xff1a;刷完一整块之后这一…

centos 6.5 安装 lamp 后mysql不能启动_CentOS 6.5 系统 LAMP(Apache+MySQL+PHP)安装步骤

先来解释一下&#xff0c;什么是 LAMP。正如标题所言&#xff0c;LAMP 实际上就是 Linux、Apache、MySQL、PHP 四个名称的缩写&#xff0c;当然最后一个 “P” 还有其他说法是 Perl 或者 Python。不用多说了&#xff0c;本文讲解的就是 Linux、Apache、MySQL、PHP 这四个东西&a…

Redis连接实例

ECS Windows服务器 如果您本地需要通过公网访问 云数据库 Redis&#xff0c;可以在 ECS Windows 云服务器中通过 netsh 进行端口映射实现。 1. 登录 ECS Windows 服务器&#xff0c;在 CMD 执行以下命令。&#xff08;公网地址与 连接地址 请替换 为您的实际地址。&#xff09;…

什么是高内聚,低耦合?

高内聚&#xff0c;低耦合是一个老生常谈的话题&#xff0c;所以拿出来说一下我们在看Linux的一些资料&#xff0c;或者是在面试&#xff0c;又或者跟一个比较牛的大佬讨论技术的时候&#xff0c;可能会听到这个概念。所以&#xff0c;什么是高内聚&#xff0c;低耦合呢&#x…

java 8 兼容_甲骨文限制 Java 9 到 Java 8 的向后兼容性

在开发者们正兴奋着准备把 Java 8 工具包转向 Java 9 的时候&#xff0c;甲骨文的首席执行官提出了要限制两个版本的兼容性。在周一下午 OpenJDK 的邮件列表中的一封邮件中&#xff0c;甲骨文的 Java 平台的首席架构师 Mark Reinhold 指出会对 JDK8 增加更多变化(大概在 2014 年…

Web API 2 入门——创建ASP.NET Web API的帮助页面(谷歌翻译)

在这篇文章中 创建API帮助页面将帮助页面添加到现有项目添加API文档在敞篷下下一步作者&#xff1a;Mike Wasson 创建Web API时&#xff0c;创建帮助页面通常很有用&#xff0c;以便其他开发人员知道如何调用API。您可以手动创建所有文档&#xff0c;但最好尽可能自动生成。 为…

Linux fork的写时复制

这个问题是一个同学在知识星球里面提问的看下面的代码#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/wait.h> #includ…

从单片机工程师的角度看嵌入式Linux

前言 这篇文章简单我们来一起梳理嵌入式Linux的一些知识&#xff0c;方便于一些想跟我一样想要由单片机进阶到嵌入式Linux的朋友做一些参考学习。现在随着嵌入式Linux的教程不断增多&#xff0c;相信应该有不少学单片机的朋友开始折腾这个了吧~嵌入式Linux学哪些东西 1、认识Li…

Java低级编程软件_JAVA语言说低级语言吗

高级语言&#xff1a;C、C、Java、Python、Pascal、Lisp、Prolog、FoxPro、易语言等都是高级语言&#xff0c;相对于低级语言来说&#xff0c;高级语言采用易于识别和记忆的字符来作为关键字&#xff0c;也更接近人类的思维方式&#xff0c;编写容易读写性好&#xff0c;开发效…

智能硬件开发神器免费送!距离产品智能化,只差一个“三明治”的距离

重磅资料包免费领取 针对人群&#xff1a;如果您对“人工智能物联网”感兴趣&#xff0c;尤其是您的企业想做产品/行业智能化&#xff0c;一定不能错过这份“物联网人必备的终极大礼包”哦&#xff5e;这几类行业玩家必看&#xff01;&#xff01;&#xff01;制造商、方案商、…

Java类的继承关键字_Java的第八天(类的继承、super关键字的使用、方法的重写)...

39.类的继承java描述类的时候&#xff0c;咱们若是发现有几个类有重复的属性和方法&#xff0c;咱们就能够采用继承的方法来设计ide使用extends关键字来继承this语法&#xff1a;设计class 子类 extends 父类{对象子类属性继承子类方法内存}资源特色&#xff1a;(1)子类会把父类…

你们班上的同学现在都怎么样了?

今天跟朋友聊天&#xff0c;聊到这个话题&#xff0c;觉的有点意思&#xff0c;所以想拿出来讨论一下。小学小学的时候&#xff0c;我们读书最厉害的应该是我们班上几个老师的孩子&#xff0c;他们像是得到了老师的武功秘籍&#xff0c;读书对他们来说就是家常便饭&#xff0c;…

java socket oc_Java Socket编程(三) 服务器Sockets

文章来源&#xff1a;aspcn 作者&#xff1a;孙雯服务器Sockets列表9.2是一个服务器应用程序的一部分.列表9.2 一个简单的服务器程序/*** 一个监听端口并提供HTML文档的程序.*/class SimpleWebServer {public static void main(String args[]){ServerSocket serverSocket null…

浅析bootstrap原理及优缺点

网格系统的实现原理&#xff0c;是通过定义容器大小&#xff0c;平分12份(也有平分成24份或32份&#xff0c;但12份是最常见的)&#xff0c;再调整内外边距&#xff0c;最后结合媒体查询&#xff0c;就制作出了强大的响应式网格系统网格系统的实现原理&#xff0c;是通过定义容…

如何把一个float存到一个长度为4的char数组中?

我以前以为它是可以这样的看代码#include "stdio.h"int main(void) {float fa 123.56;char farray[4] {0};farray[0] ((int)fa>> 24)&0xFF;farray[1] ((int)fa>> 16)&0xFF;farray[2] ((int)fa>> 8 )&0xFF;farray[3] ((int)fa>…

OSPF次末节区域配置 201

【实验拓扑】 【实验基本配置】1、按照上图配置相应接口以及OSPF【实验要求】 1、配置Area 1 为NSSA区域2、在R6上配置1条静态路由160.1.60.0/24指向 Null0&#xff0c;并充分发到OSPF中3、将路由器1的ID修改为150.1.100.100【实验分析】次末节区域&#xff08;NSSA&#xff09…