Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
2317ffbb
提交
2317ffbb
authored
4月 21, 2011
作者:
Ian Goodfellow
浏览文件
操作
浏览文件
下载
差异文件
merge
上级
5a72ab8b
6b16e20c
全部展开
显示空白字符变更
内嵌
并排
正在显示
24 个修改的文件
包含
474 行增加
和
86 行删除
+474
-86
LICENSE.txt
doc/LICENSE.txt
+1
-1
how_to_release.txt
doc/internal/how_to_release.txt
+1
-0
shape_info.txt
doc/tutorial/shape_info.txt
+72
-6
function_module.py
theano/compile/function_module.py
+3
-1
test_function_module.py
theano/compile/tests/test_function_module.py
+30
-0
gradient.py
theano/gradient.py
+22
-4
latence_gpu_transfert.py
theano/misc/latence_gpu_transfert.py
+19
-0
printing.py
theano/printing.py
+3
-2
raise_op.py
theano/raise_op.py
+36
-0
opt.py
theano/sandbox/cuda/opt.py
+1
-1
rng_mrg.py
theano/sandbox/rng_mrg.py
+2
-2
test_rng_mrg.py
theano/sandbox/test_rng_mrg.py
+27
-17
basic.py
theano/scalar/basic.py
+16
-3
__init__.py
theano/scan_module/__init__.py
+22
-7
scan.py
theano/scan_module/scan.py
+2
-14
scan_op.py
theano/scan_module/scan_op.py
+0
-0
scan_utils.py
theano/scan_module/scan_utils.py
+0
-1
test_scan.py
theano/scan_module/tests/test_scan.py
+21
-2
basic.py
theano/tensor/basic.py
+90
-9
opt.py
theano/tensor/opt.py
+9
-4
test_basic.py
theano/tensor/tests/test_basic.py
+66
-5
test_opt.py
theano/tensor/tests/test_opt.py
+19
-6
test_sharedvar.py
theano/tensor/tests/test_sharedvar.py
+2
-1
test_gradient.py
theano/tests/test_gradient.py
+10
-0
没有找到文件。
doc/LICENSE.txt
浏览文件 @
2317ffbb
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
LICENSE
LICENSE
=======
=======
Copyright (c) 2008--20
09
, Theano Development Team
Copyright (c) 2008--20
11
, Theano Development Team
All rights reserved.
All rights reserved.
Redistribution and use in source and binary forms, with or without
Redistribution and use in source and binary forms, with or without
...
...
doc/internal/how_to_release.txt
浏览文件 @
2317ffbb
...
@@ -25,6 +25,7 @@ Edit ``setup.py`` to contain the newest version number ::
...
@@ -25,6 +25,7 @@ Edit ``setup.py`` to contain the newest version number ::
* Change the ``version`` and ``release`` variables to new version number.
* Change the ``version`` and ``release`` variables to new version number.
* Change the upper copyright year to the current year if necessary.
* Change the upper copyright year to the current year if necessary.
* Update the year in the Theano/LICENSE.txt file.
``NEWS.txt`` usually contains the name and date of the release, change them
``NEWS.txt`` usually contains the name and date of the release, change them
too.
too.
...
...
doc/tutorial/shape_info.txt
浏览文件 @
2317ffbb
...
@@ -22,19 +22,85 @@ Currently shape informations are used for 2 things in Theano:
...
@@ -22,19 +22,85 @@ Currently shape informations are used for 2 things in Theano:
.. code-block:: python
.. code-block:: python
import theano
import theano
x = theano.tensor.matrix()
x = theano.tensor.matrix(
'x'
)
f = theano.function([x], (x**2).shape)
f = theano.function([x], (x**2).shape)
theano.printing.debugprint(f)
theano.printing.debugprint(f)
#
MakeVector [@26301776
] '' 2
#
MakeVector [@43860304
] '' 2
#
|Shape_i{0} [@26321296
] '' 1
#
|Shape_i{0} [@43424912
] '' 1
#
| |<TensorType(float64, matrix)> [@26153424
]
#
| |x [@43423568
]
#
|Shape_i{1} [@26322512
] '' 0
#
|Shape_i{1} [@43797968
] '' 0
#
| |<TensorType(float64, matrix)> [@26153424
]
#
| |x [@43423568
]
The output of this compiled function do not contain any multiplication
The output of this compiled function do not contain any multiplication
or power. Theano has removed them to compute directly the shape of the
or power. Theano has removed them to compute directly the shape of the
output.
output.
Shape inference problem
=======================
Theano do shape information propagation in the graph. Sometimes this
can had error. Example:
.. code-block:: python
import numpy
import theano
x = theano.tensor.matrix('x')
y = theano.tensor.matrix('y')
z = theano.tensor.join(0,x,y)
xv = numpy.random.rand(5,4)
yv = numpy.random.rand(3,3)
f = theano.function([x,y], z.shape)
theano.printing.debugprint(f)
#MakeVector [@23910032] '' 4
# |Elemwise{Add{output_types_preference=transfer_type{0}}}[(0, 0)] [@24055120] '' 3
# | |Shape_i{0} [@23154000] '' 1
# | | |x [@23151760]
# | |Shape_i{0} [@23593040] '' 2
# | | |y [@23151888]
# |Shape_i{1} [@23531152] '' 0
# | |x [@23151760]
#MakeVector [@56338064] '' 4
# |Elemwise{Add{output_types_preference=transfer_type{0}}}[(0, 0)] [@56483152] '' 3
# | |Shape_i{0} [@55586128] '' 1
# | | |<TensorType(float64, matrix)> [@55583888]
# | |Shape_i{0} [@56021072] '' 2
# | | |<TensorType(float64, matrix)> [@55584016]
# |Shape_i{1} [@55959184] '' 0
# | |<TensorType(float64, matrix)> [@55583888]
print f(xv,yv)# DONT RAISE AN ERROR AS SHOULD BE.
#[8,4]
f = theano.function([x,y], z)# Don't take the shape.
theano.printing.debugprint(f)
#Join [@44540496] '' 0
# |0 [@44540432]
# |x [@44540240]
# |y [@44540304]
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).
This make the computation of the shape faster, but can hide error. 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, ...
You can detect those problem by running the code without this
optimization with the theano 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)).
Specifing exact shape
Specifing exact shape
=====================
=====================
...
...
theano/compile/function_module.py
浏览文件 @
2317ffbb
...
@@ -659,7 +659,9 @@ def _constructor_Function(maker, input_storage, inputs_data):
...
@@ -659,7 +659,9 @@ def _constructor_Function(maker, input_storage, inputs_data):
f
=
maker
.
create
(
input_storage
,
trustme
=
True
)
f
=
maker
.
create
(
input_storage
,
trustme
=
True
)
assert
len
(
f
.
input_storage
)
==
len
(
inputs_data
)
assert
len
(
f
.
input_storage
)
==
len
(
inputs_data
)
for
container
,
x
in
zip
(
f
.
input_storage
,
inputs_data
):
for
container
,
x
in
zip
(
f
.
input_storage
,
inputs_data
):
assert
(
container
.
data
is
x
)
or
(
container
.
data
==
x
)
assert
(
container
.
data
is
x
)
or
\
(
isinstance
(
x
,
numpy
.
ndarray
)
and
(
container
.
data
==
x
)
.
all
())
or
\
(
container
.
data
==
x
)
return
f
return
f
copy_reg
.
pickle
(
Function
,
_pickle_Function
)
copy_reg
.
pickle
(
Function
,
_pickle_Function
)
...
...
theano/compile/tests/test_function_module.py
浏览文件 @
2317ffbb
...
@@ -566,6 +566,36 @@ class T_picklefunction(unittest.TestCase):
...
@@ -566,6 +566,36 @@ class T_picklefunction(unittest.TestCase):
assert
numpy
.
all
(
nl
[
6
][
nl
[
2
]]
==
numpy
.
asarray
([
2
,
3.
,
4
]))
assert
numpy
.
all
(
nl
[
6
][
nl
[
2
]]
==
numpy
.
asarray
([
2
,
3.
,
4
]))
def
test_broken_pickle_with_shared
(
self
):
saves
=
[]
def
pers_save
(
obj
):
if
isinstance
(
obj
,
numpy
.
ndarray
):
saves
.
append
(
obj
)
return
len
(
saves
)
-
1
else
:
return
None
def
pers_load
(
id
):
return
saves
[
id
]
a
=
numpy
.
random
.
rand
(
4
,
5
)
b
=
numpy
.
random
.
rand
(
5
,
4
)
x
=
theano
.
tensor
.
matrix
()
y
=
theano
.
shared
(
b
)
f
=
theano
.
function
([
x
],
theano
.
tensor
.
dot
(
x
,
y
))
import
StringIO
fp
=
StringIO
.
StringIO
()
p
=
cPickle
.
Pickler
(
fp
,
2
)
p
.
persistent_id
=
pers_save
p
.
dump
(
f
)
fp2
=
StringIO
.
StringIO
(
fp
.
getvalue
())
fp
.
close
()
p
=
cPickle
.
Unpickler
(
fp2
)
p
.
persistent_load
=
pers_load
f2
=
p
.
load
()
fp2
.
close
()
def
test_pickle_class_with_functions
(
self
):
def
test_pickle_class_with_functions
(
self
):
...
...
theano/gradient.py
浏览文件 @
2317ffbb
"""Driver for general gradient calculations."""
"""Driver for gradient calculations."""
__authors__
=
"James Bergstra"
__copyright__
=
"(c) 2011, Universite de Montreal"
__license__
=
"3-clause BSD License"
__contact__
=
"theano-dev <theano-dev@googlegroups.com>"
__docformat__
=
"restructuredtext en"
__docformat__
=
"restructuredtext en"
import
logging
_logger
=
logging
.
getLogger
(
'theano.gradient'
)
import
sys
import
sys
import
gof
#, gof.variable
import
numpy
#for numeric_grad
import
numpy
#for numeric_grad
import
gof
#, gof.variable
from
gof.python25
import
all
from
gof.python25
import
all
import
gof.utils
import
gof.utils
import
logging
from
raise_op
import
Raise
_logger
=
logging
.
getLogger
(
'theano.gradient'
)
def
warning
(
*
msg
):
def
warning
(
*
msg
):
_logger
.
warning
(
'WARNING theano.gradient: '
+
' '
.
join
(
msg
))
_logger
.
warning
(
'WARNING theano.gradient: '
+
' '
.
join
(
msg
))
def
info
(
*
msg
):
def
info
(
*
msg
):
...
@@ -106,4 +114,14 @@ def grad_sources_inputs(sources, graph_inputs, warn_type=True):
...
@@ -106,4 +114,14 @@ def grad_sources_inputs(sources, graph_inputs, warn_type=True):
gmap
[
r
]
=
g_r
gmap
[
r
]
=
g_r
return
gmap
return
gmap
def
unimplemented_grad
(
op
,
x_pos
,
x
):
"""
Return an un-computable symbolic variable of type `x.type`.
If any function tries to compute this un-computable variable, an exception
(NotImplementedError) will be raised indicating that the gradient on the
`x_pos`'th input of `op` has not been implemented.
"""
msg
=
'
%
s.grad not implemented for input
%
i'
%
(
op
,
x_pos
)
return
Raise
(
msg
=
msg
)(
x
)
theano/misc/latence_gpu_transfert.py
0 → 100644
浏览文件 @
2317ffbb
import
time
import
numpy
import
theano
y
=
theano
.
tensor
.
fvector
()
x
=
theano
.
shared
(
numpy
.
zeros
(
1
,
dtype
=
'float32'
))
f1
=
theano
.
function
([
y
],
updates
=
{
x
:
y
})
f2
=
theano
.
function
([],
theano
.
sandbox
.
cuda
.
host_from_gpu
(
x
))
print
f1
.
maker
.
env
.
toposort
()
print
f2
.
maker
.
env
.
toposort
()
for
i
in
[
1
,
10
,
100
,
1000
,
10000
,
100000
,
1000000
,
10000000
]:
o
=
numpy
.
zeros
(
i
,
dtype
=
'float32'
)
t0
=
time
.
time
();
f1
(
o
);
t1
=
time
.
time
();
tf1
=
t1
-
t0
t0
=
time
.
time
();
f2
();
t1
=
time
.
time
();
print
"
%8
i
%6.1
f ns
%7.1
f ns"
%
(
i
,
tf1
*
1e6
,(
t1
-
t0
)
*
1e6
)
theano/printing.py
浏览文件 @
2317ffbb
...
@@ -669,9 +669,10 @@ def pydotprint_variables(vars,
...
@@ -669,9 +669,10 @@ def pydotprint_variables(vars,
else
:
else
:
#a var id is needed as otherwise var with the same type will be merged in the graph.
#a var id is needed as otherwise var with the same type will be merged in the graph.
varstr
=
str
(
var
.
type
)
varstr
=
str
(
var
.
type
)
if
len
(
dstr
)
>
max_label_size
:
dstr
=
dstr
[:
max_label_size
-
1
]
+
'...'
varstr
+=
' '
+
str
(
len
(
var_str
))
varstr
+=
' '
+
str
(
len
(
var_str
))
if
len
(
varstr
)
>
max_label_size
:
varstr
=
varstr
[:
max_label_size
-
3
]
+
'...'
var_str
[
var
]
=
varstr
var_str
[
var
]
=
varstr
return
varstr
return
varstr
...
...
theano/raise_op.py
0 → 100644
浏览文件 @
2317ffbb
"""Symbolic Op for raising an exception."""
__authors__
=
"James Bergstra"
__copyright__
=
"(c) 2011, Universite de Montreal"
__license__
=
"3-clause BSD License"
__contact__
=
"theano-dev <theano-dev@googlegroups.com>"
__docformat__
=
"restructuredtext en"
import
gof
class
Raise
(
gof
.
Op
):
"""Op whose perform() raises an exception.
"""
def
__init__
(
self
,
msg
=
""
,
exc
=
NotImplementedError
):
"""
msg - the argument to the exception
exc - an exception class to raise in self.perform
"""
self
.
msg
=
msg
self
.
exc
=
exc
def
__eq__
(
self
,
other
):
# Note: the msg does not technically have to be in the hash and eq
# because it doesn't affect the return value.
return
(
type
(
self
)
==
type
(
other
)
and
self
.
msg
==
other
.
msg
and
self
.
exc
==
other
.
exc
)
def
__hash__
(
self
):
return
hash
((
type
(
self
),
self
.
msg
,
self
.
exc
))
def
__str__
(
self
):
return
"Raise{
%
s(
%
s)}"
%
(
self
.
exc
,
self
.
msg
)
def
make_node
(
self
,
x
):
return
gof
.
Apply
(
self
,
[
x
],
[
x
.
type
()])
def
perform
(
self
,
node
,
inputs
,
out_storage
):
raise
self
.
exc
(
self
.
msg
)
theano/sandbox/cuda/opt.py
浏览文件 @
2317ffbb
...
@@ -32,7 +32,7 @@ gpu_seqopt = SequenceDB()
...
@@ -32,7 +32,7 @@ gpu_seqopt = SequenceDB()
gpu_seqopt
.
register
(
'gpu_local_optimizations'
,
gpu_optimizer
,
1
,
gpu_seqopt
.
register
(
'gpu_local_optimizations'
,
gpu_optimizer
,
1
,
'fast_run'
,
'inplace'
)
'fast_run'
,
'inplace'
)
gpu_seqopt
.
register
(
'gpu_cut_transfers'
,
gpu_cut_copies
,
2
,
gpu_seqopt
.
register
(
'gpu_cut_transfers'
,
gpu_cut_copies
,
2
,
'fast_run'
,
'
inplace
'
)
'fast_run'
,
'
gpu
'
)
optdb
.
register
(
'gpu_opt'
,
optdb
.
register
(
'gpu_opt'
,
gpu_seqopt
,
gpu_seqopt
,
optdb
.
__position__
.
get
(
'add_destroy_handler'
,
49.5
)
-
1
,
optdb
.
__position__
.
get
(
'add_destroy_handler'
,
49.5
)
-
1
,
...
...
theano/sandbox/rng_mrg.py
浏览文件 @
2317ffbb
...
@@ -815,11 +815,11 @@ class MRG_RandomStreams(object):
...
@@ -815,11 +815,11 @@ class MRG_RandomStreams(object):
else
:
else
:
final_samples
=
normal_samples
[:
prod
(
size
)]
final_samples
=
normal_samples
[:
prod
(
size
)]
final_samples
=
avg
+
std
*
final_samples
if
size
:
if
size
:
final_samples
=
final_samples
.
reshape
(
size
)
final_samples
=
final_samples
.
reshape
(
size
)
final_samples
=
avg
+
std
*
final_samples
return
final_samples
return
final_samples
@local_optimizer
([
None
])
@local_optimizer
([
None
])
...
...
theano/sandbox/test_rng_mrg.py
浏览文件 @
2317ffbb
...
@@ -294,21 +294,29 @@ def basictest(f, steps, sample_size, prefix="", allow_01=False, inputs=[],
...
@@ -294,21 +294,29 @@ def basictest(f, steps, sample_size, prefix="", allow_01=False, inputs=[],
ival
=
numpy
.
asarray
(
ival
)
ival
=
numpy
.
asarray
(
ival
)
if
i
==
0
:
if
i
==
0
:
mean
=
numpy
.
array
(
ival
,
copy
=
True
)
mean
=
numpy
.
array
(
ival
,
copy
=
True
)
avg_std
=
numpy
.
std
(
ival
)
#avg_std = numpy.std(ival)
avg_std
=
numpy
.
sqrt
(
numpy
.
mean
((
ival
-
target_avg
)
**
2
))
min_
=
ival
.
min
()
min_
=
ival
.
min
()
max_
=
ival
.
max
()
max_
=
ival
.
max
()
else
:
else
:
alpha
=
1.0
/
(
1
+
i
)
alpha
=
1.0
/
(
1
+
i
)
mean
=
alpha
*
ival
+
(
1
-
alpha
)
*
mean
mean
=
alpha
*
ival
+
(
1
-
alpha
)
*
mean
avg_std
=
alpha
*
numpy
.
std
(
ival
)
+
(
1
-
alpha
)
*
avg_std
#avg_std = alpha * numpy.std(ival) + (1-alpha)*avg_std
avg_std
=
alpha
*
numpy
.
sqrt
(
numpy
.
mean
((
ival
-
target_avg
)
**
2
))
+
(
1
-
alpha
)
*
avg_std
min_
=
min
(
min_
,
ival
.
min
())
min_
=
min
(
min_
,
ival
.
min
())
max_
=
max
(
max_
,
ival
.
max
())
max_
=
max
(
max_
,
ival
.
max
())
if
not
allow_01
:
if
not
allow_01
:
assert
min_
>
0
assert
min_
>
0
assert
max_
<
1
assert
max_
<
1
print
prefix
,
'mean'
,
numpy
.
mean
(
mean
)
if
hasattr
(
target_avg
,
'shape'
):
# looks if target_avg is an array
assert
abs
(
numpy
.
mean
(
mean
)
-
target_avg
)
<
mean_rtol
,
'bad mean?
%
f
%
f'
%
(
numpy
.
mean
(
mean
),
target_avg
)
diff
=
numpy
.
mean
(
abs
(
mean
-
target_avg
))
print
prefix
,
'mean diff with mean'
,
diff
assert
diff
<
mean_rtol
,
'bad mean?
%
f
%
f'
%
(
mean
,
target_avg
)
else
:
# if target_avg is a scalar, then we can do the mean of `mean` to get something more precise
mean
=
numpy
.
mean
(
mean
)
print
prefix
,
'mean'
,
mean
assert
abs
(
mean
-
target_avg
)
<
mean_rtol
,
'bad mean?
%
f
%
f'
%
(
numpy
.
mean
(
mean
),
target_avg
)
print
prefix
,
'std'
,
avg_std
print
prefix
,
'std'
,
avg_std
if
target_std
is
not
None
:
if
target_std
is
not
None
:
assert
abs
(
avg_std
-
target_std
)
<
.
01
,
'bad std?
%
f
%
f'
%
(
avg_std
,
target_std
)
assert
abs
(
avg_std
-
target_std
)
<
.
01
,
'bad std?
%
f
%
f'
%
(
avg_std
,
target_std
)
...
@@ -450,30 +458,32 @@ def test_binomial():
...
@@ -450,30 +458,32 @@ def test_binomial():
def
test_normal0
():
def
test_normal0
():
steps
=
50
steps
=
50
std
=
2.
if
mode
in
[
'DEBUG_MODE'
,
'DebugMode'
,
'FAST_COMPILE'
]:
if
mode
in
[
'DEBUG_MODE'
,
'DebugMode'
,
'FAST_COMPILE'
]:
sample_size
=
(
25
,
30
)
sample_size
=
(
25
,
30
)
rtol
=.
02
default_
rtol
=.
02
else
:
else
:
sample_size
=
(
999
,
50
)
sample_size
=
(
999
,
50
)
rtol
=.
01
default_
rtol
=.
01
sample_size_odd
=
(
sample_size
[
0
],
sample_size
[
1
]
-
1
)
sample_size_odd
=
(
sample_size
[
0
],
sample_size
[
1
]
-
1
)
x
=
tensor
.
matrix
()
x
=
tensor
.
matrix
()
for
size
,
const_size
,
var_input
,
input
in
[
for
size
,
const_size
,
var_input
,
input
,
avg
,
rtol
in
[
(
sample_size
,
sample_size
,
[],
[]),
(
sample_size
,
sample_size
,
[],
[],
-
5.
,
default_rtol
),
(
x
.
shape
,
sample_size
,
[
x
],
[
numpy
.
zeros
(
sample_size
,
dtype
=
config
.
floatX
)]),
(
x
.
shape
,
sample_size
,
[
x
],
[
numpy
.
zeros
(
sample_size
,
dtype
=
config
.
floatX
)],
-
5.
,
default_rtol
),
(
sample_size_odd
,
sample_size_odd
,
[],
[]),
#test odd value
(
sample_size_odd
,
sample_size_odd
,
[],
[],
-
5.
,
default_rtol
),
#test odd value
(
x
.
shape
,
sample_size_odd
,
[
x
],
[
numpy
.
zeros
(
sample_size_odd
,
dtype
=
config
.
floatX
)]),
#test odd value
(
x
.
shape
,
sample_size_odd
,
[
x
],
[
numpy
.
zeros
(
sample_size_odd
,
dtype
=
config
.
floatX
)],
-
5.
,
default_rtol
),
#test odd value
(
sample_size
,
sample_size
,
[],
[],
numpy
.
arange
(
numpy
.
prod
(
sample_size
),
dtype
=
'float32'
)
.
reshape
(
sample_size
),
10.
*
std
/
numpy
.
sqrt
(
steps
)),
]:
]:
print
''
print
''
print
'ON CPU:'
print
'ON CPU:'
R
=
MRG_RandomStreams
(
234
,
use_cuda
=
False
)
R
=
MRG_RandomStreams
(
234
,
use_cuda
=
False
)
n
=
R
.
normal
(
size
=
size
,
avg
=
-
5.0
,
std
=
2.0
)
n
=
R
.
normal
(
size
=
size
,
avg
=
avg
,
std
=
std
)
f
=
theano
.
function
(
var_input
,
n
,
mode
=
mode
)
f
=
theano
.
function
(
var_input
,
n
,
mode
=
mode
)
theano
.
printing
.
debugprint
(
f
)
theano
.
printing
.
debugprint
(
f
)
out
=
f
(
*
input
)
out
=
f
(
*
input
)
print
'random?[:10]
\n
'
,
out
[
0
,
0
:
10
]
print
'random?[:10]
\n
'
,
out
[
0
,
0
:
10
]
basictest
(
f
,
steps
,
const_size
,
target_avg
=
-
5.0
,
target_std
=
2.0
,
prefix
=
'mrg '
,
allow_01
=
True
,
inputs
=
input
,
mean_rtol
=
rtol
)
basictest
(
f
,
steps
,
const_size
,
target_avg
=
avg
,
target_std
=
std
,
prefix
=
'mrg '
,
allow_01
=
True
,
inputs
=
input
,
mean_rtol
=
rtol
)
sys
.
stdout
.
flush
()
sys
.
stdout
.
flush
()
...
@@ -481,7 +491,7 @@ def test_normal0():
...
@@ -481,7 +491,7 @@ def test_normal0():
print
''
print
''
print
'ON GPU:'
print
'ON GPU:'
R
=
MRG_RandomStreams
(
234
,
use_cuda
=
True
)
R
=
MRG_RandomStreams
(
234
,
use_cuda
=
True
)
n
=
R
.
normal
(
size
=
size
,
avg
=
-
5.0
,
std
=
2.0
,
dtype
=
'float32'
)
n
=
R
.
normal
(
size
=
size
,
avg
=
avg
,
std
=
std
,
dtype
=
'float32'
)
assert
n
.
dtype
==
'float32'
#well, it's really that this test w GPU doesn't make sense otw
assert
n
.
dtype
==
'float32'
#well, it's really that this test w GPU doesn't make sense otw
f
=
theano
.
function
(
var_input
,
theano
.
Out
(
f
=
theano
.
function
(
var_input
,
theano
.
Out
(
theano
.
sandbox
.
cuda
.
basic_ops
.
gpu_from_host
(
n
),
theano
.
sandbox
.
cuda
.
basic_ops
.
gpu_from_host
(
n
),
...
@@ -493,7 +503,7 @@ def test_normal0():
...
@@ -493,7 +503,7 @@ def test_normal0():
print
'random?[:10]
\n
'
,
gpu_out
[
0
,
0
:
10
]
print
'random?[:10]
\n
'
,
gpu_out
[
0
,
0
:
10
]
print
'----'
print
'----'
sys
.
stdout
.
flush
()
sys
.
stdout
.
flush
()
basictest
(
f
,
steps
,
const_size
,
target_avg
=
-
5.0
,
target_std
=
2.0
,
prefix
=
'gpu mrg '
,
allow_01
=
True
,
inputs
=
input
,
mean_rtol
=
rtol
)
basictest
(
f
,
steps
,
const_size
,
target_avg
=
avg
,
target_std
=
std
,
prefix
=
'gpu mrg '
,
allow_01
=
True
,
inputs
=
input
,
mean_rtol
=
rtol
)
# Need to allow some rounding error as their is float
# Need to allow some rounding error as their is float
# computation that are done on the gpu vs cpu
# computation that are done on the gpu vs cpu
assert
numpy
.
allclose
(
out
,
gpu_out
,
rtol
=
5e-6
,
atol
=
5e-6
)
assert
numpy
.
allclose
(
out
,
gpu_out
,
rtol
=
5e-6
,
atol
=
5e-6
)
...
@@ -503,10 +513,10 @@ def test_normal0():
...
@@ -503,10 +513,10 @@ def test_normal0():
print
'ON CPU w NUMPY:'
print
'ON CPU w NUMPY:'
RR
=
theano
.
tensor
.
shared_randomstreams
.
RandomStreams
(
234
)
RR
=
theano
.
tensor
.
shared_randomstreams
.
RandomStreams
(
234
)
nn
=
RR
.
normal
(
size
=
size
,
avg
=
-
5.0
,
std
=
2.0
)
nn
=
RR
.
normal
(
size
=
size
,
avg
=
avg
,
std
=
std
)
ff
=
theano
.
function
(
var_input
,
nn
)
ff
=
theano
.
function
(
var_input
,
nn
)
basictest
(
ff
,
steps
,
const_size
,
target_avg
=
-
5.0
,
target_std
=
2.0
,
prefix
=
'numpy '
,
allow_01
=
True
,
inputs
=
input
,
mean_rtol
=
rtol
)
basictest
(
ff
,
steps
,
const_size
,
target_avg
=
avg
,
target_std
=
std
,
prefix
=
'numpy '
,
allow_01
=
True
,
inputs
=
input
,
mean_rtol
=
rtol
)
def
basic_multinomialtest
(
f
,
steps
,
sample_size
,
target_pvals
,
prefix
=
""
,
mean_rtol
=
0.04
):
def
basic_multinomialtest
(
f
,
steps
,
sample_size
,
target_pvals
,
prefix
=
""
,
mean_rtol
=
0.04
):
...
...
theano/scalar/basic.py
浏览文件 @
2317ffbb
import
operator
"""
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
WARNING
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
This directory is for the internal of Theano.
You are strongly adviced to don't use it except if you know
what you do!
If you want to use scalar variable in a Theano graph,
you probably want to use theano.tensor.[c,z,f,d,b,w,i,l,]scalar!
"""
import
math
import
math
from
copy
import
copy
from
copy
import
copy
...
@@ -584,8 +597,8 @@ class ScalarOp(Op):
...
@@ -584,8 +597,8 @@ class ScalarOp(Op):
if
not
isinstance
(
variables
,
(
list
,
tuple
))
or
any
(
not
isinstance
(
x
,
Type
)
for
x
in
variables
):
if
not
isinstance
(
variables
,
(
list
,
tuple
))
or
any
(
not
isinstance
(
x
,
Type
)
for
x
in
variables
):
raise
TypeError
(
"output_types_preference should return a list or a tuple of types"
,
self
.
output_types_preference
,
variables
)
raise
TypeError
(
"output_types_preference should return a list or a tuple of types"
,
self
.
output_types_preference
,
variables
)
if
len
(
variables
)
!=
self
.
nout
:
if
len
(
variables
)
!=
self
.
nout
:
raise
TypeError
(
"Not the right number of outputs
produced for
%
s(
%
s) by
%
s. Expected
%
s, got ?
s."
raise
TypeError
(
"Not the right number of outputs
types produced for
%
s(
%
s) by
%
s. Expected
%
s, got
%
s."
%
(
self
,
", "
.
join
(
str
(
input
.
type
)
for
input
in
input
s
),
%
(
self
,
", "
.
join
(
str
(
type
)
for
type
in
variable
s
),
self
.
output_types_preference
,
self
.
nout
,
len
(
variables
)))
self
.
output_types_preference
,
self
.
nout
,
len
(
variables
)))
return
variables
return
variables
else
:
else
:
...
...
theano/scan_module/__init__.py
浏览文件 @
2317ffbb
...
@@ -81,7 +81,8 @@ optdb.register( 'scanOp_make_inplace'
...
@@ -81,7 +81,8 @@ optdb.register( 'scanOp_make_inplace'
,
opt
.
in2out
(
scan_make_inplace
,
ignore_newtrees
=
True
)
,
opt
.
in2out
(
scan_make_inplace
,
ignore_newtrees
=
True
)
,
75
,
75
,
'fast_run'
,
'fast_run'
,
'inplace'
)
,
'inplace'
,
'scan'
)
...
@@ -512,7 +513,8 @@ class ScanSaveMem(gof.Optimizer):
...
@@ -512,7 +513,8 @@ class ScanSaveMem(gof.Optimizer):
optdb
.
register
(
'scanOp_save_mem'
optdb
.
register
(
'scanOp_save_mem'
,
ScanSaveMem
()
,
ScanSaveMem
()
,
1.99
,
1.99
,
'fast_run'
)
,
'fast_run'
,
'scan'
)
'''
'''
class ScanMerge(gof.Optimizer):
class ScanMerge(gof.Optimizer):
...
@@ -584,7 +586,8 @@ class ScanMerge(gof.Optimizer):
...
@@ -584,7 +586,8 @@ class ScanMerge(gof.Optimizer):
optdb.register( 'scanOp_merge'
optdb.register( 'scanOp_merge'
, ScanMerge()
, ScanMerge()
, 2.39
, 2.39
, 'fast_run')
, 'fast_run'
, 'scan')
'''
'''
...
@@ -620,7 +623,7 @@ if cuda.cuda_available:
...
@@ -620,7 +623,7 @@ if cuda.cuda_available:
return
x
return
x
@register_opt
()
@register_opt
(
'scan'
)
@local_optimizer
([])
@local_optimizer
([])
def
gpuScanOptimization
(
node
):
def
gpuScanOptimization
(
node
):
"""
"""
...
@@ -633,7 +636,19 @@ if cuda.cuda_available:
...
@@ -633,7 +636,19 @@ if cuda.cuda_available:
host_input
=
node
.
inputs
[
0
]
host_input
=
node
.
inputs
[
0
]
if
(
host_input
.
owner
and
if
(
host_input
.
owner
and
isinstance
(
host_input
.
owner
.
op
,
scan_op
.
Scan
)
and
isinstance
(
host_input
.
owner
.
op
,
scan_op
.
Scan
)
and
not
host_input
.
owner
.
op
.
info
[
'gpu'
]):
not
host_input
.
owner
.
op
.
info
[
'gpu'
]
and
len
(
host_input
.
owner
.
outputs
)
==
1
):
# Note that we are not doing the right thing here !!
# This is because the local optimizer expects only one
# output that corresponds to the input of ``node``
# If we do this for each output seperately we will have
# multiple scan ops in the graph ( as many as outputs )
# and I'm not sure they will get merged into one again
# So for now I will just cover a limited case when there
# is only one output and the local optimizer can be used
# TODO (fix) : either make sure the different scans get
# merged or implement this optimization as a global
# optimization
thescan
=
host_input
.
owner
.
op
thescan
=
host_input
.
owner
.
op
info
=
thescan
.
info
.
copy
()
info
=
thescan
.
info
.
copy
()
info
[
'gpu'
]
=
True
info
[
'gpu'
]
=
True
...
@@ -646,7 +661,7 @@ if cuda.cuda_available:
...
@@ -646,7 +661,7 @@ if cuda.cuda_available:
+
thescan
.
n_shared_outs
)
+
thescan
.
n_shared_outs
)
nw_ins
+=
[
safe_to_gpu
(
x
)
for
x
in
inputs
[
1
:
e
]
]
nw_ins
+=
[
safe_to_gpu
(
x
)
for
x
in
inputs
[
1
:
e
]
]
b
=
e
b
=
e
e
=
e
+
thescan
.
n_nit_sot
+
thescan
.
n_other_ignore
e
=
e
+
thescan
.
n_nit_sot
nw_ins
+=
inputs
[
b
:
e
]
nw_ins
+=
inputs
[
b
:
e
]
nw_ins
+=
[
safe_to_gpu
(
x
)
for
x
in
inputs
[
e
:]
]
nw_ins
+=
[
safe_to_gpu
(
x
)
for
x
in
inputs
[
e
:]
]
scan_ins
=
[
tensor_to_cuda
(
x
)
for
x
in
thescan
.
inputs
]
scan_ins
=
[
tensor_to_cuda
(
x
)
for
x
in
thescan
.
inputs
]
...
@@ -678,7 +693,7 @@ if cuda.cuda_available:
...
@@ -678,7 +693,7 @@ if cuda.cuda_available:
+
thescan
.
n_shared_outs
)
+
thescan
.
n_shared_outs
)
nw_ins
+=
[
safe_to_gpu
(
x
)
for
x
in
inputs
[
1
:
e
]
]
nw_ins
+=
[
safe_to_gpu
(
x
)
for
x
in
inputs
[
1
:
e
]
]
b
=
e
b
=
e
e
=
e
+
thescan
.
n_nit_sot
+
thescan
.
n_other_ignore
e
=
e
+
thescan
.
n_nit_sot
nw_ins
+=
inputs
[
b
:
e
]
nw_ins
+=
inputs
[
b
:
e
]
nw_ins
+=
[
safe_to_gpu
(
x
)
for
x
in
inputs
[
e
:]
]
nw_ins
+=
[
safe_to_gpu
(
x
)
for
x
in
inputs
[
e
:]
]
...
...
theano/scan_module/scan.py
浏览文件 @
2317ffbb
...
@@ -759,23 +759,14 @@ def scan( fn
...
@@ -759,23 +759,14 @@ def scan( fn
nit_sot_rightOrder
.
append
(
i
)
nit_sot_rightOrder
.
append
(
i
)
n_nit_sot
+=
1
n_nit_sot
+=
1
## Step 5.5 Sequences with no taps used
## Step 5.5 all other arguments including extra inputs
n_other_ignore
=
0
ignore_scan_seqs
=
[]
ignore_inner_seqs
=
[]
for
i
,
seq
in
enumerate
(
seqs
):
if
not
'taps'
in
seq
:
ignore_scan_seqs
.
append
(
seq
[
'input'
])
n_other_ignore
+=
1
## Step 5.6 all other arguments including extra inputs
other_scan_args
=
[]
other_scan_args
=
[]
other_inner_args
=
[]
other_inner_args
=
[]
other_scan_args
+=
[
arg
for
arg
in
non_seqs
other_scan_args
+=
[
arg
for
arg
in
non_seqs
if
not
isinstance
(
arg
,
SharedVariable
)
]
if
not
isinstance
(
arg
,
SharedVariable
)
]
## Step 5.
8
all shared variables with no update rules
## Step 5.
6
all shared variables with no update rules
def
new_variable
(
v
):
def
new_variable
(
v
):
new_v
=
safe_new
(
v
)
new_v
=
safe_new
(
v
)
if
v
.
name
:
if
v
.
name
:
...
@@ -805,7 +796,6 @@ def scan( fn
...
@@ -805,7 +796,6 @@ def scan( fn
mit_sot_inner_inputs
+
mit_sot_inner_inputs
+
sit_sot_inner_inputs
+
sit_sot_inner_inputs
+
shared_inner_inputs
+
shared_inner_inputs
+
ignore_inner_seqs
+
other_shared_inner_args
+
other_shared_inner_args
+
other_inner_args
)
other_inner_args
)
...
@@ -850,7 +840,6 @@ def scan( fn
...
@@ -850,7 +840,6 @@ def scan( fn
info
[
'n_sit_sot'
]
=
n_sit_sot
info
[
'n_sit_sot'
]
=
n_sit_sot
info
[
'n_shared_outs'
]
=
n_shared_outs
info
[
'n_shared_outs'
]
=
n_shared_outs
info
[
'n_nit_sot'
]
=
n_nit_sot
info
[
'n_nit_sot'
]
=
n_nit_sot
info
[
'n_other_ignore'
]
=
n_other_ignore
info
[
'truncate_gradient'
]
=
truncate_gradient
info
[
'truncate_gradient'
]
=
truncate_gradient
info
[
'name'
]
=
name
info
[
'name'
]
=
name
info
[
'mode'
]
=
mode
info
[
'mode'
]
=
mode
...
@@ -876,7 +865,6 @@ def scan( fn
...
@@ -876,7 +865,6 @@ def scan( fn
sit_sot_scan_inputs
+
sit_sot_scan_inputs
+
shared_scan_inputs
+
shared_scan_inputs
+
[
actual_n_steps
for
x
in
xrange
(
n_nit_sot
)
]
+
[
actual_n_steps
for
x
in
xrange
(
n_nit_sot
)
]
+
ignore_scan_seqs
+
other_shared_scan_args
+
other_shared_scan_args
+
other_scan_args
)
other_scan_args
)
...
...
theano/scan_module/scan_op.py
浏览文件 @
2317ffbb
差异被折叠。
点击展开。
theano/scan_module/scan_utils.py
浏览文件 @
2317ffbb
...
@@ -754,7 +754,6 @@ def compress_outs(op, not_required, inputs):
...
@@ -754,7 +754,6 @@ def compress_outs(op, not_required, inputs):
info
[
'n_sit_sot'
]
=
0
info
[
'n_sit_sot'
]
=
0
info
[
'n_shared_outs'
]
=
0
info
[
'n_shared_outs'
]
=
0
info
[
'n_nit_sot'
]
=
0
info
[
'n_nit_sot'
]
=
0
info
[
'n_other_ignore'
]
=
op
.
info
[
'n_other_ignore'
]
info
[
'truncate_gradient'
]
=
op
.
info
[
'truncate_gradient'
]
info
[
'truncate_gradient'
]
=
op
.
info
[
'truncate_gradient'
]
info
[
'name'
]
=
op
.
info
[
'name'
]
info
[
'name'
]
=
op
.
info
[
'name'
]
info
[
'inplace'
]
=
op
.
info
[
'inplace'
]
info
[
'inplace'
]
=
op
.
info
[
'inplace'
]
...
...
theano/scan_module/tests/test_scan.py
浏览文件 @
2317ffbb
...
@@ -242,7 +242,11 @@ class T_Scan(unittest.TestCase):
...
@@ -242,7 +242,11 @@ class T_Scan(unittest.TestCase):
W_in
=
theano
.
tensor
.
fscalar
(
'win'
)
W_in
=
theano
.
tensor
.
fscalar
(
'win'
)
W
=
theano
.
tensor
.
fscalar
(
'w'
)
W
=
theano
.
tensor
.
fscalar
(
'w'
)
mode
=
theano
.
compile
.
mode
.
get_default_mode
()
.
including
(
'gpu'
)
if
theano
.
config
.
mode
==
'FAST_COMPILE'
:
mode
=
theano
.
compile
.
mode
.
get_mode
(
'FAST_RUN'
)
else
:
mode
=
theano
.
compile
.
mode
.
get_default_mode
()
mode
=
mode
.
including
(
'gpu'
,
'scan'
)
# The following line is needed to have the first case being used
# The following line is needed to have the first case being used
# Otherwise, it is the second that is tested.
# Otherwise, it is the second that is tested.
mode
=
mode
.
excluding
(
'InputToGpuOptimizer'
)
mode
=
mode
.
excluding
(
'InputToGpuOptimizer'
)
...
@@ -314,7 +318,11 @@ class T_Scan(unittest.TestCase):
...
@@ -314,7 +318,11 @@ class T_Scan(unittest.TestCase):
x0
=
theano
.
tensor
.
fscalar
(
'x0'
)
x0
=
theano
.
tensor
.
fscalar
(
'x0'
)
W_in
=
theano
.
tensor
.
fscalar
(
'win'
)
W_in
=
theano
.
tensor
.
fscalar
(
'win'
)
W
=
theano
.
tensor
.
fscalar
(
'w'
)
W
=
theano
.
tensor
.
fscalar
(
'w'
)
mode
=
theano
.
compile
.
mode
.
get_default_mode
()
.
including
(
'gpu'
)
if
theano
.
config
.
mode
==
'FAST_COMPILE'
:
mode
=
theano
.
compile
.
mode
.
get_mode
(
'FAST_RUN'
)
else
:
mode
=
theano
.
compile
.
mode
.
get_default_mode
()
mode
=
mode
.
including
(
'gpu'
,
'scan'
)
output
,
updates
=
theano
.
scan
(
f_rnn
,
u
,
x0
,[
W_in
,
W
]
output
,
updates
=
theano
.
scan
(
f_rnn
,
u
,
x0
,[
W_in
,
W
]
,
n_steps
=
None
,
n_steps
=
None
,
truncate_gradient
=
-
1
,
truncate_gradient
=
-
1
...
@@ -1980,6 +1988,7 @@ class T_Scan(unittest.TestCase):
...
@@ -1980,6 +1988,7 @@ class T_Scan(unittest.TestCase):
self
.
assertTrue
(
nb_scan
==
2
)
self
.
assertTrue
(
nb_scan
==
2
)
nb_shape_i
=
len
([
n
for
n
in
topo
nb_shape_i
=
len
([
n
for
n
in
topo
if
isinstance
(
n
.
op
,
theano
.
tensor
.
opt
.
Shape_i
)])
if
isinstance
(
n
.
op
,
theano
.
tensor
.
opt
.
Shape_i
)])
if
theano
.
config
.
mode
!=
'FAST_COMPILE'
:
self
.
assertTrue
(
nb_shape_i
==
1
)
self
.
assertTrue
(
nb_shape_i
==
1
)
def
test_bug_josh_reported
(
self
):
def
test_bug_josh_reported
(
self
):
...
@@ -1990,6 +1999,16 @@ class T_Scan(unittest.TestCase):
...
@@ -1990,6 +1999,16 @@ class T_Scan(unittest.TestCase):
conv
=
theano
.
tensor
.
signal
.
conv
.
conv2d
(
m1
,
m2
)
conv
=
theano
.
tensor
.
signal
.
conv
.
conv2d
(
m1
,
m2
)
def
test_hash
(
self
):
x
=
theano
.
tensor
.
vector
()
y
=
theano
.
tensor
.
vector
()
scan1
,
updates
=
theano
.
scan
(
lambda
_x
:
_x
+
1
,
x
)
scan2
,
updates
=
theano
.
scan
(
lambda
_x
:
_x
+
1
,
y
)
assert
scan1
.
owner
.
op
==
scan2
.
owner
.
op
assert
hash
(
scan1
.
owner
.
op
)
==
hash
(
scan2
.
owner
.
op
)
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
#'''
#'''
print
' Use nosetests to run these tests '
print
' Use nosetests to run these tests '
...
...
theano/tensor/basic.py
浏览文件 @
2317ffbb
...
@@ -3292,7 +3292,16 @@ class Rebroadcast(Op):
...
@@ -3292,7 +3292,16 @@ class Rebroadcast(Op):
# restore the broadcasting pattern of the input
# restore the broadcasting pattern of the input
return
Rebroadcast
(
*
[(
axis
,
x
.
type
.
broadcastable
[
axis
])
for
axis
,
value
in
self
.
axis
.
iteritems
()])(
gz
),
return
Rebroadcast
(
*
[(
axis
,
x
.
type
.
broadcastable
[
axis
])
for
axis
,
value
in
self
.
axis
.
iteritems
()])(
gz
),
def
infer_shape
(
self
,
node
,
ishapes
):
def
infer_shape
(
self
,
node
,
ishapes
):
return
ishapes
assert
len
(
ishapes
)
==
1
l
=
[]
one
=
constant
(
1
)
for
ax
in
range
(
len
(
ishapes
[
0
])):
if
self
.
axis
.
get
(
ax
,
False
):
l
.
append
(
one
)
else
:
l
.
append
(
ishapes
[
0
][
ax
])
return
[
tuple
(
l
)]
def
addbroadcast
(
x
,
*
axes
):
def
addbroadcast
(
x
,
*
axes
):
"""
"""
...
@@ -3477,6 +3486,51 @@ class Join(Op):
...
@@ -3477,6 +3486,51 @@ class Join(Op):
else
:
else
:
return
node
.
owner
.
tag
.
shape_zero
return
node
.
owner
.
tag
.
shape_zero
def
infer_shape
(
self
,
node
,
ishapes
):
# Join op should get at least two inputs to join
assert
len
(
ishapes
)
>
1
# Not sure this is needed anymore :( ... basically the apply_shape
# version of the apply node (i.e. the one defined in
# gof/apply_shape) calls infer_shape methods passing None to unknown
# inputs. It can handle NotImplementedError, so for now I just raise
# that whenever I get a None. Should we just remove gof/apply_shape
# if it is depricated ??
if
ishapes
[
1
]
is
None
:
raise
NotImplementedError
n_dim
=
len
(
ishapes
[
1
])
for
shape
in
ishapes
[
1
:]:
if
shape
is
None
:
raise
NotImplementedError
for
shape_i
in
shape
:
if
shape_i
is
None
:
raise
NotImplementedError
# at this point the inputs have been broadcasted so they should
# all have the same shape
assert
len
(
shape
)
==
n_dim
out_shapes
=
[]
for
dim
in
xrange
(
n_dim
):
# we have to deal with 2 possible cases in here :
# a) we are dealing with the dimension for which we join
# (called t_side from true side of the if, where the if
# compares current dimension with the joining dimension)
# b) a non joining dimension ( in which maybe a symbolic
# assertion can be used to make sure all tensors have
# the same number of elements on this non-joined dimension
# this is f_side
# initialize
t_side
=
ishapes
[
1
][
dim
]
f_side
=
ishapes
[
1
][
dim
]
# loop over tensors and sum for the joining dimension
for
shape
in
ishapes
[
2
:]:
t_side
=
t_side
+
shape
[
dim
]
# return the dimensions found
out_shapes
.
append
(
switch
(
eq
(
dim
,
node
.
inputs
[
0
]),
t_side
,
f_side
))
return
[
tuple
(
out_shapes
)]
@_redefine_asRoutine
(
Join
())
@_redefine_asRoutine
(
Join
())
def
join
(
axis
,
*
tensors
):
def
join
(
axis
,
*
tensors
):
"""
"""
...
@@ -4622,7 +4676,8 @@ outer = Outer()
...
@@ -4622,7 +4676,8 @@ outer = Outer()
# Gradient
# Gradient
#########################
#########################
def
grad
(
cost
,
wrt
,
g_cost
=
None
,
consider_constant
=
[],
warn_type
=
False
):
def
grad
(
cost
,
wrt
,
g_cost
=
None
,
consider_constant
=
[],
warn_type
=
False
,
assume_continuously_differentiable
=
False
):
"""
"""
:type cost: Scalar (0-dimensional) `Variable`
:type cost: Scalar (0-dimensional) `Variable`
:type wrt: `Variable` or list of `Variable`s.
:type wrt: `Variable` or list of `Variable`s.
...
@@ -4634,6 +4689,14 @@ def grad(cost, wrt, g_cost=None, consider_constant=[], warn_type=False):
...
@@ -4634,6 +4689,14 @@ def grad(cost, wrt, g_cost=None, consider_constant=[], warn_type=False):
:param warn_type: a value of True will cause warnings to be logged for any Op that emits a
:param warn_type: a value of True will cause warnings to be logged for any Op that emits a
gradient that does not match its input type.
gradient that does not match its input type.
:param assume_continuously_differentiable : flag that says if grad is strict about what it returns.
If set to false it will raise an exception for any argument in
``wrt`` for which there is no gradient either because some op does
not know how to compute the gradient with respect to that argument
or the argument is not part of the computational graph. If the flag
is set to true, the ``grad`` method returns zeros like the argument
( i.e. it makes the assumption that the gradient should be 0).
:rtype: `Variable` or list of `Variable`s (depending upon `wrt`)
:rtype: `Variable` or list of `Variable`s (depending upon `wrt`)
:return: symbolic expression of gradient of `cost` with respect to `wrt`.
:return: symbolic expression of gradient of `cost` with respect to `wrt`.
...
@@ -4663,13 +4726,30 @@ def grad(cost, wrt, g_cost=None, consider_constant=[], warn_type=False):
...
@@ -4663,13 +4726,30 @@ def grad(cost, wrt, g_cost=None, consider_constant=[], warn_type=False):
list
(
inputs
)
+
list
(
consider_constant
),
list
(
inputs
)
+
list
(
consider_constant
),
warn_type
=
warn_type
)
warn_type
=
warn_type
)
# Note that it is important to use `zeros_like` when there is no gradient,
# instead of returning a scalar constant equal to zero. Otherwise we lose
# Note : If p is not in gmap there can be several reasons, among which
# the guarantee that the gradient has same shape as `wrt`.
# is the fact that p might not be part of the computational graph. A
if
isinstance
(
wrt
,
(
list
,
tuple
)):
# simple example is that for a+b for e.g. a[0] is not part of the graph,
return
[
gmap
.
get
(
p
,
zeros_like
(
p
))
for
p
in
wrt
]
# so Theano does not know how to compute TT.grad(TT.sum(a+b), a[0])
# such subtle cases can be fixed by a more careful implementation of the
# gradient, but for now Theano needs to throw an exception, and make the
# user aware that it does not know how to compute that gradient
if
not
isinstance
(
wrt
,
(
list
,
tuple
)):
wrt
=
[
wrt
]
ret
=
[]
for
p
in
wrt
:
if
p
not
in
gmap
and
not
assume_continuously_differentiable
:
raise
ValueError
((
"grad method was asked to compute the graident "
"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
)
else
:
else
:
return
gmap
.
get
(
wrt
,
zeros_like
(
wrt
))
ret
.
append
(
gmap
.
get
(
p
,
zeros_like
(
p
)))
if
len
(
ret
)
==
1
:
return
ret
[
0
]
else
:
return
ret
class
numeric_grad
:
class
numeric_grad
:
"""WRITEME"""
"""WRITEME"""
...
@@ -4938,7 +5018,8 @@ def verify_grad(fun, pt, n_tests=2, rng=None, eps=None, abs_tol=None, rel_tol=No
...
@@ -4938,7 +5018,8 @@ def verify_grad(fun, pt, n_tests=2, rng=None, eps=None, abs_tol=None, rel_tol=No
if
cast_to_output_type
:
if
cast_to_output_type
:
g_cost
=
cast
(
g_cost
,
o_output
.
dtype
)
g_cost
=
cast
(
g_cost
,
o_output
.
dtype
)
symbolic_grad
=
grad
(
cost
,
tensor_pt
,
g_cost
)
symbolic_grad
=
grad
(
cost
,
tensor_pt
,
g_cost
,
assume_continuously_differentiable
=
True
)
#if o_output.dtype in ['float32','float64']:
#if o_output.dtype in ['float32','float64']:
# assert all([x.dtype == o_output.dtype for x in symbolic_grad]),("Expected grad of type %s, got %s "%( symbolic_grad.dtype, o_output.dtyp))
# assert all([x.dtype == o_output.dtype for x in symbolic_grad]),("Expected grad of type %s, got %s "%( symbolic_grad.dtype, o_output.dtyp))
...
...
theano/tensor/opt.py
浏览文件 @
2317ffbb
...
@@ -2742,10 +2742,10 @@ def local_add_specialize(node):
...
@@ -2742,10 +2742,10 @@ def local_add_specialize(node):
new_inputs
.
append
(
input
)
new_inputs
.
append
(
input
)
if
len
(
new_inputs
)
<
len
(
node
.
inputs
):
if
len
(
new_inputs
)
<
len
(
node
.
inputs
):
dtype
=
node
.
outputs
[
0
]
.
type
.
dtype
if
len
(
new_inputs
)
==
0
:
if
len
(
new_inputs
)
==
0
:
#we got rid of the entire expression!
#we got rid of the entire expression!
ndim
=
node
.
outputs
[
0
]
.
type
.
ndim
ndim
=
node
.
outputs
[
0
]
.
type
.
ndim
dtype
=
node
.
outputs
[
0
]
.
type
.
dtype
return
fill_chain
(
return
fill_chain
(
T
.
TensorConstant
(
T
.
TensorConstant
(
T
.
TensorType
(
T
.
TensorType
(
...
@@ -2754,9 +2754,14 @@ def local_add_specialize(node):
...
@@ -2754,9 +2754,14 @@ def local_add_specialize(node):
numpy
.
zeros
((
1
,)
*
ndim
,
dtype
=
dtype
)))
numpy
.
zeros
((
1
,)
*
ndim
,
dtype
=
dtype
)))
if
len
(
new_inputs
)
==
1
:
if
len
(
new_inputs
)
==
1
:
return
fill_chain
(
new_inputs
[
0
])
ret
=
fill_chain
(
new_inputs
[
0
])
else
:
else
:
return
fill_chain
(
T
.
add
(
*
new_inputs
))
ret
=
fill_chain
(
T
.
add
(
*
new_inputs
))
# The dtype should not be changed. It can happen if the input
# that was forcing upcasting was equal to 0.
if
ret
[
0
]
.
dtype
!=
dtype
:
ret
=
[
T
.
cast
(
ret
[
0
],
dtype
)]
return
ret
else
:
else
:
return
False
return
False
register_specialize
(
local_add_specialize
)
register_specialize
(
local_add_specialize
)
...
...
theano/tensor/tests/test_basic.py
浏览文件 @
2317ffbb
...
@@ -2447,6 +2447,42 @@ class T_Join_and_Split(unittest.TestCase):
...
@@ -2447,6 +2447,42 @@ class T_Join_and_Split(unittest.TestCase):
self
.
assertRaises
(
ValueError
,
g
,
a_val
,
b_val
,
c_val
,
bad_d_val
,
e_val
)
self
.
assertRaises
(
ValueError
,
g
,
a_val
,
b_val
,
c_val
,
bad_d_val
,
e_val
)
self
.
assertRaises
(
ValueError
,
g
,
a_val
,
b_val
,
c_val
,
d_val
,
bad_e_val
)
self
.
assertRaises
(
ValueError
,
g
,
a_val
,
b_val
,
c_val
,
d_val
,
bad_e_val
)
def
test_infer_shape_join
(
self
):
x1
=
matrix
()
x2
=
matrix
()
x3
=
matrix
()
def
get_mat
(
s1
,
s2
):
return
numpy
.
asarray
(
numpy
.
random
.
uniform
(
size
=
(
s1
,
s2
)),
dtype
=
config
.
floatX
)
# Test dim 0
z
=
join
(
0
,
x1
,
x2
,
x3
)
f
=
theano
.
function
([
x1
,
x2
,
x3
],
z
.
shape
)
out
=
f
(
get_mat
(
3
,
4
),
get_mat
(
2
,
4
),
get_mat
(
1
,
4
))
assert
(
out
==
[
6
,
4
])
.
all
()
if
theano
.
config
.
mode
!=
'FAST_COMPILE'
:
for
node
in
f
.
maker
.
env
.
toposort
():
assert
not
isinstance
(
node
.
op
,
tensor
.
Join
)
# Test dim 1
z
=
join
(
1
,
x1
,
x2
,
x3
)
f
=
theano
.
function
([
x1
,
x2
,
x3
],
z
.
shape
)
out
=
f
(
get_mat
(
3
,
4
),
get_mat
(
3
,
4
),
get_mat
(
3
,
5
))
assert
(
out
==
[
3
,
13
])
.
all
()
if
theano
.
config
.
mode
!=
'FAST_COMPILE'
:
for
node
in
f
.
maker
.
env
.
toposort
():
assert
not
isinstance
(
node
.
op
,
tensor
.
Join
)
# Test hide error
if
theano
.
config
.
mode
in
[
'DebugMode'
,
'DEBUG_MODE'
,
'FAST_COMPILE'
]:
self
.
assertRaises
(
ValueError
,
f
,
get_mat
(
3
,
4
),
get_mat
(
3
,
4
),
get_mat
(
2
,
5
))
else
:
f
(
get_mat
(
3
,
4
),
get_mat
(
3
,
4
),
get_mat
(
2
,
5
))
class
test_comparison
(
unittest
.
TestCase
):
class
test_comparison
(
unittest
.
TestCase
):
def
test_gt
(
self
):
def
test_gt
(
self
):
...
@@ -3198,7 +3234,8 @@ class test_grad(unittest.TestCase):
...
@@ -3198,7 +3234,8 @@ class test_grad(unittest.TestCase):
"""grad: Test returning a single zero value from grad"""
"""grad: Test returning a single zero value from grad"""
o
=
test_grad
.
O
()
o
=
test_grad
.
O
()
a1
=
o
.
make_node
()
a1
=
o
.
make_node
()
g
=
grad
(
a1
.
outputs
[
0
],
a1
.
outputs
[
1
])
g
=
grad
(
a1
.
outputs
[
0
],
a1
.
outputs
[
1
],
assume_continuously_differentiable
=
True
)
self
.
assertTrue
(
g
.
owner
.
op
==
fill
)
self
.
assertTrue
(
g
.
owner
.
op
==
fill
)
self
.
assertTrue
(
g
.
owner
.
inputs
[
1
]
.
data
==
0
)
self
.
assertTrue
(
g
.
owner
.
inputs
[
1
]
.
data
==
0
)
try
:
try
:
...
@@ -3211,7 +3248,8 @@ class test_grad(unittest.TestCase):
...
@@ -3211,7 +3248,8 @@ class test_grad(unittest.TestCase):
"""grad: Test returning some zero value from grad"""
"""grad: Test returning some zero value from grad"""
o
=
test_grad
.
O
()
o
=
test_grad
.
O
()
a1
=
o
.
make_node
()
a1
=
o
.
make_node
()
g0
,
g1
,
g2
=
grad
(
a1
.
outputs
[
0
],
a1
.
inputs
+
[
scalar
(
'z'
)])
g0
,
g1
,
g2
=
grad
(
a1
.
outputs
[
0
],
a1
.
inputs
+
[
scalar
(
'z'
)],
assume_continuously_differentiable
=
True
)
self
.
assertTrue
(
o
.
gval0
is
g0
)
self
.
assertTrue
(
o
.
gval0
is
g0
)
self
.
assertTrue
(
o
.
gval1
is
g1
)
self
.
assertTrue
(
o
.
gval1
is
g1
)
self
.
assertTrue
(
g2
.
owner
.
op
==
fill
)
self
.
assertTrue
(
g2
.
owner
.
op
==
fill
)
...
@@ -3220,7 +3258,8 @@ class test_grad(unittest.TestCase):
...
@@ -3220,7 +3258,8 @@ class test_grad(unittest.TestCase):
def
test_zero_gradient_shape
(
self
):
def
test_zero_gradient_shape
(
self
):
"""Ensure that a zero gradient has the proper shape."""
"""Ensure that a zero gradient has the proper shape."""
x
=
dmatrix
()
x
=
dmatrix
()
f
=
theano
.
function
([
x
],
grad
(
dscalar
(),
x
))
f
=
theano
.
function
([
x
],
grad
(
dscalar
(),
x
,
assume_continuously_differentiable
=
True
))
a
=
numpy
.
ones
((
3
,
7
))
a
=
numpy
.
ones
((
3
,
7
))
self
.
assertTrue
((
f
(
a
)
==
0
)
.
all
())
# Zero gradient.
self
.
assertTrue
((
f
(
a
)
==
0
)
.
all
())
# Zero gradient.
self
.
assertTrue
(
a
.
shape
==
f
(
a
)
.
shape
)
# With proper shape.
self
.
assertTrue
(
a
.
shape
==
f
(
a
)
.
shape
)
# With proper shape.
...
@@ -4158,9 +4197,19 @@ class test_broadcast(unittest.TestCase):
...
@@ -4158,9 +4197,19 @@ class test_broadcast(unittest.TestCase):
def
test_infer_shape
(
self
):
def
test_infer_shape
(
self
):
x
=
matrix
()
x
=
matrix
()
y
=
addbroadcast
(
x
,
0
)
y
=
addbroadcast
(
x
,
0
)
f
=
theano
.
function
([
x
],
y
.
shape
)
assert
(
f
(
numpy
.
zeros
((
1
,
5
),
dtype
=
config
.
floatX
))
==
[
1
,
5
])
.
all
()
topo
=
f
.
maker
.
env
.
toposort
()
if
theano
.
config
.
mode
!=
'FAST_COMPILE'
:
assert
len
(
topo
)
==
2
assert
isinstance
(
topo
[
0
]
.
op
,
opt
.
Shape_i
)
assert
isinstance
(
topo
[
1
]
.
op
,
opt
.
MakeVector
)
x
=
matrix
()
y
=
unbroadcast
(
x
,
0
)
f
=
theano
.
function
([
x
],
y
.
shape
)
f
=
theano
.
function
([
x
],
y
.
shape
)
f
(
numpy
.
zeros
((
1
,
5
),
dtype
=
config
.
floatX
)
)
assert
(
f
(
numpy
.
zeros
((
2
,
5
),
dtype
=
config
.
floatX
))
==
[
2
,
5
])
.
all
(
)
topo
=
f
.
maker
.
env
.
toposort
()
topo
=
f
.
maker
.
env
.
toposort
()
if
theano
.
config
.
mode
!=
'FAST_COMPILE'
:
if
theano
.
config
.
mode
!=
'FAST_COMPILE'
:
assert
len
(
topo
)
==
3
assert
len
(
topo
)
==
3
...
@@ -4168,6 +4217,18 @@ class test_broadcast(unittest.TestCase):
...
@@ -4168,6 +4217,18 @@ class test_broadcast(unittest.TestCase):
assert
isinstance
(
topo
[
1
]
.
op
,
opt
.
Shape_i
)
assert
isinstance
(
topo
[
1
]
.
op
,
opt
.
Shape_i
)
assert
isinstance
(
topo
[
2
]
.
op
,
opt
.
MakeVector
)
assert
isinstance
(
topo
[
2
]
.
op
,
opt
.
MakeVector
)
x
=
row
()
y
=
unbroadcast
(
x
,
0
)
f
=
theano
.
function
([
x
],
y
.
shape
)
assert
(
f
(
numpy
.
zeros
((
1
,
5
),
dtype
=
config
.
floatX
))
==
[
1
,
5
])
.
all
()
topo
=
f
.
maker
.
env
.
toposort
()
if
theano
.
config
.
mode
!=
'FAST_COMPILE'
:
assert
len
(
topo
)
==
2
assert
isinstance
(
topo
[
0
]
.
op
,
opt
.
Shape_i
)
assert
isinstance
(
topo
[
1
]
.
op
,
opt
.
MakeVector
)
def
test_mod
():
def
test_mod
():
"""
"""
We add this test as not all language and C implementation give the same
We add this test as not all language and C implementation give the same
...
...
theano/tensor/tests/test_opt.py
浏览文件 @
2317ffbb
...
@@ -787,13 +787,18 @@ class test_fusion(unittest.TestCase):
...
@@ -787,13 +787,18 @@ class test_fusion(unittest.TestCase):
(
fx
-
fy
+
theano
.
tensor
.
sqrt
(
fz
),(
fx
,
fy
,
fz
),(
fxv
,
fyv
,
fzv
),
1
,
fxv
-
fyv
+
numpy
.
sqrt
(
fzv
),
'float32'
),
(
fx
-
fy
+
theano
.
tensor
.
sqrt
(
fz
),(
fx
,
fy
,
fz
),(
fxv
,
fyv
,
fzv
),
1
,
fxv
-
fyv
+
numpy
.
sqrt
(
fzv
),
'float32'
),
(
fx
-
fy
+
theano
.
tensor
.
inv
(
fz
),(
fx
,
fy
,
fz
),(
fxv
,
fyv
,
fzv
),
1
,
fxv
-
fyv
+
(
1
/
fzv
),
'float32'
),
#55
(
fx
-
fy
+
theano
.
tensor
.
inv
(
fz
),(
fx
,
fy
,
fz
),(
fxv
,
fyv
,
fzv
),
1
,
fxv
-
fyv
+
(
1
/
fzv
),
'float32'
),
#55
(
fx
-
fy
+
theano
.
tensor
.
neg
(
fz
),(
fx
,
fy
,
fz
),(
fxv
,
fyv
,
fzv
),
1
,
fxv
-
fyv
+
(
-
fzv
),
'float32'
),
(
fx
-
fy
+
theano
.
tensor
.
neg
(
fz
),(
fx
,
fy
,
fz
),(
fxv
,
fyv
,
fzv
),
1
,
fxv
-
fyv
+
(
-
fzv
),
'float32'
),
# (fx-fy+theano.tensor.iround(fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-fyv+numpy.round(fzv),'float32'),#TODO: trouble with the output type. To my understanding, numpy and c round fct return the same type as the input. Why we don't do this?
(
fx
-
fy
+
theano
.
tensor
.
round
(
fz
),(
fx
,
fy
,
fz
),(
fxv
,
fyv
,
fzv
),
1
,
fxv
-
fyv
+
numpy
.
round
(
fzv
),
'float32'
),
(
ix
-
iy
+
theano
.
tensor
.
iround
(
fz
),(
ix
,
iy
,
fz
),(
ixv
,
iyv
,
fzv
),
1
,
ixv
-
iyv
+
numpy
.
round
(
fzv
),
'int64'
),
#TODO: BIT OP only with ints, xor, or, and, invert, cast
# Bit op
# (fx-theano.tensor.or_(fy,fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fy|fz),'float32'),
(
fx
-
theano
.
tensor
.
or_
(
iy
,
iz
),(
fx
,
iy
,
iz
),(
fxv
,
iyv
,
izv
),
1
,
fxv
-
(
iyv
|
izv
),
'float64'
),
# (fx-theano.tensor.xor(fy,fz),(fx,fy,fz),(fxv,fyv,fzv),1,fxv-(fy^fz),'float32'),
(
fx
-
theano
.
tensor
.
xor
(
iy
,
iz
),(
fx
,
iy
,
iz
),(
fxv
,
iyv
,
izv
),
1
,
fxv
-
(
iyv
^
izv
),
'float64'
),
#60
(
fx
-
theano
.
tensor
.
and_
(
iy
,
iz
),(
fx
,
iy
,
iz
),(
fxv
,
iyv
,
izv
),
1
,
fxv
-
(
iyv
&
izv
),
'float64'
),
(
fx
-
theano
.
tensor
.
invert
(
iy
),(
fx
,
iy
),(
fxv
,
iyv
),
1
,
fxv
-
(
~
iyv
),
'float64'
),
(
fx
-
theano
.
tensor
.
cast
(
fy
,
dtype
=
'float64'
),(
fx
,
fy
),(
fxv
,
fyv
),
1
,
fxv
-
numpy
.
asarray
(
fyv
,
'float64'
),
'float64'
),
(
theano
.
tensor
.
pow
(
fx
*
fy
+
fz
,
fx
*
fy
),(
fx
,
fy
,
fz
),(
fxv
,
fyv
,
fzv
),
1
,
numpy
.
power
(
fxv
*
fyv
+
fzv
,
fxv
*
fyv
),
'float32'
),
(
theano
.
tensor
.
pow
(
fx
*
fy
+
fz
,
fx
*
fy
),(
fx
,
fy
,
fz
),(
fxv
,
fyv
,
fzv
),
1
,
numpy
.
power
(
fxv
*
fyv
+
fzv
,
fxv
*
fyv
),
'float32'
),
(
fv
+
fy
**
fz
,(
fv
,
fy
,
fz
),(
fvv
,
fyv
,
fzv
),
2
,
fvv
+
fyv
**
fzv
,
'float32'
),
#fused with a dimshuffle
(
fv
+
fy
**
fz
,(
fv
,
fy
,
fz
),(
fvv
,
fyv
,
fzv
),
2
,
fvv
+
fyv
**
fzv
,
'float32'
),
#fused with a dimshuffle
#65
(
fv
-
fy
+
tensor
.
tanh
(
fz
),(
fv
,
fy
,
fz
),(
fvv
,
fyv
,
fzv
),
2
,
fvv
-
fyv
+
numpy
.
tanh
(
fzv
),
'float32'
),
#fused with a dimshuffle
(
fv
-
fy
+
tensor
.
tanh
(
fz
),(
fv
,
fy
,
fz
),(
fvv
,
fyv
,
fzv
),
2
,
fvv
-
fyv
+
numpy
.
tanh
(
fzv
),
'float32'
),
#fused with a dimshuffle
# Cases where the same input is reused many times.
# Cases where the same input is reused many times.
...
@@ -2753,6 +2758,14 @@ def test_local_add_specialize():
...
@@ -2753,6 +2758,14 @@ def test_local_add_specialize():
s
=
tensor
.
add
(
tensor
.
zeros_like
(
a
))
s
=
tensor
.
add
(
tensor
.
zeros_like
(
a
))
assert
local_add_specialize
.
transform
(
s
.
owner
)
assert
local_add_specialize
.
transform
(
s
.
owner
)
# Test when the 0 input is forcing upcasting
a
=
tensor
.
constant
(
0
,
dtype
=
'int64'
)
b
=
tensor
.
constant
(
1
,
dtype
=
'int32'
)
s
=
a
+
b
transformed
=
local_add_specialize
.
transform
(
s
.
owner
)
assert
transformed
assert
transformed
[
0
]
.
type
==
s
.
type
def
test_local_tensor_scalar_tensor
():
def
test_local_tensor_scalar_tensor
():
dtypes
=
[
'int8'
,
'int16'
,
'int32'
,
'int64'
,
dtypes
=
[
'int8'
,
'int16'
,
'int32'
,
'int64'
,
'uint8'
,
'uint16'
,
'uint32'
,
'uint64'
,
'uint8'
,
'uint16'
,
'uint32'
,
'uint64'
,
...
...
theano/tensor/tests/test_sharedvar.py
浏览文件 @
2317ffbb
...
@@ -582,7 +582,8 @@ def makeSharedTester(shared_constructor_,
...
@@ -582,7 +582,8 @@ def makeSharedTester(shared_constructor_,
shp
=
(
1024
,
1024
)
shp
=
(
1024
,
1024
)
#Test the case with all zeros element
#Test the case with all zeros element
for
x
in
[
numpy
.
asarray
(
numpy
.
random
.
rand
(
*
shp
),
dtype
=
dtype
),
rng
=
numpy
.
random
.
RandomState
(
utt
.
fetch_seed
())
for
x
in
[
numpy
.
asarray
(
rng
.
rand
(
*
shp
),
dtype
=
dtype
),
numpy
.
zeros
(
shp
,
dtype
=
dtype
)]:
numpy
.
zeros
(
shp
,
dtype
=
dtype
)]:
zeros
=
(
x
==
0
)
.
all
()
zeros
=
(
x
==
0
)
.
all
()
x
=
self
.
cast_value
(
x
)
x
=
self
.
cast_value
(
x
)
...
...
theano/tests/test_gradient.py
浏览文件 @
2317ffbb
...
@@ -4,6 +4,7 @@
...
@@ -4,6 +4,7 @@
#
#
import
unittest
import
unittest
import
numpy
import
numpy
import
theano
from
theano
import
gof
from
theano
import
gof
from
theano.gradient
import
*
from
theano.gradient
import
*
...
@@ -250,6 +251,15 @@ class test_grad_sources_inputs(unittest.TestCase):
...
@@ -250,6 +251,15 @@ class test_grad_sources_inputs(unittest.TestCase):
self
.
assertTrue
(
g
[
a1
.
inputs
[
0
]]
==
6
)
self
.
assertTrue
(
g
[
a1
.
inputs
[
0
]]
==
6
)
self
.
assertTrue
(
g
[
a1
.
inputs
[
1
]]
==
11
)
self
.
assertTrue
(
g
[
a1
.
inputs
[
1
]]
==
11
)
def
test_unimplemented_grad
():
a
=
theano
.
tensor
.
vector
()
b
=
theano
.
gradient
.
unimplemented_grad
(
theano
.
tensor
.
add
,
1
,
a
)
f
=
theano
.
function
([
a
],
b
)
try
:
f
([
1
,
2
,
3
])
assert
0
except
NotImplementedError
:
pass
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
unittest
.
main
()
unittest
.
main
()
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论