Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
626104a8
提交
626104a8
authored
4月 15, 2015
作者:
Frédéric Bastien
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #2744 from mohammadpz/pep8
Pep8
上级
d99cb9df
24a8dc48
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
355 行增加
和
330 行删除
+355
-330
configdefaults.py
theano/configdefaults.py
+190
-168
configparser.py
theano/configparser.py
+19
-18
gradient.py
theano/gradient.py
+84
-79
ifelse.py
theano/ifelse.py
+50
-50
test_flake8.py
theano/tests/test_flake8.py
+0
-5
updates.py
theano/updates.py
+12
-10
没有找到文件。
theano/configdefaults.py
浏览文件 @
626104a8
...
...
@@ -24,7 +24,7 @@ def floatX_convert(s):
AddConfigVar
(
'floatX'
,
"Default floating-point precision for python casts"
,
EnumStr
(
'float64'
,
'float32'
,
convert
=
floatX_convert
,),
)
)
AddConfigVar
(
'warn_float64'
,
"Do an action when a tensor variable with float64 dtype is"
...
...
@@ -32,20 +32,20 @@ AddConfigVar('warn_float64',
" gpu back-end and are slow with gamer GPUs."
,
EnumStr
(
'ignore'
,
'warn'
,
'raise'
,
'pdb'
),
in_c_key
=
False
,
)
)
AddConfigVar
(
'cast_policy'
,
"Rules for implicit type casting"
,
EnumStr
(
'custom'
,
'numpy+floatX'
,
# The 'numpy' policy was originally planned to provide a smooth
# transition from numpy. It was meant to behave the same as
# numpy+floatX, but keeping float64 when numpy would. However
# the current implementation of some cast mechanisms makes i
t
# a bit more complex to add than what was expected, so it is
#
currently not available.
# numpy,
),
)
'Rules for implicit type casting'
,
EnumStr
(
'custom'
,
'numpy+floatX'
,
# The 'numpy' policy was originally planned to provide a
# smooth transition from numpy. It was meant to behave the
# same asnumpy+floatX, but keeping float64 when numpy
# would. However the current implementation of some cas
t
# mechanisms makes it a bit more complex to add than what
# was expected, so it is
currently not available.
# numpy,
),
)
# python 2.* define int / int to return int and int // int to return int.
# python 3* define int / int to return float and int // int to return int.
...
...
@@ -53,10 +53,10 @@ AddConfigVar('cast_policy',
# than numpy. When we will do the transition, we should create an int_warn
# and floatX_warn option.
AddConfigVar
(
'int_division'
,
"What to do when one computes x / y, where both x and y are of "
"integer types"
,
EnumStr
(
'int'
,
'raise'
,
'floatX'
),
in_c_key
=
False
)
"What to do when one computes x / y, where both x and y are of "
"integer types"
,
EnumStr
(
'int'
,
'raise'
,
'floatX'
),
in_c_key
=
False
)
# gpu means let the driver select the gpu. Needed in case of gpu in
# exclusive mode.
...
...
@@ -82,14 +82,14 @@ class DeviceParam(ConfigParam):
def
__str__
(
self
):
return
'
%
s (cpu, gpu*, opencl*, cuda*) '
%
(
self
.
fullname
,)
AddConfigVar
(
'device'
,
(
"Default device for computations. If gpu*, change the default to try "
"to move computation to it and to put shared variable of float32
"
"on it. Do not use upper case letters, only lower case even if
"
"NVIDIA use capital letters."
),
DeviceParam
(
'cpu'
,
allow_override
=
False
),
in_c_key
=
False
,
)
AddConfigVar
(
'device'
,
(
"Default device for computations. If gpu*, change the default to try
"
"to move computation to it and to put shared variable of float32
"
"on it. Do not use upper case letters, only lower case even if "
"NVIDIA use capital letters."
),
DeviceParam
(
'cpu'
,
allow_override
=
False
)
,
in_c_key
=
False
,
)
AddConfigVar
(
'gpuarray.init_device'
,
"""
...
...
@@ -99,28 +99,31 @@ AddConfigVar('gpuarray.init_device',
StrParam
(
''
),
in_c_key
=
False
)
AddConfigVar
(
'init_gpu_device'
,
(
"Initialize the gpu device to use, works only if device=cpu. "
"Unlike 'device', setting this option will NOT move computations, "
"nor shared variables, to the specified GPU. "
"It can be used to run GPU-specific tests on a particular GPU."
),
EnumStr
(
''
,
'gpu'
,
AddConfigVar
(
'init_gpu_device'
,
(
"Initialize the gpu device to use, works only if device=cpu. "
"Unlike 'device', setting this option will NOT move computations, "
"nor shared variables, to the specified GPU. "
"It can be used to run GPU-specific tests on a particular GPU."
),
EnumStr
(
''
,
'gpu'
,
'gpu0'
,
'gpu1'
,
'gpu2'
,
'gpu3'
,
'gpu4'
,
'gpu5'
,
'gpu6'
,
'gpu7'
,
'gpu8'
,
'gpu9'
,
'gpu10'
,
'gpu11'
,
'gpu12'
,
'gpu13'
,
'gpu14'
,
'gpu15'
,
allow_override
=
False
),
in_c_key
=
False
)
allow_override
=
False
),
in_c_key
=
False
)
AddConfigVar
(
'force_device'
,
"Raise an error if we can't use the specified device"
,
BoolParam
(
False
,
allow_override
=
False
),
in_c_key
=
False
)
AddConfigVar
(
'force_device'
,
"Raise an error if we can't use the specified device"
,
BoolParam
(
False
,
allow_override
=
False
),
in_c_key
=
False
)
AddConfigVar
(
'print_active_device'
,
"Print active device at when the GPU device is initialized."
,
BoolParam
(
True
,
allow_override
=
False
),
in_c_key
=
False
)
AddConfigVar
(
'print_active_device'
,
"Print active device at when the GPU device is initialized."
,
BoolParam
(
True
,
allow_override
=
False
),
in_c_key
=
False
)
# Do not add FAST_RUN_NOGC to this list (nor any other ALL CAPS shortcut).
...
...
@@ -129,11 +132,12 @@ AddConfigVar('print_active_device',
# scalable.
# Also, please be careful not to modify the first item in the enum when adding
# new modes, since it is the default mode.
AddConfigVar
(
'mode'
,
"Default compilation mode"
,
EnumStr
(
'Mode'
,
'ProfileMode'
,
'DebugMode'
,
'FAST_RUN'
,
'FAST_COMPILE'
,
'PROFILE_MODE'
,
'DEBUG_MODE'
),
in_c_key
=
False
)
AddConfigVar
(
'mode'
,
"Default compilation mode"
,
EnumStr
(
'Mode'
,
'ProfileMode'
,
'DebugMode'
,
'FAST_RUN'
,
'FAST_COMPILE'
,
'PROFILE_MODE'
,
'DEBUG_MODE'
),
in_c_key
=
False
)
param
=
"g++"
...
...
@@ -209,22 +213,24 @@ AddConfigVar('allow_gc',
in_c_key
=
False
)
# Keep the default optimizer the same as the one for the mode FAST_RUN
AddConfigVar
(
'optimizer'
,
(
"Default optimizer. If not None, will use this linker with the Mode "
"object (not ProfileMode(deprecated) or DebugMode)"
),
EnumStr
(
'fast_run'
,
'merge'
,
'fast_compile'
,
'None'
),
in_c_key
=
False
)
AddConfigVar
(
'optimizer'
,
(
"Default optimizer. If not None, will use this linker with the Mode "
"object (not ProfileMode(deprecated) or DebugMode)"
),
EnumStr
(
'fast_run'
,
'merge'
,
'fast_compile'
,
'None'
),
in_c_key
=
False
)
AddConfigVar
(
'optimizer_verbose'
,
"If True, we print all optimization being applied"
,
BoolParam
(
False
),
in_c_key
=
False
)
AddConfigVar
(
'on_opt_error'
,
(
"What to do when an optimization crashes: warn and skip it, raise "
"the exception, or fall into the pdb debugger."
),
EnumStr
(
'warn'
,
'raise'
,
'pdb'
),
in_c_key
=
False
)
AddConfigVar
(
'on_opt_error'
,
(
"What to do when an optimization crashes: warn and skip it, raise "
"the exception, or fall into the pdb debugger."
),
EnumStr
(
'warn'
,
'raise'
,
'pdb'
),
in_c_key
=
False
)
def
safe_no_home
(
home
):
...
...
@@ -239,23 +245,25 @@ def safe_no_home(home):
"""
if
home
:
raise
RuntimeError
(
'The `config.home` option has been removed and should not be '
'used anymore. Please set the `config.base_compiledir` option '
'instead (for instance to:
%
s)'
%
os
.
path
.
join
(
home
,
'.theano'
))
'The `config.home` option has been removed and should not be '
'used anymore. Please set the `config.base_compiledir` option '
'instead (for instance to:
%
s)'
%
os
.
path
.
join
(
home
,
'.theano'
))
return
True
AddConfigVar
(
'home'
,
"This config option was removed in 0.5: do not use it!"
,
ConfigParam
(
''
,
allow_override
=
False
,
filter
=
safe_no_home
),
in_c_key
=
False
)
AddConfigVar
(
'home'
,
"This config option was removed in 0.5: do not use it!"
,
ConfigParam
(
''
,
allow_override
=
False
,
filter
=
safe_no_home
),
in_c_key
=
False
)
AddConfigVar
(
'nocleanup'
,
"Suppress the deletion of code files that did not compile cleanly"
,
BoolParam
(
False
),
in_c_key
=
False
)
AddConfigVar
(
'nocleanup'
,
"Suppress the deletion of code files that did not compile cleanly"
,
BoolParam
(
False
),
in_c_key
=
False
)
AddConfigVar
(
'on_unused_input'
,
"What to do if a variable in the 'inputs' list of "
...
...
@@ -267,40 +275,46 @@ AddConfigVar('on_unused_input',
# So changing it after import will not modify these global variables.
# This could be done differently... but for now we simply prevent it from being
# changed at runtime.
AddConfigVar
(
'tensor.cmp_sloppy'
,
"Relax tensor._allclose (0) not at all, (1) a bit, (2) more"
,
IntParam
(
0
,
lambda
i
:
i
in
(
0
,
1
,
2
),
allow_override
=
False
),
in_c_key
=
False
)
AddConfigVar
(
'tensor.local_elemwise_fusion'
,
(
"Enable or not in fast_run mode(fast_run optimization) the elemwise "
"fusion optimization"
),
BoolParam
(
True
),
in_c_key
=
False
)
AddConfigVar
(
'gpu.local_elemwise_fusion'
,
(
"Enable or not in fast_run mode(fast_run optimization) the gpu "
"elemwise fusion optimization"
),
BoolParam
(
True
),
in_c_key
=
False
)
AddConfigVar
(
'tensor.cmp_sloppy'
,
"Relax tensor._allclose (0) not at all, (1) a bit, (2) more"
,
IntParam
(
0
,
lambda
i
:
i
in
(
0
,
1
,
2
),
allow_override
=
False
),
in_c_key
=
False
)
AddConfigVar
(
'tensor.local_elemwise_fusion'
,
(
"Enable or not in fast_run mode(fast_run optimization) the elemwise "
"fusion optimization"
),
BoolParam
(
True
),
in_c_key
=
False
)
AddConfigVar
(
'gpu.local_elemwise_fusion'
,
(
"Enable or not in fast_run mode(fast_run optimization) the gpu "
"elemwise fusion optimization"
),
BoolParam
(
True
),
in_c_key
=
False
)
# http://developer.amd.com/CPU/LIBRARIES/LIBM/Pages/default.aspx
AddConfigVar
(
'lib.amdlibm'
,
"Use amd's amdlibm numerical library"
,
BoolParam
(
False
))
AddConfigVar
(
'gpuelemwise.sync'
,
"when true, wait that the gpu fct finished and check it error code."
,
BoolParam
(
True
),
in_c_key
=
False
)
AddConfigVar
(
'traceback.limit'
,
"The number of stack to trace. -1 mean all."
,
# We default to 6 to be able to know where v1 + v2 is created in the
# user script. The bigger this number is, the more run time it takes.
# We need to default to 7 to support theano.tensor.tensor(...).
IntParam
(
7
),
in_c_key
=
False
)
AddConfigVar
(
'lib.amdlibm'
,
"Use amd's amdlibm numerical library"
,
BoolParam
(
False
))
AddConfigVar
(
'gpuelemwise.sync'
,
"when true, wait that the gpu fct finished and check it error code."
,
BoolParam
(
True
),
in_c_key
=
False
)
AddConfigVar
(
'traceback.limit'
,
"The number of stack to trace. -1 mean all."
,
# We default to 6 to be able to know where v1 + v2 is created in the
# user script. The bigger this number is, the more run time it takes.
# We need to default to 7 to support theano.tensor.tensor(...).
IntParam
(
7
),
in_c_key
=
False
)
AddConfigVar
(
'experimental.mrg'
,
"Another random number generator that work on the gpu"
,
...
...
@@ -329,14 +343,14 @@ AddConfigVar('numpy.seterr_all',
"by the following flags: seterr_divide, seterr_over, "
"seterr_under and seterr_invalid."
),
EnumStr
(
'ignore'
,
'warn'
,
'raise'
,
'call'
,
'print'
,
'log'
,
'None'
,
allow_override
=
False
),
allow_override
=
False
),
in_c_key
=
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
),
allow_override
=
False
),
in_c_key
=
False
)
AddConfigVar
(
'numpy.seterr_over'
,
...
...
@@ -344,7 +358,7 @@ AddConfigVar('numpy.seterr_over',
"see numpy.seterr. "
"'None' means using the default, defined by numpy.seterr_all."
),
EnumStr
(
'None'
,
'ignore'
,
'warn'
,
'raise'
,
'call'
,
'print'
,
'log'
,
allow_override
=
False
),
allow_override
=
False
),
in_c_key
=
False
)
AddConfigVar
(
'numpy.seterr_under'
,
...
...
@@ -352,7 +366,7 @@ AddConfigVar('numpy.seterr_under',
"see numpy.seterr. "
"'None' means using the default, defined by numpy.seterr_all."
),
EnumStr
(
'None'
,
'ignore'
,
'warn'
,
'raise'
,
'call'
,
'print'
,
'log'
,
allow_override
=
False
),
allow_override
=
False
),
in_c_key
=
False
)
AddConfigVar
(
'numpy.seterr_invalid'
,
...
...
@@ -360,7 +374,7 @@ AddConfigVar('numpy.seterr_invalid',
"see numpy.seterr. "
"'None' means using the default, defined by numpy.seterr_all."
),
EnumStr
(
'None'
,
'ignore'
,
'warn'
,
'raise'
,
'call'
,
'print'
,
'log'
,
allow_override
=
False
),
allow_override
=
False
),
in_c_key
=
False
)
###
...
...
@@ -422,30 +436,33 @@ AddConfigVar('warn.sum_div_dimshuffle_bug',
BoolParam
(
warn_default
(
'0.3'
)),
in_c_key
=
False
)
AddConfigVar
(
'warn.subtensor_merge_bug'
,
"Warn if previous versions of Theano (before 0.5rc2) could have given "
"incorrect results when indexing into a subtensor with negative "
"stride (for instance, for instance, x[a:b:-1][c])."
,
BoolParam
(
warn_default
(
'0.5'
)),
in_c_key
=
False
)
AddConfigVar
(
'warn.gpu_set_subtensor1'
,
"Warn if previous versions of Theano (before 0.6) could have given "
"incorrect results when moving to the gpu "
"set_subtensor(x[int vector], new_value)"
,
BoolParam
(
warn_default
(
'0.6'
)),
in_c_key
=
False
)
AddConfigVar
(
'warn.vm_gc_bug'
,
"There was a bug that existed in the default Theano configuration,"
" only in the development version between July 5th 2012"
" and July 30th 2012. This was not in a released version."
" If your code was affected by this bug, a warning"
" will be printed during the code execution if you use the"
" `linker=vm,vm.lazy=True,warn.vm_gc_bug=True` Theano flags."
" This warning is disabled by default as the bug was not released."
,
BoolParam
(
False
),
in_c_key
=
False
)
AddConfigVar
(
'warn.subtensor_merge_bug'
,
"Warn if previous versions of Theano (before 0.5rc2) could have given "
"incorrect results when indexing into a subtensor with negative "
"stride (for instance, for instance, x[a:b:-1][c])."
,
BoolParam
(
warn_default
(
'0.5'
)),
in_c_key
=
False
)
AddConfigVar
(
'warn.gpu_set_subtensor1'
,
"Warn if previous versions of Theano (before 0.6) could have given "
"incorrect results when moving to the gpu "
"set_subtensor(x[int vector], new_value)"
,
BoolParam
(
warn_default
(
'0.6'
)),
in_c_key
=
False
)
AddConfigVar
(
'warn.vm_gc_bug'
,
"There was a bug that existed in the default Theano configuration,"
" only in the development version between July 5th 2012"
" and July 30th 2012. This was not in a released version."
" If your code was affected by this bug, a warning"
" will be printed during the code execution if you use the"
" `linker=vm,vm.lazy=True,warn.vm_gc_bug=True` Theano flags."
" This warning is disabled by default as the bug was not released."
,
BoolParam
(
False
),
in_c_key
=
False
)
AddConfigVar
(
'warn.signal_conv2d_interface'
,
(
"Warn we use the new signal.conv2d() when its interface"
...
...
@@ -474,13 +491,14 @@ AddConfigVar('warn.inc_set_subtensor1',
BoolParam
(
warn_default
(
'0.7'
)),
in_c_key
=
False
)
AddConfigVar
(
'compute_test_value'
,
(
"If 'True', Theano will run each op at graph build time, using "
"Constants, SharedVariables and the tag 'test_value' as inputs "
"to the function. This helps the user track down problems in the "
"graph before it gets optimized."
),
EnumStr
(
'off'
,
'ignore'
,
'warn'
,
'raise'
,
'pdb'
),
in_c_key
=
False
)
AddConfigVar
(
'compute_test_value'
,
(
"If 'True', Theano will run each op at graph build time, using "
"Constants, SharedVariables and the tag 'test_value' as inputs "
"to the function. This helps the user track down problems in the "
"graph before it gets optimized."
),
EnumStr
(
'off'
,
'ignore'
,
'warn'
,
'raise'
,
'pdb'
),
in_c_key
=
False
)
AddConfigVar
(
'compute_test_value_opt'
,
...
...
@@ -497,10 +515,11 @@ AddConfigVar('unpickle_function',
BoolParam
(
True
),
in_c_key
=
False
)
AddConfigVar
(
'reoptimize_unpickled_function'
,
"Re-optimize the graph when a theano function is unpickled from the disk."
,
BoolParam
(
True
,
allow_override
=
True
),
in_c_key
=
False
)
AddConfigVar
(
'reoptimize_unpickled_function'
,
"Re-optimize the graph when a theano function is unpickled from the disk."
,
BoolParam
(
True
,
allow_override
=
True
),
in_c_key
=
False
)
"""Note to developers:
...
...
@@ -509,17 +528,18 @@ AddConfigVar('reoptimize_unpickled_function',
== 'high', you should include a call to printing.min_informative_str
on all important apply nodes.
"""
AddConfigVar
(
'exception_verbosity'
,
"If 'low', the text of exceptions will generally refer "
\
+
"to apply nodes with short names such as "
\
+
"Elemwise{add_no_inplace}. If 'high', some exceptions "
\
+
"will also refer to apply nodes with long descriptions "
\
+
""" like:
A. Elemwise{add_no_inplace}
B. log_likelihood_v_given_h
C. log_likelihood_h"""
,
EnumStr
(
'low'
,
'high'
),
in_c_key
=
False
)
AddConfigVar
(
'exception_verbosity'
,
"If 'low', the text of exceptions will generally refer "
"to apply nodes with short names such as "
"Elemwise{add_no_inplace}. If 'high', some exceptions "
"will also refer to apply nodes with long descriptions "
""" like:
A. Elemwise{add_no_inplace}
B. log_likelihood_v_given_h
C. log_likelihood_h"""
,
EnumStr
(
'low'
,
'high'
),
in_c_key
=
False
)
# Test if the env variable is set
var
=
os
.
getenv
(
'OMP_NUM_THREADS'
,
None
)
...
...
@@ -560,7 +580,7 @@ AddConfigVar('openmp',
" If it is set to 1, we disable openmp in Theano by default."
,
BoolParam
(
default_openmp
),
in_c_key
=
False
,
)
)
AddConfigVar
(
'openmp_elemwise_minsize'
,
"If OpenMP is enabled, this is the minimum size of vectors "
...
...
@@ -568,19 +588,21 @@ AddConfigVar('openmp_elemwise_minsize',
"in element wise ops."
,
IntParam
(
200000
),
in_c_key
=
False
,
)
AddConfigVar
(
'check_input'
,
"Specify if types should check their input in their C code. "
"It can be used to speed up compilation, reduce overhead "
"(particularly for scalars) and reduce the number of generated C "
"files."
,
BoolParam
(
True
))
AddConfigVar
(
'cache_optimizations'
,
"WARNING: work in progress, does not work yet. "
"Specify if the optimization cache should be used. This cache will "
"any optimized graph and its optimization. Actually slow downs a lot "
"the first optimization, and could possibly still contains some bugs. "
"Use at your own risks."
,
BoolParam
(
False
))
)
AddConfigVar
(
'check_input'
,
"Specify if types should check their input in their C code. "
"It can be used to speed up compilation, reduce overhead "
"(particularly for scalars) and reduce the number of generated C "
"files."
,
BoolParam
(
True
))
AddConfigVar
(
'cache_optimizations'
,
"WARNING: work in progress, does not work yet. "
"Specify if the optimization cache should be used. This cache will "
"any optimized graph and its optimization. Actually slow downs a lot "
"the first optimization, and could possibly still contains some bugs. "
"Use at your own risks."
,
BoolParam
(
False
))
theano/configparser.py
浏览文件 @
626104a8
...
...
@@ -44,9 +44,9 @@ def parse_config_string(config_string, issue_warnings=True):
if
len
(
kv_tuple
)
==
1
:
if
issue_warnings
:
TheanoConfigWarning
.
warn
(
(
"Config key '
%
s' has no value, ignoring it"
%
kv_tuple
[
0
]),
stacklevel
=
1
)
(
"Config key '
%
s' has no value, ignoring it"
%
kv_tuple
[
0
]),
stacklevel
=
1
)
else
:
k
,
v
=
kv_tuple
# subsequent values for k will override earlier ones
...
...
@@ -77,7 +77,7 @@ theano_cfg = ConfigParser.SafeConfigParser(
'TEMP'
:
os
.
getenv
(
"TEMP"
,
""
),
'TMP'
:
os
.
getenv
(
"TMP"
,
""
),
'PID'
:
str
(
os
.
getpid
()),
}
}
)
theano_cfg
.
read
(
config_files
)
# Having a raw version of the config around as well enables us to pass
...
...
@@ -145,7 +145,7 @@ def get_config_md5():
all_opts
=
sorted
([
c
for
c
in
_config_var_list
if
c
.
in_c_key
],
key
=
lambda
cv
:
cv
.
fullname
)
return
theano
.
gof
.
cc
.
hash_from_code
(
'
\n
'
.
join
(
[
'
%
s =
%
s'
%
(
cv
.
fullname
,
cv
.
__get__
())
for
cv
in
all_opts
]))
[
'
%
s =
%
s'
%
(
cv
.
fullname
,
cv
.
__get__
())
for
cv
in
all_opts
]))
class
TheanoConfigParser
(
object
):
...
...
@@ -217,11 +217,11 @@ def AddConfigVar(name, doc, configparam, root=config, in_c_key=True):
_i_am_a_config_class
=
True
setattr
(
root
.
__class__
,
sections
[
0
],
SubObj
())
newroot
=
getattr
(
root
,
sections
[
0
])
if
(
not
getattr
(
newroot
,
'_i_am_a_config_class'
,
False
)
or
isinstance
(
newroot
,
type
)):
if
(
not
getattr
(
newroot
,
'_i_am_a_config_class'
,
False
)
or
isinstance
(
newroot
,
type
)):
raise
TypeError
(
'Internal config nodes must be config class instances'
,
newroot
)
'Internal config nodes must be config class instances'
,
newroot
)
return
AddConfigVar
(
'.'
.
join
(
sections
[
1
:]),
doc
,
configparam
,
root
=
newroot
,
in_c_key
=
in_c_key
)
else
:
...
...
@@ -235,7 +235,8 @@ def AddConfigVar(name, doc, configparam, root=config, in_c_key=True):
if
not
callable
(
configparam
.
default
):
configparam
.
__get__
()
else
:
# We do not want to evaluate now the default value when it is a callable.
# We do not want to evaluate now the default value
# when it is a callable.
try
:
fetch_val_for_key
(
configparam
.
fullname
)
# The user provided a value, filter it now.
...
...
@@ -282,8 +283,8 @@ class ConfigParam(object):
def
__set__
(
self
,
cls
,
val
):
if
not
self
.
allow_override
and
hasattr
(
self
,
'val'
):
raise
Exception
(
"Can't change the value of this config parameter "
"after initialization!"
)
"Can't change the value of this config parameter "
"after initialization!"
)
# print "SETTING PARAM", self.fullname,(cls), val
if
self
.
filter
:
self
.
val
=
self
.
filter
(
val
)
...
...
@@ -300,7 +301,7 @@ class EnumStr(ConfigParam):
for
val
in
self
.
all
:
if
not
isinstance
(
val
,
basestring
):
raise
ValueError
(
'Valid values for an EnumStr parameter '
'should be strings'
,
val
,
type
(
val
))
'should be strings'
,
val
,
type
(
val
))
convert
=
kwargs
.
get
(
"convert"
,
None
)
...
...
@@ -332,13 +333,13 @@ class TypedParam(ConfigParam):
return
cast_val
else
:
raise
ValueError
(
'Invalid value (
%
s) for configuration variable '
'"
%
s".'
%
(
val
,
self
.
fullname
),
val
)
'Invalid value (
%
s) for configuration variable '
'"
%
s".'
%
(
val
,
self
.
fullname
),
val
)
return
cast_val
super
(
TypedParam
,
self
)
.
__init__
(
default
,
filter
,
allow_override
=
allow_override
)
allow_override
=
allow_override
)
def
__str__
(
self
):
return
'
%
s (
%
s) '
%
(
self
.
fullname
,
self
.
mytype
)
...
...
@@ -375,4 +376,4 @@ def BoolParam(default, is_valid=None, allow_override=True):
is_valid
=
is_valid_bool
return
TypedParam
(
default
,
booltype
,
is_valid
,
allow_override
=
allow_override
)
allow_override
=
allow_override
)
theano/gradient.py
浏览文件 @
626104a8
"""Driver for gradient calculations."""
__authors__
=
"James Bergstra, Razvan Pascanu, Arnaud Bergeron, Ian Goodfellow"
__copyright__
=
"(c) 2011, Universite de Montreal"
__license__
=
"3-clause BSD License"
__contact__
=
"theano-dev <theano-dev@googlegroups.com>"
__docformat__
=
"restructuredtext en"
import
__builtin__
from
itertools
import
izip
import
logging
import
time
import
warnings
_logger
=
logging
.
getLogger
(
'theano.gradient'
)
import
numpy
# for numeric_grad
np
=
numpy
import
theano
...
...
@@ -26,6 +16,15 @@ from theano.gof.null_type import NullType, null_type
from
theano.gof.op
import
get_debug_values
from
theano.compile
import
ViewOp
np
=
numpy
__authors__
=
"James Bergstra, Razvan Pascanu, Arnaud Bergeron, Ian Goodfellow"
__copyright__
=
"(c) 2011, Universite de Montreal"
__license__
=
"3-clause BSD License"
__contact__
=
"theano-dev <theano-dev@googlegroups.com>"
__docformat__
=
"restructuredtext en"
_logger
=
logging
.
getLogger
(
'theano.gradient'
)
# we can't do "import theano.tensor"
# tensor depends on theano.compile
# theano.compile depends on theano.gradient (this file)
...
...
@@ -86,7 +85,7 @@ def grad_not_implemented(op, x_pos, x, comment=""):
return
(
NullType
((
"This variable is Null because the grad method for "
"input
%
s (
%
s) of the
%
s op is not implemented.
%
s"
)
%
(
x_pos
,
x
,
op
,
comment
)))()
)
%
(
x_pos
,
x
,
op
,
comment
)))()
def
grad_undefined
(
op
,
x_pos
,
x
,
comment
=
""
):
...
...
@@ -467,16 +466,17 @@ def grad(cost, wrt, consider_constant=None,
g_cost
=
known_grads
[
cost
]
else
:
g_cost
=
_float_ones_like
(
cost
)
# g_cost may be Disconnected or NullType. A creative use of the
function,
#
sure, but nonetheless one we can and should support. So before we try
# to cast it make sure it even has a dtype
# g_cost may be Disconnected or NullType. A creative use of the
#
function, sure, but nonetheless one we can and should support.
#
So before we try
to cast it make sure it even has a dtype
if
(
hasattr
(
g_cost
.
type
,
'dtype'
)
and
cost
.
type
.
dtype
not
in
tensor
.
discrete_dtypes
):
# Here we enforce the constraint that floating point variables have
#
the same dtype as their gradient.
g_cost
=
g_cost
.
astype
(
cost
.
type
.
dtype
)
cost
.
type
.
dtype
not
in
tensor
.
discrete_dtypes
):
# Here we enforce the constraint that floating point variables
# have
the same dtype as their gradient.
g_cost
=
g_cost
.
astype
(
cost
.
type
.
dtype
)
# DO NOT enforce g_cost to be 0 if cost is an integer.
# This is to be enforced by the Op.grad method for the Op that outputs cost.
# This is to be enforced by the Op.grad method for the
# Op that outputs cost.
if
hasattr
(
g_cost
.
type
,
'dtype'
):
assert
g_cost
.
type
.
dtype
not
in
tensor
.
discrete_dtypes
...
...
@@ -491,10 +491,10 @@ def grad(cost, wrt, consider_constant=None,
' or sparse theano variable'
%
str
(
type
(
g_var
)))
if
(
not
isinstance
(
g_var
.
type
,
(
NullType
,
DisconnectedType
))
and
'float'
not
in
str
(
g_var
.
type
.
dtype
)):
'float'
not
in
str
(
g_var
.
type
.
dtype
)):
raise
TypeError
(
"Gradients must always be NullType, "
"DisconnectedType, or continuous, but grad was "
"given a known_grad of type "
+
str
(
g_var
.
type
))
"given a known_grad of type "
+
str
(
g_var
.
type
))
# DO NOT check that these gradients are equal to 0 if var is int
# The gradient is allowed to be non-zero on var in that case
...
...
@@ -734,9 +734,9 @@ def _node_to_pattern(node):
if
not
isinstance
(
output_pattern
,
list
):
raise
TypeError
(
'
%
s.connection_pattern should return'
%
node
.
op
+
' a list of lists, but element
%
d'
%
ii
+
'is
%
s of type
%
s.'
%
(
output_pattern
,
type
(
output_pattern
)))
node
.
op
+
' a list of lists, but element
%
d'
%
ii
+
'is
%
s of type
%
s.'
%
(
output_pattern
,
type
(
output_pattern
)))
else
:
connection_pattern
=
[[
True
for
output
in
node
.
outputs
]
for
ipt
in
node
.
inputs
]
...
...
@@ -846,10 +846,10 @@ def _populate_var_to_app_to_idx(outputs, wrt, consider_constant):
if
ipt
not
in
var_to_app_to_idx
:
# This object here *must* be an OrderedDict, because
# we iterate over its keys when adding up the terms of
#
the gradient on ipt. If it is a regular dict, the gra
d
#
method will return something that is analytically correct,
#
but
whose order of doing additions depends on the memory
# we iterate over its keys when adding up the terms of
the
#
gradient on ipt. If it is a regular dict, the grad metho
d
#
will return something that is analytically correct, but
# whose order of doing additions depends on the memory
# location of the apply nodes.
var_to_app_to_idx
[
ipt
]
=
OrderedDict
()
app_to_idx
=
var_to_app_to_idx
[
ipt
]
...
...
@@ -923,8 +923,8 @@ def _populate_grad_dict(var_to_app_to_idx,
grad_dict: A dictionary mapping variables to their gradients.
Should be populated by grad function, which should:
-Set the gradient with respect to the cost to 1
-Load all gradients from known_grads, possibly
overriding
the cost
-Load all gradients from known_grads, possibly
overriding
the cost
-Set the gradient for disconnected
inputs to a variable with type DisconnectedType()
...
...
@@ -1004,10 +1004,10 @@ def _populate_grad_dict(var_to_app_to_idx,
# call the op's grad method
# Each Op's grad function requires inputs and output_grads
# If the Op destroys any input, but the grad expression uses
it,
#
then chances are the resulting graph will have a dependency
#
cycle. We avoid this cycle by passing (symbolic) copies of
# each destroyed input.
# If the Op destroys any input, but the grad expression uses
#
it, then chances are the resulting graph will have a
#
dependency cycle. We avoid this cycle by passing (symbolic)
#
copies of
each destroyed input.
try
:
dinputs
=
[
node
.
inputs
[
x
[
0
]]
for
x
in
node
.
op
.
destroy_map
.
values
()]
...
...
@@ -1030,15 +1030,16 @@ def _populate_grad_dict(var_to_app_to_idx,
# If an output is of an integer dtype, then we just leave it
# alone.
# DO NOT force integer variables to have zero grad. This causes
# bugs where we fail to detect disconnected or undefined gradients.
# DO NOT force integer variables to have integer dtype. This is
# a violation of the op contract.
# bugs where we fail to detect disconnected or undefined
# gradients.
# DO NOT force integer variables to have integer dtype.
# This is a violation of the op contract.
new_output_grads
=
[]
for
o
,
og
in
zip
(
node
.
outputs
,
output_grads
):
o_dt
=
getattr
(
o
.
type
,
'dtype'
,
None
)
og_dt
=
getattr
(
og
.
type
,
'dtype'
,
None
)
if
(
o_dt
not
in
theano
.
tensor
.
discrete_dtypes
and
og_dt
and
o_dt
!=
og_dt
):
og_dt
and
o_dt
!=
og_dt
):
new_output_grads
.
append
(
og
.
astype
(
o_dt
))
else
:
new_output_grads
.
append
(
og
)
...
...
@@ -1049,7 +1050,7 @@ def _populate_grad_dict(var_to_app_to_idx,
o_dt
=
getattr
(
o
.
type
,
'dtype'
,
None
)
ng_dt
=
getattr
(
ng
.
type
,
'dtype'
,
None
)
if
(
ng_dt
is
not
None
and
o_dt
not
in
theano
.
tensor
.
discrete_dtypes
):
o_dt
not
in
theano
.
tensor
.
discrete_dtypes
):
assert
ng_dt
==
o_dt
# Someone who had obviously not read the Op contract tried
...
...
@@ -1063,14 +1064,15 @@ def _populate_grad_dict(var_to_app_to_idx,
assert
(
getattr
(
ng
.
type
,
'dtype'
,
None
)
not
in
theano
.
tensor
.
discrete_dtypes
)
# If config.compute_test_value is turned on, check that the gradients
# on the outputs of this node have the right shape.
# We also check the gradient on the inputs later--both checks are needed,
# because some gradients are only ever specified by the user, not computed
# by Op.grad, and some gradients are only computed and returned, but never
# passed as another node's output grads.
# If config.compute_test_value is turned on, check that the
# gradients on the outputs of this node have the right shape.
# We also check the gradient on the inputs later--both checks
# are needed, because some gradients are only ever specified
# by the user, not computed by Op.grad, and some gradients are
# only computed and returned, but never passed as another
# node's output grads.
for
idx
,
packed
in
enumerate
(
izip
(
node
.
outputs
,
new_output_grads
)):
new_output_grads
)):
orig_output
,
new_output_grad
=
packed
if
not
hasattr
(
orig_output
,
'shape'
):
continue
...
...
@@ -1098,14 +1100,14 @@ def _populate_grad_dict(var_to_app_to_idx,
# We can not enforce this, as AdvancedSubtensor1 has an option to
# return the sparse grad for optimization reason.
#
for ig, i in zip(input_grads, inputs):
#
if (not isinstance(ig.type, (DisconnectedType, NullType)) and
#
type(ig.type) != type(i.type)):
#
raise ValueError(
#
"%s returned the wrong type for gradient terms."
#
" Sparse inputs must have sparse grads and dense"
#
" inputs must have dense grad. Got %s, expected %s" %
(
#
str(node.op), ig.type, i.type))
# for ig, i in zip(input_grads, inputs):
# if (not isinstance(ig.type, (DisconnectedType, NullType)) and
# type(ig.type) != type(i.type)):
# raise ValueError(
# "%s returned the wrong type for gradient terms."
# " Sparse inputs must have sparse grads and dense"
#
" inputs must have dense grad. Got %s, expected %s" %
(
# str(node.op), ig.type, i.type))
# must convert to list in case the op returns a tuple
# we won't be able to post-process out the Nones if it does that
...
...
@@ -1138,7 +1140,8 @@ def _populate_grad_dict(var_to_app_to_idx,
'the grad_undefined or grad_unimplemented helper '
'functions.'
)
%
node
.
op
)
# Check that the gradient term for this input has the right shape
# Check that the gradient term for this input
# has the right shape
if
hasattr
(
term
,
'shape'
):
orig_ipt
=
inputs
[
i
]
for
orig_ipt_v
,
term_v
in
get_debug_values
(
orig_ipt
,
term
):
...
...
@@ -1384,12 +1387,13 @@ class numeric_grad(object):
total_size
=
__builtin__
.
sum
(
prod
(
sh
)
for
sh
in
shapes
)
working_dtype
=
__builtin__
.
min
(
(
self
.
type_eps
[
dt
],
dt
)
for
dt
in
dtypes
)[
1
]
working_dtype
=
__builtin__
.
min
(
(
self
.
type_eps
[
dt
],
dt
)
for
dt
in
dtypes
)[
1
]
# create un-initialized memory
x
=
numpy
.
ndarray
((
total_size
,),
dtype
=
working_dtype
)
if
(
not
out_type
is
None
)
and
(
out_type
.
startswith
(
'complex'
)):
# (not out_type is None) --> (out_type is not None) ???
if
(
out_type
is
not
None
)
and
(
out_type
.
startswith
(
'complex'
)):
gx
=
numpy
.
ndarray
((
total_size
,),
dtype
=
out_type
)
else
:
gx
=
numpy
.
ndarray
((
total_size
,),
dtype
=
working_dtype
)
...
...
@@ -1734,10 +1738,10 @@ def jacobian(expression, wrt, consider_constant=None,
from
theano.tensor
import
arange
# Check inputs have the right format
assert
isinstance
(
expression
,
Variable
),
\
"tensor.jacobian expects a Variable as `expression`"
"tensor.jacobian expects a Variable as `expression`"
assert
expression
.
ndim
<
2
,
\
(
"tensor.jacobian expects a 1 dimensional variable as "
"`expression`. If not use flatten to make it a vector"
)
(
"tensor.jacobian expects a 1 dimensional variable as "
"`expression`. If not use flatten to make it a vector"
)
using_list
=
isinstance
(
wrt
,
list
)
using_tuple
=
isinstance
(
wrt
,
tuple
)
...
...
@@ -1774,9 +1778,9 @@ def jacobian(expression, wrt, consider_constant=None,
sequences
=
arange
(
expression
.
shape
[
0
]),
non_sequences
=
[
expression
]
+
wrt
)
assert
not
updates
,
\
(
"Scan has returned a list of updates. This should not "
"happen! Report this to theano-users (also include the "
"script that generated the error)"
)
(
"Scan has returned a list of updates. This should not "
"happen! Report this to theano-users (also include the "
"script that generated the error)"
)
return
format_as
(
using_list
,
using_tuple
,
jacobs
)
...
...
@@ -1808,9 +1812,9 @@ def hessian(cost, wrt, consider_constant=None,
from
theano.tensor
import
arange
# Check inputs have the right format
assert
isinstance
(
cost
,
Variable
),
\
"tensor.hessian expects a Variable as `cost`"
"tensor.hessian expects a Variable as `cost`"
assert
cost
.
ndim
==
0
,
\
"tensor.hessian expects a 0 dimensional variable as `cost`"
"tensor.hessian expects a 0 dimensional variable as `cost`"
using_list
=
isinstance
(
wrt
,
list
)
using_tuple
=
isinstance
(
wrt
,
tuple
)
...
...
@@ -1823,10 +1827,10 @@ def hessian(cost, wrt, consider_constant=None,
hessians
=
[]
for
input
in
wrt
:
assert
isinstance
(
input
,
Variable
),
\
"tensor.hessian expects a (list of) Variable as `wrt`"
"tensor.hessian expects a (list of) Variable as `wrt`"
assert
input
.
ndim
==
1
,
\
"tensor.hessian expects a (list of) 1 dimensional variable "
\
"as `wrt`"
"tensor.hessian expects a (list of) 1 dimensional variable "
\
"as `wrt`"
expr
=
grad
(
cost
,
input
,
consider_constant
=
consider_constant
,
disconnected_inputs
=
disconnected_inputs
)
...
...
@@ -1834,16 +1838,16 @@ def hessian(cost, wrt, consider_constant=None,
# even if they are connected to cost.
# This should not be an error.
hess
,
updates
=
theano
.
scan
(
lambda
i
,
y
,
x
:
grad
(
y
[
i
],
x
,
consider_constant
=
consider_constant
,
disconnected_inputs
=
'ignore'
),
sequences
=
arange
(
expr
.
shape
[
0
]),
non_sequences
=
[
expr
,
input
])
y
[
i
],
x
,
consider_constant
=
consider_constant
,
disconnected_inputs
=
'ignore'
),
sequences
=
arange
(
expr
.
shape
[
0
]),
non_sequences
=
[
expr
,
input
])
assert
not
updates
,
\
(
"Scan has returned a list of updates. This should not "
"happen! Report this to theano-users (also include the "
"script that generated the error)"
)
(
"Scan has returned a list of updates. This should not "
"happen! Report this to theano-users (also include the "
"script that generated the error)"
)
hessians
.
append
(
hess
)
return
format_as
(
using_list
,
using_tuple
,
hessians
)
...
...
@@ -1974,6 +1978,7 @@ def disconnected_grad(x):
class
GradClip
(
ViewOp
):
# See doc in user fct grad_clip
__props__
=
()
def
__init__
(
self
,
clip_lower_bound
,
clip_upper_bound
):
# We do not put those member in __eq__ or __hash__
# as they do not influence the perform of this op.
...
...
@@ -1996,7 +2001,7 @@ def grad_clip(x, lower_bound, upper_bound):
:param x: the variable we want its gradient inputs clipped
:param lower_bound: The lower bound of the gradient value
:param upper_bound: The upper bound of the gradient value.
:examples:
x = theano.tensor.scalar()
...
...
theano/ifelse.py
浏览文件 @
626104a8
...
...
@@ -10,15 +10,6 @@ which value to report. Note also that `switch` is an elemwise operation (so
it picks each entry of a matrix according to the condition) while `ifelse`
is a global operation with a scalar condition.
"""
__docformat__
=
'restructedtext en'
__authors__
=
(
"Razvan Pascanu "
"James Bergstra "
"Dumitru Erhan "
"David Warde-Farley"
)
__copyright__
=
"(c) 2010, Universite de Montreal"
__contact__
=
"Razvan Pascanu <r.pascanu@gmail>"
from
copy
import
deepcopy
from
itertools
import
izip
import
logging
...
...
@@ -34,6 +25,15 @@ from theano.tensor import opt
from
theano.scan_module.scan_utils
import
find_up
from
theano.scan_module.scan_utils
import
clone
__docformat__
=
'restructedtext en'
__authors__
=
(
"Razvan Pascanu "
"James Bergstra "
"Dumitru Erhan "
"David Warde-Farley"
)
__copyright__
=
"(c) 2010, Universite de Montreal"
__contact__
=
"Razvan Pascanu <r.pascanu@gmail>"
_logger
=
logging
.
getLogger
(
'theano.ifelse'
)
...
...
@@ -142,8 +142,8 @@ class IfElse(PureOp):
gpu
=
False
,
name
=
'_'
.
join
(
name_tokens
))
new_outs
=
new_ifelse
(
node
.
inputs
[
0
],
*
(
new_ts_inputs
+
new_fs_inputs
),
**
dict
(
return_list
=
True
))
*
(
new_ts_inputs
+
new_fs_inputs
),
**
dict
(
return_list
=
True
))
else
:
new_outs
=
[]
...
...
@@ -160,8 +160,8 @@ class IfElse(PureOp):
def
make_node
(
self
,
c
,
*
args
):
assert
len
(
args
)
==
2
*
self
.
n_outs
,
(
"Wrong number of arguments to make_node: "
"expected
%
d, got
%
d"
%
(
2
*
self
.
n_outs
,
len
(
args
))
"Wrong number of arguments to make_node: "
"expected
%
d, got
%
d"
%
(
2
*
self
.
n_outs
,
len
(
args
))
)
if
not
self
.
gpu
:
# When gpu is true, we are given only cuda ndarrays, and we want
...
...
@@ -328,35 +328,35 @@ def ifelse(condition, then_branch, else_branch, name=None):
for
then_branch_elem
,
else_branch_elem
in
izip
(
then_branch
,
else_branch
):
if
not
isinstance
(
then_branch_elem
,
theano
.
Variable
):
then_branch_elem
=
theano
.
tensor
.
as_tensor_variable
(
then_branch_elem
)
then_branch_elem
)
if
not
isinstance
(
else_branch_elem
,
theano
.
Variable
):
else_branch_elem
=
theano
.
tensor
.
as_tensor_variable
(
else_branch_elem
)
else_branch_elem
)
if
then_branch_elem
.
type
!=
else_branch_elem
.
type
:
# If one of them is a TensorType, and the other one can be
# converted into one, then we try to do that.
# This case happens when one of the elements has a GPU type,
# for instance a shared variable that was silently moved to GPU.
if
(
isinstance
(
then_branch_elem
.
type
,
TensorType
)
and
not
isinstance
(
else_branch_elem
.
type
,
TensorType
)):
if
(
isinstance
(
then_branch_elem
.
type
,
TensorType
)
and
not
isinstance
(
else_branch_elem
.
type
,
TensorType
)):
else_branch_elem
=
then_branch_elem
.
type
.
filter_variable
(
else_branch_elem
)
else_branch_elem
)
elif
(
isinstance
(
else_branch_elem
.
type
,
TensorType
)
and
not
isinstance
(
then_branch_elem
.
type
,
TensorType
)):
elif
(
isinstance
(
else_branch_elem
.
type
,
TensorType
)
and
not
isinstance
(
then_branch_elem
.
type
,
TensorType
)):
then_branch_elem
=
else_branch_elem
.
type
.
filter_variable
(
then_branch_elem
)
then_branch_elem
)
if
then_branch_elem
.
type
!=
else_branch_elem
.
type
:
# If the types still don't match, there is a problem.
raise
TypeError
(
'The two branches should have identical types, but '
'they are
%
s and
%
s respectively. This error could be '
'raised if for example you provided a one element '
'list on the `then` branch but a tensor on the `else` '
'branch.'
%
(
then_branch_elem
.
type
,
else_branch_elem
.
type
))
'The two branches should have identical types, but '
'they are
%
s and
%
s respectively. This error could be '
'raised if for example you provided a one element '
'list on the `then` branch but a tensor on the `else` '
'branch.'
%
(
then_branch_elem
.
type
,
else_branch_elem
.
type
))
new_then_branch
.
append
(
then_branch_elem
)
new_else_branch
.
append
(
else_branch_elem
)
...
...
@@ -396,7 +396,7 @@ def cond_make_inplace(node):
optdb
.
register
(
'cond_make_inplace'
,
opt
.
in2out
(
cond_make_inplace
,
ignore_newtrees
=
True
),
95
,
'fast_run'
,
'inplace'
)
ignore_newtrees
=
True
),
95
,
'fast_run'
,
'inplace'
)
# XXX: Optimizations commented pending further debugging (certain optimizations
# make computation less lazy than it should be currently).
...
...
@@ -460,7 +460,7 @@ def ifelse_lift_single_if_through_acceptable_ops(main_node):
for
inp
in
main_node
.
inputs
:
all_inp_nodes
.
add
(
inp
.
owner
)
ifnodes
=
[
x
for
x
in
list
(
all_inp_nodes
)
if
x
and
isinstance
(
x
.
op
,
IfElse
)]
if
x
and
isinstance
(
x
.
op
,
IfElse
)]
# if we have multiple ifs as inputs .. it all becomes quite complicated
# :)
if
len
(
ifnodes
)
!=
1
:
...
...
@@ -471,7 +471,7 @@ def ifelse_lift_single_if_through_acceptable_ops(main_node):
ts
=
node
.
inputs
[
1
:][:
op
.
n_outs
]
fs
=
node
.
inputs
[
1
:][
op
.
n_outs
:]
outs
=
main_node
.
outputs
#
outs = main_node.outputs
mop
=
main_node
.
op
true_ins
=
[]
false_ins
=
[]
...
...
@@ -486,8 +486,8 @@ def ifelse_lift_single_if_through_acceptable_ops(main_node):
false_ins
.
append
(
x
)
true_eval
=
mop
(
*
true_ins
,
**
dict
(
return_list
=
True
))
false_eval
=
mop
(
*
false_ins
,
**
dict
(
return_list
=
True
))
#true_eval = clone(outs, replace = dict(zip(node.outputs, ts)))
#false_eval = clone(outs, replace = dict(zip(node.outputs, fs)))
#
true_eval = clone(outs, replace = dict(zip(node.outputs, ts)))
#
false_eval = clone(outs, replace = dict(zip(node.outputs, fs)))
nw_outs
=
ifelse
(
node
.
inputs
[
0
],
true_eval
,
false_eval
,
return_list
=
True
)
return
nw_outs
...
...
@@ -503,10 +503,10 @@ def cond_merge_ifs_true(node):
replace
=
{}
for
idx
,
tval
in
enumerate
(
t_ins
):
if
(
tval
.
owner
and
isinstance
(
tval
.
owner
.
op
,
IfElse
)
and
tval
.
owner
.
inputs
[
0
]
==
node
.
inputs
[
0
]):
ins_op
=
tval
.
owner
.
op
ins_t
=
tval
.
owner
.
inputs
[
1
:][:
ins_op
.
n_outs
]
replace
[
idx
+
1
]
=
ins_t
[
tval
.
owner
.
outputs
.
index
(
tval
)]
tval
.
owner
.
inputs
[
0
]
==
node
.
inputs
[
0
]):
ins_op
=
tval
.
owner
.
op
ins_t
=
tval
.
owner
.
inputs
[
1
:][:
ins_op
.
n_outs
]
replace
[
idx
+
1
]
=
ins_t
[
tval
.
owner
.
outputs
.
index
(
tval
)]
if
len
(
replace
.
items
())
==
0
:
return
False
...
...
@@ -527,10 +527,10 @@ def cond_merge_ifs_false(node):
replace
=
{}
for
idx
,
fval
in
enumerate
(
f_ins
):
if
(
fval
.
owner
and
isinstance
(
fval
.
owner
.
op
,
IfElse
)
and
fval
.
owner
.
inputs
[
0
]
==
node
.
inputs
[
0
]):
ins_op
=
fval
.
owner
.
op
ins_t
=
fval
.
owner
.
inputs
[
1
:][
ins_op
.
n_outs
:]
replace
[
idx
+
1
+
op
.
n_outs
]
=
\
fval
.
owner
.
inputs
[
0
]
==
node
.
inputs
[
0
]):
ins_op
=
fval
.
owner
.
op
ins_t
=
fval
.
owner
.
inputs
[
1
:][
ins_op
.
n_outs
:]
replace
[
idx
+
1
+
op
.
n_outs
]
=
\
ins_t
[
fval
.
owner
.
outputs
.
index
(
fval
)]
if
len
(
replace
.
items
())
==
0
:
...
...
@@ -555,7 +555,7 @@ class CondMerge(gof.Optimizer):
merging_node
=
cond_nodes
[
0
]
for
proposal
in
cond_nodes
[
1
:]:
if
(
proposal
.
inputs
[
0
]
==
merging_node
.
inputs
[
0
]
and
not
find_up
(
proposal
,
merging_node
)):
not
find_up
(
proposal
,
merging_node
)):
# Create a list of replacements for proposal
mn_ts
=
merging_node
.
inputs
[
1
:][:
merging_node
.
op
.
n_outs
]
mn_fs
=
merging_node
.
inputs
[
1
:][
merging_node
.
op
.
n_outs
:]
...
...
@@ -567,8 +567,8 @@ class CondMerge(gof.Optimizer):
if
merging_node
.
op
.
name
:
mn_name
=
merging_node
.
op
.
name
pl_name
=
'?'
mn_n_ts
=
len
(
mn_ts
)
mn_n_fs
=
len
(
mn_fs
)
#
mn_n_ts = len(mn_ts)
#
mn_n_fs = len(mn_fs)
if
proposal
.
op
.
name
:
pl_name
=
proposal
.
op
.
name
new_ifelse
=
IfElse
(
...
...
@@ -607,8 +607,8 @@ def cond_remove_identical(node):
if
idx
not
in
out_map
:
for
jdx
in
xrange
(
idx
+
1
,
len
(
node
.
outputs
)):
if
(
ts
[
idx
]
==
ts
[
jdx
]
and
fs
[
idx
]
==
fs
[
jdx
]
and
jdx
not
in
out_map
):
fs
[
idx
]
==
fs
[
jdx
]
and
jdx
not
in
out_map
):
out_map
[
jdx
]
=
idx
if
len
(
out_map
.
keys
())
==
0
:
...
...
@@ -652,7 +652,7 @@ def cond_merge_random_op(main_node):
for
inp
in
main_node
.
inputs
:
all_inp_nodes
.
add
(
inp
.
owner
)
cond_nodes
=
[
x
for
x
in
list
(
all_inp_nodes
)
if
x
and
isinstance
(
x
.
op
,
IfElse
)]
if
x
and
isinstance
(
x
.
op
,
IfElse
)]
if
len
(
cond_nodes
)
<
2
:
return
False
...
...
@@ -660,8 +660,8 @@ def cond_merge_random_op(main_node):
merging_node
=
cond_nodes
[
0
]
for
proposal
in
cond_nodes
[
1
:]:
if
(
proposal
.
inputs
[
0
]
==
merging_node
.
inputs
[
0
]
and
not
find_up
(
proposal
,
merging_node
)
and
not
find_up
(
merging_node
,
proposal
)):
not
find_up
(
proposal
,
merging_node
)
and
not
find_up
(
merging_node
,
proposal
)):
# Create a list of replacements for proposal
mn_ts
=
merging_node
.
inputs
[
1
:][:
merging_node
.
op
.
n_outs
]
mn_fs
=
merging_node
.
inputs
[
1
:][
merging_node
.
op
.
n_outs
:]
...
...
@@ -673,8 +673,8 @@ def cond_merge_random_op(main_node):
if
merging_node
.
op
.
name
:
mn_name
=
merging_node
.
op
.
name
pl_name
=
'?'
mn_n_ts
=
len
(
mn_ts
)
mn_n_fs
=
len
(
mn_fs
)
#
mn_n_ts = len(mn_ts)
#
mn_n_fs = len(mn_fs)
if
proposal
.
op
.
name
:
pl_name
=
proposal
.
op
.
name
new_ifelse
=
IfElse
(
...
...
theano/tests/test_flake8.py
浏览文件 @
626104a8
...
...
@@ -17,13 +17,8 @@ except ImportError:
flake8_available
=
False
whitelist_flake8
=
[
"updates.py"
,
"__init__.py"
,
"configparser.py"
,
"ifelse.py"
,
"version.py"
,
"configdefaults.py"
,
"gradient.py"
,
"compat/python2x.py"
,
"compat/six.py"
,
"compat/__init__.py"
,
...
...
theano/updates.py
浏览文件 @
626104a8
"""Defines Updates object for storing a (SharedVariable, new_value) mapping.
"""
from
theano.compat.python2x
import
OrderedDict
from
theano.compile.sharedvalue
import
SharedVariable
import
logging
import
warnings
__authors__
=
"theano-dev"
__copyright__
=
"(c) 2010, Universite de Montreal"
__license__
=
"3-clause BSD License"
...
...
@@ -8,12 +15,7 @@ __contact__ = "theano-dev <theano-dev@googlegroups.com>"
__docformat__
=
"restructuredtext en"
from
theano.compat.python2x
import
OrderedDict
from
theano.compile.sharedvalue
import
SharedVariable
import
logging
logger
=
logging
.
getLogger
(
'theano.updates'
)
import
warnings
# Must be an OrderedDict or updates will be applied in a non-deterministic
...
...
@@ -26,9 +28,9 @@ class OrderedUpdates(OrderedDict):
"""
def
__init__
(
self
,
*
key
,
**
kwargs
):
if
(
len
(
key
)
>=
1
and
isinstance
(
key
[
0
],
dict
)
and
len
(
key
[
0
])
>
1
and
not
isinstance
(
key
[
0
],
OrderedDict
)):
isinstance
(
key
[
0
],
dict
)
and
len
(
key
[
0
])
>
1
and
not
isinstance
(
key
[
0
],
OrderedDict
)):
# Warn when using as input a non-ordered dictionary.
warnings
.
warn
(
'Initializing an `OrderedUpdates` from a '
'non-ordered dictionary with 2+ elements could '
...
...
@@ -62,8 +64,8 @@ class OrderedUpdates(OrderedDict):
if
other
is
None
:
return
if
(
isinstance
(
other
,
dict
)
and
len
(
other
)
>
1
and
not
isinstance
(
other
,
OrderedDict
)):
len
(
other
)
>
1
and
not
isinstance
(
other
,
OrderedDict
)):
# Warn about non-determinism.
warnings
.
warn
(
'Updating an `OrderedUpdates` with a '
'non-ordered dictionary with 2+ elements could '
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论