第二节,基础知识之更多的例子


先声明:theano模块的内容大都是参考来源于网上,并亲手实践复现一遍,也有部分内容是自己补充


本文会列出所参考文章,如有版权问题,请联系我,我会及时删除

# -*- coding: utf-8 -*-
"""
Created on Fri Mar 23 16:53:19 2018

@author: zy
"""

‘‘‘
Theano2.1.3-基础知识之更多的例子
http://www.cnblogs.com/shouhuxianjian/p/4594517.html
‘‘‘

import theano.tensor as T
import theano

‘‘‘
现在,是时候开始系统的熟悉theano的基础对象和操作了,可以通过浏览库的部分来详细的了解 Basic Tensor Functionality.
随着这个教程的深入,你可以逐渐的让自己熟悉库的其他相关的部分和文档入口页面的其他相关的主题了。
Basic Tensor Functionality:http://deeplearning.net/software/theano/library/tensor/basic.html#libdoc-basic-tensor
‘‘‘

‘‘‘
一、Logistic函数
‘‘‘

‘‘‘
这是一个简单的例子:虽然回比两个数值相加要难一些。假设你想要设计一个逻辑曲线,首先得到一个如下的式子
s(x) = 1/(1+exp(-x))

你需要在doubles矩阵上逐元素(elementwise)的计算这个函数,也就是说你想要在矩阵的每个独立的元素上都是用这个函数
代码如下
‘‘‘
import numpy as np

x = T.dmatrix(‘x‘)
s = 1/(1+T.exp(-x))
logistic = theano.function([x],s)
inpt = np.array([[0,1],[-1,-2]],dtype=‘float64‘)
print(logistic(inpt))      #[[ 0.5         0.73105858],[ 0.26894142  0.11920292]]

‘‘‘
需要逐元素计算是因为它的操作:除法、加法、指数和减法,都是逐元素的操作。在该情况下也是:
s(x) = 1/(1+exp(-x)) = (1+tanh(x/2))/2
我们可以验证从这个可代替的式子上得到的结果是一样的
‘‘‘
s2 = (1 + T.tanh(x/2))/2
logistic2 = theano.function([x],s2)
print(logistic2(inpt))      #[[ 0.5         0.73105858],[ 0.26894142  0.11920292]]

‘‘‘
二、在同一时间对多个操作进行运算
‘‘‘

‘‘‘
 Theano支持函数有着多于一个的输出。例如,我们可以在同一时刻计算两个矩阵a和b 之间的逐元素(elementwise )的差,
 绝对值的差,平方值的差:
‘‘‘
a,b =T.dmatrices(‘a‘,‘b‘)
diff = a-b
abs_diff = T.abs_(a-b)
diff_squared = T.square(a-b)
f = theano.function([a,b],[diff,abs_diff,diff_squared])

#note:dmatrices 生成提供的名字一样数量的输出。这是一个用来分配符号变量的快捷方式,在本教程中会经常用到。
#当我们使用函数f 时,它返回三个变量(输出的时候会为了更好的可读性而被重新格式):

r1 = f([[1,1],[1,1]],[[0,1],[2,3]])
print(r1)    #[array([[ 1.,  0.],
             #       [-1., -2.]]), array([[ 1.,  0.],
             #       [ 1.,  2.]]), array([[ 1.,  0.],
             #       [ 1.,  4.]])]

‘‘‘
三、对参数设置默认值
‘‘‘

‘‘‘
假设你想要定义一个相加两个数的函数,如果你定义完之后,在调用的时候,只提供了一个参数,那么另一个输入可以假设默认
为1,可以如下所示:
‘‘‘
from theano import Param
x,y = T.dscalars(‘x‘,‘y‘)
z = x+y
f = theano.function([x,Param(y,default=1)],z)
print(f(33))                 #34.0
print(f(33,2))               #35.0

‘‘‘
使用的 Param 参数允许你指定你函数的参数有着更详细的值。这里我们通过创建一个Param实例来将y设置其默认值为1。

