01. Python 工具
02. Python 基础
03. Numpy
- Numpy 简介
- Matplotlib 基础
- Numpy 数组及其索引
- 数组类型
- 数组方法
- 数组排序
- 数组形状
- 对角线
- 数组与字符串的转换
- 数组属性方法总结
- 生成数组的函数
- 矩阵
- 一般函数
- 向量化函数
- 二元运算
- ufunc 对象
- choose 函数实现条件筛选
- 数组广播机制
- 数组读写
- 结构化数组
- 记录数组
- 内存映射
- 从 Matlab 到 Numpy
04. Scipy
05. Python 进阶
- sys 模块简介
- 与操作系统进行交互:os 模块
- CSV 文件和 csv 模块
- 正则表达式和 re 模块
- datetime 模块
- SQL 数据库
- 对象关系映射
- 函数进阶:参数传递,高阶函数,lambda 匿名函数,global 变量,递归
- 迭代器
- 生成器
- with 语句和上下文管理器
- 修饰符
- 修饰符的使用
- operator, functools, itertools, toolz, fn, funcy 模块
- 作用域
- 动态编译
06. Matplotlib
- Pyplot 教程
- 使用 style 来配置 pyplot 风格
- 处理文本(基础)
- 处理文本(数学表达式)
- 图像基础
- 注释
- 标签
- figures, subplots, axes 和 ticks 对象
- 不要迷信默认设置
- 各种绘图实例
07. 使用其他语言进行扩展
- 简介
- Python 扩展模块
- Cython:Cython 基础,将源代码转换成扩展模块
- Cython:Cython 语法,调用其他C库
- Cython:class 和 cdef class,使用 C++
- Cython:Typed memoryviews
- 生成编译注释
- ctypes
08. 面向对象编程
09. Theano 基础
- Theano 简介及其安装
- Theano 基础
- Theano 在 Windows 上的配置
- Theano 符号图结构
- Theano 配置和编译模式
- Theano 条件语句
- Theano 循环:scan(详解)
- Theano 实例:线性回归
- Theano 实例:Logistic 回归
- Theano 实例:Softmax 回归
- Theano 实例:人工神经网络
- Theano 随机数流变量
- Theano 实例:更复杂的网络
- Theano 实例:卷积神经网络
- Theano tensor 模块:基础
- Theano tensor 模块:索引
- Theano tensor 模块:操作符和逐元素操作
- Theano tensor 模块:nnet 子模块
- Theano tensor 模块:conv 子模块
10. 有趣的第三方模块
11. 有用的工具
- pprint 模块:打印 Python 对象
- pickle, cPickle 模块:序列化 Python 对象
- json 模块:处理 JSON 数据
- glob 模块:文件模式匹配
- shutil 模块:高级文件操作
- gzip, zipfile, tarfile 模块:处理压缩文件
- logging 模块:记录日志
- string 模块:字符串处理
- collections 模块:更多数据结构
- requests 模块:HTTP for Human
12. Pandas
Theano 基础
In [1]:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
首先导入 theano
及其 tensor
子模块(tensor
,张量):
In [2]:
import theano
# 一般都把 `tensor` 子模块导入并命名为 T
import theano.tensor as T
Using gpu device 1: Tesla K10.G2.8GB (CNMeM is disabled)
tensor
模块包含很多我们常用的数学操作,所以为了方便,将其命名为 T。
符号计算
theano
中,所有的算法都是用符号计算的,所以某种程度上,用 theano
写算法更像是写数学(之前在04.06 积分一节中接触过用 sympy
定义的符号变量)。
用 T.scalar
来定义一个符号标量:
In [3]:
foo = T.scalar('x')
In [4]:
print foo
x
支持符号计算:
In [5]:
bar = foo ** 2
print bar
Elemwise{pow,no_inplace}.0
这里定义 foo
是 $x$,bar
就是变量 $x^2$,但显示出来的却是看不懂的东西。
为了更好的显示 bar
,我们使用 theano.pp()
函数(pretty print
)来显示:
In [6]:
print theano.pp(bar)
(x ** TensorConstant{2})
查看类型:
In [7]:
print type(foo)
print foo.type
<class 'theano.tensor.var.TensorVariable'>
TensorType(float32, scalar)
theano 函数
有了符号变量,自然可以用符号变量来定义函数,theano.function()
函数用来生成符号函数:
theano.function(input, output)
其中 input
对应的是作为参数的符号变量组成的列表,output
对应的是输出,输出可以是一个,也可以是多个符号变量组成的列表。
例如,我们用刚才生成的 foo
和 bar
来定义函数:
In [8]:
square = theano.function([foo], bar)
使用 square
函数:
In [9]:
print square(3)
9.0
也可以使用 bar
的 eval
方法,将 x
替换为想要的值,eval
接受一个字典作为参数,键值对表示符号变量及其对应的值:
In [10]:
print bar.eval({foo: 3})
9.0
theano.tensor
除了 T.scalar()
标量之外,Theano
中还有很多符号变量类型,这些都包含在 tensor
(张量)子模块中,而且 tensor
中也有很多函数对它们进行操作。
T.scalar(name=None, dtype=config.floatX)
- 标量,shape - ()
T.vector(name=None, dtype=config.floatX)
- 向量,shape - (?,)
T.matrix(name=None, dtype=config.floatX)
- 矩阵,shape - (?,?)
T.row(name=None, dtype=config.floatX)
- 行向量,shape - (1,?)
T.col(name=None, dtype=config.floatX)
- 列向量,shape - (?,1)
T.tensor3(name=None, dtype=config.floatX)
- 3 维张量,shape - (?,?,?)
T.tensor4(name=None, dtype=config.floatX)
- 4 维张量,shape - (?,?,?,?)
shape
中为 1 的维度支持 broadcast
机制。
除了直接指定符号变量的类型(默认 floatX
),还可以直接在每类前面加上一个字母来定义不同的类型:
b
int8w
int16i
int32l
int64d
float64f
float32c
complex64z
complex128
例如 T.dvector()
表示的就是一个 float64
型的向量。
除此之外,还可以用它们的复数形式一次定义多个符号变量:
x,y,z = T.vectors('x','y','z')
x,y,z = T.vectors(3)
In [11]:
A = T.matrix('A')
x = T.vector('x')
b = T.vector('b')
T.dot()
表示矩阵乘法: $$y = Ax+b$$
In [12]:
y = T.dot(A, x) + b
T.sum()
表示进行求和: $$z = \sum{i,j} A{ij}^2$$
In [13]:
z = T.sum(A**2)
来定义一个线性函数,以 $A,x,b$ 为参数,以 $y,z$ 为输出:
In [14]:
linear_mix = theano.function([A, x, b],
[y, z])
使用这个函数:
$$ A = \begin{bmatrix} 1 & 2 & 3 \ 4 & 5 & 6 \end{bmatrix}, x = \begin{bmatrix} 1 \ 2 \ 3 \end{bmatrix}, b = \begin{bmatrix} 4 \ 5 \end{bmatrix} $$In [15]:
print linear_mix(np.array([[1, 2, 3],
[4, 5, 6]], dtype=theano.config.floatX), #A
np.array([1, 2, 3], dtype=theano.config.floatX), #x
np.array([4, 5], dtype=theano.config.floatX)) #b
[array([ 18., 37.], dtype=float32), array(91.0, dtype=float32)]
这里 dtype=theano.config.floatX
是为了与 theano
设置的浮点数精度保持一致,默认是 float64
,但是在 GPU
上一般使用 float32
会更高效一些。
我们还可以像定义普通函数一样,给 theano
函数提供默认值,需要使用 theano.Param
类:
In [16]:
linear_mix_default = theano.function([A, x, theano.Param(b, default=np.zeros(2, dtype=theano.config.floatX))],
[y, z])
计算默认参数下的结果:
In [17]:
print linear_mix_default(np.array([[1, 2, 3],
[4, 5, 6]], dtype=theano.config.floatX), #A
np.array([1, 2, 3], dtype=theano.config.floatX)) #x
[array([ 14., 32.], dtype=float32), array(91.0, dtype=float32)]
计算刚才的结果:
In [18]:
print linear_mix_default(np.array([[1, 2, 3],
[4, 5, 6]], dtype=theano.config.floatX), #A
np.array([1, 2, 3], dtype=theano.config.floatX), #x
np.array([4, 5], dtype=theano.config.floatX)) #b
[array([ 18., 37.], dtype=float32), array(91.0, dtype=float32)]
共享的变量
Theano
中可以定义共享的变量,它们可以在多个函数中被共享,共享变量类似于普通函数定义时候使用的全局变量,同时加上了 global
的属性以便在函数中修改这个全局变量的值。
In [19]:
shared_var = theano.shared(np.array([[1.0, 2.0], [3.0, 4.0]], dtype=theano.config.floatX))
print shared_var.type
CudaNdarrayType(float32, matrix)
可以通过 set_value
方法改变它的值:
In [20]:
shared_var.set_value(np.array([[3.0, 4], [2, 1]], dtype=theano.config.floatX))
通过 get_value()
方法返回它的值:
In [21]:
print shared_var.get_value()
[[ 3\. 4.]
[ 2\. 1.]]
共享变量进行运算:
In [22]:
shared_square = shared_var ** 2
f = theano.function([], shared_square)
print f()
[[ 9\. 16.]
[ 4\. 1.]]
这里函数不需要参数,因为共享变量隐式地被认为是一个参数。
得到的结果会随这个共享变量的变化而变化:
In [23]:
shared_var.set_value(np.array([[1.0, 2], [3, 4]], dtype=theano.config.floatX))
print f()
[[ 1\. 4.]
[ 9\. 16.]]
一个共享变量的值可以用 updates
关键词在 theano
函数中被更新:
In [24]:
subtract = T.matrix('subtract')
f_update = theano.function([subtract], shared_var, updates={shared_var: shared_var - subtract})
这个函数先返回当前的值,然后将当前值更新为原来的值减去参数:
In [25]:
print 'before update:'
print shared_var.get_value()
print 'the return value:'
print f_update(np.array([[1.0, 1], [1, 1]], dtype=theano.config.floatX))
print 'after update:'
print shared_var.get_value()
before update:
[[ 1\. 2.]
[ 3\. 4.]]
the return value:
<CudaNdarray object at 0x7f7f3c16a6f0>
after update:
[[ 0\. 1.]
[ 2\. 3.]]
导数
Theano
的一大好处在于它对符号变量计算导数的能力。
我们用 T.grad()
来计算导数,之前我们定义了 foo
和 bar
(分别是 $x$ 和 $x^2$),我们来计算 bar
关于 foo
的导数(应该是 $2x$):
In [26]:
bar_grad = T.grad(bar, foo) # 表示 bar (x^2) 关于 foo (x) 的导数
print bar_grad.eval({foo: 10})
20.0
再如,对之前的 $y = Ax + b$ 求 $y$ 关于 $x$ 的雅可比矩阵(应当是 $A$):
In [27]:
y_J = theano.gradient.jacobian(y, x)
print y_J.eval({A: np.array([[9.0, 8, 7], [4, 5, 6]], dtype=theano.config.floatX), #A
x: np.array([1.0, 2, 3], dtype=theano.config.floatX), #x
b: np.array([4.0, 5], dtype=theano.config.floatX)}) #b
[[ 9\. 8\. 7.]
[ 4\. 5\. 6.]]
theano.gradient.jacobian
用来计算雅可比矩阵,而 theano.gradient.hessian
可以用来计算 Hessian
矩阵。
R-op
和 L-op
Rop 用来计算 $\frac{\partial f}{\partial x}v$,Lop 用来计算 $v\frac{\partial f}{\partial x}$:
一个是雅可比矩阵与列向量的乘积,另一个是行向量与雅可比矩阵的乘积。
In [28]:
W = T.dmatrix('W')
V = T.dmatrix('V')
x = T.dvector('x')
y = T.dot(x, W)
JV = T.Rop(y, W, V)
f = theano.function([W, V, x], JV)
print f([[1, 1], [1, 1]], [[2, 2], [2, 2]], [0,1])
[ 2\. 2.]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论