Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
6888f0f3
提交
6888f0f3
authored
1月 14, 2008
作者:
Olivier Breuleux
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
bla
上级
6dcf210b
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
185 行增加
和
114 行删除
+185
-114
compile.py
compile.py
+12
-5
core.py
core.py
+141
-79
opt.py
opt.py
+12
-12
test.py
test.py
+20
-18
没有找到文件。
compile.py
浏览文件 @
6888f0f3
...
...
@@ -51,14 +51,21 @@ class prog(gof.Prog):
for
input
in
self
.
env
.
inputs
:
if
input
.
data
is
core
.
UNCOMPUTED
:
raise
Exception
(
"You must provide a value for input
%
s!"
%
input
)
for
orphan
in
self
.
env
.
orphans
():
if
orphan
.
data
is
core
.
UNCOMPUTED
:
raise
Exception
(
"Orphan
%
s is uncomputed but needed to calculate the function. "
%
input
+
\
"Try calling prog.compute_orphans() or set it manually."
)
self
.
compute_orphans
()
# for orphan in self.env.orphans():
# if orphan.data is core.UNCOMPUTED:
# raise Exception("Orphan %s is uncomputed but needed to calculate the function. " % orphan + \
# "Try calling prog.compute_orphans() or set it manually.")
return
gof
.
Prog
.
__call__
(
self
)
def
compute_orphans
(
self
):
raise
NotImplementedError
for
orphan
in
self
.
env
.
orphans
():
if
orphan
.
data
is
core
.
UNCOMPUTED
:
if
orphan
.
owner
:
orphan
.
owner
.
compute
()
else
:
raise
Exception
(
"Orphan
%
s is uncomputed but needed to calculate the function."
%
orphan
)
def
single
(
*
outputs
):
...
...
core.py
浏览文件 @
6888f0f3
...
...
@@ -108,18 +108,9 @@ def literal(x):
inplace
=
gof
.
Destroyer
view
=
gof
.
Viewer
def
assert_same_shapes
(
impl
):
def
ret
(
x
,
*
rest
):
shape
=
x
.
shape
for
other
in
rest
:
if
other
.
shape
!=
shape
:
raise
TypeError
(
"The dimensions of the inputs do not match."
)
return
impl
(
x
,
*
rest
)
return
ret
class
omega_op
(
gof
.
PythonOp
):
broadcast_op
=
False
forbid_broadcast
=
False
@staticmethod
def
__clsinit__
(
cls
,
name
,
bases
,
dct
):
...
...
@@ -129,9 +120,9 @@ class omega_op(gof.PythonOp):
grad
=
grad
.
im_func
cls
.
grad
=
staticmethod
(
grad
)
# adjust impl
if
cls
.
broadcast_op
:
cls
.
impl
=
assert_same_shapes
(
cls
.
impl
)
#
# adjust impl
# if cls.forbid_broadcast
:
#
cls.impl = assert_same_shapes(cls.impl)
# make impl a static method
gof
.
PythonOp
.
__clsinit__
(
cls
,
name
,
bases
,
dct
)
...
...
@@ -154,13 +145,15 @@ class omega_op(gof.PythonOp):
return
UNDEFINED
def
scalar_switch
(
x
,
y
,
normal_f
,
scalar_f
):
# x, y = wrap(x), wrap(y)
# if x.constant and not x.data.shape:
# return scalar_f(y, x)
# if y.constant and not y.data.shape:
# return scalar_f(x, y)
return
normal_f
(
x
,
y
)
def
scalar_switch
(
normal_f
,
scalar_f
,
scalar_f_reverse
):
def
f
(
x
,
y
):
x
,
y
=
wrap
(
x
),
wrap
(
y
)
if
x
.
constant
and
not
x
.
data
.
shape
:
return
scalar_f_reverse
(
y
,
x
)
if
y
.
constant
and
not
y
.
data
.
shape
:
return
scalar_f
(
x
,
y
)
return
normal_f
(
x
,
y
)
return
f
class
NumpyR
(
gof
.
PythonR
):
...
...
@@ -173,25 +166,25 @@ class NumpyR(gof.PythonR):
else
:
self
.
data
=
numpy
.
array
(
value
)
def
__add__
(
self
,
y
):
return
scalar_switch
(
self
,
y
,
add
,
add_scalar
)
def
__radd__
(
self
,
x
):
return
scalar_switch
(
x
,
self
,
add
,
add_scalar
)
def
__iadd__
(
self
,
y
):
return
scalar_switch
(
self
,
y
,
iadd
,
iadd_scalar
)
def
__add__
(
self
,
y
):
return
add
(
self
,
y
)
def
__radd__
(
self
,
x
):
return
add
(
x
,
self
)
def
__iadd__
(
self
,
y
):
return
iadd
(
self
,
y
)
def
__sub__
(
self
,
y
):
return
s
calar_switch
(
self
,
y
,
sub
,
sub_scalar
)
def
__rsub__
(
self
,
x
):
return
s
calar_switch
(
x
,
self
,
sub
,
sub_scalar
)
def
__isub__
(
self
,
y
):
return
scalar_switch
(
self
,
y
,
isub
,
isub_scalar
)
def
__sub__
(
self
,
y
):
return
s
ub
(
self
,
y
)
def
__rsub__
(
self
,
x
):
return
s
ub
(
x
,
self
)
def
__isub__
(
self
,
y
):
return
isub
(
self
,
y
)
def
__mul__
(
self
,
y
):
return
scalar_switch
(
self
,
y
,
mul
,
scale
)
def
__rmul__
(
self
,
x
):
return
scalar_switch
(
x
,
self
,
mul
,
scale
)
def
__imul__
(
self
,
y
):
return
scalar_switch
(
self
,
y
,
imul
,
iscale
)
def
__mul__
(
self
,
y
):
return
mul
(
self
,
y
)
def
__rmul__
(
self
,
x
):
return
mul
(
x
,
self
)
def
__imul__
(
self
,
y
):
return
imul
(
self
,
y
)
def
__div__
(
self
,
y
):
return
scalar_switch
(
self
,
y
,
div
,
inv_scale
)
def
__rdiv__
(
self
,
x
):
return
scalar_switch
(
x
,
self
,
div
,
inv_scale
)
def
__idiv__
(
self
,
y
):
return
scalar_switch
(
self
,
y
,
idiv
,
iinv_scale
)
def
__div__
(
self
,
y
):
return
div
(
self
,
y
)
def
__rdiv__
(
self
,
x
):
return
div
(
x
,
self
)
def
__idiv__
(
self
,
y
):
return
idiv
(
self
,
y
)
def
__pow__
(
self
,
y
):
return
scalar_switch
(
self
,
y
,
pow_elemwise
,
pow
)
def
__rpow__
(
self
,
x
):
return
scalar_switch
(
x
,
self
,
pow_elemwise
,
pow
)
def
__ipow__
(
self
,
y
):
return
scalar_switch
(
self
,
y
,
ipow_elemwise
,
ipow
)
def
__pow__
(
self
,
y
):
return
pow
(
self
,
y
)
def
__rpow__
(
self
,
x
):
return
pow
(
x
,
self
)
def
__ipow__
(
self
,
y
):
return
ipow
(
self
,
y
)
def
__neg__
(
self
):
return
neg
(
self
)
...
...
@@ -215,24 +208,48 @@ zeros = wrap_producer(numpy.zeros)
ones
=
wrap_producer
(
numpy
.
ones
)
# Wrapper to ensure that all inputs to the function impl have the same size (foils numpy's broadcasting)
def
assert_same_shapes
(
impl
):
def
ret
(
x
,
*
rest
):
shape
=
x
.
shape
for
other
in
rest
:
if
other
.
shape
!=
shape
:
raise
TypeError
(
"The dimensions of the inputs do not match."
)
return
impl
(
x
,
*
rest
)
return
ret
# Wrapper to ensure that the last input to impl is a scalar
def
tensor_scalar_op
(
impl
):
def
ret
(
x
,
a
):
if
a
.
shape
:
raise
TypeError
(
"The second argument to
%
s must be a scalar."
%
impl
)
return
impl
(
x
,
a
)
return
ret
## Addition ##
class
proto_add
(
omega_op
):
broadcast_op
=
True
class
proto_add_elemwise
(
omega_op
):
def
grad
(
x
,
y
,
gz
):
return
gz
class
add
(
proto_add
):
impl
=
numpy
.
ndarray
.
__add__
class
add_elemwise
(
proto_add_elemwise
):
impl
=
assert_same_shapes
(
numpy
.
ndarray
.
__add__
)
class
iadd_elemwise
(
proto_add_elemwise
,
inplace
):
impl
=
assert_same_shapes
(
numpy
.
ndarray
.
__iadd__
)
class
iadd
(
proto_add
,
inplace
):
impl
=
numpy
.
ndarray
.
__iadd__
class
add_scalar
(
omega_op
):
impl
=
numpy
.
ndarray
.
__add__
class
proto_add_scalar
(
omega_op
):
def
grad
(
x
,
a
,
gz
):
return
gz
,
sum
(
gz
)
class
add_scalar
(
proto_add_scalar
):
impl
=
tensor_scalar_op
(
numpy
.
ndarray
.
__add__
)
class
iadd_scalar
(
omega_op
,
inplace
):
impl
=
numpy
.
ndarray
.
__iadd__
class
iadd_scalar
(
proto_add_scalar
,
inplace
):
impl
=
tensor_scalar_op
(
numpy
.
ndarray
.
__iadd__
)
class
proto_twice
(
omega_op
):
...
...
@@ -251,39 +268,56 @@ class itwice(proto_twice, inplace):
## Subtraction ##
class
proto_sub
(
omega_op
):
class
proto_sub
_elemwise
(
omega_op
):
def
grad
(
x
,
y
,
gz
):
return
gz
,
-
gz
class
sub
(
proto_sub
):
impl
=
numpy
.
ndarray
.
__sub__
class
sub_elemwise
(
proto_sub_elemwise
):
impl
=
assert_same_shapes
(
numpy
.
ndarray
.
__sub__
)
class
isub_elemwise
(
proto_sub_elemwise
,
inplace
):
impl
=
assert_same_shapes
(
numpy
.
ndarray
.
__isub__
)
class
isub
(
proto_sub
,
inplace
):
impl
=
numpy
.
ndarray
.
__isub__
def
sub_scalar_r
(
x
,
a
):
return
add_scalar
(
x
,
-
a
)
class
sub_scalar
(
omega_op
):
impl
=
numpy
.
ndarray
.
__sub__
def
sub_scalar_l
(
x
,
a
):
return
add_scalar
(
-
x
,
a
)
class
isub_scalar
(
omega_op
,
inplace
):
impl
=
numpy
.
ndarray
.
__isub__
def
isub_scalar_r
(
x
,
a
):
return
iadd_scalar
(
x
,
-
a
)
def
isub_scalar_l
(
x
,
a
):
return
iadd_scalar
(
-
x
,
a
)
## Element-wise multiplication ##
class
proto_mul
(
omega_op
):
class
proto_mul
_elemwise
(
omega_op
):
def
grad
(
x
,
y
,
gz
):
return
mul
(
y
,
gz
),
mul
(
x
,
gz
)
class
mul
(
proto_mul
):
impl
=
numpy
.
ndarray
.
__mul__
class
mul_elemwise
(
proto_mul_elemwise
):
impl
=
assert_same_shapes
(
numpy
.
ndarray
.
__mul__
)
class
imul_elemwise
(
proto_mul_elemwise
,
inplace
):
impl
=
assert_same_shapes
(
numpy
.
ndarray
.
__imul__
)
class
proto_scale
(
omega_op
):
def
grad
(
x
,
a
,
gz
):
return
scale
(
a
,
gz
),
sum
(
mul_elemwise
(
x
,
gz
))
class
scale
(
proto_scale
):
impl
=
tensor_scalar_op
(
numpy
.
ndarray
.
__mul__
)
class
i
mul
(
proto_mul
,
inplace
):
impl
=
numpy
.
ndarray
.
__imul__
class
i
scale
(
proto_scale
,
inplace
):
impl
=
tensor_scalar_op
(
numpy
.
ndarray
.
__imul__
)
class
proto_sqr
(
omega_op
):
def
grad
(
x
,
gz
):
return
scale
(
mul
(
x
,
gz
),
2.0
)
return
scale
(
mul
_elemwise
(
x
,
gz
),
2.0
)
class
sqr
(
proto_sqr
):
impl
=
lambda
x
:
numpy
.
multiply
(
x
,
x
)
...
...
@@ -311,47 +345,57 @@ class exp(omega_op):
## Element-wise division ##
class
proto_div
(
omega_op
):
class
proto_div
_elemwise
(
omega_op
):
def
grad
(
x
,
y
,
gz
):
return
div
(
gz
,
y
),
-
div
(
mul
(
x
,
gz
),
sqr
(
y
))
class
div
(
proto_div
):
impl
=
numpy
.
ndarray
.
__div__
class
div
_elemwise
(
proto_div_elemwise
):
impl
=
assert_same_shapes
(
numpy
.
ndarray
.
__div__
)
class
idiv
(
proto_div
,
inplace
):
impl
=
numpy
.
ndarray
.
__idiv__
class
idiv
_elemwise
(
proto_div_elemwise
,
inplace
):
impl
=
assert_same_shapes
(
numpy
.
ndarray
.
__idiv__
)
class
inv_scale
(
omega_op
):
impl
=
numpy
.
ndarray
.
__div__
class
iinv_scale
(
omega_op
,
inplace
):
impl
=
numpy
.
ndarray
.
__idiv__
def
div_scalar_r
(
x
,
a
):
return
scale
(
x
,
inv_elemwise
(
a
))
def
div_scalar_l
(
x
,
a
):
return
scale
(
inv_elemwise
(
x
),
a
)
## Scaling ##
def
idiv_scalar_r
(
x
,
a
):
return
iscale
(
x
,
inv_elemwise
(
a
))
class
proto_scale
(
omega_op
):
def
grad
(
x
,
a
,
gz
):
return
scale
(
a
,
gz
),
sum
(
mul
(
x
,
gz
))
def
idiv_scalar_l
(
x
,
a
):
return
iscale
(
inv_elemwise
(
x
),
a
)
class
scale
(
omega_op
):
impl
=
numpy
.
ndarray
.
__mul__
class
iscale
(
omega_op
,
inplace
):
impl
=
numpy
.
ndarray
.
__imul__
## Scaling ##
class
proto_neg
(
omega_op
):
def
grad
(
x
,
gz
):
return
-
gz
class
neg
(
omega_op
):
class
neg
(
proto_neg
):
impl
=
numpy
.
ndarray
.
__neg__
class
ineg
(
omega_op
,
inplace
):
class
ineg
(
proto_neg
,
inplace
):
impl
=
lambda
x
:
x
.
__imul__
(
-
1
)
class
proto_inv_elemwise
(
omega_op
):
def
grad
(
x
,
gz
):
raise
NotImplemented
class
inv_elemwise
(
omega_op
):
impl
=
lambda
x
:
1
/
x
class
iinv_elemwise
(
omega_op
,
inplace
):
def
impl
(
x
):
x
[:]
=
1
/
x
## Dot product ##
class
dot
(
omega_op
):
...
...
@@ -427,3 +471,21 @@ class sum(omega_op):
add
=
scalar_switch
(
add_elemwise
,
add_scalar
,
add_scalar
)
iadd
=
scalar_switch
(
iadd_elemwise
,
iadd_scalar
,
iadd_scalar
)
sub
=
scalar_switch
(
sub_elemwise
,
sub_scalar_r
,
sub_scalar_l
)
isub
=
scalar_switch
(
isub_elemwise
,
isub_scalar_r
,
isub_scalar_l
)
mul
=
scalar_switch
(
mul_elemwise
,
scale
,
scale
)
imul
=
scalar_switch
(
imul_elemwise
,
iscale
,
iscale
)
div
=
scalar_switch
(
div_elemwise
,
div_scalar_r
,
div_scalar_l
)
idiv
=
scalar_switch
(
idiv_elemwise
,
idiv_scalar_r
,
idiv_scalar_l
)
# pow = scalar_switch(pow_elemwise, pow_scalar_r, pow_scalar_l)
# ipow = scalar_switch(ipow_elemwise, ipow_scalar_r, ipow_scalar_l)
opt.py
浏览文件 @
6888f0f3
...
...
@@ -36,25 +36,25 @@ def export_opts(opts):
# List of optimizations to perform. They are listed in the order they are applied.
opts
=
[
[
'double_transpose_eliminator'
,
pattern_opt
((
transpose
,
(
transpose
,
'x'
)),
'x'
)],
#
['double_transpose_eliminator', pattern_opt((transpose, (transpose, 'x')),
#
'x')],
[
'addxx_to_twice'
,
pattern_opt
((
add
,
'x'
,
'x'
),
(
twice
,
'x'
))],
# ['addxx_to_twice', pattern_opt((add_elemwise
, 'x', 'x'),
#
(twice, 'x'))],
[
'twice_to_itwice'
,
op_sub
(
twice
,
itwice
)],
#
['twice_to_itwice', op_sub(twice, itwice)],
[
'mulxx_to_sqr'
,
pattern_opt
((
mul
,
'x'
,
'x'
),
(
sqr
,
'x'
))],
# ['mulxx_to_sqr', pattern_opt((mul_elemwise
, 'x', 'x'),
#
(sqr, 'x'))],
[
'sqr_to_isqr'
,
op_sub
(
sqr
,
isqr
)],
#
['sqr_to_isqr', op_sub(sqr, isqr)],
[
'add_to_iadd'
,
op_sub
(
add
,
iadd
)],
# ['add_to_iadd', op_sub(add_elemwise, iadd_elemwise
)],
[
'add_to_iadd_reverse'
,
pattern_opt
((
add
,
'x'
,
'y'
),
(
iadd
,
'y'
,
'x'
))],
# ['add_to_iadd_reverse', pattern_opt((add_elemwise
, 'x', 'y'),
# (iadd_elemwise
, 'y', 'x'))],
[
'remove_copies'
,
gof
.
OpRemover
(
array_copy
)],
#
['remove_copies', gof.OpRemover(array_copy)],
[
None
,
gof
.
DummyRemover
]
# has to be at the end
...
...
test.py
浏览文件 @
6888f0f3
...
...
@@ -154,39 +154,41 @@ class sigmoid(core.omega_op):
def
grad
(
x
,
gz
):
return
gz
*
sigmoid
(
x
)
*
(
1
-
sigmoid
(
x
))
numpy
.
random
.
seed
(
1
)
#
x = core.zeros((1, 10))
#
w = core.input(numpy.random.rand(10, 15))
x
=
core
.
zeros
((
1
,
10
))
w
=
core
.
input
(
numpy
.
random
.
rand
(
10
,
15
))
x
=
numpy
.
zeros
((
1
,
10
))
w
=
numpy
.
random
.
rand
(
10
,
15
)
#
x = numpy.zeros((1, 10))
#
w = numpy.random.rand(10, 15)
#print x.data, w.data
import
inspect
#
import inspect
def
omega_compile
(
f
):
args
,
varargs
,
kwargs
,
defaults
=
inspect
.
getargspec
(
f
)
assert
not
varargs
assert
not
kwargs
def
ret
(
*
args
):
outputs
=
core
.
build
(
f
,
*
args
)
return
compile
.
prog
(
args
,
outputs
)
return
ret
# def omega_compile(f):
# args, varargs, kwargs, defaults = inspect.getargspec(f)
# assert not varargs
# assert not kwargs
# def ret(*args):
# outputs = core.build(f, *args)
# return compile.prog(args, outputs)
# return ret
# @omega_compile
@omega_compile
def
autoassociator
(
w
,
x
):
forward
=
sigmoid
(
core
.
dot
(
sigmoid
(
core
.
dot
(
x
,
w
)),
w
.
T
))
rec_error
=
core
.
sum
(
core
.
sqr
(
x
-
forward
))
w
-=
0.1
*
grad
.
grad
(
rec_error
,
w
)
return
w
,
rec_error
#
w2, rec_error = core.build(autoassociator, w, x)
# #
f = compile.to_func([w, x], [w2, rec_error])
#
f = compile.single(w2, rec_error)
w2
,
rec_error
=
core
.
build
(
autoassociator
,
w
,
x
)
f
=
compile
.
to_func
([
w
,
x
],
[
w2
,
rec_error
])
#f = compile.single(w2, rec_error)
for
i
in
dataset_1hot
(
x
.
data
,
numpy
.
ndarray
((
1
,
)),
10000
):
w2
,
rec_error
=
f
(
)
#
w.data, x.data)
w2
,
rec_error
=
f
(
w
.
data
,
x
.
data
)
if
not
(
i
%
1000
):
print
rec_error
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论