有着默认值的输入必须在没有默认值的输入的后面(和python的函数一样的顺序)可以对多个输入进行设置默认值。
这些参数可以通过位置或者名称来进行设定,就像标准的python中一样:
‘‘‘
x, y, w = T.dscalars(‘x‘, ‘y‘, ‘w‘)
z = (x + y) * w
f = theano.function([x, Param(y, default=1), Param(w, default=2, name=‘w_by_name‘)], z)    #对符号变量w名字重命名
print(f(33))       #68.0
print(f(33,2))     #70.0
print(f(33,0,1))   #33.0
print(f(33,w_by_name=1,y=0))   #33.0   

‘‘‘
note:Param 不知道作为参数传入的局部变量y和w的名称。这些符号变量对象都有name属性(和上面例子一样通过dscalars来设置)
,这些是我们构建的函数中的关键参数的名称。这就是 Param(y, default=1)中的工作机制。在Param(w, default=2, name=‘w_by_name‘)
的情况下 ,我们用在这个函数中使用过的名字来覆盖符号变量的名字属性。
你可以看看库中的 Function 来更详细的了解。
function:http://deeplearning.net/software/theano/library/compile/function.html#usingfunction
‘‘‘

‘‘‘
四、使用共享变量
‘‘‘

‘‘‘
同样的也可以让函数有一个内部状态。例如,我们想要在开始就设置一个累加器,先初始化为0。那么,在每次的函数调用, 该状态就
会被函数的参数递增的。首先定义一个accumulator 函数。然后将参数增加到内部状态上,然后返回增加之前的状态值。
‘‘‘

state = theano.shared(0)
inc = T.iscalar(‘inc‘)
accumulator = theano.function([inc],state,updates=[(state,state+inc)])

‘‘‘
该代码引入了一些新的概念。 shared 函数构建所谓的 shared variables。这些都是混合符号和非符号变量,他们的值可以在多个
 函数中共享,就像是由dmatrices(...)返回的对象一样,不过他们同样有着一个内部值,这个值是通过这个在所有函数中使用的符号
 变量定义的。被称作共享变量是因为它的值在许多函数之间共享的。该值可以被 .get_value() 和 .set_value() 方法所访问和修改。
 该代码中另一个新事物就是function. updates的参数 updates 必须被以(shared-variable, new expression)这种对形式的列表
 所赋值。它同样可以是一个字典,其中的键是共享变量而值是新表达式。。不管怎么说,它表示“不论什么时候运行,它会将.value的
 每个共享变量替换成对应的表达式的结果” 。也就是说,我们的累加器会用状态state的和以及递增数来替换状态state的值。
 shared variables:http://deeplearning.net/software/theano/library/compile/shared.html#libdoc-compile-shared
‘‘‘
print(state.get_value())      #0
print(accumulator(1))         #0
print(state.get_value())      #1

state.set_value(-1)
print(accumulator(3))         #-1
print(state.get_value())      #2

#正如上面说的,你可以定义超过一个函数来使用相同的共享变量。这些函数都能够更新这个值。
decrementor = theano.function([inc], state, updates=[(state, state-inc)])
print(decrementor(2))         #2
print(state.get_value())      #0

‘‘‘
你也许会惊讶为什么这个更新机制会存在。你总可以通过返回一个新的表达式来得到一个相似的结果,然后在NumPy里面使用它们。
该更新机制是一个语法上的方便,不过在这里主要是因为效率问题。对共享变量的更新有时候可以使用in-place算法更快的完成
(了例如: low-rank矩阵更新).。同样的,theano有着更多有关在哪和如何来分配共享权重的函数,这些都是在需要使用在
GPU上很重要的组成部分.

有时候你想要使用一个共享变量来表示一些公式,却不想要使用它们的值。在这种情况下,你可以使用function函数的givens
的参数,这个用来代替这种情况下graph中的特定的节点。
‘‘‘
fn_of_state = state * 2 + inc
# The type of foo must match the shared variable we are replacing
# with the ``givens``
foo = T.scalar(dtype=state.dtype)
skip_shared = theano.function([inc, foo], fn_of_state,
                           givens=[(state, foo)])                   #使用foo变量替代state共享变量的值,并不更改state的值
