Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
123d9007
提交
123d9007
authored
9月 02, 2016
作者:
Frédéric Bastien
提交者:
GitHub
9月 02, 2016
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #4756 from Thrandis/ccw2
Theano variable arguments for pooling 2
上级
0d478806
166cac0a
显示空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
575 行增加
和
426 行删除
+575
-426
Theano.pyproj
Theano.pyproj
+1
-1
downsample.txt
doc/library/tensor/signal/downsample.txt
+2
-5
index.txt
doc/library/tensor/signal/index.txt
+1
-1
dnn.py
theano/gpuarray/dnn.py
+7
-16
dnn.py
theano/sandbox/cuda/dnn.py
+6
-15
opt.py
theano/sandbox/cuda/opt.py
+50
-26
test_blas.py
theano/sandbox/cuda/tests/test_blas.py
+6
-6
test_mlp.py
theano/sandbox/cuda/tests/test_mlp.py
+3
-2
downsample.py
theano/tensor/signal/downsample.py
+0
-26
pool.py
theano/tensor/signal/pool.py
+375
-216
old_pool_interface.pkl
theano/tensor/signal/tests/old_pool_interface.pkl
+0
-0
test_pool.py
theano/tensor/signal/tests/test_pool.py
+124
-112
没有找到文件。
Theano.pyproj
浏览文件 @
123d9007
...
@@ -187,7 +187,7 @@
...
@@ -187,7 +187,7 @@
<Compile
Include=
"theano\tensor\sharedvar.py"
/>
<Compile
Include=
"theano\tensor\sharedvar.py"
/>
<Compile
Include=
"theano\tensor\shared_randomstreams.py"
/>
<Compile
Include=
"theano\tensor\shared_randomstreams.py"
/>
<Compile
Include=
"theano\tensor\signal\conv.py"
/>
<Compile
Include=
"theano\tensor\signal\conv.py"
/>
<Compile
Include=
"theano\tensor\signal\
downsample
.py"
/>
<Compile
Include=
"theano\tensor\signal\
pool
.py"
/>
<Compile
Include=
"theano\tensor\signal\__init__.py"
/>
<Compile
Include=
"theano\tensor\signal\__init__.py"
/>
<Compile
Include=
"theano\tensor\tensor_grad.py"
/>
<Compile
Include=
"theano\tensor\tensor_grad.py"
/>
<Compile
Include=
"theano\tensor\xlogx.py"
/>
<Compile
Include=
"theano\tensor\xlogx.py"
/>
...
...
doc/library/tensor/signal/downsample.txt
浏览文件 @
123d9007
...
@@ -9,9 +9,6 @@
...
@@ -9,9 +9,6 @@
:synopsis: ops for performing various forms of downsampling
:synopsis: ops for performing various forms of downsampling
.. moduleauthor:: LISA
.. moduleauthor:: LISA
.. seealso:: :func:`theano.tensor.nnet.neighbours.images2neibs`
.. note::
.. function:: fft(*todo)
[James has some code for this, but hasn't gotten it into the source tree yet.]
This module is deprecated. Use the functions in :func:`theano.tensor.nnet.signal.pool`
doc/library/tensor/signal/index.txt
浏览文件 @
123d9007
...
@@ -20,5 +20,5 @@ forms of signal processing.
...
@@ -20,5 +20,5 @@ forms of signal processing.
:maxdepth: 1
:maxdepth: 1
conv
conv
downsample
pool
pool
downsample
theano/gpuarray/dnn.py
浏览文件 @
123d9007
...
@@ -1859,13 +1859,10 @@ def local_gpua_pool_dnn_alternative(op, ctx_name, inputs, outputs):
...
@@ -1859,13 +1859,10 @@ def local_gpua_pool_dnn_alternative(op, ctx_name, inputs, outputs):
raise_no_cudnn
()
raise_no_cudnn
()
if
not
op
.
ignore_border
:
if
not
op
.
ignore_border
:
return
return
img
,
=
inputs
img
,
ws
,
stride
,
pad
=
inputs
img
=
as_gpuarray_variable
(
img
,
ctx_name
)
img
=
as_gpuarray_variable
(
img
,
ctx_name
)
ds
=
op
.
ds
stride
=
op
.
st
pad
=
op
.
padding
mode
=
op
.
mode
mode
=
op
.
mode
return
dnn_pool
(
gpu_contiguous
(
img
),
d
s
,
stride
=
stride
,
pad
=
pad
,
mode
=
mode
)
return
dnn_pool
(
gpu_contiguous
(
img
),
w
s
,
stride
=
stride
,
pad
=
pad
,
mode
=
mode
)
@register_opt
(
'cudnn'
,
'fast_compile'
)
@register_opt
(
'cudnn'
,
'fast_compile'
)
...
@@ -1876,20 +1873,17 @@ def local_gpua_pool_dnn_grad_stride(op, ctx_name, inputs, outputs):
...
@@ -1876,20 +1873,17 @@ def local_gpua_pool_dnn_grad_stride(op, ctx_name, inputs, outputs):
raise_no_cudnn
()
raise_no_cudnn
()
if
not
op
.
ignore_border
:
if
not
op
.
ignore_border
:
return
return
inp
,
out
,
out_grad
=
inputs
inp
,
out
,
out_grad
,
ws
,
stride
,
pad
=
inputs
inp
=
as_gpuarray_variable
(
inp
,
ctx_name
)
inp
=
as_gpuarray_variable
(
inp
,
ctx_name
)
out
=
as_gpuarray_variable
(
out
,
ctx_name
)
out
=
as_gpuarray_variable
(
out
,
ctx_name
)
out_grad
=
as_gpuarray_variable
(
out_grad
,
ctx_name
)
out_grad
=
as_gpuarray_variable
(
out_grad
,
ctx_name
)
ds
=
op
.
ds
st
=
op
.
st
pad
=
op
.
padding
mode
=
op
.
mode
mode
=
op
.
mode
return
GpuDnnPoolGrad
(
mode
=
mode
)(
gpu_contiguous
(
inp
),
return
GpuDnnPoolGrad
(
mode
=
mode
)(
gpu_contiguous
(
inp
),
gpu_contiguous
(
out
),
gpu_contiguous
(
out
),
gpu_contiguous
(
out_grad
),
gpu_contiguous
(
out_grad
),
d
s
,
w
s
,
st
,
st
ride
,
pad
)
pad
)
...
@@ -1901,12 +1895,9 @@ def local_gpua_avg_pool_dnn_grad_stride(op, ctx_name, inputs, outputs):
...
@@ -1901,12 +1895,9 @@ def local_gpua_avg_pool_dnn_grad_stride(op, ctx_name, inputs, outputs):
raise_no_cudnn
()
raise_no_cudnn
()
if
not
op
.
ignore_border
:
if
not
op
.
ignore_border
:
return
return
inp
,
out_grad
=
inputs
inp
,
out_grad
,
ws
,
stride
,
pad
=
inputs
inp
=
as_gpuarray_variable
(
inp
,
ctx_name
)
inp
=
as_gpuarray_variable
(
inp
,
ctx_name
)
out_grad
=
as_gpuarray_variable
(
out_grad
,
ctx_name
)
out_grad
=
as_gpuarray_variable
(
out_grad
,
ctx_name
)
ds
=
op
.
ds
st
=
op
.
st
pad
=
op
.
padding
mode
=
op
.
mode
mode
=
op
.
mode
cg
=
gpu_contiguous
(
out_grad
)
cg
=
gpu_contiguous
(
out_grad
)
...
@@ -1914,7 +1905,7 @@ def local_gpua_avg_pool_dnn_grad_stride(op, ctx_name, inputs, outputs):
...
@@ -1914,7 +1905,7 @@ def local_gpua_avg_pool_dnn_grad_stride(op, ctx_name, inputs, outputs):
# We reuse cg because cuDNN does not use the value of the `out`
# We reuse cg because cuDNN does not use the value of the `out`
# argument but still checks its shape for average pooling. This
# argument but still checks its shape for average pooling. This
# has been observed in v2 and v3 as far as I know.
# has been observed in v2 and v3 as far as I know.
return
GpuDnnPoolGrad
(
mode
=
mode
)(
gpu_contiguous
(
inp
),
cg
,
cg
,
ds
,
st
,
pad
)
return
GpuDnnPoolGrad
(
mode
=
mode
)(
gpu_contiguous
(
inp
),
cg
,
cg
,
ws
,
stride
,
pad
)
@register_opt
(
'cudnn'
,
'fast_compile'
)
@register_opt
(
'cudnn'
,
'fast_compile'
)
...
...
theano/sandbox/cuda/dnn.py
浏览文件 @
123d9007
...
@@ -2962,14 +2962,11 @@ if True:
...
@@ -2962,14 +2962,11 @@ if True:
if
isinstance
(
node
.
op
,
Pool
):
if
isinstance
(
node
.
op
,
Pool
):
if
not
node
.
op
.
ignore_border
:
if
not
node
.
op
.
ignore_border
:
return
return
img
,
=
node
.
inputs
img
,
ws
,
stride
,
pad
=
node
.
inputs
ds
=
node
.
op
.
ds
stride
=
node
.
op
.
st
pad
=
node
.
op
.
padding
mode
=
node
.
op
.
mode
mode
=
node
.
op
.
mode
if
(
img
.
owner
and
isinstance
(
img
.
owner
.
op
,
HostFromGpu
)):
if
(
img
.
owner
and
isinstance
(
img
.
owner
.
op
,
HostFromGpu
)):
ret
=
dnn_pool
(
gpu_contiguous
(
img
.
owner
.
inputs
[
0
]),
ret
=
dnn_pool
(
gpu_contiguous
(
img
.
owner
.
inputs
[
0
]),
d
s
,
stride
=
stride
,
pad
=
pad
,
mode
=
mode
)
w
s
,
stride
=
stride
,
pad
=
pad
,
mode
=
mode
)
return
[
host_from_gpu
(
ret
)]
return
[
host_from_gpu
(
ret
)]
@register_opt
(
'cudnn'
)
@register_opt
(
'cudnn'
)
...
@@ -2996,10 +2993,7 @@ if True:
...
@@ -2996,10 +2993,7 @@ if True:
if
isinstance
(
node
.
op
,
MaxPoolGrad
):
if
isinstance
(
node
.
op
,
MaxPoolGrad
):
if
not
node
.
op
.
ignore_border
:
if
not
node
.
op
.
ignore_border
:
return
return
inp
,
out
,
inp_grad
=
node
.
inputs
inp
,
out
,
inp_grad
,
ws
,
stride
,
pad
=
node
.
inputs
ds
=
node
.
op
.
ds
st
=
node
.
op
.
st
pad
=
node
.
op
.
padding
mode
=
node
.
op
.
mode
mode
=
node
.
op
.
mode
if
((
inp
.
owner
and
isinstance
(
inp
.
owner
.
op
,
HostFromGpu
))
or
if
((
inp
.
owner
and
isinstance
(
inp
.
owner
.
op
,
HostFromGpu
))
or
...
@@ -3010,7 +3004,7 @@ if True:
...
@@ -3010,7 +3004,7 @@ if True:
ret
=
GpuDnnPoolGrad
(
mode
=
mode
)(
gpu_contiguous
(
inp
),
ret
=
GpuDnnPoolGrad
(
mode
=
mode
)(
gpu_contiguous
(
inp
),
gpu_contiguous
(
out
),
gpu_contiguous
(
out
),
gpu_contiguous
(
inp_grad
),
gpu_contiguous
(
inp_grad
),
ds
,
st
,
pad
)
ws
,
stride
,
pad
)
return
[
host_from_gpu
(
ret
)]
return
[
host_from_gpu
(
ret
)]
@register_opt
(
'cudnn'
)
@register_opt
(
'cudnn'
)
...
@@ -3021,10 +3015,7 @@ if True:
...
@@ -3021,10 +3015,7 @@ if True:
if
isinstance
(
node
.
op
,
AveragePoolGrad
):
if
isinstance
(
node
.
op
,
AveragePoolGrad
):
if
not
node
.
op
.
ignore_border
:
if
not
node
.
op
.
ignore_border
:
return
return
inp
,
inp_grad
=
node
.
inputs
inp
,
inp_grad
,
ws
,
stride
,
pad
=
node
.
inputs
ds
=
node
.
op
.
ds
st
=
node
.
op
.
st
pad
=
node
.
op
.
padding
mode
=
node
.
op
.
mode
mode
=
node
.
op
.
mode
if
((
inp
.
owner
and
isinstance
(
inp
.
owner
.
op
,
HostFromGpu
))
or
if
((
inp
.
owner
and
isinstance
(
inp
.
owner
.
op
,
HostFromGpu
))
or
...
@@ -3034,7 +3025,7 @@ if True:
...
@@ -3034,7 +3025,7 @@ if True:
ret
=
GpuDnnPoolGrad
(
mode
=
mode
)(
gpu_contiguous
(
inp
),
ret
=
GpuDnnPoolGrad
(
mode
=
mode
)(
gpu_contiguous
(
inp
),
contiguous_inp_grad
,
contiguous_inp_grad
,
contiguous_inp_grad
,
contiguous_inp_grad
,
ds
,
st
,
pad
)
ws
,
stride
,
pad
)
return
[
host_from_gpu
(
ret
)]
return
[
host_from_gpu
(
ret
)]
@register_opt
(
'cudnn'
)
@register_opt
(
'cudnn'
)
...
...
theano/sandbox/cuda/opt.py
浏览文件 @
123d9007
...
@@ -1891,37 +1891,61 @@ def local_convtransp3d_gemm(node):
...
@@ -1891,37 +1891,61 @@ def local_convtransp3d_gemm(node):
gpu_optimizer
.
register
(
"convtransp3d_gemm"
,
local_convtransp3d_gemm
)
gpu_optimizer
.
register
(
"convtransp3d_gemm"
,
local_convtransp3d_gemm
)
def
_check_constant_args_pool
(
ws
,
stride
,
pad
,
node
):
"""Check if the args of pool are constants. Warns if not."""
try
:
ws_w
=
tensor
.
get_scalar_constant_value
(
ws
[
0
])
ws_h
=
tensor
.
get_scalar_constant_value
(
ws
[
1
])
stride_w
=
tensor
.
get_scalar_constant_value
(
stride
[
0
])
stride_h
=
tensor
.
get_scalar_constant_value
(
stride
[
1
])
pad_w
=
tensor
.
get_scalar_constant_value
(
pad
[
0
])
pad_h
=
tensor
.
get_scalar_constant_value
(
pad
[
1
])
except
tensor
.
NotScalarConstantError
:
msg
=
(
"Pool with tensor variable for the window size, stride or "
"padding is only supported in the new GPU backend, so this op "
"will run on CPU. (op
%
s)"
%
node
)
if
config
.
assert_no_cpu_op
==
"warn"
:
_logger
.
warning
(
msg
)
elif
config
.
assert_no_cpu_op
==
"raise"
:
raise
AssertionError
(
msg
)
return
None
ws
=
(
ws_w
,
ws_h
)
stride
=
(
stride_w
,
stride_h
)
pad
=
(
pad_w
,
pad_h
)
return
ws
,
stride
,
pad
@register_opt
()
@register_opt
()
@local_optimizer
([
pool
.
Pool
])
@local_optimizer
([
pool
.
Pool
])
def
local_gpu_downsample_factor_max
(
node
):
def
local_gpu_downsample_factor_max
(
node
):
if
(
isinstance
(
node
.
op
,
pool
.
Pool
)
and
if
isinstance
(
node
.
op
,
pool
.
Pool
):
node
.
op
.
ds
==
node
.
op
.
st
):
assert
node
.
op
.
__props__
==
(
'ignore_border'
,
'mode'
)
x
,
ws
,
stride
,
pad
=
node
.
inputs
assert
node
.
op
.
__props__
==
(
'ds'
,
'ignore_border'
,
'st'
,
'padding'
,
ret
=
_check_constant_args_pool
(
ws
,
stride
,
pad
,
node
)
'mode'
)
if
ret
is
None
:
if
node
.
op
.
padding
!=
(
0
,
0
)
or
node
.
op
.
mode
!=
'max'
:
return
ws
,
stride
,
pad
=
ret
if
(
pad
)
!=
(
0
,
0
)
or
node
.
op
.
mode
!=
'max'
or
stride
!=
ws
:
return
return
x
,
=
node
.
inputs
if
(
x
.
owner
and
isinstance
(
x
.
owner
.
op
,
HostFromGpu
)):
if
(
x
.
owner
and
isinstance
(
x
.
owner
.
op
,
HostFromGpu
)):
gpu_ds
=
GpuDownsampleFactorMax
(
node
.
op
.
d
s
,
node
.
op
.
ignore_border
)
gpu_ds
=
GpuDownsampleFactorMax
(
w
s
,
node
.
op
.
ignore_border
)
return
[
host_from_gpu
(
gpu_ds
(
x
.
owner
.
inputs
[
0
]))]
return
[
host_from_gpu
(
gpu_ds
(
x
.
owner
.
inputs
[
0
]))]
@register_opt
()
@register_opt
()
@local_optimizer
([
pool
.
MaxPoolGrad
])
@local_optimizer
([
pool
.
MaxPoolGrad
])
def
local_gpu_downsample_factor_max_grad
(
node
):
def
local_gpu_downsample_factor_max_grad
(
node
):
if
(
isinstance
(
node
.
op
,
pool
.
MaxPoolGrad
)
and
node
.
op
.
ds
==
node
.
op
.
st
):
if
isinstance
(
node
.
op
,
pool
.
MaxPoolGrad
):
assert
node
.
op
.
__props__
==
(
'ds'
,
'ignore_border'
,
'st'
,
'padding'
,
assert
node
.
op
.
__props__
==
(
'ignore_border'
,
'mode'
)
'mode'
)
x
,
z
,
gz
,
ws
,
stride
,
pad
=
node
.
inputs
if
(
node
.
op
.
padding
!=
(
0
,
0
)
or
ret
=
_check_constant_args_pool
(
ws
,
stride
,
pad
,
node
)
node
.
op
.
mode
!=
'max'
or
if
ret
is
None
:
node
.
op
.
st
!=
node
.
op
.
ds
):
return
ws
,
stride
,
pad
=
ret
if
pad
!=
(
0
,
0
)
or
node
.
op
.
mode
!=
'max'
or
stride
!=
ws
:
return
return
x
,
z
,
gz
=
node
.
inputs
if
(
x
.
owner
and
isinstance
(
x
.
owner
.
op
,
HostFromGpu
)):
if
(
x
.
owner
and
isinstance
(
x
.
owner
.
op
,
HostFromGpu
)):
gpu_ds_grad
=
GpuDownsampleFactorMaxGrad
(
node
.
op
.
ds
,
gpu_ds_grad
=
GpuDownsampleFactorMaxGrad
(
ws
,
node
.
op
.
ignore_border
)
node
.
op
.
ignore_border
)
return
[
host_from_gpu
(
gpu_ds_grad
(
x
.
owner
.
inputs
[
0
],
return
[
host_from_gpu
(
gpu_ds_grad
(
x
.
owner
.
inputs
[
0
],
as_cuda_ndarray_variable
(
z
),
as_cuda_ndarray_variable
(
z
),
as_cuda_ndarray_variable
(
gz
)))]
as_cuda_ndarray_variable
(
gz
)))]
...
@@ -1931,16 +1955,16 @@ def local_gpu_downsample_factor_max_grad(node):
...
@@ -1931,16 +1955,16 @@ def local_gpu_downsample_factor_max_grad(node):
@local_optimizer
([
pool
.
DownsampleFactorMaxGradGrad
])
@local_optimizer
([
pool
.
DownsampleFactorMaxGradGrad
])
def
local_gpu_downsample_factor_max_grad_grad
(
node
):
def
local_gpu_downsample_factor_max_grad_grad
(
node
):
if
isinstance
(
node
.
op
,
pool
.
DownsampleFactorMaxGradGrad
):
if
isinstance
(
node
.
op
,
pool
.
DownsampleFactorMaxGradGrad
):
assert
node
.
op
.
__props__
==
(
'ds'
,
'ignore_border'
,
'st'
,
assert
node
.
op
.
__props__
==
(
'ignore_border'
,
'mode'
)
'padding'
,
'mode'
)
x
,
z
,
gx
,
ws
,
stride
,
pad
=
node
.
inputs
if
(
node
.
op
.
padding
!=
(
0
,
0
)
or
ret
=
_check_constant_args_pool
(
ws
,
stride
,
pad
,
node
)
node
.
op
.
mode
!=
'max'
or
if
ret
is
None
:
node
.
op
.
st
!=
node
.
op
.
ds
):
return
ws
,
stride
,
pad
=
ret
if
pad
!=
(
0
,
0
)
or
node
.
op
.
mode
!=
'max'
or
stride
!=
ws
:
return
return
x
,
z
,
gx
=
node
.
inputs
if
(
x
.
owner
and
isinstance
(
x
.
owner
.
op
,
HostFromGpu
)):
if
(
x
.
owner
and
isinstance
(
x
.
owner
.
op
,
HostFromGpu
)):
op
=
GpuDownsampleFactorMaxGradGrad
(
node
.
op
.
ds
,
op
=
GpuDownsampleFactorMaxGradGrad
(
ws
,
node
.
op
.
ignore_border
)
node
.
op
.
ignore_border
)
return
[
host_from_gpu
(
op
(
x
.
owner
.
inputs
[
0
],
return
[
host_from_gpu
(
op
(
x
.
owner
.
inputs
[
0
],
as_cuda_ndarray_variable
(
z
),
as_cuda_ndarray_variable
(
z
),
as_cuda_ndarray_variable
(
gx
)))]
as_cuda_ndarray_variable
(
gx
)))]
...
...
theano/sandbox/cuda/tests/test_blas.py
浏览文件 @
123d9007
...
@@ -369,12 +369,12 @@ def test_downsample():
...
@@ -369,12 +369,12 @@ def test_downsample():
continue
continue
for
ignore_border
in
(
True
,
False
):
for
ignore_border
in
(
True
,
False
):
# print 'test_downsample', shp, ds, ignore_border
# print 'test_downsample', shp, ds, ignore_border
ds_op
=
Pool
(
ds
,
ignore_border
=
ignore_border
)
ds_op
=
Pool
(
ignore_border
=
ignore_border
)
a
=
tcn
.
shared_constructor
(
my_rand
(
*
shp
),
'a'
)
a
=
tcn
.
shared_constructor
(
my_rand
(
*
shp
),
'a'
)
f
=
pfunc
([],
ds_op
(
tensor
.
as_tensor_variable
(
a
)),
f
=
pfunc
([],
ds_op
(
tensor
.
as_tensor_variable
(
a
)
,
ds
),
mode
=
mode_with_gpu
.
excluding
(
'cudnn'
))
mode
=
mode_with_gpu
.
excluding
(
'cudnn'
))
f2
=
pfunc
([],
ds_op
(
tensor
.
as_tensor_variable
(
a
)),
f2
=
pfunc
([],
ds_op
(
tensor
.
as_tensor_variable
(
a
)
,
ds
),
mode
=
mode_without_gpu
)
mode
=
mode_without_gpu
)
assert
any
([
isinstance
(
node
.
op
,
assert
any
([
isinstance
(
node
.
op
,
tcn
.
blas
.
GpuDownsampleFactorMax
)
tcn
.
blas
.
GpuDownsampleFactorMax
)
...
@@ -393,12 +393,12 @@ def test_downsample():
...
@@ -393,12 +393,12 @@ def test_downsample():
g
=
pfunc
(
g
=
pfunc
(
[],
[],
tensor
.
grad
(
ds_op
(
tensor
.
as_tensor_variable
(
a
))
.
sum
(),
tensor
.
grad
(
ds_op
(
tensor
.
as_tensor_variable
(
a
)
,
ds
)
.
sum
(),
a
),
a
),
mode
=
mode_with_gpu
.
excluding
(
'cudnn'
))
mode
=
mode_with_gpu
.
excluding
(
'cudnn'
))
g2
=
pfunc
(
g2
=
pfunc
(
[],
[],
tensor
.
grad
(
ds_op
(
tensor
.
as_tensor_variable
(
a
))
.
sum
(),
tensor
.
grad
(
ds_op
(
tensor
.
as_tensor_variable
(
a
)
,
ds
)
.
sum
(),
a
),
a
),
mode
=
mode_without_gpu
)
mode
=
mode_without_gpu
)
assert
any
([
isinstance
(
node
.
op
,
assert
any
([
isinstance
(
node
.
op
,
...
@@ -409,7 +409,7 @@ def test_downsample():
...
@@ -409,7 +409,7 @@ def test_downsample():
assert
numpy
.
allclose
(
g
(),
g2
()),
shp
assert
numpy
.
allclose
(
g
(),
g2
()),
shp
ggf
=
gradient
.
Lop
(
tensor
.
grad
((
ds_op
(
ggf
=
gradient
.
Lop
(
tensor
.
grad
((
ds_op
(
tensor
.
as_tensor_variable
(
a
))
**
2
)
.
sum
(),
a
),
a
,
a
)
tensor
.
as_tensor_variable
(
a
)
,
ds
)
**
2
)
.
sum
(),
a
),
a
,
a
)
ref_mode
=
copy
.
copy
(
mode_without_gpu
)
ref_mode
=
copy
.
copy
(
mode_without_gpu
)
ref_mode
.
check_py_code
=
False
ref_mode
.
check_py_code
=
False
...
...
theano/sandbox/cuda/tests/test_mlp.py
浏览文件 @
123d9007
...
@@ -381,9 +381,10 @@ def build_conv_nnet2_classif(use_gpu, isize, ksize, n_batch,
...
@@ -381,9 +381,10 @@ def build_conv_nnet2_classif(use_gpu, isize, ksize, n_batch,
(
n_kern
,
logical_hid_shape
[
0
]
//
2
,
logical_hid_shape
[
1
]
//
2
),
(
n_kern
,
logical_hid_shape
[
0
]
//
2
,
logical_hid_shape
[
1
]
//
2
),
shape_kern1
[
2
:],
n_kern1
,
n_batch
,
1
,
1
,
verbose
=
verbose
,
version
=
version
)
shape_kern1
[
2
:],
n_kern1
,
n_batch
,
1
,
1
,
verbose
=
verbose
,
version
=
version
)
ds_op
=
pool
.
Pool
(
(
2
,
2
),
ignore_border
=
False
)
ds_op
=
pool
.
Pool
(
ignore_border
=
False
)
if
downsample_ops
:
if
downsample_ops
:
hid
=
tensor
.
tanh
(
ds_op
(
conv_op
(
x
,
w0
)
+
b0
.
dimshuffle
((
0
,
'x'
,
'x'
))))
hid
=
tensor
.
tanh
(
ds_op
(
conv_op
(
x
,
w0
)
+
b0
.
dimshuffle
((
0
,
'x'
,
'x'
)),
(
2
,
2
)))
else
:
else
:
hid
=
tensor
.
tanh
(
hid
=
tensor
.
tanh
(
(
conv_op
(
x
,
w0
)
+
b0
.
dimshuffle
(
(
conv_op
(
x
,
w0
)
+
b0
.
dimshuffle
(
...
...
theano/tensor/signal/downsample.py
deleted
100644 → 0
浏览文件 @
0d478806
from
__future__
import
absolute_import
,
print_function
,
division
from
.
import
pool
import
warnings
warnings
.
warn
(
"downsample module has been moved to the theano.tensor.signal.pool module."
)
max_pool_2d_same_size
=
pool
.
max_pool_2d_same_size
max_pool_2d
=
pool
.
pool_2d
DownsampleFactorMax
=
pool
.
Pool
PoolGrad
=
pool
.
PoolGrad
MaxPoolGrad
=
pool
.
MaxPoolGrad
AveragePoolGrad
=
pool
.
AveragePoolGrad
# This is for compatibility with pickled things. It should go away at
# some point.
class
DownsampleFactorMaxGrad
(
object
):
def
__new__
(
self
,
ds
,
ignore_border
,
st
=
None
,
padding
=
(
0
,
0
),
mode
=
'max'
):
if
mode
==
'max'
:
return
MaxPoolGrad
(
ds
=
ds
,
ignore_border
=
ignore_border
,
st
=
st
,
padding
=
padding
)
else
:
return
AveragePoolGrad
(
ds
=
ds
,
ignore_border
=
ignore_border
,
st
=
st
,
padding
=
padding
,
mode
=
mode
)
DownsampleFactorMaxGradGrad
=
pool
.
DownsampleFactorMaxGradGrad
theano/tensor/signal/pool.py
浏览文件 @
123d9007
...
@@ -9,11 +9,11 @@ from __future__ import absolute_import, print_function, division
...
@@ -9,11 +9,11 @@ from __future__ import absolute_import, print_function, division
import
warnings
import
warnings
import
numpy
import
numpy
from
six
import
integer_types
from
six.moves
import
xrange
from
six.moves
import
xrange
import
six.moves.builtins
as
builtins
import
six.moves.builtins
as
builtins
import
theano
import
theano
from
theano
import
gof
,
OpenMPOp
,
tensor
,
Variable
,
Apply
from
theano
import
gof
,
OpenMPOp
,
tensor
,
Variable
,
Apply
from
theano.gradient
import
DisconnectedType
def
max_pool_2d_same_size
(
input
,
patch_size
):
def
max_pool_2d_same_size
(
input
,
patch_size
):
...
@@ -27,13 +27,13 @@ def max_pool_2d_same_size(input, patch_size):
...
@@ -27,13 +27,13 @@ def max_pool_2d_same_size(input, patch_size):
----------
----------
input : 4-D theano tensor of input images
input : 4-D theano tensor of input images
Input images. Max pooling will be done over the 2 last dimensions.
Input images. Max pooling will be done over the 2 last dimensions.
patch_size : tuple of length 2
patch_size : tuple of length 2
or theano vector of ints of size 2.
Size of the patch (patch height, patch width).
Size of the patch (patch height, patch width).
(2,2) will retain only one non-zero value per patch of 4 values.
(2,2) will retain only one non-zero value per patch of 4 values.
"""
"""
output
=
Pool
(
patch_size
,
True
)(
input
)
output
=
Pool
(
True
)(
input
,
patch_size
)
outs
=
MaxPoolGrad
(
patch_size
,
True
)(
input
,
output
,
output
)
outs
=
MaxPoolGrad
(
True
)(
input
,
output
,
output
,
patch_size
)
return
outs
return
outs
...
@@ -49,17 +49,17 @@ def pool_2d(input, ds, ignore_border=None, st=None, padding=(0, 0),
...
@@ -49,17 +49,17 @@ def pool_2d(input, ds, ignore_border=None, st=None, padding=(0, 0),
----------
----------
input : N-D theano tensor of input images
input : N-D theano tensor of input images
Input images. Max pooling will be done over the 2 last dimensions.
Input images. Max pooling will be done over the 2 last dimensions.
ds : tuple of length 2
ds : tuple of length 2
or theano vector of ints of size 2.
Factor by which to downscale (vertical ds, horizontal ds).
Factor by which to downscale (vertical ds, horizontal ds).
(2,2) will halve the image in each dimension.
(2,2) will halve the image in each dimension.
ignore_border : bool (default None, will print a warning and set to False)
ignore_border : bool (default None, will print a warning and set to False)
When True, (5,5) input with ds=(2,2) will generate a (2,2) output.
When True, (5,5) input with ds=(2,2) will generate a (2,2) output.
(3,3) otherwise.
(3,3) otherwise.
st : tuple of two ints
st : tuple of two ints
or theano vector of ints of size 2.
Stride size, which is the number of shifts over rows/cols to get the
Stride size, which is the number of shifts over rows/cols to get the
next pool region. If st is None, it is considered equal to ds
next pool region. If st is None, it is considered equal to ds
(no overlap on pooling regions).
(no overlap on pooling regions).
padding : tuple of two ints
padding : tuple of two ints
or theano vector of ints of size 2.
(pad_h, pad_w), pad zeros to extend beyond four borders of the
(pad_h, pad_w), pad zeros to extend beyond four borders of the
images, pad_h is the size of the top and bottom margins, and
images, pad_h is the size of the top and bottom margins, and
pad_w is the size of the left and right margins.
pad_w is the size of the left and right margins.
...
@@ -85,9 +85,8 @@ def pool_2d(input, ds, ignore_border=None, st=None, padding=(0, 0),
...
@@ -85,9 +85,8 @@ def pool_2d(input, ds, ignore_border=None, st=None, padding=(0, 0),
stacklevel
=
2
)
stacklevel
=
2
)
ignore_border
=
False
ignore_border
=
False
if
input
.
ndim
==
4
:
if
input
.
ndim
==
4
:
op
=
Pool
(
ds
,
ignore_border
,
st
=
st
,
padding
=
padding
,
op
=
Pool
(
ignore_border
,
mode
=
mode
)
mode
=
mode
)
output
=
op
(
input
,
ds
,
st
,
padding
)
output
=
op
(
input
)
return
output
return
output
# extract image dimensions
# extract image dimensions
...
@@ -104,9 +103,8 @@ def pool_2d(input, ds, ignore_border=None, st=None, padding=(0, 0),
...
@@ -104,9 +103,8 @@ def pool_2d(input, ds, ignore_border=None, st=None, padding=(0, 0),
input_4D
=
tensor
.
reshape
(
input
,
new_shape
,
ndim
=
4
)
input_4D
=
tensor
.
reshape
(
input
,
new_shape
,
ndim
=
4
)
# downsample mini-batch of images
# downsample mini-batch of images
op
=
Pool
(
ds
,
ignore_border
,
st
=
st
,
padding
=
padding
,
op
=
Pool
(
ignore_border
,
mode
=
mode
)
mode
=
mode
)
output
=
op
(
input_4D
,
ds
,
st
,
padding
)
output
=
op
(
input_4D
)
# restore to original shape
# restore to original shape
outshp
=
tensor
.
join
(
0
,
input
.
shape
[:
-
2
],
output
.
shape
[
-
2
:])
outshp
=
tensor
.
join
(
0
,
input
.
shape
[:
-
2
],
output
.
shape
[
-
2
:])
...
@@ -143,7 +141,7 @@ class Pool(OpenMPOp):
...
@@ -143,7 +141,7 @@ class Pool(OpenMPOp):
"""
"""
__props__
=
(
'
ds'
,
'ignore_border'
,
'st'
,
'padding
'
,
'mode'
)
__props__
=
(
'
ignore_border
'
,
'mode'
)
@staticmethod
@staticmethod
def
out_shape
(
imgshape
,
ds
,
ignore_border
=
False
,
st
=
None
,
padding
=
(
0
,
0
)):
def
out_shape
(
imgshape
,
ds
,
ignore_border
=
False
,
st
=
None
,
padding
=
(
0
,
0
)):
...
@@ -188,9 +186,9 @@ class Pool(OpenMPOp):
...
@@ -188,9 +186,9 @@ class Pool(OpenMPOp):
r
=
tensor
.
extract_constant
(
r
)
r
=
tensor
.
extract_constant
(
r
)
c
=
tensor
.
extract_constant
(
c
)
c
=
tensor
.
extract_constant
(
c
)
if
padding
[
0
]:
if
padding
[
0
]:
r
+=
padding
[
0
]
*
2
r
=
r
+
padding
[
0
]
*
2
if
padding
[
1
]:
if
padding
[
1
]:
c
+=
padding
[
1
]
*
2
c
=
c
+
padding
[
1
]
*
2
if
ignore_border
:
if
ignore_border
:
if
ds
[
0
]
==
st
[
0
]:
if
ds
[
0
]
==
st
[
0
]:
...
@@ -234,50 +232,84 @@ class Pool(OpenMPOp):
...
@@ -234,50 +232,84 @@ class Pool(OpenMPOp):
rval
=
list
(
imgshape
[:
-
2
])
+
[
nr
,
nc
]
rval
=
list
(
imgshape
[:
-
2
])
+
[
nr
,
nc
]
return
rval
return
rval
def
__init__
(
self
,
ds
,
ignore_border
=
False
,
st
=
None
,
padding
=
(
0
,
0
),
def
__init__
(
self
,
ignore_border
=
False
,
mode
=
'max'
,
openmp
=
None
):
mode
=
'max'
,
openmp
=
None
):
super
(
Pool
,
self
)
.
__init__
(
openmp
=
openmp
)
super
(
Pool
,
self
)
.
__init__
(
openmp
=
openmp
)
self
.
ds
=
tuple
(
ds
)
if
not
all
([
isinstance
(
d
,
integer_types
)
for
d
in
ds
]):
raise
ValueError
(
"Pool downsample parameters must be ints."
" Got
%
s"
%
str
(
ds
))
if
st
is
None
:
st
=
ds
assert
isinstance
(
st
,
(
tuple
,
list
))
self
.
st
=
tuple
(
st
)
self
.
ignore_border
=
ignore_border
self
.
ignore_border
=
ignore_border
self
.
padding
=
tuple
(
padding
)
if
self
.
padding
!=
(
0
,
0
)
and
not
ignore_border
:
raise
NotImplementedError
(
'padding works only with ignore_border=True'
)
if
self
.
padding
[
0
]
>=
self
.
ds
[
0
]
or
self
.
padding
[
1
]
>=
self
.
ds
[
1
]:
raise
NotImplementedError
(
'padding_h and padding_w must be smaller than strides'
)
if
mode
not
in
[
'max'
,
'average_inc_pad'
,
'average_exc_pad'
,
'sum'
]:
if
mode
not
in
[
'max'
,
'average_inc_pad'
,
'average_exc_pad'
,
'sum'
]:
raise
ValueError
(
raise
ValueError
(
"Pool mode parameter only support 'max', 'sum',"
"Pool mode parameter only support 'max', 'sum',"
" 'average_inc_pad' and 'average_exc_pad'. Got
%
s"
%
mode
)
" 'average_inc_pad' and 'average_exc_pad'. Got
%
s"
%
mode
)
self
.
mode
=
mode
self
.
mode
=
mode
def
make_node
(
self
,
x
):
def
prepare_node
(
self
,
node
,
storage_map
,
compute_map
):
if
len
(
node
.
inputs
)
==
1
:
# Old interface
self
.
mode
=
node
.
op
.
mode
ws
=
theano
.
tensor
.
constant
(
node
.
op
.
ds
)
st
=
theano
.
tensor
.
constant
(
node
.
op
.
st
)
pad
=
theano
.
tensor
.
constant
(
node
.
op
.
padding
)
node
.
inputs
.
append
(
ws
)
node
.
inputs
.
append
(
st
)
node
.
inputs
.
append
(
pad
)
if
isinstance
(
ws
,
theano
.
Constant
):
storage_map
[
ws
]
=
[
ws
.
data
]
compute_map
[
ws
]
=
[
True
]
else
:
storage_map
[
ws
]
=
[
None
]
compute_map
[
ws
]
=
[
False
]
if
isinstance
(
st
,
theano
.
Constant
):
storage_map
[
st
]
=
[
st
.
data
]
compute_map
[
st
]
=
[
True
]
else
:
storage_map
[
st
]
=
[
None
]
compute_map
[
st
]
=
[
False
]
if
isinstance
(
pad
,
theano
.
Constant
):
storage_map
[
pad
]
=
[
pad
.
data
]
compute_map
[
pad
]
=
[
True
]
else
:
storage_map
[
pad
]
=
[
None
]
compute_map
[
pad
]
=
[
False
]
def
make_node
(
self
,
x
,
ws
,
stride
=
None
,
pad
=
(
0
,
0
)):
# TODO: consider restricting the dtype?
# TODO: consider restricting the dtype?
x
=
tensor
.
as_tensor_variable
(
x
)
x
=
tensor
.
as_tensor_variable
(
x
)
if
stride
is
None
:
stride
=
ws
if
isinstance
(
pad
,
(
tuple
,
list
)):
if
tuple
(
pad
)
!=
(
0
,
0
)
and
not
self
.
ignore_border
:
raise
NotImplementedError
(
'padding works only with ignore_border=True'
)
if
isinstance
(
ws
,
(
tuple
,
list
)):
if
pad
[
0
]
>=
ws
[
0
]
or
pad
[
1
]
>=
ws
[
1
]:
raise
NotImplementedError
(
'padding_h and padding_w must be smaller than strides'
)
ws
=
tensor
.
as_tensor_variable
(
ws
)
stride
=
tensor
.
as_tensor_variable
(
stride
)
pad
=
tensor
.
as_tensor_variable
(
pad
)
assert
ws
.
ndim
==
1
assert
stride
.
ndim
==
1
assert
pad
.
ndim
==
1
if
x
.
type
.
ndim
!=
4
:
if
x
.
type
.
ndim
!=
4
:
raise
TypeError
()
raise
TypeError
()
if
not
ws
.
dtype
.
startswith
(
'int'
):
raise
TypeError
(
'Pool downsample parameters must be ints.'
)
if
not
stride
.
dtype
.
startswith
(
'int'
):
raise
TypeError
(
'Stride parameters must be ints.'
)
if
not
pad
.
dtype
.
startswith
(
'int'
):
raise
TypeError
(
'Padding parameters must be ints.'
)
# If the input shape are broadcastable we can have 0 in the output shape
# If the input shape are broadcastable we can have 0 in the output shape
broad
=
x
.
broadcastable
[:
2
]
+
(
False
,
False
)
broad
=
x
.
broadcastable
[:
2
]
+
(
False
,
False
)
out
=
tensor
.
TensorType
(
x
.
dtype
,
broad
)
out
=
tensor
.
TensorType
(
x
.
dtype
,
broad
)
return
gof
.
Apply
(
self
,
[
x
],
[
out
()])
return
gof
.
Apply
(
self
,
[
x
,
ws
,
stride
,
pad
],
[
out
()])
def
perform
(
self
,
node
,
inp
,
out
):
def
perform
(
self
,
node
,
inp
,
out
):
x
,
=
inp
x
,
ws
,
stride
,
pad
=
inp
z
,
=
out
z
,
=
out
assert
ws
.
shape
==
stride
.
shape
==
pad
.
shape
==
(
2
,)
if
len
(
x
.
shape
)
!=
4
:
if
len
(
x
.
shape
)
!=
4
:
raise
NotImplementedError
(
raise
NotImplementedError
(
'Pool requires 4D input for now'
)
'Pool requires 4D input for now'
)
z_shape
=
self
.
out_shape
(
x
.
shape
,
self
.
ds
,
self
.
ignore_border
,
self
.
st
,
z_shape
=
self
.
out_shape
(
x
.
shape
,
ws
,
self
.
ignore_border
,
stride
,
pad
)
self
.
padding
)
if
not
self
.
ignore_border
:
if
not
self
.
ignore_border
:
assert
z_shape
[
2
]
>
0
assert
z_shape
[
2
]
>
0
assert
z_shape
[
3
]
>
0
assert
z_shape
[
3
]
>
0
...
@@ -288,16 +320,16 @@ class Pool(OpenMPOp):
...
@@ -288,16 +320,16 @@ class Pool(OpenMPOp):
pr
=
zz
.
shape
[
-
2
]
pr
=
zz
.
shape
[
-
2
]
# number of pooling output cols
# number of pooling output cols
pc
=
zz
.
shape
[
-
1
]
pc
=
zz
.
shape
[
-
1
]
ds0
,
ds1
=
self
.
d
s
ws0
,
ws1
=
w
s
st0
,
st1
=
s
elf
.
st
st0
,
st1
=
s
tride
pad_h
=
self
.
padding
[
0
]
pad_h
=
pad
[
0
]
pad_w
=
self
.
padding
[
1
]
pad_w
=
pad
[
1
]
img_rows
=
x
.
shape
[
-
2
]
+
2
*
pad_h
img_rows
=
x
.
shape
[
-
2
]
+
2
*
pad_h
img_cols
=
x
.
shape
[
-
1
]
+
2
*
pad_w
img_cols
=
x
.
shape
[
-
1
]
+
2
*
pad_w
inc_pad
=
self
.
mode
==
'average_inc_pad'
inc_pad
=
self
.
mode
==
'average_inc_pad'
# pad the image
# pad the image
if
self
.
padding
!=
(
0
,
0
):
if
(
pad_h
,
pad_w
)
!=
(
0
,
0
):
y
=
numpy
.
zeros
(
y
=
numpy
.
zeros
(
(
x
.
shape
[
0
],
x
.
shape
[
1
],
img_rows
,
img_cols
),
(
x
.
shape
[
0
],
x
.
shape
[
1
],
img_rows
,
img_cols
),
dtype
=
x
.
dtype
)
dtype
=
x
.
dtype
)
...
@@ -314,40 +346,41 @@ class Pool(OpenMPOp):
...
@@ -314,40 +346,41 @@ class Pool(OpenMPOp):
for
k
in
xrange
(
x
.
shape
[
1
]):
for
k
in
xrange
(
x
.
shape
[
1
]):
for
r
in
xrange
(
pr
):
for
r
in
xrange
(
pr
):
row_st
=
r
*
st0
row_st
=
r
*
st0
row_end
=
builtins
.
min
(
row_st
+
d
s0
,
img_rows
)
row_end
=
builtins
.
min
(
row_st
+
w
s0
,
img_rows
)
if
not
inc_pad
:
if
not
inc_pad
:
row_st
=
builtins
.
max
(
row_st
,
self
.
padding
[
0
]
)
row_st
=
builtins
.
max
(
row_st
,
pad_h
)
row_end
=
builtins
.
min
(
row_end
,
x
.
shape
[
-
2
]
+
pad_h
)
row_end
=
builtins
.
min
(
row_end
,
x
.
shape
[
-
2
]
+
pad_h
)
for
c
in
xrange
(
pc
):
for
c
in
xrange
(
pc
):
col_st
=
c
*
st1
col_st
=
c
*
st1
col_end
=
builtins
.
min
(
col_st
+
d
s1
,
img_cols
)
col_end
=
builtins
.
min
(
col_st
+
w
s1
,
img_cols
)
if
not
inc_pad
:
if
not
inc_pad
:
col_st
=
builtins
.
max
(
col_st
,
self
.
padding
[
1
]
)
col_st
=
builtins
.
max
(
col_st
,
pad_w
)
col_end
=
builtins
.
min
(
col_end
,
col_end
=
builtins
.
min
(
col_end
,
x
.
shape
[
-
1
]
+
pad_w
)
x
.
shape
[
-
1
]
+
pad_w
)
zz
[
n
,
k
,
r
,
c
]
=
func
(
y
[
zz
[
n
,
k
,
r
,
c
]
=
func
(
y
[
n
,
k
,
row_st
:
row_end
,
col_st
:
col_end
])
n
,
k
,
row_st
:
row_end
,
col_st
:
col_end
])
def
infer_shape
(
self
,
node
,
in_shapes
):
def
infer_shape
(
self
,
node
,
in_shapes
):
shp
=
self
.
out_shape
(
in_shapes
[
0
],
self
.
ds
,
ws
,
stride
,
pad
=
[
node
.
inputs
[
1
],
node
.
inputs
[
2
],
node
.
inputs
[
3
]]
self
.
ignore_border
,
self
.
st
,
self
.
padding
)
shp
=
self
.
out_shape
(
in_shapes
[
0
],
ws
,
self
.
ignore_border
,
stride
,
pad
)
return
[
shp
]
return
[
shp
]
def
grad
(
self
,
inp
,
grads
):
def
grad
(
self
,
inp
,
grads
):
x
,
=
inp
x
,
ws
,
stride
,
pad
=
inp
gz
,
=
grads
gz
,
=
grads
disc
=
[
DisconnectedType
()()
for
i
in
inp
[
1
:]]
if
self
.
mode
==
'max'
:
if
self
.
mode
==
'max'
:
maxout
=
self
(
x
)
maxout
=
self
(
x
,
ws
,
stride
,
pad
)
return
[
MaxPoolGrad
(
self
.
ds
,
return
[
MaxPoolGrad
(
ignore_border
=
self
.
ignore_border
)(
ignore_border
=
self
.
ignore_border
,
x
,
maxout
,
gz
,
ws
=
ws
,
stride
=
stride
,
pad
=
pad
)]
+
disc
st
=
self
.
st
,
padding
=
self
.
padding
)(
x
,
maxout
,
gz
)]
else
:
else
:
return
[
AveragePoolGrad
(
self
.
ds
,
return
[
AveragePoolGrad
(
ignore_border
=
self
.
ignore_border
,
ignore_border
=
self
.
ignore_border
,
st
=
self
.
st
,
padding
=
self
.
padding
,
mode
=
self
.
mode
)(
mode
=
self
.
mode
)(
x
,
gz
)]
x
,
gz
,
ws
=
ws
,
stride
=
stride
,
pad
=
pad
)]
+
disc
def
connection_pattern
(
self
,
node
):
return
[[
1
],
[
0
],
[
0
],
[
0
]]
def
c_headers
(
self
):
def
c_headers
(
self
):
headers
=
[
'<algorithm>'
]
headers
=
[
'<algorithm>'
]
...
@@ -357,21 +390,41 @@ class Pool(OpenMPOp):
...
@@ -357,21 +390,41 @@ class Pool(OpenMPOp):
def
c_code
(
self
,
node
,
name
,
inp
,
out
,
sub
):
def
c_code
(
self
,
node
,
name
,
inp
,
out
,
sub
):
if
self
.
mode
not
in
(
'max'
,
'sum'
,
'average_exc_pad'
,
'average_inc_pad'
):
if
self
.
mode
not
in
(
'max'
,
'sum'
,
'average_exc_pad'
,
'average_inc_pad'
):
raise
theano
.
gof
.
utils
.
MethodNotDefined
()
raise
theano
.
gof
.
utils
.
MethodNotDefined
()
x
,
=
inp
x
,
ws
,
stride
,
pad
=
inp
z
,
=
out
z
,
=
out
fail
=
sub
[
'fail'
]
fail
=
sub
[
'fail'
]
ignore_border
=
int
(
self
.
ignore_border
)
ignore_border
=
int
(
self
.
ignore_border
)
ds0
,
ds1
=
self
.
ds
st0
,
st1
=
self
.
st
pd0
,
pd1
=
self
.
padding
if
self
.
openmp
:
if
self
.
openmp
:
omp_parallel
=
'#pragma omp parallel for private(r_st, r_end, c_st, c_end, collector) schedule(static)'
omp_parallel
=
'#pragma omp parallel for private(r_st, r_end, c_st, c_end, collector) schedule(static)'
else
:
else
:
omp_parallel
=
''
omp_parallel
=
''
ccode
=
"""
ccode
=
"""
int ws0, ws1, st0, st1, pd0, pd1;
int typenum = PyArray_ObjectType((PyObject*)
%(x)
s, 0);
int typenum = PyArray_ObjectType((PyObject*)
%(x)
s, 0);
int z_r, z_c; // shape of the output
int z_r, z_c; // shape of the output
int r, c; // shape of the padded_input
int r, c; // shape of the padded_input
if(PyArray_DIM(
%(ws)
s, 0)!=2)
{
PyErr_SetString(PyExc_ValueError, "ws must be a vector of size 2");
%(fail)
s;
}
if(PyArray_DIM(
%(stride)
s, 0)!=2)
{
PyErr_SetString(PyExc_ValueError, "stride must be a vector of size 2");
%(fail)
s;
}
if(PyArray_DIM(
%(pad)
s, 0)!=2)
{
PyErr_SetString(PyExc_ValueError, "pad must be a vector of size 2");
%(fail)
s;
}
// Getting ws, stride and pad
ws0 = *((npy_intp*)PyArray_GETPTR1(
%(ws)
s, 0));
ws1 = *((npy_intp*)PyArray_GETPTR1(
%(ws)
s, 1));
st0 = *((npy_intp*)PyArray_GETPTR1(
%(stride)
s, 0));
st1 = *((npy_intp*)PyArray_GETPTR1(
%(stride)
s, 1));
pd0 = *((npy_intp*)PyArray_GETPTR1(
%(pad)
s, 0));
pd1 = *((npy_intp*)PyArray_GETPTR1(
%(pad)
s, 1));
if(PyArray_NDIM(
%(x)
s)!=4)
if(PyArray_NDIM(
%(x)
s)!=4)
{
{
PyErr_SetString(PyExc_ValueError, "x must be a 4d ndarray");
PyErr_SetString(PyExc_ValueError, "x must be a 4d ndarray");
...
@@ -379,9 +432,9 @@ class Pool(OpenMPOp):
...
@@ -379,9 +432,9 @@ class Pool(OpenMPOp):
}
}
r = PyArray_DIMS(
%(x)
s)[2];
r = PyArray_DIMS(
%(x)
s)[2];
c = PyArray_DIMS(
%(x)
s)[3];
c = PyArray_DIMS(
%(x)
s)[3];
r +=
%(pd0)
s
* 2;
r +=
pd0
* 2;
c +=
%(pd1)
s
* 2;
c +=
pd1
* 2;
if (
%(pd0)
s != 0 &&
%(pd1)
s
!= 0 && !
%(ignore_border)
s)
if (
pd0 != 0 && pd1
!= 0 && !
%(ignore_border)
s)
{
{
PyErr_SetString(PyExc_ValueError,
PyErr_SetString(PyExc_ValueError,
"padding must be (0,0) when ignore border is False");
"padding must be (0,0) when ignore border is False");
...
@@ -390,42 +443,42 @@ class Pool(OpenMPOp):
...
@@ -390,42 +443,42 @@ class Pool(OpenMPOp):
if (
%(ignore_border)
s)
if (
%(ignore_border)
s)
{
{
// '/' in C is different from '/' in python
// '/' in C is different from '/' in python
if (r -
%(ds0)
s
< 0)
if (r -
ws0
< 0)
{
{
z_r = 0;
z_r = 0;
}
}
else
else
{
{
z_r = (r -
%(ds0)
s) /
%(st0)
s
+ 1;
z_r = (r -
ws0) / st0
+ 1;
}
}
if (c -
%(ds1)
s
< 0)
if (c -
ws1
< 0)
{
{
z_c = 0;
z_c = 0;
}
}
else
else
{
{
z_c = (c -
%(ds1)
s) /
%(st1)
s
+ 1;
z_c = (c -
ws1) / st1
+ 1;
}
}
}
}
else
else
{
{
// decide how many rows the output has
// decide how many rows the output has
if (
%(st0)
s >=
%(ds0)
s
)
if (
st0 >= ws0
)
{
{
z_r = (r - 1) /
%(st0)
s
+ 1;
z_r = (r - 1) /
st0
+ 1;
}
}
else
else
{
{
z_r = std::max(0, (r - 1 -
%(ds0)
s +
%(st0)
s) /
%(st0)
s
) + 1;
z_r = std::max(0, (r - 1 -
ws0 + st0) / st0
) + 1;
}
}
// decide how many columns the output has
// decide how many columns the output has
if (
%(st1)
s >=
%(ds1)
s
)
if (
st1 >= ws1
)
{
{
z_c = (c - 1) /
%(st1)
s
+ 1;
z_c = (c - 1) /
st1
+ 1;
}
}
else
else
{
{
z_c = std::max(0, (c - 1 -
%(ds1)
s +
%(st0)
s) /
%(st1)
s
) + 1;
z_c = std::max(0, (c - 1 -
ws1 + st0) / st1
) + 1;
}
}
assert(z_r > 0);
assert(z_r > 0);
assert(z_c > 0);
assert(z_c > 0);
...
@@ -458,30 +511,30 @@ class Pool(OpenMPOp):
...
@@ -458,30 +511,30 @@ class Pool(OpenMPOp):
int b = t
%%
PyArray_DIMS(
%(x)
s)[0];
int b = t
%%
PyArray_DIMS(
%(x)
s)[0];
int k = t / PyArray_DIMS(
%(x)
s)[0];
int k = t / PyArray_DIMS(
%(x)
s)[0];
for(int i=0; i < z_r; i++){
for(int i=0; i < z_r; i++){
r_st = i *
%(st0)
s
;
r_st = i *
st0
;
r_end = r_st +
%(ds0)
s
;
r_end = r_st +
ws0
;
// skip the padding
// skip the padding
r_st = r_st <
%(pd0)
s ?
%(pd0)
s
: r_st;
r_st = r_st <
pd0 ? pd0
: r_st;
r_end = r_end > (r -
%(pd0)
s) ? r -
%(pd0)
s
: r_end;
r_end = r_end > (r -
pd0) ? r - pd0
: r_end;
// from padded_img space to img space
// from padded_img space to img space
r_st -=
%(pd0)
s
;
r_st -=
pd0
;
r_end -=
%(pd0)
s
;
r_end -=
pd0
;
// handle the case where no padding, ignore border is True
// handle the case where no padding, ignore border is True
if (
%(ignore_border)
s)
if (
%(ignore_border)
s)
{
{
r_end = r_end > r ? r : r_end;
r_end = r_end > r ? r : r_end;
}
}
for(int j=0; j<z_c; j++){
for(int j=0; j<z_c; j++){
c_st = j *
%(st1)
s
;
c_st = j *
st1
;
c_end = c_st +
%(ds1)
s
;
c_end = c_st +
ws1
;
// skip the padding
// skip the padding
c_st = c_st <
%(pd1)
s ?
%(pd1)
s
: c_st;
c_st = c_st <
pd1 ? pd1
: c_st;
c_end = c_end > (c -
%(pd1)
s) ? c -
%(pd1)
s
: c_end;
c_end = c_end > (c -
pd1) ? c - pd1
: c_end;
dtype_
%(z)
s * z = (
dtype_
%(z)
s * z = (
(dtype_
%(z)
s*)(PyArray_GETPTR4(
%(z)
s, b, k, i, j)));
(dtype_
%(z)
s*)(PyArray_GETPTR4(
%(z)
s, b, k, i, j)));
// change coordinates from padding_img space into img space
// change coordinates from padding_img space into img space
c_st -=
%(pd1)
s
;
c_st -=
pd1
;
c_end -=
%(pd1)
s
;
c_end -=
pd1
;
// handle the case where no padding, ignore border is True
// handle the case where no padding, ignore border is True
if (
%(ignore_border)
s)
if (
%(ignore_border)
s)
{
{
...
@@ -523,7 +576,7 @@ class Pool(OpenMPOp):
...
@@ -523,7 +576,7 @@ class Pool(OpenMPOp):
"""
"""
elif
self
.
mode
==
'average_inc_pad'
and
self
.
ignore_border
:
elif
self
.
mode
==
'average_inc_pad'
and
self
.
ignore_border
:
ccode
+=
"""
ccode
+=
"""
z[0] = collector / (
%(ds0)
s *
%(ds1)
s
);
z[0] = collector / (
ws0 * ws1
);
"""
"""
else
:
else
:
ccode
+=
"""
ccode
+=
"""
...
@@ -538,11 +591,11 @@ class Pool(OpenMPOp):
...
@@ -538,11 +591,11 @@ class Pool(OpenMPOp):
return
ccode
%
locals
()
return
ccode
%
locals
()
def
c_code_cache_version
(
self
):
def
c_code_cache_version
(
self
):
return
(
0
,
6
,
8
,
4
,
self
.
openmp
)
return
(
0
,
6
,
8
,
6
,
self
.
openmp
)
class
PoolGrad
(
OpenMPOp
):
class
PoolGrad
(
OpenMPOp
):
__props__
=
(
'
ds'
,
'ignore_border'
,
'st'
,
'padding
'
,
'mode'
)
__props__
=
(
'
ignore_border
'
,
'mode'
)
@staticmethod
@staticmethod
def
out_shape
(
imgshape
,
ds
,
ignore_border
=
False
,
st
=
None
,
padding
=
(
0
,
0
)):
def
out_shape
(
imgshape
,
ds
,
ignore_border
=
False
,
st
=
None
,
padding
=
(
0
,
0
)):
...
@@ -624,13 +677,8 @@ class PoolGrad(OpenMPOp):
...
@@ -624,13 +677,8 @@ class PoolGrad(OpenMPOp):
rval
=
list
(
imgshape
[:
-
2
])
+
[
nr
,
nc
]
rval
=
list
(
imgshape
[:
-
2
])
+
[
nr
,
nc
]
return
rval
return
rval
def
__init__
(
self
,
ds
,
ignore_border
,
st
=
None
,
padding
=
(
0
,
0
),
mode
=
'max'
,
openmp
=
None
):
def
__init__
(
self
,
ignore_border
,
mode
=
'max'
,
openmp
=
None
):
self
.
ds
=
tuple
(
ds
)
self
.
ignore_border
=
ignore_border
self
.
ignore_border
=
ignore_border
if
st
is
None
:
st
=
ds
self
.
st
=
tuple
(
st
)
self
.
padding
=
tuple
(
padding
)
if
mode
not
in
[
'max'
,
'sum'
,
'average_inc_pad'
,
'average_exc_pad'
]:
if
mode
not
in
[
'max'
,
'sum'
,
'average_inc_pad'
,
'average_exc_pad'
]:
raise
ValueError
(
raise
ValueError
(
"Pool mode parameter only support 'max', 'sum',"
"Pool mode parameter only support 'max', 'sum',"
...
@@ -638,43 +686,86 @@ class PoolGrad(OpenMPOp):
...
@@ -638,43 +686,86 @@ class PoolGrad(OpenMPOp):
self
.
mode
=
mode
self
.
mode
=
mode
super
(
PoolGrad
,
self
)
.
__init__
(
openmp
=
openmp
)
super
(
PoolGrad
,
self
)
.
__init__
(
openmp
=
openmp
)
def
prepare_node
(
self
,
node
,
storage_map
,
compute_map
):
if
len
(
node
.
inputs
)
<
5
:
# 5 for AveragePoolGrad, 6 for MaxPoolGrad
# Old interface
self
.
mode
=
node
.
op
.
mode
ws
=
theano
.
tensor
.
constant
(
node
.
op
.
ds
)
st
=
theano
.
tensor
.
constant
(
node
.
op
.
st
)
pad
=
theano
.
tensor
.
constant
(
node
.
op
.
padding
)
node
.
inputs
.
append
(
ws
)
node
.
inputs
.
append
(
st
)
node
.
inputs
.
append
(
pad
)
if
isinstance
(
ws
,
theano
.
Constant
):
storage_map
[
ws
]
=
[
ws
.
data
]
compute_map
[
ws
]
=
[
True
]
else
:
storage_map
[
ws
]
=
[
None
]
compute_map
[
ws
]
=
[
False
]
if
isinstance
(
st
,
theano
.
Constant
):
storage_map
[
st
]
=
[
st
.
data
]
compute_map
[
st
]
=
[
True
]
else
:
storage_map
[
st
]
=
[
None
]
compute_map
[
st
]
=
[
False
]
if
isinstance
(
pad
,
theano
.
Constant
):
storage_map
[
pad
]
=
[
pad
.
data
]
compute_map
[
pad
]
=
[
True
]
else
:
storage_map
[
pad
]
=
[
None
]
compute_map
[
pad
]
=
[
False
]
def
infer_shape
(
self
,
node
,
in_shapes
):
def
infer_shape
(
self
,
node
,
in_shapes
):
return
[
in_shapes
[
0
]]
return
[
in_shapes
[
0
]]
class
MaxPoolGrad
(
PoolGrad
):
class
MaxPoolGrad
(
PoolGrad
):
def
__init__
(
self
,
ds
,
ignore_border
,
st
=
None
,
padding
=
(
0
,
0
)
,
openmp
=
None
):
def
__init__
(
self
,
ignore_border
,
openmp
=
None
):
PoolGrad
.
__init__
(
self
,
ds
,
ignore_border
,
st
,
padding
,
'max'
,
openmp
)
PoolGrad
.
__init__
(
self
,
ignore_border
,
mode
=
'max'
,
openmp
=
openmp
)
def
make_node
(
self
,
x
,
maxout
,
gz
):
def
make_node
(
self
,
x
,
maxout
,
gz
,
ws
,
stride
=
None
,
pad
=
(
0
,
0
)
):
# make_node should only be called by the grad function of
# make_node should only be called by the grad function of
# Pool, so these asserts should not fail.
# Pool, so these asserts should not fail.
x
=
tensor
.
as_tensor_variable
(
x
)
x
=
tensor
.
as_tensor_variable
(
x
)
maxout
=
tensor
.
as_tensor_variable
(
maxout
)
maxout
=
tensor
.
as_tensor_variable
(
maxout
)
gz
=
tensor
.
as_tensor_variable
(
gz
)
gz
=
tensor
.
as_tensor_variable
(
gz
)
if
stride
is
None
:
stride
=
ws
ws
=
tensor
.
as_tensor_variable
(
ws
)
stride
=
tensor
.
as_tensor_variable
(
stride
)
pad
=
tensor
.
as_tensor_variable
(
pad
)
assert
isinstance
(
x
,
Variable
)
and
x
.
ndim
==
4
assert
isinstance
(
x
,
Variable
)
and
x
.
ndim
==
4
assert
isinstance
(
maxout
,
Variable
)
and
maxout
.
ndim
==
4
assert
isinstance
(
maxout
,
Variable
)
and
maxout
.
ndim
==
4
assert
isinstance
(
gz
,
Variable
)
and
gz
.
ndim
==
4
assert
isinstance
(
gz
,
Variable
)
and
gz
.
ndim
==
4
assert
isinstance
(
ws
,
Variable
)
and
ws
.
ndim
==
1
return
Apply
(
self
,
[
x
,
maxout
,
gz
],
[
x
.
type
()])
assert
isinstance
(
stride
,
Variable
)
and
stride
.
ndim
==
1
assert
isinstance
(
pad
,
Variable
)
and
pad
.
ndim
==
1
if
not
ws
.
dtype
.
startswith
(
'int'
):
raise
TypeError
(
'Pool downsample parameters must be ints.'
)
if
not
stride
.
dtype
.
startswith
(
'int'
):
raise
TypeError
(
'Stride parameters must be ints.'
)
if
not
pad
.
dtype
.
startswith
(
'int'
):
raise
TypeError
(
'Padding parameters must be ints.'
)
return
Apply
(
self
,
[
x
,
maxout
,
gz
,
ws
,
stride
,
pad
],
[
x
.
type
()])
def
perform
(
self
,
node
,
inp
,
out
):
def
perform
(
self
,
node
,
inp
,
out
):
assert
self
.
mode
==
'max'
assert
self
.
mode
==
'max'
x
,
maxout
,
gz
=
inp
x
,
maxout
,
gz
,
ws
,
stride
,
pad
=
inp
gx_stg
,
=
out
gx_stg
,
=
out
assert
ws
.
shape
==
stride
.
shape
==
pad
.
shape
==
(
2
,)
# number of pooling output rows
# number of pooling output rows
pr
=
maxout
.
shape
[
-
2
]
pr
=
maxout
.
shape
[
-
2
]
# number of pooling output cols
# number of pooling output cols
pc
=
maxout
.
shape
[
-
1
]
pc
=
maxout
.
shape
[
-
1
]
ds0
,
ds1
=
self
.
d
s
ws0
,
ws1
=
w
s
st0
,
st1
=
s
elf
.
st
st0
,
st1
=
s
tride
pad_h
=
self
.
padding
[
0
]
pad_h
=
pad
[
0
]
pad_w
=
self
.
padding
[
1
]
pad_w
=
pad
[
1
]
img_rows
=
x
.
shape
[
-
2
]
+
2
*
pad_h
img_rows
=
x
.
shape
[
-
2
]
+
2
*
pad_h
img_cols
=
x
.
shape
[
-
1
]
+
2
*
pad_w
img_cols
=
x
.
shape
[
-
1
]
+
2
*
pad_w
# pad the image
# pad the image
if
self
.
padding
!=
(
0
,
0
):
if
(
pad_h
,
pad_w
)
!=
(
0
,
0
):
y
=
numpy
.
zeros
(
y
=
numpy
.
zeros
(
(
x
.
shape
[
0
],
x
.
shape
[
1
],
img_rows
,
img_cols
),
(
x
.
shape
[
0
],
x
.
shape
[
1
],
img_rows
,
img_cols
),
dtype
=
x
.
dtype
)
dtype
=
x
.
dtype
)
...
@@ -685,11 +776,11 @@ class MaxPoolGrad(PoolGrad):
...
@@ -685,11 +776,11 @@ class MaxPoolGrad(PoolGrad):
for
n
in
xrange
(
x
.
shape
[
0
]):
for
n
in
xrange
(
x
.
shape
[
0
]):
for
k
in
xrange
(
x
.
shape
[
1
]):
for
k
in
xrange
(
x
.
shape
[
1
]):
for
r
in
xrange
(
pr
):
for
r
in
xrange
(
pr
):
row_st
=
builtins
.
max
(
r
*
st0
,
self
.
padding
[
0
]
)
row_st
=
builtins
.
max
(
r
*
st0
,
pad_h
)
row_end
=
builtins
.
min
(
row_st
+
d
s0
,
img_rows
)
row_end
=
builtins
.
min
(
row_st
+
w
s0
,
img_rows
)
for
c
in
xrange
(
pc
):
for
c
in
xrange
(
pc
):
col_st
=
builtins
.
max
(
c
*
st1
,
self
.
padding
[
1
]
)
col_st
=
builtins
.
max
(
c
*
st1
,
pad_w
)
col_end
=
builtins
.
min
(
col_st
+
d
s1
,
img_cols
)
col_end
=
builtins
.
min
(
col_st
+
w
s1
,
img_cols
)
for
row_ind
in
xrange
(
row_st
,
row_end
):
for
row_ind
in
xrange
(
row_st
,
row_end
):
for
col_ind
in
xrange
(
col_st
,
col_end
):
for
col_ind
in
xrange
(
col_st
,
col_end
):
if
(
maxout
[
n
,
k
,
r
,
c
]
==
y
[
n
,
k
,
row_ind
,
col_ind
]):
if
(
maxout
[
n
,
k
,
r
,
c
]
==
y
[
n
,
k
,
row_ind
,
col_ind
]):
...
@@ -699,23 +790,23 @@ class MaxPoolGrad(PoolGrad):
...
@@ -699,23 +790,23 @@ class MaxPoolGrad(PoolGrad):
gx_stg
[
0
]
=
gx
gx_stg
[
0
]
=
gx
def
grad
(
self
,
inp
,
grads
):
def
grad
(
self
,
inp
,
grads
):
x
,
maxout
,
gz
=
inp
x
,
maxout
,
gz
,
ws
,
stride
,
pad
=
inp
ggx
,
=
grads
ggx
,
=
grads
return
[
theano
.
tensor
.
zeros_like
(
x
),
return
(
[
theano
.
tensor
.
zeros_like
(
x
),
theano
.
tensor
.
zeros_like
(
maxout
),
theano
.
tensor
.
zeros_like
(
maxout
),
DownsampleFactorMaxGradGrad
(
DownsampleFactorMaxGradGrad
(
ignore_border
=
self
.
ignore_border
)(
self
.
ds
,
ignore_border
=
self
.
ignore_border
,
x
,
maxout
,
ggx
,
ws
,
stride
,
pad
)]
+
st
=
self
.
st
,
padding
=
self
.
padding
)(
x
,
maxout
,
ggx
)]
[
DisconnectedType
()()
for
i
in
inp
[
3
:]])
def
connection_pattern
(
self
,
node
):
return
[[
1
],
[
1
],
[
1
],
[
0
],
[
0
],
[
0
]]
def
c_code
(
self
,
node
,
name
,
inp
,
out
,
sub
):
def
c_code
(
self
,
node
,
name
,
inp
,
out
,
sub
):
assert
self
.
mode
==
'max'
assert
self
.
mode
==
'max'
x
,
z
,
gz
=
inp
x
,
z
,
gz
,
ws
,
stride
,
pad
=
inp
gx
,
=
out
gx
,
=
out
fail
=
sub
[
'fail'
]
fail
=
sub
[
'fail'
]
ignore_border
=
int
(
self
.
ignore_border
)
ignore_border
=
int
(
self
.
ignore_border
)
ds0
,
ds1
=
self
.
ds
st0
,
st1
=
self
.
st
pd0
,
pd1
=
self
.
padding
if
self
.
openmp
:
if
self
.
openmp
:
omp_parallel
=
'#pragma omp parallel for private(r_st, r_end, c_st, c_end, maximum) schedule(static)'
omp_parallel
=
'#pragma omp parallel for private(r_st, r_end, c_st, c_end, maximum) schedule(static)'
else
:
else
:
...
@@ -725,6 +816,9 @@ class MaxPoolGrad(PoolGrad):
...
@@ -725,6 +816,9 @@ class MaxPoolGrad(PoolGrad):
int x_typenum = PyArray_ObjectType((PyObject*)
%(x)
s, 0);
int x_typenum = PyArray_ObjectType((PyObject*)
%(x)
s, 0);
int z_typenum = PyArray_ObjectType((PyObject*)
%(z)
s, 0);
int z_typenum = PyArray_ObjectType((PyObject*)
%(z)
s, 0);
int gz_typenum = PyArray_ObjectType((PyObject*)
%(gz)
s, 0);
int gz_typenum = PyArray_ObjectType((PyObject*)
%(gz)
s, 0);
int ws0, ws1, st0, st1, pd0, pd1;
int z_r, z_c;
int r, c; // shape of the padded_input
if ((x_typenum != z_typenum) || (x_typenum != gz_typenum))
if ((x_typenum != z_typenum) || (x_typenum != gz_typenum))
{
{
PyErr_SetString(PyExc_ValueError, "input types must all match");
PyErr_SetString(PyExc_ValueError, "input types must all match");
...
@@ -745,14 +839,34 @@ class MaxPoolGrad(PoolGrad):
...
@@ -745,14 +839,34 @@ class MaxPoolGrad(PoolGrad):
PyErr_SetString(PyExc_ValueError, "gz must be a 4d ndarray");
PyErr_SetString(PyExc_ValueError, "gz must be a 4d ndarray");
%(fail)
s;
%(fail)
s;
}
}
int z_r, z_c;
if(PyArray_DIM(
%(ws)
s, 0)!=2)
{
PyErr_SetString(PyExc_ValueError, "ws must be a vector of size 2");
%(fail)
s;
}
if(PyArray_DIM(
%(stride)
s, 0)!=2)
{
PyErr_SetString(PyExc_ValueError, "stride must be a vector of size 2");
%(fail)
s;
}
if(PyArray_DIM(
%(pad)
s, 0)!=2)
{
PyErr_SetString(PyExc_ValueError, "pad must be a vector of size 2");
%(fail)
s;
}
// Getting ws, stride and pad
ws0 = *((npy_intp*)PyArray_GETPTR1(
%(ws)
s, 0));
ws1 = *((npy_intp*)PyArray_GETPTR1(
%(ws)
s, 1));
st0 = *((npy_intp*)PyArray_GETPTR1(
%(stride)
s, 0));
st1 = *((npy_intp*)PyArray_GETPTR1(
%(stride)
s, 1));
pd0 = *((npy_intp*)PyArray_GETPTR1(
%(pad)
s, 0));
pd1 = *((npy_intp*)PyArray_GETPTR1(
%(pad)
s, 1));
z_r = PyArray_DIMS(
%(z)
s)[2];
z_r = PyArray_DIMS(
%(z)
s)[2];
z_c = PyArray_DIMS(
%(z)
s)[3];
z_c = PyArray_DIMS(
%(z)
s)[3];
int r, c; // shape of the padded_input
r = PyArray_DIMS(
%(x)
s)[2];
r = PyArray_DIMS(
%(x)
s)[2];
c = PyArray_DIMS(
%(x)
s)[3];
c = PyArray_DIMS(
%(x)
s)[3];
r +=
%(pd0)
s
* 2;
r +=
pd0
* 2;
c +=
%(pd1)
s
* 2;
c +=
pd1
* 2;
// allocating memory for gx
// allocating memory for gx
if ((!
%(gx)
s)
if ((!
%(gx)
s)
|| !PyArray_ISCONTIGUOUS(
%(gx)
s)
|| !PyArray_ISCONTIGUOUS(
%(gx)
s)
...
@@ -778,23 +892,23 @@ class MaxPoolGrad(PoolGrad):
...
@@ -778,23 +892,23 @@ class MaxPoolGrad(PoolGrad):
int b = t
%%
PyArray_DIMS(
%(x)
s)[0];
int b = t
%%
PyArray_DIMS(
%(x)
s)[0];
int k = t / PyArray_DIMS(
%(x)
s)[0];
int k = t / PyArray_DIMS(
%(x)
s)[0];
for(int i=0; i < z_r; i++){
for(int i=0; i < z_r; i++){
r_st = i *
%(st0)
s
;
r_st = i *
st0
;
r_end = r_st +
%(ds0)
s
;
r_end = r_st +
ws0
;
// skip the padding
// skip the padding
r_st = r_st <
%(pd0)
s ?
%(pd0)
s
: r_st;
r_st = r_st <
pd0 ? pd0
: r_st;
r_end = r_end > (r -
%(pd0)
s) ? r -
%(pd0)
s
: r_end;
r_end = r_end > (r -
pd0) ? r - pd0
: r_end;
// from padded_img space to img space
// from padded_img space to img space
r_st -=
%(pd0)
s
;
r_st -=
pd0
;
r_end -=
%(pd0)
s
;
r_end -=
pd0
;
for(int j=0; j<z_c; j++){
for(int j=0; j<z_c; j++){
c_st = j *
%(st1)
s
;
c_st = j *
st1
;
c_end = c_st +
%(ds1)
s
;
c_end = c_st +
ws1
;
// skip the padding
// skip the padding
c_st = c_st <
%(pd1)
s ?
%(pd1)
s
: c_st;
c_st = c_st <
pd1 ? pd1
: c_st;
c_end = c_end > (c -
%(pd1)
s) ? c -
%(pd1)
s
: c_end;
c_end = c_end > (c -
pd1) ? c - pd1
: c_end;
// change coordinates from padding_img space into img space
// change coordinates from padding_img space into img space
c_st -=
%(pd1)
s
;
c_st -=
pd1
;
c_end -=
%(pd1)
s
;
c_end -=
pd1
;
// the maximum value
// the maximum value
maximum = ((dtype_
%(z)
s*)(PyArray_GETPTR4(
%(z)
s,b,k,i,j)))[0];
maximum = ((dtype_
%(z)
s*)(PyArray_GETPTR4(
%(z)
s,b,k,i,j)))[0];
// the gradient corresponding to this maximum value in z
// the gradient corresponding to this maximum value in z
...
@@ -820,36 +934,48 @@ class MaxPoolGrad(PoolGrad):
...
@@ -820,36 +934,48 @@ class MaxPoolGrad(PoolGrad):
"""
%
locals
()
"""
%
locals
()
def
c_code_cache_version
(
self
):
def
c_code_cache_version
(
self
):
return
(
0
,
7
,
self
.
openmp
)
return
(
0
,
9
,
self
.
openmp
)
class
AveragePoolGrad
(
PoolGrad
):
class
AveragePoolGrad
(
PoolGrad
):
def
__init__
(
self
,
ds
,
ignore_border
,
st
=
None
,
padding
=
(
0
,
0
),
def
__init__
(
self
,
ignore_border
,
mode
=
'average_inc_pad'
):
mode
=
'average_inc_pad'
):
assert
mode
in
[
'sum'
,
'average_inc_pad'
,
'average_exc_pad'
]
assert
mode
in
[
'sum'
,
'average_inc_pad'
,
'average_exc_pad'
]
PoolGrad
.
__init__
(
self
,
ds
,
ignore_border
,
st
,
padding
,
mode
)
PoolGrad
.
__init__
(
self
,
ignore_border
,
mode
)
# There is an extra dummy parameter to match the parameter count
# There is an extra dummy parameter to match the parameter count
# of MaxPoolGrad. They have to keep the same interface because of
# of MaxPoolGrad. They have to keep the same interface because of
# the DownsampleFactorMaxGrad trick to keep old scripts working
# the DownsampleFactorMaxGrad trick to keep old scripts working
# (see downsample.py for details on this).
# (see downsample.py for details on this).
def
make_node
(
self
,
x
,
gz
,
dummy
=
None
):
def
make_node
(
self
,
x
,
gz
,
ws
,
stride
=
None
,
pad
=
(
0
,
0
),
dummy
=
None
):
# make_node should only be called by the grad function of
# make_node should only be called by the grad function of
# Pool, so these asserts should not fail.
# Pool, so these asserts should not fail.
x
=
tensor
.
as_tensor_variable
(
x
)
x
=
tensor
.
as_tensor_variable
(
x
)
gz
=
tensor
.
as_tensor_variable
(
gz
)
gz
=
tensor
.
as_tensor_variable
(
gz
)
if
stride
is
None
:
stride
=
ws
ws
=
tensor
.
as_tensor_variable
(
ws
)
stride
=
tensor
.
as_tensor_variable
(
stride
)
pad
=
tensor
.
as_tensor_variable
(
pad
)
assert
isinstance
(
x
,
Variable
)
and
x
.
ndim
==
4
assert
isinstance
(
x
,
Variable
)
and
x
.
ndim
==
4
assert
isinstance
(
gz
,
Variable
)
and
gz
.
ndim
==
4
assert
isinstance
(
gz
,
Variable
)
and
gz
.
ndim
==
4
assert
isinstance
(
ws
,
Variable
)
and
ws
.
ndim
==
1
return
Apply
(
self
,
[
x
,
gz
],
[
x
.
type
()])
assert
isinstance
(
stride
,
Variable
)
and
stride
.
ndim
==
1
assert
isinstance
(
pad
,
Variable
)
and
pad
.
ndim
==
1
if
not
ws
.
dtype
.
startswith
(
'int'
):
raise
TypeError
(
'Pool downsample parameters must be ints.'
)
if
not
stride
.
dtype
.
startswith
(
'int'
):
raise
TypeError
(
'Stride parameters must be ints.'
)
if
not
pad
.
dtype
.
startswith
(
'int'
):
raise
TypeError
(
'Padding parameters must be ints.'
)
return
Apply
(
self
,
[
x
,
gz
,
ws
,
stride
,
pad
],
[
x
.
type
()])
def
perform
(
self
,
node
,
inp
,
out
):
def
perform
(
self
,
node
,
inp
,
out
):
if
self
.
mode
==
'average_exc_pad'
and
self
.
padding
!=
(
0
,
0
):
x
,
gz
,
ws
,
stride
,
pad
=
inp
raise
NotImplementedError
()
x
,
gz
=
inp
gx_stg
,
=
out
gx_stg
,
=
out
z_shape
=
self
.
out_shape
(
x
.
shape
,
self
.
ds
,
self
.
ignore_border
,
self
.
st
,
assert
ws
.
shape
==
stride
.
shape
==
pad
.
shape
==
(
2
,)
self
.
padding
)
if
self
.
mode
==
'average_exc_pad'
and
pad
[
0
]
!=
0
and
pad
[
1
]
!=
0
:
raise
NotImplementedError
()
z_shape
=
self
.
out_shape
(
x
.
shape
,
ws
,
self
.
ignore_border
,
stride
,
pad
)
if
(
gx_stg
[
0
]
is
None
)
or
(
gx_stg
[
0
]
.
shape
!=
z_shape
):
if
(
gx_stg
[
0
]
is
None
)
or
(
gx_stg
[
0
]
.
shape
!=
z_shape
):
gx_stg
[
0
]
=
numpy
.
empty
(
z_shape
,
dtype
=
x
.
dtype
)
gx_stg
[
0
]
=
numpy
.
empty
(
z_shape
,
dtype
=
x
.
dtype
)
zz
=
gx_stg
[
0
]
zz
=
gx_stg
[
0
]
...
@@ -857,17 +983,17 @@ class AveragePoolGrad(PoolGrad):
...
@@ -857,17 +983,17 @@ class AveragePoolGrad(PoolGrad):
pr
=
zz
.
shape
[
-
2
]
pr
=
zz
.
shape
[
-
2
]
# number of pooling output cols
# number of pooling output cols
pc
=
zz
.
shape
[
-
1
]
pc
=
zz
.
shape
[
-
1
]
ds0
,
ds1
=
self
.
d
s
ws0
,
ws1
=
w
s
st0
,
st1
=
s
elf
.
st
st0
,
st1
=
s
tride
pad_h
=
self
.
padding
[
0
]
pad_h
=
pad
[
0
]
pad_w
=
self
.
padding
[
1
]
pad_w
=
pad
[
1
]
img_rows
=
x
.
shape
[
-
2
]
+
2
*
pad_h
img_rows
=
x
.
shape
[
-
2
]
+
2
*
pad_h
img_cols
=
x
.
shape
[
-
1
]
+
2
*
pad_w
img_cols
=
x
.
shape
[
-
1
]
+
2
*
pad_w
inc_pad
=
self
.
mode
==
'average_inc_pad'
inc_pad
=
self
.
mode
==
'average_inc_pad'
sum_mode
=
self
.
mode
==
'sum'
sum_mode
=
self
.
mode
==
'sum'
# pad the image
# pad the image
if
self
.
padding
!=
(
0
,
0
):
if
(
pad_h
,
pad_w
)
!=
(
0
,
0
):
y
=
numpy
.
zeros
(
y
=
numpy
.
zeros
(
(
x
.
shape
[
0
],
x
.
shape
[
1
],
img_rows
,
img_cols
),
(
x
.
shape
[
0
],
x
.
shape
[
1
],
img_rows
,
img_cols
),
dtype
=
x
.
dtype
)
dtype
=
x
.
dtype
)
...
@@ -881,15 +1007,14 @@ class AveragePoolGrad(PoolGrad):
...
@@ -881,15 +1007,14 @@ class AveragePoolGrad(PoolGrad):
if
sum_mode
or
inc_pad
:
if
sum_mode
or
inc_pad
:
row_st
=
r
*
st0
row_st
=
r
*
st0
else
:
else
:
row_st
=
builtins
.
max
(
r
*
st0
,
self
.
padding
[
0
]
)
row_st
=
builtins
.
max
(
r
*
st0
,
pad_h
)
row_end
=
builtins
.
min
(
row_st
+
d
s0
,
img_rows
)
row_end
=
builtins
.
min
(
row_st
+
w
s0
,
img_rows
)
for
c
in
xrange
(
pc
):
for
c
in
xrange
(
pc
):
if
sum_mode
or
inc_pad
:
if
sum_mode
or
inc_pad
:
col_st
=
c
*
st1
col_st
=
c
*
st1
else
:
else
:
col_st
=
builtins
.
max
(
c
*
st1
,
col_st
=
builtins
.
max
(
c
*
st1
,
pad_w
)
self
.
padding
[
1
])
col_end
=
builtins
.
min
(
col_st
+
ws1
,
img_cols
)
col_end
=
builtins
.
min
(
col_st
+
ds1
,
img_cols
)
if
sum_mode
:
if
sum_mode
:
val
=
gz
[
n
,
k
,
r
,
c
]
val
=
gz
[
n
,
k
,
r
,
c
]
else
:
else
:
...
@@ -901,39 +1026,26 @@ class AveragePoolGrad(PoolGrad):
...
@@ -901,39 +1026,26 @@ class AveragePoolGrad(PoolGrad):
gx_stg
[
0
]
=
gx
gx_stg
[
0
]
=
gx
def
grad
(
self
,
inp
,
grads
):
def
grad
(
self
,
inp
,
grads
):
x
,
gz
=
inp
x
,
gz
,
ws
,
stride
,
pad
=
inp
ggx
,
=
grads
ggx
,
=
grads
return
[
theano
.
tensor
.
zeros_like
(
x
),
return
([
theano
.
tensor
.
zeros_like
(
x
),
Pool
(
self
.
ds
,
ignore_border
=
self
.
ignore_border
,
Pool
(
ignore_border
=
self
.
ignore_border
,
mode
=
self
.
mode
)(
ggx
,
st
=
self
.
st
,
padding
=
self
.
padding
,
mode
=
self
.
mode
)(
ggx
)]
ws
,
stride
,
pad
)]
+
[
DisconnectedType
()()
for
i
in
inp
[
2
:]])
def
connection_pattern
(
self
,
node
):
return
[[
1
],
[
1
],
[
0
],
[
0
],
[
0
]]
class
DownsampleFactorMaxGradGrad
(
OpenMPOp
):
class
DownsampleFactorMaxGradGrad
(
OpenMPOp
):
__props__
=
(
'
ds'
,
'ignore_border'
,
'st'
,
'padding
'
,
'mode'
)
__props__
=
(
'
ignore_border
'
,
'mode'
)
def
__init__
(
self
,
ds
,
ignore_border
,
st
=
None
,
padding
=
(
0
,
0
),
mode
=
'max'
,
openmp
=
None
):
def
__init__
(
self
,
ignore_border
,
mode
=
'max'
,
openmp
=
None
):
self
.
ds
=
tuple
(
ds
)
if
not
all
([
isinstance
(
d
,
integer_types
)
for
d
in
ds
]):
raise
ValueError
(
"Pool downsample parameters must be ints."
" Got
%
s"
%
str
(
ds
))
if
st
is
None
:
st
=
ds
assert
isinstance
(
st
,
(
tuple
,
list
))
self
.
st
=
tuple
(
st
)
self
.
ignore_border
=
ignore_border
self
.
ignore_border
=
ignore_border
self
.
padding
=
tuple
(
padding
)
if
self
.
padding
!=
(
0
,
0
)
and
not
ignore_border
:
raise
NotImplementedError
(
'padding works only with ignore_border=True'
)
if
self
.
padding
[
0
]
>=
self
.
ds
[
0
]
or
self
.
padding
[
1
]
>=
self
.
ds
[
1
]:
raise
NotImplementedError
(
'padding_h and padding_w must be smaller than strides'
)
self
.
mode
=
mode
self
.
mode
=
mode
super
(
DownsampleFactorMaxGradGrad
,
self
)
.
__init__
(
openmp
=
openmp
)
super
(
DownsampleFactorMaxGradGrad
,
self
)
.
__init__
(
openmp
=
openmp
)
assert
self
.
mode
==
'max'
assert
self
.
mode
==
'max'
def
make_node
(
self
,
x
,
maxout
,
gz
):
def
make_node
(
self
,
x
,
maxout
,
gz
,
ws
,
stride
=
None
,
pad
=
(
0
,
0
)
):
# make_node should only be called by the grad function of
# make_node should only be called by the grad function of
# MaxPoolGrad, so these asserts should not fail.
# MaxPoolGrad, so these asserts should not fail.
x
=
tensor
.
as_tensor_variable
(
x
)
x
=
tensor
.
as_tensor_variable
(
x
)
...
@@ -942,12 +1054,34 @@ class DownsampleFactorMaxGradGrad(OpenMPOp):
...
@@ -942,12 +1054,34 @@ class DownsampleFactorMaxGradGrad(OpenMPOp):
assert
x
.
ndim
==
4
assert
x
.
ndim
==
4
assert
maxout
.
ndim
==
4
assert
maxout
.
ndim
==
4
assert
gz
.
ndim
==
4
assert
gz
.
ndim
==
4
if
stride
is
None
:
return
Apply
(
self
,
[
x
,
maxout
,
gz
],
[
x
.
type
()])
stride
=
ws
if
isinstance
(
pad
,
(
tuple
,
list
)):
if
tuple
(
pad
)
!=
(
0
,
0
)
and
not
self
.
ignore_border
:
raise
NotImplementedError
(
'padding works only with ignore_border=True'
)
if
isinstance
(
ws
,
(
tuple
,
list
)):
if
pad
[
0
]
>=
ws
[
0
]
or
pad
[
1
]
>=
ws
[
1
]:
raise
NotImplementedError
(
'padding_h and padding_w must be smaller than strides'
)
ws
=
tensor
.
as_tensor_variable
(
ws
)
stride
=
tensor
.
as_tensor_variable
(
stride
)
pad
=
tensor
.
as_tensor_variable
(
pad
)
assert
ws
.
ndim
==
1
assert
stride
.
ndim
==
1
assert
pad
.
ndim
==
1
if
not
ws
.
dtype
.
startswith
(
'int'
):
raise
TypeError
(
'Pool downsample parameters must be ints.'
)
if
not
stride
.
dtype
.
startswith
(
'int'
):
raise
TypeError
(
'Stride parameters must be ints.'
)
if
not
pad
.
dtype
.
startswith
(
'int'
):
raise
TypeError
(
'Padding parameters must be ints.'
)
return
Apply
(
self
,
[
x
,
maxout
,
gz
,
ws
,
stride
,
pad
],
[
x
.
type
()])
def
perform
(
self
,
node
,
inp
,
out
):
def
perform
(
self
,
node
,
inp
,
out
):
x
,
maxout
,
ggx
=
inp
x
,
maxout
,
ggx
,
ws
,
stride
,
pad
=
inp
z
,
=
out
z
,
=
out
assert
ws
.
shape
==
stride
.
shape
==
pad
.
shape
==
(
2
,)
if
len
(
x
.
shape
)
!=
4
:
if
len
(
x
.
shape
)
!=
4
:
raise
NotImplementedError
(
raise
NotImplementedError
(
'DownsampleFactorMaxGradGrad requires 4D input for now'
)
'DownsampleFactorMaxGradGrad requires 4D input for now'
)
...
@@ -958,14 +1092,14 @@ class DownsampleFactorMaxGradGrad(OpenMPOp):
...
@@ -958,14 +1092,14 @@ class DownsampleFactorMaxGradGrad(OpenMPOp):
pr
=
ggz
.
shape
[
-
2
]
pr
=
ggz
.
shape
[
-
2
]
# number of pooling output cols
# number of pooling output cols
pc
=
ggz
.
shape
[
-
1
]
pc
=
ggz
.
shape
[
-
1
]
ds0
,
ds1
=
self
.
d
s
ws0
,
ws1
=
w
s
st0
,
st1
=
s
elf
.
st
st0
,
st1
=
s
tride
pd0
,
pd1
=
self
.
padding
pd0
,
pd1
=
pad
img_rows
=
x
.
shape
[
-
2
]
+
2
*
pd0
img_rows
=
x
.
shape
[
-
2
]
+
2
*
pd0
img_cols
=
x
.
shape
[
-
1
]
+
2
*
pd1
img_cols
=
x
.
shape
[
-
1
]
+
2
*
pd1
# pad the image and its gradients
# pad the image and its gradients
if
self
.
padding
!=
(
0
,
0
)
:
if
pd0
!=
0
and
pd1
!=
0
:
y_padded
=
numpy
.
zeros
(
y_padded
=
numpy
.
zeros
(
(
x
.
shape
[
0
],
x
.
shape
[
1
],
img_rows
,
img_cols
),
(
x
.
shape
[
0
],
x
.
shape
[
1
],
img_rows
,
img_cols
),
dtype
=
x
.
dtype
)
+
x
.
min
()
-
1
dtype
=
x
.
dtype
)
+
x
.
min
()
-
1
...
@@ -982,10 +1116,10 @@ class DownsampleFactorMaxGradGrad(OpenMPOp):
...
@@ -982,10 +1116,10 @@ class DownsampleFactorMaxGradGrad(OpenMPOp):
for
k
in
xrange
(
x
.
shape
[
1
]):
for
k
in
xrange
(
x
.
shape
[
1
]):
for
r
in
xrange
(
pr
):
for
r
in
xrange
(
pr
):
row_st
=
r
*
st0
row_st
=
r
*
st0
row_end
=
builtins
.
min
(
row_st
+
d
s0
,
img_rows
)
row_end
=
builtins
.
min
(
row_st
+
w
s0
,
img_rows
)
for
c
in
xrange
(
pc
):
for
c
in
xrange
(
pc
):
col_st
=
c
*
st1
col_st
=
c
*
st1
col_end
=
builtins
.
min
(
col_st
+
d
s1
,
img_cols
)
col_end
=
builtins
.
min
(
col_st
+
w
s1
,
img_cols
)
for
row_ind
in
xrange
(
row_st
,
row_end
):
for
row_ind
in
xrange
(
row_st
,
row_end
):
for
col_ind
in
xrange
(
col_st
,
col_end
):
for
col_ind
in
xrange
(
col_st
,
col_end
):
if
(
maxout
[
n
,
k
,
r
,
c
]
==
y_padded
[
n
,
k
,
row_ind
,
col_ind
]):
if
(
maxout
[
n
,
k
,
r
,
c
]
==
y_padded
[
n
,
k
,
row_ind
,
col_ind
]):
...
@@ -995,38 +1129,63 @@ class DownsampleFactorMaxGradGrad(OpenMPOp):
...
@@ -995,38 +1129,63 @@ class DownsampleFactorMaxGradGrad(OpenMPOp):
return
[
in_shapes
[
1
]]
return
[
in_shapes
[
1
]]
def
grad
(
self
,
inp
,
grads
):
def
grad
(
self
,
inp
,
grads
):
x
,
maxout
,
ggx
=
inp
x
,
maxout
,
ggx
,
ws
,
stride
,
pad
=
inp
gz
,
=
grads
gz
,
=
grads
return
[
theano
.
tensor
.
zeros_like
(
x
),
return
[
theano
.
tensor
.
zeros_like
(
x
),
theano
.
tensor
.
zeros_like
(
maxout
),
theano
.
tensor
.
zeros_like
(
maxout
),
MaxPoolGrad
(
MaxPoolGrad
(
ignore_border
=
self
.
ignore_border
)(
x
,
maxout
,
gz
,
self
.
ds
,
ignore_border
=
self
.
ignore_border
,
ws
,
stride
,
pad
),
st
=
self
.
st
,
padding
=
self
.
padding
)(
x
,
maxout
,
gz
)]
DisconnectedType
()(),
DisconnectedType
()(),
DisconnectedType
()()]
def
connection_pattern
(
self
,
node
):
return
[[
1
],
[
1
],
[
1
],
[
0
],
[
0
],
[
0
]]
def
c_code
(
self
,
node
,
name
,
inp
,
out
,
sub
):
def
c_code
(
self
,
node
,
name
,
inp
,
out
,
sub
):
if
self
.
mode
!=
'max'
:
if
self
.
mode
!=
'max'
:
raise
theano
.
gof
.
utils
.
MethodNotDefined
()
raise
theano
.
gof
.
utils
.
MethodNotDefined
()
x
,
maxout
,
ggx
=
inp
x
,
maxout
,
ggx
,
ws
,
stride
,
pad
=
inp
z
,
=
out
# the grad of grad
z
,
=
out
# the grad of grad
fail
=
sub
[
'fail'
]
fail
=
sub
[
'fail'
]
ignore_border
=
int
(
self
.
ignore_border
)
ignore_border
=
int
(
self
.
ignore_border
)
ds0
,
ds1
=
self
.
ds
st0
,
st1
=
self
.
st
pd0
,
pd1
=
self
.
padding
if
self
.
openmp
:
if
self
.
openmp
:
omp_parallel
=
'#pragma omp parallel for private(r_st, r_end, c_st, c_end, maximum) schedule(static)'
omp_parallel
=
'#pragma omp parallel for private(r_st, r_end, c_st, c_end, maximum) schedule(static)'
else
:
else
:
omp_parallel
=
''
omp_parallel
=
''
return
"""
return
"""
int ws0, ws1, st0, st1, pd0, pd1;
int z_typenum = PyArray_ObjectType((PyObject*)
%(maxout)
s, 0);
int z_typenum = PyArray_ObjectType((PyObject*)
%(maxout)
s, 0);
int z_r, z_c;
int z_r, z_c;
int r, c; // shape of the padded_input
if(PyArray_DIM(
%(ws)
s, 0)!=2)
{
PyErr_SetString(PyExc_ValueError, "ws must be a vector of size 2");
%(fail)
s;
}
if(PyArray_DIM(
%(stride)
s, 0)!=2)
{
PyErr_SetString(PyExc_ValueError, "stride must be a vector of size 2");
%(fail)
s;
}
if(PyArray_DIM(
%(pad)
s, 0)!=2)
{
PyErr_SetString(PyExc_ValueError, "pad must be a vector of size 2");
%(fail)
s;
}
// Getting ws, stride and pad
ws0 = *((npy_intp*)PyArray_GETPTR1(
%(ws)
s, 0));
ws1 = *((npy_intp*)PyArray_GETPTR1(
%(ws)
s, 1));
st0 = *((npy_intp*)PyArray_GETPTR1(
%(stride)
s, 0));
st1 = *((npy_intp*)PyArray_GETPTR1(
%(stride)
s, 1));
pd0 = *((npy_intp*)PyArray_GETPTR1(
%(pad)
s, 0));
pd1 = *((npy_intp*)PyArray_GETPTR1(
%(pad)
s, 1));
z_r = PyArray_DIMS(
%(maxout)
s)[2];
z_r = PyArray_DIMS(
%(maxout)
s)[2];
z_c = PyArray_DIMS(
%(maxout)
s)[3];
z_c = PyArray_DIMS(
%(maxout)
s)[3];
int r, c; // shape of the padded_input
r = PyArray_DIMS(
%(x)
s)[2];
r = PyArray_DIMS(
%(x)
s)[2];
c = PyArray_DIMS(
%(x)
s)[3];
c = PyArray_DIMS(
%(x)
s)[3];
r +=
%(pd0)
s
* 2;
r +=
pd0
* 2;
c +=
%(pd1)
s
* 2;
c +=
pd1
* 2;
// allocating memory for output
// allocating memory for output
if ((!
%(z)
s)
if ((!
%(z)
s)
|| !PyArray_ISCONTIGUOUS(
%(z)
s)
|| !PyArray_ISCONTIGUOUS(
%(z)
s)
...
@@ -1050,23 +1209,23 @@ class DownsampleFactorMaxGradGrad(OpenMPOp):
...
@@ -1050,23 +1209,23 @@ class DownsampleFactorMaxGradGrad(OpenMPOp):
int b = t
%%
PyArray_DIMS(
%(x)
s)[0];
int b = t
%%
PyArray_DIMS(
%(x)
s)[0];
int k = t / PyArray_DIMS(
%(x)
s)[0];
int k = t / PyArray_DIMS(
%(x)
s)[0];
for(int i=0; i < z_r; i++){
for(int i=0; i < z_r; i++){
r_st = i *
%(st0)
s
;
r_st = i *
st0
;
r_end = r_st +
%(ds0)
s
;
r_end = r_st +
ws0
;
// skip the padding
// skip the padding
r_st = r_st <
%(pd0)
s ?
%(pd0)
s
: r_st;
r_st = r_st <
pd0 ? pd0
: r_st;
r_end = r_end > (r -
%(pd0)
s) ? r -
%(pd0)
s
: r_end;
r_end = r_end > (r -
pd0) ? r - pd0
: r_end;
// from padded_img space to img space
// from padded_img space to img space
r_st -=
%(pd0)
s
;
r_st -=
pd0
;
r_end -=
%(pd0)
s
;
r_end -=
pd0
;
for(int j=0; j<z_c; j++){
for(int j=0; j<z_c; j++){
c_st = j *
%(st1)
s
;
c_st = j *
st1
;
c_end = c_st +
%(ds1)
s
;
c_end = c_st +
ws1
;
// skip the padding
// skip the padding
c_st = c_st <
%(pd1)
s ?
%(pd1)
s
: c_st;
c_st = c_st <
pd1 ? pd1
: c_st;
c_end = c_end > (c -
%(pd1)
s) ? c -
%(pd1)
s
: c_end;
c_end = c_end > (c -
pd1) ? c - pd1
: c_end;
// from padding_img space into img space
// from padding_img space into img space
c_st -=
%(pd1)
s
;
c_st -=
pd1
;
c_end -=
%(pd1)
s
;
c_end -=
pd1
;
// the maximum value
// the maximum value
maximum = ((dtype_
%(maxout)
s*)(PyArray_GETPTR4(
%(maxout)
s,b,k,i,j)))[0];
maximum = ((dtype_
%(maxout)
s*)(PyArray_GETPTR4(
%(maxout)
s,b,k,i,j)))[0];
// z at this position
// z at this position
...
@@ -1090,4 +1249,4 @@ class DownsampleFactorMaxGradGrad(OpenMPOp):
...
@@ -1090,4 +1249,4 @@ class DownsampleFactorMaxGradGrad(OpenMPOp):
"""
%
locals
()
"""
%
locals
()
def
c_code_cache_version
(
self
):
def
c_code_cache_version
(
self
):
return
(
0
,
1
,
self
.
openmp
)
return
(
0
,
3
,
self
.
openmp
)
theano/tensor/signal/tests/old_pool_interface.pkl
0 → 100644
浏览文件 @
123d9007
File added
theano/tensor/signal/tests/test_pool.py
浏览文件 @
123d9007
from
__future__
import
absolute_import
,
print_function
,
division
from
__future__
import
absolute_import
,
print_function
,
division
from
nose.plugins.skip
import
SkipTest
from
itertools
import
product
from
itertools
import
product
import
os
import
unittest
import
unittest
from
six
import
reraise
from
six.moves
import
cPickle
import
six.moves.builtins
as
builtins
import
six.moves.builtins
as
builtins
import
sys
import
numpy
import
numpy
...
@@ -14,8 +19,6 @@ from theano.tensor.signal.pool import (Pool, pool_2d,
...
@@ -14,8 +19,6 @@ from theano.tensor.signal.pool import (Pool, pool_2d,
max_pool_2d_same_size
,
max_pool_2d_same_size
,
DownsampleFactorMaxGradGrad
)
DownsampleFactorMaxGradGrad
)
from
theano.tensor.signal.downsample
import
DownsampleFactorMaxGrad
from
theano
import
function
from
theano
import
function
...
@@ -197,9 +200,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -197,9 +200,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
utt
.
assert_allclose
(
output_val
,
numpy_output_val
)
utt
.
assert_allclose
(
output_val
,
numpy_output_val
)
# Pool op
# Pool op
maxpool_op
=
Pool
(
maxpoolshp
,
maxpool_op
=
Pool
(
ignore_border
=
ignore_border
,
ignore_border
=
ignore_border
,
mode
=
mode
)(
images
,
maxpoolshp
)
mode
=
mode
)(
images
)
output_shape
=
Pool
.
out_shape
(
imval
.
shape
,
maxpoolshp
,
output_shape
=
Pool
.
out_shape
(
imval
.
shape
,
maxpoolshp
,
ignore_border
=
ignore_border
)
ignore_border
=
ignore_border
)
...
@@ -245,9 +247,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -245,9 +247,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
"outshape is
%
s, calculated shape is
%
s"
"outshape is
%
s, calculated shape is
%
s"
%
(
outputshp
,
numpy_output_val
.
shape
))
%
(
outputshp
,
numpy_output_val
.
shape
))
maxpool_op
=
\
maxpool_op
=
\
Pool
(
maxpoolshp
,
Pool
(
ignore_border
=
ignore_border
,
mode
=
mode
)(
ignore_border
=
ignore_border
,
images
,
maxpoolshp
,
stride
)
st
=
stride
,
mode
=
mode
)(
images
)
f
=
function
([
images
],
maxpool_op
)
f
=
function
([
images
],
maxpool_op
)
output_val
=
f
(
imval
)
output_val
=
f
(
imval
)
utt
.
assert_allclose
(
output_val
,
numpy_output_val
)
utt
.
assert_allclose
(
output_val
,
numpy_output_val
)
...
@@ -286,9 +287,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -286,9 +287,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
"outshape is
%
s, calculated shape is
%
s"
"outshape is
%
s, calculated shape is
%
s"
%
(
outputshp
,
numpy_output_val
.
shape
))
%
(
outputshp
,
numpy_output_val
.
shape
))
maxpool_op
=
\
maxpool_op
=
\
Pool
(
maxpoolshp
,
Pool
(
ignore_border
=
ignore_border
,
mode
=
mode
)(
ignore_border
=
ignore_border
,
images
,
maxpoolshp
,
stride
)
st
=
stride
,
mode
=
mode
)(
images
)
f
=
function
([
images
],
maxpool_op
)
f
=
function
([
images
],
maxpool_op
)
output_val
=
f
(
imval
)
output_val
=
f
(
imval
)
utt
.
assert_allclose
(
output_val
,
numpy_output_val
)
utt
.
assert_allclose
(
output_val
,
numpy_output_val
)
...
@@ -315,10 +315,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -315,10 +315,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
numpy_output_val
=
self
.
numpy_max_pool_2d_stride_padding
(
numpy_output_val
=
self
.
numpy_max_pool_2d_stride_padding
(
imval
,
maxpoolsize
,
ignore_border
,
imval
,
maxpoolsize
,
ignore_border
,
stridesize
,
paddingsize
,
mode
)
stridesize
,
paddingsize
,
mode
)
maxpool_op
=
Pool
(
maxpool_op
=
Pool
(
ignore_border
=
ignore_border
,
mode
=
mode
)(
maxpoolsize
,
images
,
maxpoolsize
,
stridesize
,
paddingsize
)
ignore_border
=
ignore_border
,
st
=
stridesize
,
padding
=
paddingsize
,
mode
=
mode
)(
images
)
f
=
function
([
images
],
maxpool_op
)
f
=
function
([
images
],
maxpool_op
)
output_val
=
f
(
imval
)
output_val
=
f
(
imval
)
utt
.
assert_allclose
(
output_val
,
numpy_output_val
)
utt
.
assert_allclose
(
output_val
,
numpy_output_val
)
...
@@ -340,12 +338,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -340,12 +338,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
paddingsize
=
paddingsizes
[
i
]
paddingsize
=
paddingsizes
[
i
]
def
mp
(
input
):
def
mp
(
input
):
return
Pool
(
return
Pool
(
ignore_border
=
True
,
mode
=
mode
)(
maxpoolsize
,
ignore_border
=
True
,
input
,
maxpoolsize
,
stridesize
,
paddingsize
)
st
=
stridesize
,
padding
=
paddingsize
,
mode
=
mode
,
)(
input
)
utt
.
verify_grad
(
mp
,
[
imval
],
rng
=
rng
)
utt
.
verify_grad
(
mp
,
[
imval
],
rng
=
rng
)
def
test_DownsampleFactorMax_grad
(
self
):
def
test_DownsampleFactorMax_grad
(
self
):
...
@@ -361,9 +355,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -361,9 +355,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
'average_inc_pad'
,
'average_inc_pad'
,
'average_exc_pad'
]):
'average_exc_pad'
]):
def
mp
(
input
):
def
mp
(
input
):
return
Pool
(
maxpoolshp
,
return
Pool
(
ignore_border
=
ignore_border
,
mode
=
mode
)(
ignore_border
=
ignore_border
,
input
,
maxpoolshp
)
mode
=
mode
)(
input
)
utt
.
verify_grad
(
mp
,
[
imval
],
rng
=
rng
)
utt
.
verify_grad
(
mp
,
[
imval
],
rng
=
rng
)
def
test_DownsampleFactorMax_grad_st
(
self
):
def
test_DownsampleFactorMax_grad_st
(
self
):
...
@@ -381,9 +374,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -381,9 +374,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
'average_exc_pad'
],
'average_exc_pad'
],
stridesizes
):
stridesizes
):
def
mp
(
input
):
def
mp
(
input
):
return
Pool
(
maxpoolshp
,
return
Pool
(
ignore_border
=
ignore_border
,
mode
=
mode
)(
ignore_border
=
ignore_border
,
input
,
maxpoolshp
,
stride
)
st
=
stride
,
mode
=
mode
)(
input
)
utt
.
verify_grad
(
mp
,
[
imval
],
rng
=
rng
)
utt
.
verify_grad
(
mp
,
[
imval
],
rng
=
rng
)
def
test_DownsampleFactorMax_grad_st_extra
(
self
):
def
test_DownsampleFactorMax_grad_st_extra
(
self
):
...
@@ -404,10 +396,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -404,10 +396,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
maxpoolshp
=
maxpoolshps
[
indx
]
maxpoolshp
=
maxpoolshps
[
indx
]
for
ignore_border
in
[
True
,
False
]:
for
ignore_border
in
[
True
,
False
]:
def
mp
(
input
):
def
mp
(
input
):
return
Pool
(
maxpoolshp
,
return
Pool
(
ignore_border
=
ignore_border
,
mode
=
mode
)(
ignore_border
=
ignore_border
,
input
,
maxpoolshp
,
stride
)
st
=
stride
,
mode
=
mode
)(
input
)
utt
.
verify_grad
(
mp
,
[
imval
],
rng
=
rng
)
utt
.
verify_grad
(
mp
,
[
imval
],
rng
=
rng
)
def
test_DownsampleFactorMaxGrad_grad
(
self
):
def
test_DownsampleFactorMaxGrad_grad
(
self
):
...
@@ -426,11 +416,9 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -426,11 +416,9 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
grad_val
=
rng
.
rand
(
*
grad_shape
)
*
10.0
grad_val
=
rng
.
rand
(
*
grad_shape
)
*
10.0
def
mp
(
input
,
grad
):
def
mp
(
input
,
grad
):
out
=
Pool
(
out
=
Pool
(
ignore_border
=
ignore_border
)(
input
,
maxpoolshp
)
maxpoolshp
,
ignore_border
=
ignore_border
)(
input
)
grad_op
=
MaxPoolGrad
(
ignore_border
=
ignore_border
)
grad_op
=
MaxPoolGrad
(
return
grad_op
(
input
,
out
,
grad
,
maxpoolshp
)
maxpoolshp
,
ignore_border
=
ignore_border
)
return
grad_op
(
input
,
out
,
grad
)
utt
.
verify_grad
(
mp
,
[
imval
,
grad_val
],
rng
=
rng
)
utt
.
verify_grad
(
mp
,
[
imval
,
grad_val
],
rng
=
rng
)
...
@@ -451,9 +439,9 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -451,9 +439,9 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
grad_val
=
rng
.
rand
(
*
grad_shape
)
*
10.0
grad_val
=
rng
.
rand
(
*
grad_shape
)
*
10.0
def
mp
(
input
,
grad
):
def
mp
(
input
,
grad
):
grad_op
=
AveragePoolGrad
(
grad_op
=
AveragePoolGrad
(
ignore_border
=
ignore_border
,
avgpoolshp
,
ignore_border
=
ignore_border
,
mode
=
mode
)
mode
=
mode
)
return
grad_op
(
input
,
grad
)
return
grad_op
(
input
,
grad
,
avgpoolshp
)
utt
.
verify_grad
(
mp
,
[
imval
,
grad_val
],
rng
=
rng
)
utt
.
verify_grad
(
mp
,
[
imval
,
grad_val
],
rng
=
rng
)
...
@@ -474,13 +462,10 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -474,13 +462,10 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
grad_val
=
rng
.
rand
(
*
grad_shape
)
grad_val
=
rng
.
rand
(
*
grad_shape
)
def
mp
(
input
,
grad
):
def
mp
(
input
,
grad
):
out
=
Pool
(
out
=
Pool
(
ignore_border
=
ignore_border
)(
maxpoolshp
,
ignore_border
=
ignore_border
,
input
,
maxpoolshp
,
stride
)
st
=
stride
)(
input
)
grad_op
=
MaxPoolGrad
(
ignore_border
=
ignore_border
)
grad_op
=
MaxPoolGrad
(
return
grad_op
(
input
,
out
,
grad
,
maxpoolshp
,
stride
)
maxpoolshp
,
ignore_border
=
ignore_border
,
st
=
stride
)
return
grad_op
(
input
,
out
,
grad
)
utt
.
verify_grad
(
mp
,
[
imval
,
grad_val
],
rng
=
rng
)
utt
.
verify_grad
(
mp
,
[
imval
,
grad_val
],
rng
=
rng
)
...
@@ -503,9 +488,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -503,9 +488,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
def
mp
(
input
,
grad
):
def
mp
(
input
,
grad
):
grad_op
=
AveragePoolGrad
(
grad_op
=
AveragePoolGrad
(
avgpoolshp
,
ignore_border
=
ignore_border
,
ignore_border
=
ignore_border
,
mode
=
mode
)
st
=
stride
,
mode
=
mode
)
return
grad_op
(
input
,
grad
,
avgpoolshp
,
stride
)
return
grad_op
(
input
,
grad
)
utt
.
verify_grad
(
mp
,
[
imval
,
grad_val
],
rng
=
rng
)
utt
.
verify_grad
(
mp
,
[
imval
,
grad_val
],
rng
=
rng
)
...
@@ -531,13 +515,10 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -531,13 +515,10 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
grad_val
=
rng
.
rand
(
*
grad_shape
)
grad_val
=
rng
.
rand
(
*
grad_shape
)
def
mp
(
input
,
grad
):
def
mp
(
input
,
grad
):
out
=
Pool
(
out
=
Pool
(
ignore_border
=
ignore_border
)(
input
,
maxpoolshp
,
maxpoolshp
,
ignore_border
=
ignore_border
,
stride
)
st
=
stride
)(
input
)
grad_op
=
MaxPoolGrad
(
ignore_border
=
ignore_border
)
grad_op
=
MaxPoolGrad
(
return
grad_op
(
input
,
out
,
grad
,
maxpoolshp
,
stride
)
maxpoolshp
,
ignore_border
=
ignore_border
,
st
=
stride
)
return
grad_op
(
input
,
out
,
grad
)
# skip the grad verification when the output is empty
# skip the grad verification when the output is empty
if
numpy
.
prod
(
grad_shape
)
==
0
:
if
numpy
.
prod
(
grad_shape
)
==
0
:
...
@@ -567,10 +548,9 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -567,10 +548,9 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
grad_val
=
rng
.
rand
(
*
grad_shape
)
grad_val
=
rng
.
rand
(
*
grad_shape
)
def
mp
(
input
,
grad
):
def
mp
(
input
,
grad
):
grad_op
=
AveragePoolGrad
(
grad_op
=
AveragePoolGrad
(
ignore_border
=
ignore_border
,
avgpoolshp
,
ignore_border
=
ignore_border
,
mode
=
mode
)
st
=
stride
,
mode
=
mode
)
return
grad_op
(
input
,
grad
,
avgpoolshp
,
stride
)
return
grad_op
(
input
,
grad
)
# skip the grad verification when the output is empty
# skip the grad verification when the output is empty
if
numpy
.
prod
(
grad_shape
)
==
0
:
if
numpy
.
prod
(
grad_shape
)
==
0
:
...
@@ -598,14 +578,11 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -598,14 +578,11 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
grad_val
=
rng
.
rand
(
*
grad_shape
)
*
10.0
grad_val
=
rng
.
rand
(
*
grad_shape
)
*
10.0
def
mp
(
input
,
grad
):
def
mp
(
input
,
grad
):
out
=
Pool
(
out
=
Pool
(
ignore_border
=
True
)(
input
,
maxpoolsize
,
stridesize
,
maxpoolsize
,
ignore_border
=
True
,
paddingsize
)
st
=
stridesize
,
grad_op
=
MaxPoolGrad
(
ignore_border
=
True
)
padding
=
paddingsize
,
return
grad_op
(
input
,
out
,
grad
,
maxpoolsize
,
stridesize
,
)(
input
)
paddingsize
)
grad_op
=
MaxPoolGrad
(
maxpoolsize
,
ignore_border
=
True
,
st
=
stridesize
,
padding
=
paddingsize
)
return
grad_op
(
input
,
out
,
grad
)
utt
.
verify_grad
(
mp
,
[
imval
,
grad_val
],
rng
=
rng
)
utt
.
verify_grad
(
mp
,
[
imval
,
grad_val
],
rng
=
rng
)
def
test_AveragePoolPaddingStride_grad_grad
(
self
):
def
test_AveragePoolPaddingStride_grad_grad
(
self
):
...
@@ -630,10 +607,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -630,10 +607,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
grad_val
=
rng
.
rand
(
*
grad_shape
)
*
10.0
grad_val
=
rng
.
rand
(
*
grad_shape
)
*
10.0
def
mp
(
input
,
grad
):
def
mp
(
input
,
grad
):
grad_op
=
AveragePoolGrad
(
avgpoolsize
,
ignore_border
=
True
,
grad_op
=
AveragePoolGrad
(
ignore_border
=
True
,
mode
=
mode
)
st
=
stridesize
,
padding
=
paddingsize
,
return
grad_op
(
input
,
grad
,
avgpoolsize
,
stridesize
,
paddingsize
)
mode
=
mode
)
return
grad_op
(
input
,
grad
)
utt
.
verify_grad
(
mp
,
[
imval
,
grad_val
],
rng
=
rng
)
utt
.
verify_grad
(
mp
,
[
imval
,
grad_val
],
rng
=
rng
)
def
test_DownsampleFactorMax_hessian
(
self
):
def
test_DownsampleFactorMax_hessian
(
self
):
...
@@ -669,16 +644,12 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -669,16 +644,12 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
paddingsize
=
paddingsizes
[
i
]
paddingsize
=
paddingsizes
[
i
]
def
mp
(
input1
,
input2
):
def
mp
(
input1
,
input2
):
pooled_out
=
Pool
(
op1
=
Pool
(
ignore_border
=
True
)
maxpoolsize
,
ignore_border
=
True
,
pooled_out
=
op1
(
input1
,
maxpoolsize
,
stride
=
stridesize
,
st
=
stridesize
,
pad
=
paddingsize
)
padding
=
paddingsize
,
op2
=
DownsampleFactorMaxGradGrad
(
ignore_border
=
True
)
)(
input1
)
out
=
op2
(
input1
,
pooled_out
,
input2
,
ws
=
maxpoolsize
,
out
=
DownsampleFactorMaxGradGrad
(
stride
=
stridesize
,
pad
=
paddingsize
)
ds
=
maxpoolsize
,
ignore_border
=
True
,
st
=
stridesize
,
padding
=
paddingsize
)(
input1
,
pooled_out
,
input2
)
return
out
return
out
utt
.
verify_grad
(
mp
,
[
imval1
,
imval2
],
rng
=
rng
)
utt
.
verify_grad
(
mp
,
[
imval1
,
imval2
],
rng
=
rng
)
...
@@ -813,19 +784,18 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -813,19 +784,18 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
continue
continue
# checking shapes generated by Pool
# checking shapes generated by Pool
self
.
_compile_and_check
([
image
],
self
.
_compile_and_check
([
image
],
[
Pool
(
maxpoolshp
,
[
Pool
(
ignore_border
=
ignore_border
)
ignore_border
=
ignore_border
,
(
image
,
maxpoolshp
,
pad
=
padding
)],
padding
=
padding
)(
image
)],
[
image_val
],
Pool
)
[
image_val
],
Pool
)
# checking shapes generated by MaxPoolGrad
# checking shapes generated by MaxPoolGrad
maxout_val
=
rng
.
rand
(
*
out_shapes
[
k
][
i
][
j
])
maxout_val
=
rng
.
rand
(
*
out_shapes
[
k
][
i
][
j
])
gz_val
=
rng
.
rand
(
*
out_shapes
[
k
][
i
][
j
])
gz_val
=
rng
.
rand
(
*
out_shapes
[
k
][
i
][
j
])
self
.
_compile_and_check
([
image
,
maxout
,
gz
],
self
.
_compile_and_check
([
image
,
maxout
,
gz
],
[
MaxPoolGrad
(
maxpoolshp
,
[
MaxPoolGrad
(
ignore_border
=
ignore_border
,
ignore_border
=
ignore_border
)
padding
=
padding
)
(
image
,
maxout
,
gz
,
maxpoolshp
,
(
image
,
maxout
,
gz
)],
pad
=
padding
)],
[
image_val
,
maxout_val
,
gz_val
],
[
image_val
,
maxout_val
,
gz_val
],
MaxPoolGrad
,
MaxPoolGrad
,
warn
=
False
)
warn
=
False
)
...
@@ -835,33 +805,75 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
...
@@ -835,33 +805,75 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
image_val
=
rng
.
rand
(
4
,
6
,
1
,
1
)
image_val
=
rng
.
rand
(
4
,
6
,
1
,
1
)
self
.
_compile_and_check
(
self
.
_compile_and_check
(
[
image
],
[
image
],
[
Pool
((
2
,
2
),
[
Pool
(
ignore_border
=
True
)(
image
,
(
2
,
2
),
pad
=
(
0
,
0
))],
ignore_border
=
True
,
padding
=
(
0
,
0
))(
image
)],
[
image_val
],
Pool
)
[
image_val
],
Pool
)
def
test_DownsampleFactorMaxGrad
(
self
):
def
test_pooling_with_tensor_vars
(
self
):
im
=
theano
.
tensor
.
tensor4
()
x
=
tensor
.
ftensor4
()
maxout
=
theano
.
tensor
.
tensor4
()
window_size
=
tensor
.
ivector
()
grad
=
theano
.
tensor
.
tensor4
()
stride
=
tensor
.
ivector
()
padding
=
tensor
.
ivector
()
data
=
numpy
.
random
.
normal
(
0
,
1
,
(
1
,
1
,
5
,
5
))
.
astype
(
'float32'
)
# checking variable params vs fixed params
for
ignore_border
in
[
True
,
False
]:
for
mode
in
[
'max'
,
'sum'
,
'average_inc_pad'
,
'average_exc_pad'
]:
for
mode
in
[
'max'
,
'sum'
,
'average_inc_pad'
,
'average_exc_pad'
]:
f
=
theano
.
function
([
im
,
maxout
,
grad
],
y
=
pool_2d
(
x
,
window_size
,
ignore_border
,
stride
,
padding
,
DownsampleFactorMaxGrad
(
ds
=
(
3
,
3
),
mode
)
ignore_border
=
False
,
dx
=
theano
.
gradient
.
grad
(
y
.
sum
(),
x
)
mode
=
mode
)(
im
,
maxout
,
grad
),
var_fct
=
theano
.
function
([
x
,
window_size
,
stride
,
padding
],
on_unused_input
=
'ignore'
)
[
y
,
dx
])
for
ws
in
(
4
,
2
,
5
):
if
mode
==
'max'
:
for
st
in
(
2
,
3
):
assert
any
(
isinstance
(
n
.
op
,
MaxPoolGrad
)
for
pad
in
(
0
,
1
):
for
n
in
f
.
maker
.
fgraph
.
toposort
())
if
(
pad
>
st
or
st
>
ws
or
assert
not
any
(
isinstance
(
n
.
op
,
AveragePoolGrad
)
(
pad
!=
0
and
not
ignore_border
)
or
for
n
in
f
.
maker
.
fgraph
.
toposort
())
(
mode
==
'average_exc_pad'
and
pad
!=
0
)):
else
:
continue
assert
not
any
(
isinstance
(
n
.
op
,
MaxPoolGrad
)
y
=
pool_2d
(
x
,
(
ws
,
ws
),
ignore_border
,
(
st
,
st
),
for
n
in
f
.
maker
.
fgraph
.
toposort
())
(
pad
,
pad
),
mode
)
assert
any
(
isinstance
(
n
.
op
,
AveragePoolGrad
)
dx
=
theano
.
gradient
.
grad
(
y
.
sum
(),
x
)
for
n
in
f
.
maker
.
fgraph
.
toposort
())
fix_fct
=
theano
.
function
([
x
],
[
y
,
dx
])
var_y
,
var_dx
=
var_fct
(
data
,
(
ws
,
ws
),
(
st
,
st
),
(
pad
,
pad
))
fix_y
,
fix_dx
=
fix_fct
(
data
)
utt
.
assert_allclose
(
var_y
,
fix_y
)
utt
.
assert_allclose
(
var_dx
,
fix_dx
)
def
test_old_pool_interface
(
self
):
if
sys
.
version_info
[
0
]
!=
3
:
# Only tested with python 3 because of pickling issues.
raise
SkipTest
(
'Skip old pool interface with python 2.x'
)
# 1. Load the old version
testfile_dir
=
os
.
path
.
dirname
(
os
.
path
.
realpath
(
__file__
))
fname
=
'old_pool_interface.pkl'
with
open
(
os
.
path
.
join
(
testfile_dir
,
fname
),
'rb'
)
as
fp
:
try
:
old_fct
=
cPickle
.
load
(
fp
,
encoding
=
'latin1'
)
except
ImportError
:
# Windows sometimes fail with nonsensical errors like:
# ImportError: No module named type
# ImportError: No module named copy_reg
# when "type" and "copy_reg" are builtin modules.
if
sys
.
platform
==
'win32'
:
exc_type
,
exc_value
,
exc_trace
=
sys
.
exc_info
()
reraise
(
SkipTest
,
exc_value
,
exc_trace
)
raise
# 2. Create the new version
x
=
theano
.
tensor
.
ftensor4
()
y
=
pool_2d
(
x
,
(
2
,
2
),
mode
=
'max'
,
ignore_border
=
True
)
z
=
pool_2d
(
x
,
(
2
,
2
),
mode
=
'average_exc_pad'
,
ignore_border
=
True
)
dy_dx
=
theano
.
gradient
.
grad
(
y
.
sum
(),
x
)
dz_dx
=
theano
.
gradient
.
grad
(
z
.
sum
(),
x
)
new_fct
=
theano
.
function
([
x
],
[
y
,
z
,
dy_dx
,
dz_dx
])
# 3. Assert that the answer is the same
rng
=
numpy
.
random
.
RandomState
(
utt
.
fetch_seed
())
image_val
=
rng
.
rand
(
4
,
6
,
7
,
9
)
.
astype
(
numpy
.
float32
)
old_out
=
old_fct
(
image_val
)
new_out
=
new_fct
(
image_val
)
for
o
,
n
in
zip
(
old_out
,
new_out
):
utt
.
assert_allclose
(
o
,
n
)
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
unittest
.
main
()
unittest
.
main
()
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论