Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
a08fc0c1
提交
a08fc0c1
authored
2月 19, 2016
作者:
Frédéric Bastien
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #4069 from hantek/docassert
Add doc for opt.py
上级
028459c3
a5da2c07
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
87 行增加
和
65 行删除
+87
-65
index.txt
doc/library/tensor/index.txt
+1
-0
opt.txt
doc/library/tensor/opt.txt
+12
-0
opt.py
theano/tensor/opt.py
+74
-65
没有找到文件。
doc/library/tensor/index.txt
浏览文件 @
a08fc0c1
...
@@ -25,5 +25,6 @@ They are grouped into the following sections:
...
@@ -25,5 +25,6 @@ They are grouped into the following sections:
utils
utils
extra_ops
extra_ops
io
io
opt
slinalg
slinalg
nlinalg
nlinalg
doc/library/tensor/opt.txt
0 → 100644
浏览文件 @
a08fc0c1
===================================================================
:mod:`tensor.opt` -- Tensor Optimizations
===================================================================
.. module:: tensor.opt
:platform: Unix, Windows
:synopsis: Tensor Optimizations
.. moduleauthor:: LISA
.. automodule:: theano.tensor.opt
:members:
theano/tensor/opt.py
浏览文件 @
a08fc0c1
...
@@ -828,9 +828,12 @@ class ShapeFeature(object):
...
@@ -828,9 +828,12 @@ class ShapeFeature(object):
Shape_i and MakeVector Ops.
Shape_i and MakeVector Ops.
This optimizer has several goals:
This optimizer has several goals:
1. to 'lift' Shapes to as close to the inputs as possible.
1. to 'lift' Shapes to as close to the inputs as possible.
2. to infer the shape of every node in the graph in terms of the
2. to infer the shape of every node in the graph in terms of the
input shapes.
input shapes.
3. remove all fills (T.second, T.fill) from the graph
3. remove all fills (T.second, T.fill) from the graph
Lifting shapes as close to the inputs as possible is important for
Lifting shapes as close to the inputs as possible is important for
...
@@ -880,8 +883,7 @@ class ShapeFeature(object):
...
@@ -880,8 +883,7 @@ class ShapeFeature(object):
execution by default. (NOT IMPLEMENTED YET, BUT IS IN TRAC)
execution by default. (NOT IMPLEMENTED YET, BUT IS IN TRAC)
Using Shape information in Optimizations
**Using Shape information in Optimizations**
========================================
To use this shape information in OPTIMIZATIONS, use the
To use this shape information in OPTIMIZATIONS, use the
``shape_of`` dictionary.
``shape_of`` dictionary.
...
@@ -898,7 +900,7 @@ class ShapeFeature(object):
...
@@ -898,7 +900,7 @@ class ShapeFeature(object):
shape_of_output_zero = shape_of[node.output[0]]
shape_of_output_zero = shape_of[node.output[0]]
The ``shape_of_output_zero
''
symbol will contain a tuple, whose
The ``shape_of_output_zero
``
symbol will contain a tuple, whose
elements are either integers or symbolic integers.
elements are either integers or symbolic integers.
TODO: check to see if the symbols are necessarily
TODO: check to see if the symbols are necessarily
...
@@ -2091,10 +2093,11 @@ class Assert(T.Op):
...
@@ -2091,10 +2093,11 @@ class Assert(T.Op):
Examples
Examples
--------
--------
T = theano.tensor
>>> import theano
x = T.vector('x')
>>> T = theano.tensor
assert_op = T.opt.Assert()
>>> x = T.vector('x')
func = theano.function([x], assert_op(x, x.size<2))
>>> assert_op = T.opt.Assert()
>>> func = theano.function([x], assert_op(x, x.size<2))
"""
"""
...
@@ -2638,10 +2641,12 @@ def merge_two_slices(slice1, len1, slice2, len2):
...
@@ -2638,10 +2641,12 @@ def merge_two_slices(slice1, len1, slice2, len2):
"""
"""
This function merges two slices into a single slice. The code works on
This function merges two slices into a single slice. The code works on
the assumption that:
the assumption that:
a) slice1 is actually a slice and not an index, while slice2
can be just an index.
a) slice1 is actually a slice and not an index, while slice2
b) the two slices **have been applied consecutively** on the same
can be just an index.
tensor
b) the two slices **have been applied consecutively** on the same
tensor
The output slice is **not** in canonical form, but actually just a slice
The output slice is **not** in canonical form, but actually just a slice
that can be applied to a tensor to produce the same output as applying
that can be applied to a tensor to produce the same output as applying
...
@@ -4067,7 +4072,8 @@ register_canonicalize(gof.OpRemove(T.tensor_copy), name='remove_tensor_copy')
...
@@ -4067,7 +4072,8 @@ register_canonicalize(gof.OpRemove(T.tensor_copy), name='remove_tensor_copy')
class
Canonizer
(
gof
.
LocalOptimizer
):
class
Canonizer
(
gof
.
LocalOptimizer
):
"""
"""
Simplification tool.
Simplification tool. The variable is a local_optimizer. It is best used
with a TopoOptimizer in in_to_out order.
Usage: Canonizer(main, inverse, reciprocal, calculate)
Usage: Canonizer(main, inverse, reciprocal, calculate)
...
@@ -4086,34 +4092,33 @@ class Canonizer(gof.LocalOptimizer):
...
@@ -4086,34 +4092,33 @@ class Canonizer(gof.LocalOptimizer):
calculate
calculate
Function that takes a list of numpy.ndarray instances
Function that takes a list of numpy.ndarray instances
for the numerator, another list for the denumerator,
for the numerator, another list for the denumerator,
and calculates inverse(main(
*num), main(
*denum)). It
and calculates inverse(main(
\
*num), main(
\
*denum)). It
takes a keyword argument, aslist. If True, the value
takes a keyword argument, aslist. If True, the value
should be returned as a list of one element, unless
should be returned as a list of one element, unless
the value is such that value = main(). In that case,
the value is such that value = main(). In that case,
the return value should be an empty list.
the return value should be an empty list.
The variable is a local_optimizer. It is best used with a TopoOptimizer in
in_to_out order.
Examples
Examples
--------
--------
T = theano.tensor
>>> import theano.tensor as T
add_canonizer = Canonizer(T.add, T.sub, T.neg,
>>> from theano.tensor.opt import Canonizer
lambda n, d: sum(n) - sum(d))
>>> add_canonizer = Canonizer(T.add, T.sub, T.neg,
\\
mul_canonizer = Canonizer(T.mul, T.true_div, T.inv,
... lambda n, d: sum(n) - sum(d))
lambda n, d: prod(n) / prod(d))
>>> mul_canonizer = Canonizer(T.mul, T.true_div, T.inv,
\\
... lambda n, d: prod(n) / prod(d))
Examples of optimizations mul_canonizer can perform:
Examples of optimizations mul_canonizer can perform:
x / x -> 1
(x * y) / x -> y
| x / x -> 1
x / y / x -> 1 / y
| (x * y) / x -> y
x / y / z -> x / (y * z)
| x / y / x -> 1 / y
x / (y / z) -> (x * z) / y
| x / y / z -> x / (y * z)
(a / b) * (b / c) * (c / d) -> a / d
| x / (y / z) -> (x * z) / y
(2.0 * x) / (4.0 * y) -> (0.5 * x) / y
| (a / b) * (b / c) * (c / d) -> a / d
2 * x / 2 -> x
| (2.0 * x) / (4.0 * y) -> (0.5 * x) / y
x * y * z -> Elemwise(T.mul){x,y,z} #only one pass over the memory.
| 2 * x / 2 -> x
!-> Elemwise(T.mul){x,Elemwise(T.mul){y,z}}
| x * y * z -> Elemwise(T.mul){x,y,z} #only one pass over the memory.
| !-> Elemwise(T.mul){x,Elemwise(T.mul){y,z}}
"""
"""
...
@@ -4136,23 +4141,23 @@ class Canonizer(gof.LocalOptimizer):
...
@@ -4136,23 +4141,23 @@ class Canonizer(gof.LocalOptimizer):
def
get_num_denum
(
self
,
input
):
def
get_num_denum
(
self
,
input
):
"""
"""
This extract two lists, num and denum, such that the input is:
This extract two lists, num and denum, such that the input is:
self.inverse(self.main(
*num), self.main(
*denum)). It returns
self.inverse(self.main(
\
*num), self.main(
\
*denum)). It returns
the two lists in a (num, denum) pair.
the two lists in a (num, denum) pair.
For example, for main, inverse and reciprocal = *, / and inv(),
For example, for main, inverse and reciprocal =
\
*, / and inv(),
input -> returned value (num, denum)
|
input -> returned value (num, denum)
x*y -> ([x, y], [])
|
x*y -> ([x, y], [])
inv(x) -> ([], [x])
|
inv(x) -> ([], [x])
inv(x) * inv(y) -> ([], [x, y])
|
inv(x) * inv(y) -> ([], [x, y])
x*y/z -> ([x, y], [z])
|
x*y/z -> ([x, y], [z])
log(x) / y * (z + x) / y -> ([log(x), z + x], [y, y])
|
log(x) / y * (z + x) / y -> ([log(x), z + x], [y, y])
(((a / b) * c) / d) -> ([a, c], [b, d])
|
(((a / b) * c) / d) -> ([a, c], [b, d])
a / (b / c) -> ([a, c], [b])
|
a / (b / c) -> ([a, c], [b])
log(x) -> ([log(x)], [])
|
log(x) -> ([log(x)], [])
x**y -> ([x**y], [])
|
x**y -> ([x**y], [])
x * y * z -> ([x, y, z], [])
|
x * y * z -> ([x, y, z], [])
"""
"""
...
@@ -4255,27 +4260,28 @@ class Canonizer(gof.LocalOptimizer):
...
@@ -4255,27 +4260,28 @@ class Canonizer(gof.LocalOptimizer):
def
merge_num_denum
(
self
,
num
,
denum
):
def
merge_num_denum
(
self
,
num
,
denum
):
"""
"""
Utility function which takes two lists, num and denum, and
Utility function which takes two lists, num and denum, and
returns something which is equivalent to inverse(main(*num),
returns something which is equivalent to inverse(main(
\
*num),
main(*denum)), but depends on the length of num and the length
main(
\
*denum)), but depends on the length of num and the length
of denum (in order to minimize the number of operations).
of denum (in order to minimize the number of operations).
Let n = len(num) and d = len(denum):
Let n = len(num) and d = len(denum):
n=0, d=0: neutral element (given by self.calculate([], []))
|
n=0, d=0: neutral element (given by self.calculate([], []))
(for example, this would be 0 if main is addition
|
(for example, this would be 0 if main is addition
and 1 if main is multiplication)
|
and 1 if main is multiplication)
n=1, d=0: num[0]
|
n=1, d=0: num[0]
n=0, d=1: reciprocal(denum[0])
|
n=0, d=1: reciprocal(denum[0])
n=1, d=1: inverse(num[0], denum[0])
|
n=1, d=1: inverse(num[0], denum[0])
n=0, d>1: reciprocal(main(
*denum))
| n=0, d>1: reciprocal(main(
\
*denum))
n>1, d=0: main(
*num)
| n>1, d=0: main(
\
*num)
n=1, d>1: inverse(num[0], main(
*denum))
| n=1, d>1: inverse(num[0], main(
\
*denum))
n>1, d=1: inverse(main(
*num), denum[0])
| n>1, d=1: inverse(main(
\
*num), denum[0])
n>1, d>1: inverse(main(*num), main(
*denum))
| n>1, d>1: inverse(main(
\
*num), main(
\
*denum))
Given the values of n and d to which they are associated, all
Given the values of n and d to which they are associated, all
of the above are equivalent to:
of the above are equivalent to:
inverse(main(*num), main(*denum))
inverse(main(
\
*num), main(
\
*denum))
"""
"""
ln
,
ld
=
len
(
num
),
len
(
denum
)
ln
,
ld
=
len
(
num
),
len
(
denum
)
...
@@ -4320,7 +4326,10 @@ class Canonizer(gof.LocalOptimizer):
...
@@ -4320,7 +4326,10 @@ class Canonizer(gof.LocalOptimizer):
def
simplify
(
self
,
num
,
denum
,
out_type
):
def
simplify
(
self
,
num
,
denum
,
out_type
):
"""
"""
Shorthand for:
Shorthand for:
self.simplify_constants(*self.simplify_factors(num, denum))
.. code-block:: python
self.simplify_constants(*self.simplify_factors(num, denum))
"""
"""
rval
=
self
.
simplify_constants
(
*
self
.
simplify_factors
(
num
,
denum
),
rval
=
self
.
simplify_constants
(
*
self
.
simplify_factors
(
num
,
denum
),
...
@@ -4338,9 +4347,9 @@ class Canonizer(gof.LocalOptimizer):
...
@@ -4338,9 +4347,9 @@ class Canonizer(gof.LocalOptimizer):
from both lists. Modifies the lists inplace. Returns the
from both lists. Modifies the lists inplace. Returns the
modified lists. For example:
modified lists. For example:
[x], [x] -> [], []
|
[x], [x] -> [], []
[x, y], [x] -> [y], []
|
[x, y], [x] -> [y], []
[a, b], [c, d] -> [a, b], [c, d]
|
[a, b], [c, d] -> [a, b], [c, d]
"""
"""
for
v
in
list
(
num
):
for
v
in
list
(
num
):
...
@@ -4363,9 +4372,9 @@ class Canonizer(gof.LocalOptimizer):
...
@@ -4363,9 +4372,9 @@ class Canonizer(gof.LocalOptimizer):
--------
--------
Let main be multiplication:
Let main be multiplication:
[2, 3, x], [] -> [6, x], []
|
[2, 3, x], [] -> [6, x], []
[x, y, 2], [4, z] -> [0.5, x, y], [z]
|
[x, y, 2], [4, z] -> [0.5, x, y], [z]
[x, 2, y], [z, 2] -> [x, y], [z]
|
[x, 2, y], [z, 2] -> [x, y], [z]
"""
"""
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论