print(skip_shared(1, 3))  # we‘re using 3 for the state, not state.value    3*2+1 = 7
print(state.get_value())  # old state still there, but we didn‘t use it     0

‘‘‘
givens 参数可以用来代替任何符号变量,不只是共享变量。你还可以用来代替常量、表达式。不过要注意,不要让由givens替
换的表达式之间有着相互依赖关系,替换的顺序是没法保证的,所以替换之后是有可能以任意顺序来执行的。

在实际中,有关使用givens的一个好的方法就是替换公式的任何部分的时候使用的是不同的表达式,只不过该表达式有着相同
shape和dtype的张量而已。

note:Theano 共享变量的广播模式默认情况下对于每个维度来说都是False。共享变量的size可以随着时间变化,所以我们
没法使用shape来找到可广播的模式。如果你想要一个不同的模式,只要将它像参数一样传递 theano.shared(..., broadcastable=(True, False))。
‘‘‘

‘‘‘
五、使用随机数
‘‘‘

‘‘‘
因为在theano中,你首先会将任何事情进行符号化,然后编译这个表达式来得到函数,然后使用伪随机数不是和Numpy中一样简单的,当然也不会太复杂。

将随机放入theano的计算中就是将随机变量放到你的graph中。theano将会对每个这样的变量分配一个 NumPy RandomStream 对象
 (一个随机生成器) ,然后必要的时候提取出来。我们称这类随机数序列为a random stream. 随机流的核心也是共享变量,所以
 对共享变量的观察在这里也是一样的。theano的随机对象的定义和实现在 RandomStreams 更低的版本,也就是其父类RandomStreamsBase.
 RandomStreams:http://deeplearning.net/software/theano/library/tensor/shared_randomstreams.html#libdoc-tensor-shared-randomstreams
 RandomStreamsBase:http://deeplearning.net/software/theano/library/tensor/raw_random.html#libdoc-tensor-raw-random
‘‘‘

from theano.tensor.shared_randomstreams import RandomStreams
srng = RandomStreams(seed = 234)         #创建一个随机生成器
rv_u = srng.uniform((2,2))               #表示一个从均匀分布中提取2*2的矩阵的随机流
rv_n = srng.normal((2,2))                #表示一个从标准正太分布中提取的2*2矩阵的一个随机流。 

f= theano.function([],rv_u)
g = theano.function([], rv_n, no_default_updates=True)    #Not updating rv_n.rng
nearly_zeros = theano.function([],rv_u+rv_u - 2*rv_u)

#现在让我们来使用这些对象。如果我们调用 f(),我们就得到了均匀随机数。 随机数生成器的内部状态是自动进行更新的,所以
#我们在每个时间上得到的是不同的随机数:

f_val0 = f()
f_val1 = f()  #different numbers from f_val0
print(f_val0)                   #[[ 0.12672381  0.97091597]
                                # [ 0.13989098  0.88754827]]
print(f_val1)                   #[[ 0.31971416  0.47584376]
                                # [ 0.24129163  0.42046082]]

#当我们增加额外的参数 no_default_updates=True 到 function (as in g),那么随机数生成器状态不会受到返回函数调用的影响。
#所以,例如,调用g 函数多次,而返回的是同样的数值:

g_val0 = g()  # different numbers from f_val0 and f_val1
g_val1 = g()  # same numbers as g_val0!
print(g_val0)                   #[[ 0.37328446 -0.65746671]
                                # [-0.36302373 -0.97484624]]
print(g_val1)                   #[[ 0.37328446 -0.65746671]
                                # [-0.36302373 -0.97484624]] 

print(nearly_zeros())           #[[ 0.  0.]
                                # [ 0.  0.]]

