Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
2d6f8566
提交
2d6f8566
authored
12月 08, 2009
作者:
Pascal Lamblin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add support for non-scalar random distributions, by adding a new keyword
argument "ndim_added" to random_function. Use that mechanism for "multinomial" and "permutation" distributions.
上级
f39f3d69
隐藏空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
45 行增加
和
12 行删除
+45
-12
raw_random.py
theano/tensor/raw_random.py
+45
-12
没有找到文件。
theano/tensor/raw_random.py
浏览文件 @
2d6f8566
...
...
@@ -64,7 +64,13 @@ class RandomFunction(gof.Op):
:param args: a list of default arguments for the function
:param kwargs: if the 'inplace' key is there, its value will be used to determine if the op operates inplace or not
:param kwargs:
If the 'inplace' key is there, its value will be used to
determine if the op operates inplace or not.
If the 'ndim_added' key is there, its value indicates how
many more dimensions this op will add to the output, in
addition to the shape's dimensions (used in multinomial and
permutation).
"""
self
.
__setstate__
([
fn
,
outtype
,
args
,
kwargs
])
...
...
@@ -73,11 +79,13 @@ class RandomFunction(gof.Op):
and
self
.
fn
==
other
.
fn
\
and
self
.
outtype
==
other
.
outtype
\
and
self
.
args
==
other
.
args
\
and
self
.
inplace
==
other
.
inplace
and
self
.
inplace
==
other
.
inplace
\
and
self
.
ndim_added
==
other
.
ndim_added
def
__hash__
(
self
):
return
hash
(
type
(
self
))
^
hash
(
self
.
fn
)
\
^
hash
(
self
.
outtype
)
^
hash
(
self
.
args
)
^
hash
(
self
.
inplace
)
^
hash
(
self
.
outtype
)
^
hash
(
self
.
args
)
\
^
hash
(
self
.
inplace
)
^
hash
(
self
.
ndim_added
)
def
__getstate__
(
self
):
return
self
.
state
...
...
@@ -96,15 +104,19 @@ class RandomFunction(gof.Op):
self
.
inplace
=
kwargs
.
pop
(
'inplace'
,
False
)
if
self
.
inplace
:
self
.
destroy_map
=
{
0
:
[
0
]}
self
.
ndim_added
=
kwargs
.
pop
(
'ndim_added'
,
0
)
def
make_node
(
self
,
r
,
shape
,
*
args
):
"""
:param r: a numpy.RandomState instance, or a Variable of Type RandomStateType that will
contain a RandomState instance.
:param shape: an lvector with the shape of the tensor output by this Op. At runtime,
the value associated with this lvector must have a length that matches the number of
dimensions promised by `self.outtype`.
:param shape: an lvector with a shape defining how many samples to draw.
In the case of scalar distributions, it is the shape of the tensor output by this Op.
In that case, at runtime, the value associated with this lvector must have a length
equal to the number of dimensions promised by `self.outtype`.
In general, the number of output dimenstions is equal to
len(self.outtype)+self.ndim_added.
:param args: the values associated with these variables will be passed to the RandomState
function during perform as extra "*args"-style arguments. These should be castable to
...
...
@@ -167,7 +179,7 @@ class RandomFunction(gof.Op):
r
,
shape
,
args
=
inputs
[
0
],
inputs
[
1
],
inputs
[
2
:]
assert
type
(
r
)
==
numpy
.
random
.
RandomState
r_orig
=
r
assert
self
.
outtype
.
ndim
==
len
(
shape
)
assert
self
.
outtype
.
ndim
==
len
(
shape
)
+
self
.
ndim_added
if
not
self
.
inplace
:
r
=
copy
(
r
)
rout
[
0
]
=
r
...
...
@@ -204,6 +216,10 @@ def random_function(fn, dtype, *rfargs, **rfkwargs):
the user can give an integer as first argument, which will be interpreted as the
number of dimensions.
If the distribution is not scalar (e.g., a multinomial), the output will have
more dimensions than what the shape argument suggests. The "ndim_added" keyword
arguments allows to specify how many dimensions to add (for a multinomial, 1).
The number of dimensions for the following shape arguments can be inferred:
- shape(x)
- make_lvector(x, y, z, ...)
...
...
@@ -224,6 +240,8 @@ def random_function(fn, dtype, *rfargs, **rfkwargs):
if
ndim
is
None
:
raise
ValueError
(
'Cannot infer the number of dimensions from the shape argument.'
)
# note: rf could be cached for future use
ndim_added
=
rfkwargs
.
get
(
'ndim_added'
,
0
)
ndim
+=
ndim_added
rf
=
RandomFunction
(
fn
,
tensor
.
TensorType
(
dtype
=
dtype
,
broadcastable
=
(
False
,)
*
ndim
),
*
rfargs
,
**
rfkwargs
)
return
rf
(
r
,
shape
,
*
args
,
**
kwargs
)
return
f
...
...
@@ -296,16 +314,30 @@ def permutation_helper(random_state, n, shape):
out
[
i
]
=
random_state
.
permutation
(
n
)
return
out
permutation
=
random_function
(
permutation_helper
,
'int64'
,
1
)
permutation
=
random_function
(
permutation_helper
,
'int64'
,
1
,
ndim_added
=
1
)
permutation
.
__doc__
=
"""
Usage: permutation(random_state, size, n)
Returns a permutation of the integers between 0 and n-1.
Returns permutations of the integers between 0 and n-1, as many times
as required by size. For instance, if size=(p,q), p*q permutations
will be generated, and the output shape will be (p,q,n), because each
permutation is of size n.
If the size argument is ambiguous on the number of dimensions, the first
argument may be a plain integer i, which should correspond to len(size).
Note that the output will then be of dimension i+1.
"""
multinomial
=
random_function
(
'multinomial'
,
'float64'
,
1
,
[
0.5
,
0.5
])
multinomial
=
random_function
(
'multinomial'
,
'float64'
,
1
,
[
0.5
,
0.5
]
,
ndim_added
=
1
)
multinomial
.
__doc__
=
"""
Usage: multinomial(random_state, size, n, pvals)
Sample from a multinomial distribution defined by probabilities pvals.
Sample from a multinomial distribution defined by probabilities pvals,
as many times as required by size. For instance, if size=(p,q), p*q
samples will be drawn, and the output shape will be (p,q,len(pvals)).
If the size argument is ambiguous on the number of dimensions, the first
argument may be a plain integer i, which should correspond to len(size).
Note that the output will then be of dimension i+1.
"""
...
...
@@ -313,7 +345,8 @@ Sample from a multinomial distribution defined by probabilities pvals.
def
random_make_inplace
(
node
):
op
=
node
.
op
if
isinstance
(
op
,
RandomFunction
)
and
not
op
.
inplace
:
return
RandomFunction
(
op
.
fn
,
op
.
outtype
,
*
op
.
args
,
**
dict
(
inplace
=
True
))
.
make_node
(
*
node
.
inputs
)
.
outputs
opkwargs
=
dict
(
inplace
=
True
,
ndim_added
=
op
.
ndim_added
)
return
RandomFunction
(
op
.
fn
,
op
.
outtype
,
*
op
.
args
,
**
opkwargs
)
.
make_node
(
*
node
.
inputs
)
.
outputs
return
False
optdb
.
register
(
'random_make_inplace'
,
opt
.
in2out
(
random_make_inplace
,
ignore_newtrees
=
True
),
99
,
'fast_run'
,
'inplace'
)
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论