Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
da637496
提交
da637496
authored
4月 17, 2008
作者:
turian@grenat.iro.umontreal.ca
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Improvements to sparse handling
上级
13a8641c
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
149 行增加
和
75 行删除
+149
-75
_test_sparse.py
_test_sparse.py
+34
-52
base_tensor.py
base_tensor.py
+1
-1
gradient.py
gradient.py
+4
-0
sparse.py
sparse.py
+109
-21
tensor.py
tensor.py
+1
-1
没有找到文件。
_test_sparse.py
浏览文件 @
da637496
...
@@ -2,6 +2,7 @@ from sparse import *
...
@@ -2,6 +2,7 @@ from sparse import *
import
unittest
import
unittest
import
compile
import
compile
import
gradient
class
T_transpose
(
unittest
.
TestCase
):
class
T_transpose
(
unittest
.
TestCase
):
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -35,12 +36,13 @@ class T_Add(unittest.TestCase):
...
@@ -35,12 +36,13 @@ class T_Add(unittest.TestCase):
def
test0
(
self
):
def
test0
(
self
):
sp_a
=
sparse
.
csc_matrix
(
sparse
.
speye
(
5
,
3
))
sp_a
=
sparse
.
csc_matrix
(
sparse
.
speye
(
5
,
3
))
a
=
assparse
(
sp_a
)
a
=
assparse
(
sp_a
)
self
.
failUnless
(
a
.
data
is
sp_a
)
sp_b
=
sparse
.
csc_matrix
(
sparse
.
speye
(
5
,
3
))
sp_b
=
sparse
.
csc_matrix
(
sparse
.
speye
(
5
,
3
))
b
=
assparse
(
sp_b
)
b
=
assparse
(
sp_b
)
self
.
failUnless
(
b
.
data
is
sp_b
)
self
.
failUnless
(
a
.
data
is
sp_a
)
apb
=
add
(
a
,
b
)
apb
=
add_s_s
(
a
,
b
)
self
.
failUnless
(
apb
.
dtype
==
a
.
dtype
,
apb
.
dtype
)
self
.
failUnless
(
apb
.
dtype
==
a
.
dtype
,
apb
.
dtype
)
self
.
failUnless
(
apb
.
format
==
a
.
format
,
apb
.
format
)
self
.
failUnless
(
apb
.
format
==
a
.
format
,
apb
.
format
)
...
@@ -55,7 +57,7 @@ class T_conversion(unittest.TestCase):
...
@@ -55,7 +57,7 @@ class T_conversion(unittest.TestCase):
def
test0
(
self
):
def
test0
(
self
):
a
=
tensor
.
astensor
(
numpy
.
random
.
rand
(
5
))
a
=
tensor
.
astensor
(
numpy
.
random
.
rand
(
5
))
s
=
sparse_from_dense
(
a
,
'csc'
)
s
=
sparse_from_dense
(
a
,
'csc'
)
val
=
compile
.
eval_outputs
([
s
])
val
=
compile
.
eval_outputs
([
s
])
self
.
failUnless
(
str
(
val
.
dtype
)
==
'float64'
)
self
.
failUnless
(
str
(
val
.
dtype
)
==
'float64'
)
self
.
failUnless
(
val
.
format
==
'csc'
)
self
.
failUnless
(
val
.
format
==
'csc'
)
...
@@ -79,6 +81,7 @@ class T_conversion(unittest.TestCase):
...
@@ -79,6 +81,7 @@ class T_conversion(unittest.TestCase):
class
_testCase_dot
(
unittest
.
TestCase
):
class
_testCase_dot
(
unittest
.
TestCase
):
""" Types of sparse matrices to use for testing """
""" Types of sparse matrices to use for testing """
mtypes
=
[
sparse
.
csc_matrix
,
sparse
.
csr_matrix
]
mtypes
=
[
sparse
.
csc_matrix
,
sparse
.
csr_matrix
]
mtypes_str
=
[
"csc"
,
"csr"
]
#mtypes = [sparse.csc_matrix, sparse.csr_matrix, sparse.dok_matrix, sparse.lil_matrix, sparse.coo_matrix]
#mtypes = [sparse.csc_matrix, sparse.csr_matrix, sparse.dok_matrix, sparse.lil_matrix, sparse.coo_matrix]
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -126,7 +129,6 @@ class _testCase_dot(unittest.TestCase):
...
@@ -126,7 +129,6 @@ class _testCase_dot(unittest.TestCase):
zop
=
transpose
(
dot
(
y
,
x
))
zop
=
transpose
(
dot
(
y
,
x
))
z
=
compile
.
eval_outputs
([
zop
])
z
=
compile
.
eval_outputs
([
zop
])
self
.
failUnless
(
z
.
shape
==
(
500
,
2
))
self
.
failUnless
(
z
.
shape
==
(
500
,
2
))
print
mtype
,
type
(
z
)
# self.failUnless(type(z) is mtype)
# self.failUnless(type(z) is mtype)
w
=
mtype
((
500
,
2
))
w
=
mtype
((
500
,
2
))
...
@@ -147,61 +149,41 @@ class _testCase_dot(unittest.TestCase):
...
@@ -147,61 +149,41 @@ class _testCase_dot(unittest.TestCase):
w
=
w
.
todense
()
w
=
w
.
todense
()
self
.
failUnless
((
z
==
w
)
.
all
()
==
True
)
self
.
failUnless
((
z
==
w
)
.
all
()
==
True
)
# def test_basic1(self):
# """dot: sparse left"""
# a = numpy.asarray([[1, 0, 3, 0, 5], [0, 0, -2, 0, 0]],
# dtype='float64')
# b = numpy.random.rand(5, 3)
# for mtype in [sparse.csr_matrix, sparse.csc_matrix, sparse.dok_matrix,
# sparse.lil_matrix]:#, sparse.coo_matrix]:
# #print type(a), mtype
# m = mtype(a)
# ab = m.dot(b)
# try:
# z = dot(assparse(m), gof.Result(data=b))
# self.failUnless(z.data.shape == ab.shape)
# self.failUnless(type(z.data) == type(ab))
# except Exception, e:
# print 'cccc', mtype, e, str(e)
# raise
def
test_missing
(
self
):
def
test_missing
(
self
):
raise
NotImplementedError
(
'tests commented out'
)
raise
NotImplementedError
(
'tests commented out'
)
# def test_basic2(self):
def
test_graph_bprop0
(
self
):
# """dot: sparse right"""
# a = numpy.random.rand(2, 5)
# b = numpy.asarray([[1, 0, 3, 0, 5], [0, 0, -2, 0, 0]],
# dtype='float64').transpose()
#
# for mtype in [sparse.csr_matrix, sparse.csc_matrix, sparse.dok_matrix,
# sparse.lil_matrix]:#, sparse.coo_matrix]:
# m = mtype(b)
# ab = m.transpose().dot(a.transpose()).transpose()
# z = dot(gof.Result(data=a),assparse(mtype(b)))
# self.failUnless(z.data.shape == ab.shape)
# self.failUnless(type(z.data) == type(ab))
#
# def test_graph_bprop0(self):
# x = tensor.astensor(numpy.random.rand(10,2))
# x = tensor.astensor(numpy.random.rand(10,2))
# w = assparse(sparse.csr_matrix(
# w = assparse(sparse.csr_matrix(
# numpy.asarray([[1, 0, 3, 0, 5], [0, 0, -2, 0,0]],dtype='float64')
# numpy.asarray([[1, 0, 3, 0, 5], [0, 0, -2, 0,0]],dtype='float64')
# ))
# ))
#
for
mtype
in
self
.
mtypes_str
:
# for epoch in xrange(50):
# x = tensor.astensor([[1., 2], [3, 4], [2, 1]])
# xw = dense_from_sparse(dot(x, w))
# w = assparse(mtype((500,3)))
# y = dense_from_sparse(dot(xw, transpose(w)))
# w.data[(10, 1)] = 1
# loss = core.sum(core.sqr(x-y))
# w.data[(20, 2)] = 2
# gy = y-x
# g = grad.Grad({y:gy})
x
=
tensor
.
Tensor
(
'float64'
,
broadcastable
=
[
False
,
False
],
name
=
'x'
)
# g.bprop()
w
=
SparseResult
(
'float64'
,
mtype
)
# lr = 0.002
xw
=
dense_from_sparse
(
dot
(
x
,
w
))
# g(w).data[1,0] = 0
y
=
dense_from_sparse
(
dot
(
xw
,
w
.
T
))
# g(w).data[1,4] = 0
diff
=
x
-
y
# w.data = -lr * g(w).data + w.data
loss
=
tensor
.
sum
(
tensor
.
sqr
(
diff
))
#
gw
=
gradient
.
grad
(
loss
,
w
)
# self.failUnless('3.08560636025' == str(loss.data))
trainfn
=
compile
.
Function
([
x
,
w
],
[
y
,
loss
,
gw
])
#
# for epoch in xrange(50):
# gy = y-x
# g = grad.Grad({y:gy})
# g.bprop()
# lr = 0.002
# g(w).data[1,0] = 0
# g(w).data[1,4] = 0
# w.data = -lr * g(w).data + w.data
# print loss.data
self
.
failUnless
(
'3.08560636025'
==
str
(
loss
.
data
))
# def test_graph_bprop1(self):
# def test_graph_bprop1(self):
# x = tensor.astensor(numpy.random.rand(10,2))
# x = tensor.astensor(numpy.random.rand(10,2))
# w = assparse(sparse.csr_matrix(
# w = assparse(sparse.csr_matrix(
...
...
base_tensor.py
浏览文件 @
da637496
...
@@ -108,7 +108,7 @@ class BaseTensor(Result):
...
@@ -108,7 +108,7 @@ class BaseTensor(Result):
#
#
def
desc
(
self
):
def
desc
(
self
):
"""
"""
Returns a hashable description of this
BaseTensor
.
Returns a hashable description of this
L{BaseTensor}
.
"""
"""
if
self
.
data
is
not
None
:
if
self
.
data
is
not
None
:
return
(
BaseTensor
,
self
.
dtype
,
self
.
broadcastable
,
self
.
data
.
data
[:])
return
(
BaseTensor
,
self
.
dtype
,
self
.
broadcastable
,
self
.
data
.
data
[:])
...
...
gradient.py
浏览文件 @
da637496
...
@@ -120,6 +120,10 @@ def grad_sources_inputs(sources, graph_inputs):
...
@@ -120,6 +120,10 @@ def grad_sources_inputs(sources, graph_inputs):
def
grad
(
cost
,
param
,
g_cost
=
1.0
):
def
grad
(
cost
,
param
,
g_cost
=
1.0
):
"""
"""
@type cost: L{Result}
@type param: L{Result} or list of L{Result}s.
@rtype: L{Result} or list of L{Result}s (depending upon I{param})
@return: symbolic expression of gradient of I{cost} wrt I{param}.
@return: symbolic expression of gradient of I{cost} wrt I{param}.
If I{param} is a list, then return a list containing the gradient of I{cost} wrt
If I{param} is a list, then return a list containing the gradient of I{cost} wrt
each element of the list.
each element of the list.
...
...
sparse.py
浏览文件 @
da637496
...
@@ -11,7 +11,46 @@ import numpy
...
@@ -11,7 +11,46 @@ import numpy
from
scipy
import
sparse
from
scipy
import
sparse
import
gof.op
,
gof
.
result
import
gof.op
,
gof
.
result
import
tensor
import
tensor
,
base_tensor
## Type checking
def
_is_sparse_result
(
x
):
"""
@rtype: boolean
@return: True iff x is a L{SparseResult} (and not a L{base_tensor.BaseTensor})
"""
if
not
isinstance
(
x
,
SparseResult
)
and
not
isinstance
(
x
,
base_tensor
.
BaseTensor
):
raise
NotImplementedError
(
"_is_sparse should only be called on sparse.SparseResult or base_tensor.BaseTensor, not,"
,
x
)
return
isinstance
(
x
,
SparseResult
)
def
_is_dense_result
(
x
):
"""
@rtype: boolean
@return: True unless x is a L{SparseResult} (and not a L{base_tensor.BaseTensor})
"""
if
not
isinstance
(
x
,
SparseResult
)
and
not
isinstance
(
x
,
base_tensor
.
BaseTensor
):
raise
NotImplementedError
(
"_is_sparse should only be called on sparse.SparseResult or base_tensor.BaseTensor, not,"
,
x
)
return
isinstance
(
x
,
SparseResult
)
def
_is_sparse
(
x
):
"""
@rtype: boolean
@return: True iff x is a L{scipy.sparse.spmatrix} (and not a L{numpy.ndarray})
"""
if
not
isinstance
(
x
,
sparse
.
spmatrix
)
and
not
isinstance
(
x
,
numpy
.
ndarray
):
raise
NotImplementedError
(
"_is_sparse should only be called on sparse.scipy.sparse.spmatrix or numpy.ndarray, not,"
,
x
)
return
isinstance
(
x
,
sparse
.
spmatrix
)
def
_is_dense
(
x
):
"""
@rtype: boolean
@return: True unless x is a L{scipy.sparse.spmatrix} (and not a L{numpy.ndarray})
"""
if
not
isinstance
(
x
,
sparse
.
spmatrix
)
and
not
isinstance
(
x
,
numpy
.
ndarray
):
raise
NotImplementedError
(
"_is_sparse should only be called on sparse.scipy.sparse.spmatrix or numpy.ndarray, not,"
,
x
)
return
isinstance
(
x
,
numpy
.
ndarray
)
# Wrapper type
# Wrapper type
...
@@ -26,13 +65,14 @@ def assparse(sp, **kwargs):
...
@@ -26,13 +65,14 @@ def assparse(sp, **kwargs):
@todo Verify that sp is sufficiently sparse, and raise a warning if it is not
@todo Verify that sp is sufficiently sparse, and raise a warning if it is not
"""
"""
if
isinstance
(
sp
,
SparseResult
):
if
isinstance
(
sp
,
SparseResult
):
r
eturn
sp
r
val
=
sp
else
:
else
:
# @todo Verify that sp is sufficiently sparse, and raise a
# @todo Verify that sp is sufficiently sparse, and raise a
# warning if it is not
# warning if it is not
rval
=
SparseResult
(
str
(
sp
.
dtype
),
sp
.
format
,
**
kwargs
)
rval
=
SparseResult
(
str
(
sp
.
dtype
),
sp
.
format
,
**
kwargs
)
rval
.
data
=
sp
rval
.
data
=
sp
return
rval
assert
_is_sparse_result
(
rval
)
return
rval
class
SparseResult
(
gof
.
result
.
Result
):
class
SparseResult
(
gof
.
result
.
Result
):
"""
"""
...
@@ -44,8 +84,7 @@ class SparseResult(gof.result.Result):
...
@@ -44,8 +84,7 @@ class SparseResult(gof.result.Result):
Methods:
Methods:
Notes:
@note As far as I can tell, L{scipy.sparse} objects must be matrices, i.e. have dimension 2.
"""
"""
format_cls
=
{
format_cls
=
{
'csr'
:
sparse
.
csr_matrix
,
'csr'
:
sparse
.
csr_matrix
,
...
@@ -101,7 +140,6 @@ class SparseResult(gof.result.Result):
...
@@ -101,7 +140,6 @@ class SparseResult(gof.result.Result):
def
__add__
(
left
,
right
):
return
add
(
left
,
right
)
def
__add__
(
left
,
right
):
return
add
(
left
,
right
)
def
__radd__
(
right
,
left
):
return
add
(
left
,
right
)
def
__radd__
(
right
,
left
):
return
add
(
left
,
right
)
#
#
# Conversion
# Conversion
#
#
...
@@ -113,9 +151,11 @@ class DenseFromSparse(gof.op.Op):
...
@@ -113,9 +151,11 @@ class DenseFromSparse(gof.op.Op):
self
.
inputs
=
[
assparse
(
x
)]
self
.
inputs
=
[
assparse
(
x
)]
self
.
outputs
=
[
tensor
.
Tensor
(
x
.
dtype
,[
0
,
0
])]
self
.
outputs
=
[
tensor
.
Tensor
(
x
.
dtype
,[
0
,
0
])]
def
impl
(
self
,
x
):
def
impl
(
self
,
x
):
assert
_is_sparse
(
x
)
return
numpy
.
asarray
(
x
.
todense
())
return
numpy
.
asarray
(
x
.
todense
())
def
grad
(
self
,
x
,
gz
):
def
grad
(
self
,
(
x
,),
(
gz
,)):
return
sparse_from_dense
(
gz
,
x
.
format
)
assert
_is_sparse_result
(
x
)
and
_is_dense_result
(
gz
)
return
sparse_from_dense
(
gz
,
x
.
format
),
dense_from_sparse
=
gof
.
op
.
constructor
(
DenseFromSparse
)
dense_from_sparse
=
gof
.
op
.
constructor
(
DenseFromSparse
)
class
SparseFromDense
(
gof
.
op
.
Op
):
class
SparseFromDense
(
gof
.
op
.
Op
):
...
@@ -130,9 +170,11 @@ class SparseFromDense(gof.op.Op):
...
@@ -130,9 +170,11 @@ class SparseFromDense(gof.op.Op):
def
impl
(
self
,
x
,
fmt
):
def
impl
(
self
,
x
,
fmt
):
# this would actually happen anyway when we try to assign to
# this would actually happen anyway when we try to assign to
# self.outputs[0].data, but that seems hackish -JB
# self.outputs[0].data, but that seems hackish -JB
assert
_is_dense
(
x
)
return
SparseResult
.
format_cls
[
fmt
](
x
)
return
SparseResult
.
format_cls
[
fmt
](
x
)
def
grad
(
self
,
(
x
,
fmt
),
gz
):
def
grad
(
self
,
(
x
,
fmt
),
(
gz
,)):
return
dense_from_sparse
(
gz
)
assert
_is_dense_result
(
x
)
and
_is_sparse_result
(
gz
)
return
dense_from_sparse
(
gz
),
None
sparse_from_dense
=
gof
.
op
.
constructor
(
SparseFromDense
)
sparse_from_dense
=
gof
.
op
.
constructor
(
SparseFromDense
)
# Linear Algebra
# Linear Algebra
...
@@ -147,12 +189,15 @@ class Transpose(gof.op.Op):
...
@@ -147,12 +189,15 @@ class Transpose(gof.op.Op):
self
.
inputs
=
[
x
]
self
.
inputs
=
[
x
]
self
.
outputs
=
[
SparseResult
(
x
.
dtype
,
Transpose
.
format_map
[
x
.
format
])]
self
.
outputs
=
[
SparseResult
(
x
.
dtype
,
Transpose
.
format_map
[
x
.
format
])]
def
impl
(
self
,
x
):
def
impl
(
self
,
x
):
assert
_is_sparse
(
x
)
return
x
.
transpose
()
return
x
.
transpose
()
def
grad
(
self
,
x
,
gz
):
def
grad
(
self
,
(
x
,),
(
gz
,)):
return
transpose
(
gz
)
assert
_is_sparse_result
(
x
)
and
_is_sparse_result
(
gz
)
return
transpose
(
gz
),
transpose
=
gof
.
op
.
constructor
(
Transpose
)
transpose
=
gof
.
op
.
constructor
(
Transpose
)
class
AddSS
(
gof
.
op
.
Op
):
#add two sparse matrices
class
AddSS
(
gof
.
op
.
Op
):
''' Add two sparse matrices '''
def
__init__
(
self
,
x
,
y
,
**
kwargs
):
def
__init__
(
self
,
x
,
y
,
**
kwargs
):
gof
.
op
.
Op
.
__init__
(
self
,
**
kwargs
)
gof
.
op
.
Op
.
__init__
(
self
,
**
kwargs
)
x
,
y
=
[
assparse
(
x
),
assparse
(
y
)]
x
,
y
=
[
assparse
(
x
),
assparse
(
y
)]
...
@@ -163,10 +208,49 @@ class AddSS(gof.op.Op): #add two sparse matrices
...
@@ -163,10 +208,49 @@ class AddSS(gof.op.Op): #add two sparse matrices
raise
NotImplementedError
()
raise
NotImplementedError
()
self
.
outputs
=
[
SparseResult
(
x
.
dtype
,
x
.
format
)]
self
.
outputs
=
[
SparseResult
(
x
.
dtype
,
x
.
format
)]
def
impl
(
self
,
x
,
y
):
def
impl
(
self
,
x
,
y
):
assert
_is_sparse
(
x
)
and
_is_sparse
(
y
)
return
x
+
y
return
x
+
y
def
grad
(
self
,
(
x
,
y
),
gz
):
def
grad
(
self
,
(
x
,
y
),
(
gz
,)):
assert
_is_sparse_result
(
x
)
and
_is_sparse_result
(
y
)
assert
_is_sparse_result
(
gz
)
return
gz
,
gz
return
gz
,
gz
add_s_s
=
gof
.
op
.
constructor
(
AddSS
)
add_s_s
=
gof
.
op
.
constructor
(
AddSS
)
class
AddSD
(
gof
.
op
.
Op
):
''' Add a sparse and a dense matrix '''
def
__init__
(
self
,
x
,
y
,
**
kwargs
):
gof
.
op
.
Op
.
__init__
(
self
,
**
kwargs
)
x
,
y
=
[
assparse
(
x
),
tensor
.
astensor
(
y
)]
self
.
inputs
=
[
x
,
y
]
if
x
.
dtype
!=
y
.
dtype
:
raise
NotImplementedError
()
# The magic number two here arises because L{scipy.sparse}
# objects must be matrices (have dimension 2)
assert
len
(
y
.
broadcastable
)
==
2
self
.
outputs
=
[
tensor
.
Tensor
(
y
.
dtype
,
y
.
broadcastable
)]
def
impl
(
self
,
x
,
y
):
assert
_is_sparse
(
x
)
and
_is_dense
(
y
)
return
x
+
y
def
grad
(
self
,
(
x
,
y
),
(
gz
,)):
assert
_is_sparse_result
(
x
)
and
_is_dense_result
(
y
)
assert
_is_dense_result
(
gz
)
return
SparseFromDense
(
gz
),
gz
add_s_d
=
gof
.
op
.
constructor
(
AddSD
)
def
add
(
x
,
y
):
"""
Add two matrices, at least one of which is sparse.
"""
if
hasattr
(
x
,
'getnnz'
):
x
=
assparse
(
x
)
if
hasattr
(
y
,
'getnnz'
):
y
=
assparse
(
y
)
x_is_sparse_result
=
_is_sparse_result
(
x
)
y_is_sparse_result
=
_is_sparse_result
(
y
)
assert
x_is_sparse_result
or
y_is_sparse_result
if
x_is_sparse_result
and
y_is_sparse_result
:
return
add_s_s
(
x
,
y
)
elif
x_is_sparse_result
and
not
y_is_sparse_result
:
return
add_s_d
(
x
,
y
)
elif
y_is_sparse_result
and
not
x_is_sparse_result
:
return
add_s_d
(
y
,
x
)
else
:
raise
NotImplementedError
()
class
Dot
(
gof
.
op
.
Op
):
class
Dot
(
gof
.
op
.
Op
):
"""
"""
...
@@ -178,6 +262,8 @@ class Dot(gof.op.Op):
...
@@ -178,6 +262,8 @@ class Dot(gof.op.Op):
when L{Dot} is in the middle of a larger graph, because the types
when L{Dot} is in the middle of a larger graph, because the types
of gy will match that of y. This conversion might be inefficient if
of gy will match that of y. This conversion might be inefficient if
the gradients are graph outputs though, hence this mask.
the gradients are graph outputs though, hence this mask.
@todo: Simplify code by splitting into DotSS and DotSD.
"""
"""
def
__init__
(
self
,
x
,
y
,
grad_preserves_dense
=
True
):
def
__init__
(
self
,
x
,
y
,
grad_preserves_dense
=
True
):
"""
"""
...
@@ -186,6 +272,7 @@ class Dot(gof.op.Op):
...
@@ -186,6 +272,7 @@ class Dot(gof.op.Op):
if
x
.
dtype
!=
y
.
dtype
:
if
x
.
dtype
!=
y
.
dtype
:
raise
NotImplementedError
()
raise
NotImplementedError
()
assert
_is_sparse_result
(
x
)
# These are the conversions performed by scipy.sparse.dot
# These are the conversions performed by scipy.sparse.dot
if
x
.
format
==
"csc"
or
x
.
format
==
"coo"
:
if
x
.
format
==
"csc"
or
x
.
format
==
"coo"
:
myformat
=
"csc"
myformat
=
"csc"
...
@@ -204,9 +291,10 @@ class Dot(gof.op.Op):
...
@@ -204,9 +291,10 @@ class Dot(gof.op.Op):
"""
"""
self
.
outputs
[
0
]
.
data
=
self
.
inputs
[
0
]
.
data
.
dot
(
self
.
inputs
[
1
]
.
data
)
self
.
outputs
[
0
]
.
data
=
self
.
inputs
[
0
]
.
data
.
dot
(
self
.
inputs
[
1
]
.
data
)
def
grad
(
self
,
(
x
,
y
),
(
gz
,)):
def
grad
(
self
,
(
x
,
y
),
(
gz
,)):
assert
_is_sparse_result
(
gz
)
rval
=
[
dot
(
gz
,
y
.
T
),
dot
(
x
.
T
,
gz
)]
rval
=
[
dot
(
gz
,
y
.
T
),
dot
(
x
.
T
,
gz
)]
assert
isinstance
(
self
.
inputs
[
0
],
SparseResult
)
assert
_is_sparse_result
(
x
)
if
not
isinstance
(
self
.
inputs
[
1
],
SparseResult
):
if
_is_dense_result
(
y
):
if
self
.
grad_preserves_dense
:
if
self
.
grad_preserves_dense
:
rval
[
1
]
=
dense_from_sparse
(
rval
[
1
])
rval
[
1
]
=
dense_from_sparse
(
rval
[
1
])
return
rval
return
rval
...
@@ -222,12 +310,12 @@ def dot(x, y, grad_preserves_dense=True):
...
@@ -222,12 +310,12 @@ def dot(x, y, grad_preserves_dense=True):
if
hasattr
(
x
,
'getnnz'
):
x
=
assparse
(
x
)
if
hasattr
(
x
,
'getnnz'
):
x
=
assparse
(
x
)
if
hasattr
(
y
,
'getnnz'
):
y
=
assparse
(
y
)
if
hasattr
(
y
,
'getnnz'
):
y
=
assparse
(
y
)
x_is_sparse
=
isinstance
(
x
,
SparseResult
)
x_is_sparse
_result
=
_is_sparse_result
(
x
)
y_is_sparse
=
isinstance
(
y
,
SparseResult
)
y_is_sparse
_result
=
_is_sparse_result
(
y
)
if
not
x_is_sparse
and
not
y_is_sparse
:
if
not
x_is_sparse
_result
and
not
y_is_sparse_result
:
raise
TypeError
()
raise
TypeError
()
if
x_is_sparse
:
if
x_is_sparse
_result
:
return
Dot
(
x
,
y
,
grad_preserves_dense
)
.
outputs
[
0
]
return
Dot
(
x
,
y
,
grad_preserves_dense
)
.
outputs
[
0
]
else
:
else
:
assert
y_is_sparse
assert
y_is_sparse
_result
return
transpose
(
Dot
(
y
.
T
,
x
.
T
,
grad_preserves_dense
)
.
outputs
[
0
])
return
transpose
(
Dot
(
y
.
T
,
x
.
T
,
grad_preserves_dense
)
.
outputs
[
0
])
tensor.py
浏览文件 @
da637496
...
@@ -84,7 +84,7 @@ def astensor(data, broadcastable=None, name=None):
...
@@ -84,7 +84,7 @@ def astensor(data, broadcastable=None, name=None):
raise
ValueError
(
"Cannot rename an existing Tensor."
)
raise
ValueError
(
"Cannot rename an existing Tensor."
)
return
data
return
data
elif
isinstance
(
data
,
Result
):
elif
isinstance
(
data
,
Result
):
raise
TypeError
(
"Cannot make a Tensor out of a non-Tensor result
."
)
raise
TypeError
(
"Cannot make a Tensor out of a non-Tensor result
:"
,
data
)
if
data
is
None
and
broadcastable
is
None
:
if
data
is
None
and
broadcastable
is
None
:
raise
TypeError
(
"Cannot make a Tensor out of None."
)
raise
TypeError
(
"Cannot make a Tensor out of None."
)
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论