#一个重要的备注是随机变量在任何单一函数执行中最多被提取一次。所以,即使 rv_u 随机变量在输出表达式中出现了三次,
#nearly_zero函数可以保证返回的值可以逼近0 (除了舍入导致的错误):
#nearly_zeros = function([], rv_u + rv_u - 2 * rv_u)  

‘‘‘
随机变量可以被独立或集体的被传入种子。你可以只对随机变量通过seeding或者使用.rng.set_value()的.rng 属性来指定传入种子:
‘‘‘
rng_val = rv_u.rng.get_value(borrow=True)   # Get the rng for rv_u
rng_val.seed(89234)                         # seeds the generator
rv_u.rng.set_value(rng_val, borrow=True)    # Assign back seeded rng  

#你同样可以对所有的随机变量通过RandomStreams对象的seed方法来分配种子。该种子将会被用来传递给一个临时随机数生成器,
#然后对每个随机变量生成种子。
srng.seed(902340)                           # seeds rv_u and rv_n with different seeds each 

‘‘‘
在函数之间共享流
‘‘‘

#和通常的共享变量一样,用于随机变量的随机数生成器都是函数中常见的。所以我们的nearly_zeros 函数将会使用上面介绍的函数
# f 来更新生成器的状态。例如:
state_after_v0 = rv_u.rng.get_value().get_state()
nearly_zeros()       # this affects rv_u‘s generator
v1 = f()
rng = rv_u.rng.get_value(borrow=True)
rng.set_state(state_after_v0)
rv_u.rng.set_value(rng, borrow=True)
v2 = f()             # v2 != v1
v3 = f()             # v3 == v1  

‘‘‘
在theano graphs之间复制随机状态
‘‘‘

‘‘‘
在一些使用的情况中,用户有可能想要将所有随机数生成器的“state”从一个给定的theano graph (例如, g1,和下面编译的函数f1一起的) 到
另一个 graph (例如 g2,和函数f2一起的).。如果你想要从之前模型的pickled版本的参数中初始化模型的state,那么这个问题就会出现。
theano.tensor.shared_randomstreams.RandomStreams 和 theano.sandbox.rng_mrg.MRG_RandomStreams 可以通过复制state_updates
参数的元素来获得

每次从一个RandomStreams对象中得到一个随机变量,一个元组就会被添入到 state_updates 列表中。第一个元素就是一个共享变量,用来
表示与这个具体的变量相关联的随机数生成器的状态,第二个元素用来表示对应于随机数生成过程(即RandomFunction{uniform}.0)的theano graph。

 一个关于如何“random states”可以从一个theano function迁移到另一个的例子如下:
‘‘‘

import theano
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,))  

g1 = Graph(seed=123)
f1 = theano.function([], g1.y)  

g2 = Graph(seed=987)
f2 = theano.function([], g2.y)  

print (‘By default, the two functions are out of sync.‘)
print (‘f1() returns ‘, f1() )
print (‘f2() returns ‘, f2()  )

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())  

print (‘We now copy the state of the theano random number generators.‘  )
copy_random_state(g1, g2)
print (‘f1() returns ‘, f1() )
print (‘f2() returns ‘, f2()  )

‘‘‘
会有如下的输出:

By default, the two functions are out of sync.
f1() returns  [ 0.72803009]
f2() returns  [ 0.55056769]
# We now copy the state of the theano random number generators.
f1() returns  [ 0.59044123]
f2() returns  [ 0.59044123]  

‘‘‘

‘‘‘
其他随机分布
other distributions implemented.
http://deeplearning.net/software/theano/library/tensor/raw_random.html#libdoc-tensor-raw-random
‘‘‘

‘‘‘
其他实现
     这里有2个基于 CURAND 和 MRG31k3p.的两个实现。该RandomStream 只工作在CPU上,
     而 MRG31k3p 既能在CPU 上也能在GPU上。CURAND 只工作在 GPU上。
     http://deeplearning.net/software/theano/library/sandbox/cuda/op.html#module-theano.sandbox.cuda.rng_curand
     http://deeplearning.net/software/theano/library/sandbox/rng_mrg.html#libdoc-rng-mrg
