Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
ff2a27d5
提交
ff2a27d5
authored
4月 26, 2011
作者:
Ian Goodfellow
浏览文件
操作
浏览文件
下载
差异文件
merged
上级
a233573d
83c7e294
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
19 个修改的文件
包含
432 行增加
和
121 行删除
+432
-121
how_to_release.txt
doc/internal/how_to_release.txt
+2
-1
config.txt
doc/library/config.txt
+75
-4
shape_info.txt
doc/tutorial/shape_info.txt
+16
-13
__init__.py
theano/__init__.py
+30
-0
debugmode.py
theano/compile/debugmode.py
+7
-1
function_module.py
theano/compile/function_module.py
+48
-4
io.py
theano/compile/io.py
+8
-2
pfunc.py
theano/compile/pfunc.py
+13
-1
test_function_module.py
theano/compile/tests/test_function_module.py
+2
-5
configdefaults.py
theano/configdefaults.py
+39
-1
basic.py
theano/scalar/basic.py
+4
-4
scan.py
theano/scan_module/scan.py
+1
-9
scan_op.py
theano/scan_module/scan_op.py
+0
-0
scan_utils.py
theano/scan_module/scan_utils.py
+0
-0
test_scan.py
theano/scan_module/tests/test_scan.py
+27
-0
test_basic.py
theano/sparse/tests/test_basic.py
+57
-0
basic.py
theano/tensor/basic.py
+16
-7
test_basic.py
theano/tensor/tests/test_basic.py
+87
-64
test_opt.py
theano/tensor/tests/test_opt.py
+0
-5
没有找到文件。
doc/internal/how_to_release.txt
浏览文件 @
ff2a27d5
...
...
@@ -25,7 +25,8 @@ Edit ``setup.py`` to contain the newest version number ::
* Change the ``version`` and ``release`` variables to new version number.
* Change the upper copyright year to the current year if necessary.
* Update the year in the Theano/LICENSE.txt file.
Update the year in the ``Theano/LICENSE.txt`` file too, if necessary.
``NEWS.txt`` usually contains the name and date of the release, change them
too.
...
...
doc/library/config.txt
浏览文件 @
ff2a27d5
...
...
@@ -296,8 +296,79 @@ import theano and print the config variable, as in:
Default: False
Remove compiled file when not needed anymore.
This mean it remove file that he tried to compile but failed.
Set to True to keep the source file that failed to compile to
debug them.
If False, source code files are removed when they are not needed anymore.
This means files whose compilation failed are deleted.
Set to True to keep those files in order to debug compilation errors.
.. attribute:: config.DebugMode
This section contains various attributes configuring the behaviour
of mode :class:`~debugmode.DebugMode`.
.. attribute:: config.numpy.seterr_all
String Value: ``'ignore'``, ``'warn'``, ``'raise'``, ``'call'``,
``'print'``, ``'log'``, ``'None'``
Default: ``'ignore'``
Set the default behaviour described by `numpy.seterr
<http://docs.scipy.org/doc/numpy/reference/generated/numpy.seterr.html>`__.
``'None'`` means that numpy's default behaviour will not be changed (unless
one of the other `config.numpy.seterr_*` overrides it), but this behaviour
can change between numpy releases.
This flag sets the default behaviour for all kinds of floating-pont
errors, and it can be overriden for specific errors by setting one
(or more) of the flags below.
This flag's value cannot be modified during the program execution.
.. attribute:: config.numpy.seterr_divide
String Value: ``'None'``, ``'ignore'``, ``'warn'``, ``'raise'``,
``'call'``, ``'print'``, ``'log'``
Default: ``'None'``
Sets numpy's behavior for division by zero. ``'None'`` means using the
default, defined by config.numpy.seterr_all.
This flag's value cannot be modified during the program execution.
.. attribute:: config.numpy.seterr_over
String Value: ``'None'``, ``'ignore'``, ``'warn'``, ``'raise'``,
``'call'``, ``'print'``, ``'log'``
Default: ``'None'``
Sets numpy's behavior for floating-point overflow. ``'None'`` means
using the default, defined by config.numpy.seterr_all.
This flag's value cannot be modified during the program execution.
.. attribute:: config.numpy.seterr_under
String Value: ``'None'``, ``'ignore'``, ``'warn'``, ``'raise'``,
``'call'``, ``'print'``, ``'log'``
Default: ``'None'``
Sets numpy's behavior for floating-point underflow. ``'None'`` means
using the default, defined by config.numpy.seterr_all.
This flag's value cannot be modified during the program execution.
.. attribute:: numpy.seterr_invalid
String Value: ``'None'``, ``'ignore'``, ``'warn'``, ``'raise'``,
``'call'``, ``'print'``, ``'log'``
Default: ``'None'``
Sets numpy's behavior for invalid floating-point operation. ``'None'``
means using the default, defined by :attr:`config.numpy.seterr_all`.
This flag's value cannot be modified during the program execution.
doc/tutorial/shape_info.txt
浏览文件 @
ff2a27d5
...
...
@@ -38,11 +38,11 @@ output.
Shape inference problem
=======================
Theano
do shape information propag
ation in the graph. Sometimes this
can
had error. E
xample:
Theano
propagates shape inform
ation in the graph. Sometimes this
can
lead to errors. For e
xample:
.. code-block:: python
import numpy
import theano
x = theano.tensor.matrix('x')
...
...
@@ -71,10 +71,10 @@ can had error. Example:
# |Shape_i{1} [@55959184] '' 0
# | |<TensorType(float64, matrix)> [@55583888]
print f(xv,yv)# DO
N
T RAISE AN ERROR AS SHOULD BE.
print f(xv,yv)# DO
ES NO
T RAISE AN ERROR AS SHOULD BE.
#[8,4]
f = theano.function([x,y], z)# Do
n'
t take the shape.
f = theano.function([x,y], z)# Do
no
t take the shape.
theano.printing.debugprint(f)
#Join [@44540496] '' 0
# |0 [@44540432]
...
...
@@ -84,22 +84,25 @@ can had error. Example:
f(xv,yv)
# Raise a dimensions mismatch error.
As you see, when you ask for the shape of some computation(join in the
example), we sometimes compute
the shape without executing the
computation
(there is no join in the first output or debugprint).
As you see, when you ask for the shape of some computation
(join in the
example), we sometimes compute
an inferred shape directly, without executing
the computation itself
(there is no join in the first output or debugprint).
This make
the computation of the shape faster, but can hide error
. In
This make
s the computation of the shape faster, but it can hide errors
. In
the example, the computation of the shape of join is done on the first
theano variable in the join, not on the other.
This can probably happen with many other op as elemwise, dot, ...
Indeed, to make some optimizations (for speed or stability, for instance),
Theano can assume that the computation is correct and consistent
in the first place, this is the case here.
You can detect those problem by running the code without this
optimization
with the t
heano flag
optimization
, with the T
heano flag
`optimizer_excluding=local_shape_to_shape_i`. You can also have the
same effect by running in the mode FAST_COMPILE
(won'
t apply this
optimization
and most other optimization too) or DEBUG_MODE(
will test
before and after all optimizations(much slower)).
same effect by running in the mode FAST_COMPILE
(it will no
t apply this
optimization
, nor most other optimizations) or DEBUG_MODE (it
will test
before and after all optimizations
(much slower)).
Specifing exact shape
...
...
theano/__init__.py
浏览文件 @
ff2a27d5
...
...
@@ -81,6 +81,36 @@ import gof
if
config
.
device
.
startswith
(
'gpu'
)
or
config
.
init_gpu_device
.
startswith
(
'gpu'
):
import
theano.sandbox.cuda
# Use config.numpy to call numpy.seterr
import
numpy
if
config
.
numpy
.
seterr_all
==
'None'
:
_all
=
None
else
:
_all
=
config
.
numpy
.
seterr_all
if
config
.
numpy
.
seterr_divide
==
'None'
:
_divide
=
None
else
:
_divide
=
config
.
numpy
.
seterr_divide
if
config
.
numpy
.
seterr_over
==
'None'
:
_over
=
None
else
:
_over
=
config
.
numpy
.
seterr_over
if
config
.
numpy
.
seterr_under
==
'None'
:
_under
=
None
else
:
_under
=
config
.
numpy
.
seterr_under
if
config
.
numpy
.
seterr_invalid
==
'None'
:
_invalid
=
None
else
:
_invalid
=
config
.
numpy
.
seterr_invalid
numpy
.
seterr
(
all
=
_all
,
divide
=
_divide
,
over
=
_over
,
under
=
_under
,
invalid
=
_invalid
)
del
_all
,
_divide
,
_over
,
_under
,
_invalid
## import scalar_opt
### This is defined here because it is designed to work across symbolic datatypes
...
...
theano/compile/debugmode.py
浏览文件 @
ff2a27d5
...
...
@@ -535,7 +535,13 @@ def _check_inputs(node, storage_map, r_vals, dr_vals, active_nodes, clobber_dr_v
if
warn_input_not_reused
and
destroyed_res_list
:
dmap
=
getattr
(
node
.
op
,
'destroy_map'
,{})
for
oo
,
ii
in
dmap
.
iteritems
():
if
storage_map
[
node
.
outputs
[
oo
]][
0
]
is
not
storage_map
[
node
.
inputs
[
ii
[
0
]]][
0
]:
out_var
=
storage_map
[
node
.
outputs
[
oo
]][
0
]
in_var
=
storage_map
[
node
.
inputs
[
ii
[
0
]]][
0
]
if
isinstance
(
node
.
op
,
theano
.
compile
.
mode
.
OutputGuard
):
# The point of OutputGuard is to be declared as destructive
# while not destroying anything
continue
if
out_var
is
not
in_var
:
opt_warning
(
"input idx
%
d marked as destroyed was not changed for node '
%
s'"
%
(
ii
[
0
],
str
(
node
)))
if
warn_input_not_reused
:
...
...
theano/compile/function_module.py
浏览文件 @
ff2a27d5
...
...
@@ -190,7 +190,36 @@ class DeepCopyOp(theano.gof.Op):
else
:
super
(
DeepCopyOp
,
self
)
.
c_code
(
node
,
name
,
inames
,
onames
,
sub
)
class
ViewOp
(
theano
.
gof
.
Op
):
def
__init__
(
self
):
self
.
view_map
=
{
0
:[
0
]}
def
__str__
(
self
):
return
self
.
__class__
.
__name__
def
__hash__
(
self
):
return
hash
(
type
(
self
))
def
__eq__
(
self
,
other
):
return
type
(
self
)
==
type
(
other
)
def
make_node
(
self
,
x
):
return
theano
.
gof
.
Apply
(
self
,
[
x
],
[
x
.
type
()])
def
perform
(
self
,
node
,
args
,
outs
):
outs
[
0
][
0
]
=
args
[
0
]
def
infer_shape
(
self
,
node
,
input_shapes
):
return
input_shapes
def
grad
(
self
,
args
,
g_outs
):
return
g_outs
deep_copy_op
=
DeepCopyOp
()
view_op
=
ViewOp
()
DUPLICATE
=
[
'DUPLICATE'
]
# unique id object used as a placeholder for duplicate entries
class
Function
(
object
):
...
...
@@ -771,7 +800,10 @@ def insert_deepcopy(env, wrapped_inputs, wrapped_outputs):
# We could don't put deep copy if both outputs have borrow==True
# and not(wrapped_outputs[i].borrow and wrapped_outputs[j].borrow):
if
env
.
outputs
[
j
]
in
views_of_output_i
:
env
.
change_input
(
'output'
,
i
,
deep_copy_op
(
env
.
outputs
[
i
]))
if
wrapped_outputs
[
i
]
.
borrow
and
wrapped_outputs
[
j
]
.
borrow
:
env
.
change_input
(
'output'
,
i
,
view_op
(
env
.
outputs
[
i
]))
else
:
env
.
change_input
(
'output'
,
i
,
deep_copy_op
(
env
.
outputs
[
i
]))
copied
=
True
break
...
...
@@ -784,10 +816,22 @@ def insert_deepcopy(env, wrapped_inputs, wrapped_outputs):
continue
if
input_j
in
updated_env_inputs
:
continue
# We could don't put deep_copy_op if the input and the output have borrow==True
if
input_j
in
views_of_output_i
:
env
.
change_input
(
'output'
,
i
,
deep_copy_op
(
env
.
outputs
[
i
]))
break
# We don't put deep_copy_op if the input and the output have borrow==True
if
input_j
in
env
.
inputs
:
j
=
env
.
inputs
.
index
(
input_j
)
if
wrapped_outputs
[
i
]
.
borrow
and
wrapped_inputs
[
j
]
.
borrow
:
env
.
change_input
(
'output'
,
i
,
view_op
(
env
.
outputs
[
i
]))
break
else
:
env
.
change_input
(
'output'
,
i
,
deep_copy_op
(
env
.
outputs
[
i
]))
break
elif
wrapped_outputs
[
i
]
.
borrow
:
env
.
change_input
(
'output'
,
i
,
view_op
(
env
.
outputs
[
i
]))
break
else
:
env
.
change_input
(
'output'
,
i
,
deep_copy_op
(
env
.
outputs
[
i
]))
break
NODEFAULT
=
[
'NODEFAULT'
]
class
FunctionMaker
(
object
):
...
...
theano/compile/io.py
浏览文件 @
ff2a27d5
...
...
@@ -164,6 +164,11 @@ class In(SymbolicInput):
True: permit the compiled function to modify the python object being passed as the input
False: do not permit the compiled function to modify the python object being passed as the input.
borrow: Bool (default: False if update is None, True if update is not None)
True: permit the output of the compiled function to be aliased to the input
False: do not permit any output to be aliased to the input
strict: Bool (default: False)
True: means that the value you pass for this input must have exactly the right type
False: the value you pass for this input may be cast automatically to the proper type
...
...
@@ -194,7 +199,7 @@ class In(SymbolicInput):
def
__init__
(
self
,
variable
,
name
=
None
,
value
=
None
,
update
=
None
,
mutable
=
None
,
strict
=
False
,
allow_downcast
=
None
,
autoname
=
True
,
implicit
=
None
,
borrow
=
None
):
# mutable implies the output can be both aliased to the input and that the input can be
# destroyed. borrow simply implies the output can be aliased to the input. Thus
# mutable=True should require borrow=True. Raise warning when borrow is explicitely set
...
...
@@ -210,7 +215,7 @@ class In(SymbolicInput):
# borrow=None basically means False. We can't set default value to False because of the
# above business with mutable.
if
borrow
is
None
:
if
borrow
is
None
:
borrow
=
False
if
implicit
is
None
:
...
...
@@ -226,6 +231,7 @@ class In(SymbolicInput):
autoname
=
autoname
,
implicit
=
implicit
)
self
.
value
=
value
self
.
borrow
=
borrow
if
self
.
implicit
and
value
is
None
:
raise
TypeError
(
'An implicit input must be given a default value'
)
...
...
theano/compile/pfunc.py
浏览文件 @
ff2a27d5
...
...
@@ -244,7 +244,7 @@ def rebuild_collect_shared( outputs
class
Param
(
object
):
def
__init__
(
self
,
variable
,
default
=
None
,
name
=
None
,
mutable
=
False
,
strict
=
False
,
allow_downcast
=
None
,
implicit
=
None
):
strict
=
False
,
allow_downcast
=
None
,
implicit
=
None
,
borrow
=
False
):
"""
:param variable: A variable in an expression graph to use as a compiled-function parameter
...
...
@@ -255,6 +255,11 @@ class Param(object):
:param mutable: True -> function is allowed to modify this argument.
:param borrow: True -> function is allowed to alias some output to
this input
False: do not permit any output to be aliased to the input
:param strict: False -> function arguments may be copied or casted to match the
type required by the parameter `variable`. True -> function arguments must exactly match the type
required by `variable`.
...
...
@@ -271,9 +276,15 @@ class Param(object):
self
.
default
=
default
self
.
name
=
name
self
.
mutable
=
mutable
# Mutable implies borrow. You can get borrow = False because of the
# default and it is a bit annoying to require the user to set both
# borrow and mutable to True
if
mutable
:
borrow
=
True
self
.
strict
=
strict
self
.
allow_downcast
=
allow_downcast
self
.
implicit
=
implicit
self
.
borrow
=
borrow
def
pfunc
(
params
,
outputs
=
None
,
mode
=
None
,
updates
=
[],
givens
=
[],
no_default_updates
=
False
,
accept_inplace
=
False
,
name
=
None
,
...
...
@@ -396,6 +407,7 @@ def _pfunc_param_to_in(param, strict=False, allow_downcast=None):
value
=
param
.
default
,
mutable
=
param
.
mutable
,
strict
=
param
.
strict
,
borrow
=
param
.
borrow
,
allow_downcast
=
param
.
allow_downcast
,
implicit
=
param
.
implicit
)
raise
TypeError
(
'Unknown parameter type:
%
s'
%
type
(
param
))
...
...
theano/compile/tests/test_function_module.py
浏览文件 @
ff2a27d5
...
...
@@ -304,11 +304,8 @@ class T_function(unittest.TestCase):
assert
(
out
==
4
)
.
all
()
out
[
0
]
=
3
out2
=
f
()
# Currently we don't do this optimization!
# As this is a corner case that is not usefull for use
# We probably won't optimize it.
assert
out2
is
not
out
assert
(
out2
==
4
)
.
all
()
assert
out2
is
out
assert
(
out2
==
3
)
.
all
()
def
test_borrow_input
(
self
):
...
...
theano/configdefaults.py
浏览文件 @
ff2a27d5
...
...
@@ -71,7 +71,7 @@ AddConfigVar('home',
#This expanduser works on windows (see discussion on theano-users, July 13 2010)
AddConfigVar
(
'nocleanup'
,
"
s
uppress the deletion of code files that did not compile cleanly"
,
"
S
uppress the deletion of code files that did not compile cleanly"
,
BoolParam
(
False
))
AddConfigVar
(
'tensor.cmp_sloppy'
,
...
...
@@ -115,6 +115,44 @@ AddConfigVar('experimental.mrg',
"Another random number generator that work on the gpu"
,
BoolParam
(
False
))
AddConfigVar
(
'numpy.seterr_all'
,
(
"Sets numpy's behaviour for floating-point errors, "
,
"see numpy.seterr. "
"'None' means not to change numpy's default, which can be "
"different for different numpy releases. "
"This flag sets the default behaviour for all kinds of floating-"
"point errors, its effect can be overriden for specific errors "
"by the following flags: seterr_divide, seterr_over, "
"seterr_under and seterr_invalid."
),
EnumStr
(
'ignore'
,
'warn'
,
'raise'
,
'call'
,
'print'
,
'log'
,
'None'
,
allow_override
=
False
))
AddConfigVar
(
'numpy.seterr_divide'
,
(
"Sets numpy's behavior for division by zero, see numpy.seterr. "
"'None' means using the default, defined by numpy.seterr_all."
),
EnumStr
(
'None'
,
'ignore'
,
'warn'
,
'raise'
,
'call'
,
'print'
,
'log'
,
allow_override
=
False
))
AddConfigVar
(
'numpy.seterr_over'
,
(
"Sets numpy's behavior for floating-point overflow, "
"see numpy.seterr. "
"'None' means using the default, defined by numpy.seterr_all."
),
EnumStr
(
'None'
,
'ignore'
,
'warn'
,
'raise'
,
'call'
,
'print'
,
'log'
,
allow_override
=
False
))
AddConfigVar
(
'numpy.seterr_under'
,
(
"Sets numpy's behavior for floating-point underflow, "
"see numpy.seterr. "
"'None' means using the default, defined by numpy.seterr_all."
),
EnumStr
(
'None'
,
'ignore'
,
'warn'
,
'raise'
,
'call'
,
'print'
,
'log'
,
allow_override
=
False
))
AddConfigVar
(
'numpy.seterr_invalid'
,
(
"Sets numpy's behavior for invalid floating-point operation, "
"see numpy.seterr. "
"'None' means using the default, defined by numpy.seterr_all."
),
EnumStr
(
'None'
,
'ignore'
,
'warn'
,
'raise'
,
'call'
,
'print'
,
'log'
,
allow_override
=
False
))
###
### To disable some warning about old bug that are fixed now.
...
...
theano/scalar/basic.py
浏览文件 @
ff2a27d5
...
...
@@ -5,10 +5,10 @@ WARNING
This directory is for the internal of Theano.
You are strongly advi
ced to don't use it
except if you know
what you
do
!
You are strongly advi
sed not to use it,
except if you know
what you
are doing
!
If you want to use scalar variable in a Theano graph,
If you want to use
a
scalar variable in a Theano graph,
you probably want to use theano.tensor.[c,z,f,d,b,w,i,l,]scalar!
"""
...
...
@@ -113,7 +113,7 @@ class Scalar(Type):
raise
TypeError
(
"Could not convert
%
s (value=
%
s) to
%
s"
%
(
type
(
data
),
data
,
self
.
dtype
),
e
)
def
values_eq_approx
(
self
,
a
,
b
,
tolerance
=
1e-4
):
return
abs
(
a
-
b
)
/
(
a
+
b
)
<
tolerance
return
abs
(
a
-
b
)
<=
((
abs
(
a
)
+
abs
(
b
))
*
tolerance
)
def
c_headers
(
self
):
l
=
[
'<math.h>'
]
...
...
theano/scan_module/scan.py
浏览文件 @
ff2a27d5
...
...
@@ -846,15 +846,7 @@ def scan( fn
info
[
'inplace'
]
=
False
info
[
'gpu'
]
=
False
revised_outs
=
[]
for
o
in
new_outs
:
if
(
o
in
inner_inputs
or
isinstance
(
o
,
tensor
.
Constant
)):
revised_outs
.
append
(
scan_utils
.
cloneOp
(
o
))
else
:
revised_outs
.
append
(
o
)
local_op
=
scan_op
.
Scan
(
inner_inputs
,
revised_outs
,
info
)
local_op
=
scan_op
.
Scan
(
inner_inputs
,
new_outs
,
info
)
##
### Step 8. Compute the outputs using the scan op
...
...
theano/scan_module/scan_op.py
浏览文件 @
ff2a27d5
差异被折叠。
点击展开。
theano/scan_module/scan_utils.py
浏览文件 @
ff2a27d5
差异被折叠。
点击展开。
theano/scan_module/tests/test_scan.py
浏览文件 @
ff2a27d5
...
...
@@ -2007,7 +2007,34 @@ class T_Scan(unittest.TestCase):
assert
scan1
.
owner
.
op
==
scan2
.
owner
.
op
assert
hash
(
scan1
.
owner
.
op
)
==
hash
(
scan2
.
owner
.
op
)
def
test_same
(
self
):
# This test is checking a bug discovered by Arnaud and it is based
# on his code
x
=
theano
.
tensor
.
fmatrix
(
'x'
)
mem_val
=
numpy
.
zeros
((
2
,),
dtype
=
'float32'
)
memory
=
theano
.
shared
(
mem_val
.
copy
())
W
=
theano
.
shared
(
numpy
.
random
.
random
((
5
,
2
))
.
astype
(
'float32'
))
def
f
(
inp
,
mem
):
i
=
theano
.
tensor
.
join
(
0
,
inp
,
mem
)
d
=
theano
.
tensor
.
dot
(
i
,
W
)
return
d
,
d
outs
,
updts
=
theano
.
scan
(
f
,
sequences
=
[
x
],
non_sequences
=
[],
outputs_info
=
[
None
,
memory
])
f
=
theano
.
function
([
x
],
outs
[
0
])
f2
=
theano
.
function
([
x
],
outs
[
1
])
x_val
=
numpy
.
random
.
random
((
4
,
3
))
.
astype
(
'float32'
)
f_vals
=
f
(
x_val
)
memory
.
set_value
(
mem_val
.
copy
())
f2_vals
=
f2
(
x_val
)
assert
numpy
.
allclose
(
f_vals
,
f2_vals
)
if
__name__
==
'__main__'
:
#'''
...
...
theano/sparse/tests/test_basic.py
浏览文件 @
ff2a27d5
...
...
@@ -190,6 +190,63 @@ class T_AddMul(unittest.TestCase):
self
.
assertTrue
(
numpy
.
all
(
val
.
todense
()
==
numpy
.
array
([[
1
,
0
],
[
9
,
0
],
[
0
,
36
]])))
def
test_upcast
(
self
):
array1
=
numpy
.
array
([[
1
,
0
],
[
3
,
0
],
[
0
,
6
]],
dtype
=
'float32'
)
array2
=
numpy
.
array
([[
1
,
0
],
[
3
,
0
],
[
0
,
6
]],
dtype
=
'int32'
)
array3
=
numpy
.
array
([[
1
,
0
],
[
3
,
0
],
[
0
,
6
]],
dtype
=
'int8'
)
# AddSS and MulSS
for
mtype
in
_mtypes
:
a
=
mtype
(
array1
)
aR
=
as_sparse_variable
(
a
)
b
=
mtype
(
array2
)
bR
=
as_sparse_variable
(
b
)
c
=
mtype
(
array3
)
cR
=
as_sparse_variable
(
c
)
# Ops that do not upcast
self
.
assertRaises
(
NotImplementedError
,
add
,
aR
,
bR
)
self
.
assertRaises
(
NotImplementedError
,
add
,
bR
,
aR
)
self
.
assertRaises
(
NotImplementedError
,
add
,
bR
,
cR
)
self
.
assertRaises
(
NotImplementedError
,
add
,
cR
,
bR
)
self
.
assertRaises
(
NotImplementedError
,
add
,
aR
,
cR
)
self
.
assertRaises
(
NotImplementedError
,
add
,
cR
,
aR
)
self
.
assertRaises
(
NotImplementedError
,
mul
,
aR
,
bR
)
self
.
assertRaises
(
NotImplementedError
,
mul
,
bR
,
aR
)
self
.
assertRaises
(
NotImplementedError
,
mul
,
bR
,
cR
)
self
.
assertRaises
(
NotImplementedError
,
mul
,
cR
,
bR
)
self
.
assertRaises
(
NotImplementedError
,
mul
,
aR
,
cR
)
self
.
assertRaises
(
NotImplementedError
,
mul
,
cR
,
aR
)
# AddSD and MulSD
for
mtype
in
_mtypes
:
a
=
mtype
(
array1
)
a_sv
=
as_sparse_variable
(
a
)
a_dv
=
tensor
.
as_tensor_variable
(
array1
)
b
=
mtype
(
array2
)
b_sv
=
as_sparse_variable
(
b
)
b_dv
=
tensor
.
as_tensor_variable
(
array2
)
c
=
mtype
(
array3
)
c_sv
=
as_sparse_variable
(
c
)
c_dv
=
tensor
.
as_tensor_variable
(
array3
)
# add does not upcast
self
.
assertRaises
(
NotImplementedError
,
add
,
a_sv
,
b_dv
)
self
.
assertRaises
(
NotImplementedError
,
add
,
b_sv
,
a_dv
)
self
.
assertRaises
(
NotImplementedError
,
add
,
b_sv
,
c_dv
)
self
.
assertRaises
(
NotImplementedError
,
add
,
c_sv
,
b_dv
)
self
.
assertRaises
(
NotImplementedError
,
add
,
a_sv
,
c_dv
)
self
.
assertRaises
(
NotImplementedError
,
add
,
c_sv
,
a_dv
)
# mul upcasts the dense input if needed
self
.
assertRaises
(
NotImplementedError
,
mul
,
a_sv
,
b_dv
)
self
.
assertRaises
(
NotImplementedError
,
mul
,
b_sv
,
a_dv
)
assert
mul
(
b_sv
,
c_dv
)
.
dtype
==
'int32'
self
.
assertRaises
(
NotImplementedError
,
mul
,
c_sv
,
b_dv
)
assert
mul
(
a_sv
,
c_dv
)
.
dtype
==
'float32'
self
.
assertRaises
(
NotImplementedError
,
mul
,
c_sv
,
a_dv
)
class
T_conversion
(
unittest
.
TestCase
):
def
setUp
(
self
):
...
...
theano/tensor/basic.py
浏览文件 @
ff2a27d5
...
...
@@ -3753,7 +3753,7 @@ class Reshape(Op):
shp_orig
=
shp
shp
=
as_tensor_variable
(
shp
,
ndim
=
1
)
if
not
shp
.
dtype
.
startswith
(
'int'
):
raise
TypeError
(
"Shape must be integers"
)
raise
TypeError
(
"Shape must be integers"
,
shp
,
shp
.
dtype
)
assert
shp
.
ndim
==
1
if
isinstance
(
shp
,
TensorConstant
):
bcast
=
[
s
==
1
for
s
in
shp
.
data
]
...
...
@@ -3788,9 +3788,18 @@ class Reshape(Op):
g_out
,
=
grads
return
[
reshape
(
g_out
,
shape
(
x
),
ndim
=
x
.
ndim
),
None
]
def
infer_shape
(
self
,
node
,
ishapes
):
#we can't just put node.inputs[1] as not all op support interation
#and this is needed in the ShapeOptimizer
return
[
tuple
([
node
.
inputs
[
1
][
i
]
for
i
in
range
(
self
.
ndim
)])]
# inputs[1] can contain at most one value of '-1', meaning the actual
# shape of the output will be automatically computed by reshape, so
# that the total number of elements stays the same.
# TODO: Maybe put that formula here?
# It's not trivial, because we would have to check if the product of
# all the non-minus-one shapes is a divisor of the product of the
# original shapes.
return
[
tuple
([
switch
(
eq
(
node
.
inputs
[
1
][
i
],
-
1
),
theano
.
tensor
.
opt
.
Shape_i
(
i
)(
node
.
outputs
[
0
]),
node
.
inputs
[
1
][
i
])
for
i
in
range
(
self
.
ndim
)]
)]
def
reshape
(
x
,
newshape
,
ndim
=
None
,
name
=
None
):
if
ndim
is
None
:
...
...
@@ -4739,10 +4748,10 @@ def grad(cost, wrt, g_cost=None, consider_constant=[], warn_type=False,
ret
=
[]
for
p
in
wrt
:
if
p
not
in
gmap
and
not
assume_continuously_differentiable
:
raise
ValueError
((
"grad method was asked to compute the gra
id
ent "
raise
ValueError
((
"grad method was asked to compute the gra
di
ent "
"with respect to a variable that is not part of "
"the computational graph of the cost or is used "
"by a non-differentiable operator
"
),
p
)
"the computational graph of the cost
,
or is used "
"by a non-differentiable operator
"
),
p
)
else
:
ret
.
append
(
gmap
.
get
(
p
,
zeros_like
(
p
)))
...
...
theano/tensor/tests/test_basic.py
浏览文件 @
ff2a27d5
...
...
@@ -3290,79 +3290,102 @@ class T_op_cache(unittest.TestCase):
a
=
numpy
.
random
.
rand
(
5
,
2
)
.
astype
(
config
.
floatX
)
self
.
assertTrue
(
numpy
.
all
(
fn_py
(
a
)
==
fn_c_or_py
(
a
)))
class
T_reshape
(
unittest
.
TestCase
):
def
setUp
(
self
):
utt
.
seed_rng
()
def
test_reshape
():
a
=
dvector
()
b
=
dmatrix
()
d
=
dmatrix
()
#basic to 1 dim(without list)
c
=
reshape
(
b
,
as_tensor_variable
(
6
),
ndim
=
1
)
f
=
inplace_func
([
b
],
c
)
assert
numpy
.
all
(
f
(
numpy
.
asarray
([[
0
,
1
,
2
],[
3
,
4
,
5
]]))
==
numpy
.
asarray
([
0
,
1
,
2
,
3
,
4
,
5
]))
#print f.maker.env.toposort()
#check that we remove the useless reshape
#basic to 1 dim(with list)
c
=
reshape
(
b
,
(
as_tensor_variable
(
6
),),
ndim
=
1
)
f
=
inplace_func
([
b
],
c
)
assert
numpy
.
all
(
f
(
numpy
.
asarray
([[
0
,
1
,
2
],[
3
,
4
,
5
]]))
==
numpy
.
asarray
([
0
,
1
,
2
,
3
,
4
,
5
]))
#print f.maker.env.toposort()
#check that we remove the useless reshape
#basic to shape object of same ndim
c
=
reshape
(
b
,
d
.
shape
)
f
=
inplace_func
([
b
,
d
],
c
)
assert
numpy
.
all
(
f
(
numpy
.
asarray
([[
0
,
1
,
2
],[
3
,
4
,
5
]]),[[
0
,
1
],[
2
,
3
],[
4
,
5
]])
==
numpy
.
asarray
([[
0
,
1
],[
2
,
3
],[
4
,
5
]]))
#basic to 2 dims
c
=
reshape
(
a
,
[
2
,
3
])
f
=
inplace_func
([
a
],
c
)
assert
numpy
.
all
(
f
(
numpy
.
asarray
([
0
,
1
,
2
,
3
,
4
,
5
]))
==
numpy
.
asarray
([[
0
,
1
,
2
],
[
3
,
4
,
5
]]))
#test that it works without inplace operations
a_val
=
numpy
.
asarray
([
0
,
1
,
2
,
3
,
4
,
5
])
a_val_copy
=
numpy
.
asarray
([
0
,
1
,
2
,
3
,
4
,
5
])
b_val
=
numpy
.
asarray
([[
0
,
1
,
2
],[
3
,
4
,
5
]])
def
test_reshape
(
self
):
a
=
dvector
()
b
=
dmatrix
()
d
=
dmatrix
()
#basic to 1 dim(without list)
c
=
reshape
(
b
,
as_tensor_variable
(
6
),
ndim
=
1
)
f
=
inplace_func
([
b
],
c
)
assert
numpy
.
all
(
f
(
numpy
.
asarray
([[
0
,
1
,
2
],[
3
,
4
,
5
]]))
==
numpy
.
asarray
([
0
,
1
,
2
,
3
,
4
,
5
]))
#print f.maker.env.toposort()
#check that we remove the useless reshape
#basic to 1 dim(with list)
c
=
reshape
(
b
,
(
as_tensor_variable
(
6
),),
ndim
=
1
)
f
=
inplace_func
([
b
],
c
)
assert
numpy
.
all
(
f
(
numpy
.
asarray
([[
0
,
1
,
2
],[
3
,
4
,
5
]]))
==
numpy
.
asarray
([
0
,
1
,
2
,
3
,
4
,
5
]))
#print f.maker.env.toposort()
#check that we remove the useless reshape
#basic to shape object of same ndim
c
=
reshape
(
b
,
d
.
shape
)
f
=
inplace_func
([
b
,
d
],
c
)
assert
numpy
.
all
(
f
(
numpy
.
asarray
([[
0
,
1
,
2
],[
3
,
4
,
5
]]),[[
0
,
1
],[
2
,
3
],[
4
,
5
]])
==
numpy
.
asarray
([[
0
,
1
],[
2
,
3
],[
4
,
5
]]))
#basic to 2 dims
c
=
reshape
(
a
,
[
2
,
3
])
f
=
inplace_func
([
a
],
c
)
assert
numpy
.
all
(
f
(
numpy
.
asarray
([
0
,
1
,
2
,
3
,
4
,
5
]))
==
numpy
.
asarray
([[
0
,
1
,
2
],
[
3
,
4
,
5
]]))
#test that it works without inplace operations
a_val
=
numpy
.
asarray
([
0
,
1
,
2
,
3
,
4
,
5
])
a_val_copy
=
numpy
.
asarray
([
0
,
1
,
2
,
3
,
4
,
5
])
b_val
=
numpy
.
asarray
([[
0
,
1
,
2
],[
3
,
4
,
5
]])
f_sub
=
inplace_func
([
a
,
b
],
c
-
b
)
assert
numpy
.
all
(
f_sub
(
a_val
,
b_val
)
==
0.0
)
assert
numpy
.
all
(
a_val
==
a_val_copy
)
#test that it works with inplace operations
a_val
=
theano
.
_asarray
([
0
,
1
,
2
,
3
,
4
,
5
],
dtype
=
'float64'
)
a_val_copy
=
theano
.
_asarray
([
0
,
1
,
2
,
3
,
4
,
5
],
dtype
=
'float64'
)
b_val
=
theano
.
_asarray
([[
0
,
1
,
2
],[
3
,
4
,
5
]],
dtype
=
'float64'
)
f_sub
=
inplace_func
([
a
,
b
],
c
-
b
)
assert
numpy
.
all
(
f_sub
(
a_val
,
b_val
)
==
0.0
)
assert
numpy
.
all
(
a_val
==
a_val_copy
)
# verify gradient
def
just_vals
(
v
):
return
Reshape
(
2
)(
v
,
theano
.
_asarray
([
2
,
3
],
dtype
=
'int32'
))
utt
.
verify_grad
(
just_vals
,
[
a_val
])
#test infer_shape
f_sub
=
function
([
a
,
b
],
(
c
-
b
)
.
shape
)
if
config
.
mode
==
"FAST_COMPILE"
:
assert
len
(
f_sub
.
maker
.
env
.
toposort
())
==
3
else
:
topo
=
f_sub
.
maker
.
env
.
toposort
()
assert
len
(
topo
)
==
1
topo
[
0
]
.
op
==
theano
.
compile
.
function_module
.
deep_copy_op
#assert numpy.all(f_sub(a_val,numpy.asarray([[0,1],[2,3],[4,5]]))==[2,3])#work in FAST_RUN, but fail on other!
#assert numpy.all(f_sub(a_val,numpy.asarray([[0,1],[2,3],[4,5],[6,7]]))==[2,3])#work in FAST_RUN, but fail on other!
f_sub
=
inplace_func
([
a
,
b
],
c
-
b
)
assert
numpy
.
all
(
f_sub
(
a_val
,
b_val
)
==
0.0
)
assert
numpy
.
all
(
a_val
==
a_val_copy
)
# test broadcast flag for constant value of 1
c
=
reshape
(
b
,
(
b
.
shape
[
0
],
b
.
shape
[
1
],
1
))
f
=
inplace_func
([
b
],
c
)
assert
numpy
.
all
(
f
(
numpy
.
asarray
([[
0
,
1
,
2
],[
3
,
4
,
5
]]))
==
numpy
.
asarray
([[[
0
],[
1
],[
2
]],[[
3
],[
4
],[
5
]]]))
assert
f
.
maker
.
env
.
toposort
()[
-
2
]
.
outputs
[
0
]
.
type
.
broadcastable
==
(
False
,
False
,
True
)
#test that it works with inplace operations
a_val
=
theano
.
_asarray
([
0
,
1
,
2
,
3
,
4
,
5
],
dtype
=
'float64'
)
a_val_copy
=
theano
.
_asarray
([
0
,
1
,
2
,
3
,
4
,
5
],
dtype
=
'float64'
)
b_val
=
theano
.
_asarray
([[
0
,
1
,
2
],[
3
,
4
,
5
]],
dtype
=
'float64'
)
assert
numpy
.
all
(
f_sub
(
a_val
,
b_val
)
==
[
2
,
3
])
f_sub
=
inplace_func
([
a
,
b
],
c
-
b
)
assert
numpy
.
all
(
f_sub
(
a_val
,
b_val
)
==
0.0
)
assert
numpy
.
all
(
a_val
==
a_val_copy
)
def
test_infer_shape
(
self
):
a
=
matrix
(
'a'
)
shapes
=
ivector
(
'shapes'
)
ndim
=
2
# verify gradient
def
just_vals
(
v
):
return
Reshape
(
2
)(
v
,
theano
.
_asarray
([
2
,
3
],
dtype
=
'int32'
))
utt
.
verify_grad
(
just_vals
,
[
a_val
])
r
=
a
.
reshape
(
shapes
,
ndim
=
2
)
z
=
zeros_like
(
r
)
#test infer_shape
f_sub
=
function
([
a
,
b
],
(
c
-
b
)
.
shape
)
if
config
.
mode
==
"FAST_COMPILE"
:
assert
len
(
f_sub
.
maker
.
env
.
toposort
())
==
3
else
:
topo
=
f_sub
.
maker
.
env
.
toposort
()
assert
len
(
topo
)
==
1
topo
[
0
]
.
op
==
theano
.
compile
.
function_module
.
deep_copy_op
#assert numpy.all(f_sub(a_val,numpy.asarray([[0,1],[2,3],[4,5]]))==[2,3])#work in FAST_RUN, but fail on other!
#assert numpy.all(f_sub(a_val,numpy.asarray([[0,1],[2,3],[4,5],[6,7]]))==[2,3])#work in FAST_RUN, but fail on other!
f
=
function
([
a
,
shapes
],
z
.
shape
)
# test broadcast flag for constant value of 1
c
=
reshape
(
b
,
(
b
.
shape
[
0
],
b
.
shape
[
1
],
1
))
f
=
inplace_func
([
b
],
c
)
assert
numpy
.
all
(
f
(
numpy
.
asarray
([[
0
,
1
,
2
],[
3
,
4
,
5
]]))
==
numpy
.
asarray
([[[
0
],[
1
],[
2
]],[[
3
],[
4
],[
5
]]]))
assert
f
.
maker
.
env
.
toposort
()[
-
2
]
.
outputs
[
0
]
.
type
.
broadcastable
==
(
False
,
False
,
True
)
rng
=
numpy
.
random
.
RandomState
(
seed
=
utt
.
fetch_seed
())
a_val
=
rng
.
uniform
(
size
=
(
3
,
4
))
.
astype
(
config
.
floatX
)
self
.
assertTrue
((
f
(
a_val
,
[
4
,
3
])
==
[
4
,
3
])
.
all
())
self
.
assertTrue
((
f
(
a_val
,
[
-
1
,
3
])
==
[
4
,
3
])
.
all
())
self
.
assertTrue
((
f
(
a_val
,
[
4
,
-
1
])
==
[
4
,
3
])
.
all
())
self
.
assertRaises
(
ValueError
,
f
,
a_val
,
[
-
1
,
5
])
self
.
assertRaises
(
ValueError
,
f
,
a_val
,
[
7
,
-
1
])
self
.
assertRaises
(
ValueError
,
f
,
a_val
,
[
7
,
5
])
self
.
assertRaises
(
ValueError
,
f
,
a_val
,
[
-
1
,
-
1
])
assert
numpy
.
all
(
f_sub
(
a_val
,
b_val
)
==
[
2
,
3
])
def
test_make_column_matrix_broadcastable
():
# The goal of the operation made by `b` is to ensure the second dimension
...
...
theano/tensor/tests/test_opt.py
浏览文件 @
ff2a27d5
...
...
@@ -2787,11 +2787,6 @@ def test_local_tensor_scalar_tensor():
assert
len
(
cast_nodes
)
==
0
f
(
0
)
@dec.knownfailureif
(
isinstance
(
theano
.
compile
.
mode
.
get_default_mode
(),
theano
.
compile
.
debugmode
.
DebugMode
),
(
"This test fails in DEBUG_MODE, but the generated code is OK. "
"It is actually a problem of DEBUG_MODE, see #624."
))
def
test_local_scalar_tensor_scalar
():
dtypes
=
[
'int8'
,
'int16'
,
'int32'
,
'int64'
,
'uint8'
,
'uint16'
,
'uint32'
,
'uint64'
,
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论