‘‘‘

‘‘‘
六、逻辑回归案例
‘‘‘
rng = np.random

N=400                     #实例个数
feats = 784                #特征个数
#随机生成训练集数据
#numpy.random.randn(d0, d1, …, dn)是从标准正态分布中返回一个或多个样本值。
#numpy.random.rand(d0, d1, …, dn)的随机样本位于[0, 1)中。
#rng.randint(size=N,low=0,high=2) 生成0或者1的类别
D = [np.asarray(rng.randn(N,feats),dtype=‘float32‘) ,np.asarray(rng.randint(size=N,low=0,high=2),dtype=‘float32‘)]

#迭代次数
training_steps = 10000

#声明theano符号变量
x = T.matrix(‘x‘)       #float32
y = T.vector(‘y‘)       #float32
w = theano.shared(np.asarray(rng.randn(feats),dtype=‘float32‘),name  = ‘w‘)    #float32
print(w.type)
b = theano.shared(np.float32(0.0),name  = ‘b‘)                                   #float32 类型最好一致
print(b.type)

print(‘Initial model‘)
#print(w.get_value(),b.get_value())

#定义代价函数,预测函数表达式
p_1 = 1/(1 + T.exp(-T.dot(x,w)-b))          #目标为1的概率
prediction = p_1 > 0.5                        #预测阈值  >0.5 预测类别为1  否则为0

xent = -y*T.log(p_1) - (1-y)*T.log(1-p_1)    #交叉熵代价函数  维数为:实例个数*1
cost = xent.mean() + 0.01*(w**2).sum()       #加入正则项   求平均
gw,gb = T.grad(cost,[w,b])

#定义编译函数

#训练函数
train = theano.function(
                inputs = [x,y],
                outputs = [prediction,xent],
                updates=[(w,w-0.1*gw),(b,b-0.1*gb)])

#预测函数
predict = theano.function([x],prediction)

#准确率
acc = T.mean(T.eq(T.cast(y,‘bool‘) ,prediction))
accuracy = theano.function([x,y],acc)

for i in range(training_steps):
    pred,err=train(D[0],D[1])

print(‘Final Model‘)
print(w.get_value(),b.get_value())
print (‘target values for D:‘, D[1])
print (‘prediction on D:‘, predict(D[0]))
print(‘accuracy:‘,accuracy(D[0],D[1]))

原文地址:https://www.cnblogs.com/zyly/p/8634350.html

时间: 2024-10-14 01:14:23

第二节,基础知识之更多的例子的相关文章

【读书笔记】《鸟哥Linux私房菜-基础知识篇》第二节 基础命令

第二节 基础命令 uname –r 查询Linux核心版本. 装置及装置在Linux内的文件名 IDE硬盘机 /dev/hd[a-d] SCSI/SATA/USB硬盘机 /dev/sd[a-p] USB快闪碟 /dev/sd[a-p] 软盘驱动器 /dev/fd[0-1] 打印机 25针:/dev/lp[0-2] USB:/dev/usb/lp[0-15] 鼠标 USB:/dev/usb/mouse[0-15] PS2:/dev/psaux 当前CDROM/DVDROM /dev/cdrom 当

汇编第二章--基础知识梳理与总结

第一章,我们介绍了有关汇编语言的基础知识,在第二章我们主要介绍寄存器. CPU的主要部件是寄存器,在8086CPU有14个寄存器,它们分别是:AX.BX.CX.DX.SI.DI.SP.BP.IP.CS.SS.DS.ES.PSW.8086CPU的所有寄存器都是16位的,可以存放两个字节.AX.BX.CX.DX这4个寄存器通常用来存放一般性的数据,称为通用寄存器.由于8086CPU的上一代CPU中的寄存器都是8位的,为了保持兼容,8086CPU的AX.BX.CX.DX这4个寄存器都可分为两个独立使用

Theano2.1.3-基础知识之更多的例子

来自:http://deeplearning.net/software/theano/tutorial/examples.html More Examples 现在,是时候开始系统的熟悉theano的基础对象和操作了,可以通过浏览库的部分来详细的了解 Basic Tensor Functionality. 随着这个教程的深入,你可以逐渐的让自己熟悉库的其他相关的部分和文档入口页面的其他相关的主题了. 一.Logistic 函数 这是一个简单的例子,虽然会比两个数值相加要难一些.假设你想要计算一个

Python第二天--基础知识(2)

1.保存并执行程序 在文本文件写入:print("hello") 通过 python + 文本路径 执行 这里后缀名是不影响执行的,python解释器也相当于一个文本编辑器,它会打开文件取读取内容 Python文件头: 第一行用于指定解释器(env 表示会自动找python解释器,windons中不生效) 第二行用于指定编码格式 #!usr/bin/env python # -*- coding: utf-8 -*- 2.注释 python中,在代码遇见#,那么后面的内容都会忽略不执行

读《精通css》--第二章基础知识

一. 常用的选择器:类型选择器和后代选择器.ID选择器和类选择器.伪类选择器(:link,:visited,:hover,:active,:focus) 二. 通用选择器:*  ( 通配符,也可以用来对某个元素的所有后代应用样式) 三. 高级选择器:CSS有向后兼容性,即如果浏览器不理解某个选择器,那么它会忽略整个规则.对于站点功能或布局很重要的任何元素上,都应该避免使用这些高级选择器. 1. 子选择器和相邻同胞选择器:> +    (IE6不支持) 2. 属性选择器:根据属性是否存在 或者 属

BurpSuite学习第一节--基础知识

一.BurpSuite的用处 Burp Suite是进行Web应用安全测试集成平台.在安全人员常用工具表(https://sectools.org/),burp suite排在第十三位 二.功能模块 Burp suite的模块几乎包含整个安全测试过程,从最初对目标程序的信息采集,到漏洞扫描及其利用 主要模块: Target(目标)--- Proxy(代理)---是一个拦截HTTP/S的代理服务器,作为一个在浏览器和目标应用程序之间的中间人.允许拦截,查看,修改在两个方向上的原始数据流 Spide

第二节课知识总结

1.4.1系统环境变量 path 环境变量在cmd窗口输入Javac,如提示错误信息,在cmd中输入"set path"查看当前系统的环境变量set path="path";program files.Java\jdk1.7.0_10\bin;--------将"javac"所在的目录添加到path环境变量中配置系统环境变量具体步骤如下:1.查看windows系统属性中的环境变量2.设置path系统环境变量3.查看和验证设置的系统环境变量1.4.

第二章 面试需要的基础知识

2.1 面试官谈基础知识 基础很重要 算法.复杂的 编程能力 数据结构 2.2 编程语言 程序员写代码总是基于某一种编程语言,因此技术面试的时候直接或者间接都会涉及至少一种编程语言.在面试的过程中,面试官要么直接问语言的语法,要么让应聘者用-~种编程语言写代码解决一个问题,通过写出的代码来判断应聘者对他使用的语言的掌握程度.现在流行的编程语言很多,不同公司开发用的语言也不尽相同.做底层开发比如经常写驱动的人更习惯用C, Linux下有很多程序员用C++开发应用程序,基于Windows的C#项目已

第二章 TCP/IP 基础知识

? TCP/IP ?transmission control protocol and ip internet protocol 是互联网众多通信协议中最为著名的. ? 2.2 TCP/IP 的标准化 2.2.2 TCP/IP 标准化精髓 TCP/IP 协议始终具有很强的实用性. 相比于TCP/IP ,OSI 之所以未能达到普及,主要原因在于未能尽早的制定可行性较强的协议.未能提出应对技术快速更新的协议以及没有能及时进行后期的改良的方案. 2.2.3 TCP/IP 规范 --RFC 那些需要标准