提交 bd1a12ed authored 作者: Frédéric Bastien's avatar Frédéric Bastien 提交者: GitHub

Merge pull request #5751 from laurent-dinh/to_choice

MultinomialWOReplacementFromUniform := ChoiceFromUniform
# TODO test dtype != float32 # TODO test dtype != float32
from __future__ import absolute_import, print_function, division from __future__ import absolute_import, print_function, division
import os import os
import warnings
try: try:
import pygpu import pygpu
...@@ -232,7 +233,7 @@ KERNEL void k_multi_warp_multinomial( ...@@ -232,7 +233,7 @@ KERNEL void k_multi_warp_multinomial(
return (3,) return (3,)
class GPUAMultinomialWOReplacementFromUniform(GpuKernelBase, Op): class GPUAChoiceFromUniform(GpuKernelBase, Op):
""" """
The output is transposed compared to MultinomialWOReplacementFromUniform. The output is transposed compared to MultinomialWOReplacementFromUniform.
We must insert a Transpose op after it. We must insert a Transpose op after it.
...@@ -506,13 +507,22 @@ def local_gpua_multinomial(op, context_name, inputs, outputs): ...@@ -506,13 +507,22 @@ def local_gpua_multinomial(op, context_name, inputs, outputs):
@register_opt('fast_compile') @register_opt('fast_compile')
@op_lifter([theano.sandbox.multinomial.MultinomialWOReplacementFromUniform]) @op_lifter([theano.sandbox.multinomial.ChoiceFromUniform])
@register_opt2([theano.sandbox.multinomial.MultinomialWOReplacementFromUniform], 'fast_compile') @register_opt2([theano.sandbox.multinomial.ChoiceFromUniform], 'fast_compile')
def local_gpua_multinomial_wor(op, context_name, inputs, outputs): def local_gpua_multinomial_wor(op, context_name, inputs, outputs):
# TODO : need description for function # TODO : need description for function
p, u, n = inputs p, u, n = inputs
m, = outputs m, = outputs
if ((p.dtype == u.dtype == 'float32') and (m.dtype == 'int64')): if ((p.dtype == u.dtype == 'float32') and (m.dtype == 'int64')):
gpu_op = GPUAMultinomialWOReplacementFromUniform(op.odtype) gpu_op = GPUAChoiceFromUniform(op.odtype)
return GpuDimShuffle([False, False], [1, 0])( return GpuDimShuffle([False, False], [1, 0])(
gpu_op(p, u, n)) gpu_op(p, u, n))
class GPUAMultinomialWOReplacementFromUniform(GPUAChoiceFromUniform):
def __init__(self, *args, **kwargs):
warnings.warn("GPUAMultinomialWOReplacementFromUniform is deprecated, "
"use GPUAChoiceFromUniform instead.",
DeprecationWarning,
stacklevel=2)
super(GPUAMultinomialWOReplacementFromUniform, self).__init__(*args, **kwargs)
ccopy_reg
_reconstructor
p1
(ctheano.gpuarray.multinomial
GPUAMultinomialWOReplacementFromUniform
p2
c__builtin__
object
p3
NtRp4
(dp5
S'odtype'
p6
S'float32'
p7
sb.
\ No newline at end of file
from __future__ import absolute_import, print_function, division from __future__ import absolute_import, print_function, division
import os
import numpy as np import numpy as np
import unittest import unittest
import theano import theano
from theano import config, function, tensor from theano import config, function, tensor
from theano.compat import PY3
from theano.misc.pkl_utils import CompatUnpickler
from theano.sandbox import multinomial from theano.sandbox import multinomial
from theano.sandbox.rng_mrg import MRG_RandomStreams as RandomStreams from theano.sandbox.rng_mrg import MRG_RandomStreams as RandomStreams
...@@ -13,7 +16,7 @@ import theano.tests.unittest_tools as utt ...@@ -13,7 +16,7 @@ import theano.tests.unittest_tools as utt
from .config import mode_with_gpu from .config import mode_with_gpu
from ..multinomial import (GPUAMultinomialFromUniform, from ..multinomial import (GPUAMultinomialFromUniform,
GPUAMultinomialWOReplacementFromUniform) GPUAChoiceFromUniform)
def test_multinomial_output_dtype(): def test_multinomial_output_dtype():
...@@ -172,12 +175,12 @@ class test_OP_wor(unittest.TestCase): ...@@ -172,12 +175,12 @@ class test_OP_wor(unittest.TestCase):
def test_select_distinct(self): def test_select_distinct(self):
""" """
Tests that MultinomialWOReplacementFromUniform always selects distinct elements Tests that ChoiceFromUniform always selects distinct elements
""" """
p = tensor.fmatrix() p = tensor.fmatrix()
u = tensor.fvector() u = tensor.fvector()
n = tensor.iscalar() n = tensor.iscalar()
m = multinomial.MultinomialWOReplacementFromUniform('auto')(p, u, n) m = multinomial.ChoiceFromUniform('auto')(p, u, n)
f = function([p, u, n], m, allow_input_downcast=True) f = function([p, u, n], m, allow_input_downcast=True)
...@@ -195,13 +198,13 @@ class test_OP_wor(unittest.TestCase): ...@@ -195,13 +198,13 @@ class test_OP_wor(unittest.TestCase):
def test_fail_select_alot(self): def test_fail_select_alot(self):
""" """
Tests that MultinomialWOReplacementFromUniform fails when asked to sample more Tests that ChoiceFromUniform fails when asked to sample more
elements than the actual number of elements elements than the actual number of elements
""" """
p = tensor.fmatrix() p = tensor.fmatrix()
u = tensor.fvector() u = tensor.fvector()
n = tensor.iscalar() n = tensor.iscalar()
m = multinomial.MultinomialWOReplacementFromUniform('auto')(p, u, n) m = multinomial.ChoiceFromUniform('auto')(p, u, n)
f = function([p, u, n], m, allow_input_downcast=True) f = function([p, u, n], m, allow_input_downcast=True)
...@@ -215,13 +218,13 @@ class test_OP_wor(unittest.TestCase): ...@@ -215,13 +218,13 @@ class test_OP_wor(unittest.TestCase):
def test_select_proportional_to_weight(self): def test_select_proportional_to_weight(self):
""" """
Tests that MultinomialWOReplacementFromUniform selects elements, on average, Tests that ChoiceFromUniform selects elements, on average,
proportional to the their probabilities proportional to the their probabilities
""" """
p = tensor.fmatrix() p = tensor.fmatrix()
u = tensor.fvector() u = tensor.fvector()
n = tensor.iscalar() n = tensor.iscalar()
m = multinomial.MultinomialWOReplacementFromUniform('auto')(p, u, n) m = multinomial.ChoiceFromUniform('auto')(p, u, n)
f = function([p, u, n], m, allow_input_downcast=True) f = function([p, u, n], m, allow_input_downcast=True)
...@@ -324,11 +327,11 @@ def test_gpu_opt_wor(): ...@@ -324,11 +327,11 @@ def test_gpu_opt_wor():
p = tensor.fmatrix() p = tensor.fmatrix()
u = tensor.fvector() u = tensor.fvector()
n = tensor.iscalar() n = tensor.iscalar()
m = multinomial.MultinomialWOReplacementFromUniform('auto')(p, u, n) m = multinomial.ChoiceFromUniform('auto')(p, u, n)
assert m.dtype == 'int64', m.dtype assert m.dtype == 'int64', m.dtype
f = function([p, u, n], m, allow_input_downcast=True, mode=mode_with_gpu) f = function([p, u, n], m, allow_input_downcast=True, mode=mode_with_gpu)
assert any([type(node.op) is GPUAMultinomialWOReplacementFromUniform assert any([type(node.op) is GPUAChoiceFromUniform
for node in f.maker.fgraph.toposort()]) for node in f.maker.fgraph.toposort()])
n_samples = 3 n_samples = 3
pval = np.arange(10000 * 4, dtype='float32').reshape((10000, 4)) + 0.1 pval = np.arange(10000 * 4, dtype='float32').reshape((10000, 4)) + 0.1
...@@ -338,13 +341,24 @@ def test_gpu_opt_wor(): ...@@ -338,13 +341,24 @@ def test_gpu_opt_wor():
# Test with a row, it was failing in the past. # Test with a row, it was failing in the past.
r = tensor.frow() r = tensor.frow()
m = multinomial.MultinomialWOReplacementFromUniform('auto')(r, u, n) m = multinomial.ChoiceFromUniform('auto')(r, u, n)
assert m.dtype == 'int64', m.dtype assert m.dtype == 'int64', m.dtype
f = function([r, u, n], m, allow_input_downcast=True, mode=mode_with_gpu) f = function([r, u, n], m, allow_input_downcast=True, mode=mode_with_gpu)
assert any([type(node.op) is GPUAMultinomialWOReplacementFromUniform assert any([type(node.op) is GPUAChoiceFromUniform
for node in f.maker.fgraph.toposort()]) for node in f.maker.fgraph.toposort()])
pval = np.arange(1 * 4, dtype='float32').reshape((1, 4)) + 0.1 pval = np.arange(1 * 4, dtype='float32').reshape((1, 4)) + 0.1
pval = pval / pval.sum(axis=1)[:, None] pval = pval / pval.sum(axis=1)[:, None]
uval = np.ones_like(pval[:, 0]) * 0.5 uval = np.ones_like(pval[:, 0]) * 0.5
f(pval, uval, 1) f(pval, uval, 1)
def test_unpickle_legacy_op():
testfile_dir = os.path.dirname(os.path.realpath(__file__))
fname = 'test_gpuarray_multinomial_wo_replacement.pkl'
if not PY3:
with open(os.path.join(testfile_dir, fname), 'r') as fp:
u = CompatUnpickler(fp)
m = u.load()
assert isinstance(m, GPUAChoiceFromUniform)
from __future__ import absolute_import, print_function, division from __future__ import absolute_import, print_function, division
import numpy import numpy
import warnings
import theano import theano
from theano import Op, Apply from theano import Op, Apply
...@@ -211,7 +212,7 @@ class MultinomialFromUniform(Op): ...@@ -211,7 +212,7 @@ class MultinomialFromUniform(Op):
z[0][n, numpy.searchsorted(cumsum, unis_n)] += 1 z[0][n, numpy.searchsorted(cumsum, unis_n)] += 1
class MultinomialWOReplacementFromUniform(MultinomialFromUniform): class ChoiceFromUniform(MultinomialFromUniform):
""" """
Converts samples from a uniform into sample (without replacement) from a Converts samples from a uniform into sample (without replacement) from a
multinomial. multinomial.
...@@ -626,3 +627,12 @@ def local_gpu_multinomial(node): ...@@ -626,3 +627,12 @@ def local_gpu_multinomial(node):
# The dimshuffle is on the cpu, but will be moved to the # The dimshuffle is on the cpu, but will be moved to the
# gpu by an opt. # gpu by an opt.
return [gpu_from_host(ret)] return [gpu_from_host(ret)]
class MultinomialWOReplacementFromUniform(ChoiceFromUniform):
def __init__(self, *args, **kwargs):
warnings.warn("MultinomialWOReplacementFromUniform is deprecated, "
"use ChoiceFromUniform instead.",
DeprecationWarning,
stacklevel=2)
super(MultinomialWOReplacementFromUniform, self).__init__(*args, **kwargs)
...@@ -1513,7 +1513,7 @@ class MRG_RandomStreams(object): ...@@ -1513,7 +1513,7 @@ class MRG_RandomStreams(object):
shape = p[:, 0].shape * size shape = p[:, 0].shape * size
unis = self.uniform(size=shape, ndim=1, nstreams=nstreams) unis = self.uniform(size=shape, ndim=1, nstreams=nstreams)
op = multinomial.MultinomialWOReplacementFromUniform(dtype) op = multinomial.ChoiceFromUniform(dtype)
return op(p, unis, as_tensor_variable(size)) return op(p, unis, as_tensor_variable(size))
def multinomial_wo_replacement(self, size=None, n=1, pvals=None, def multinomial_wo_replacement(self, size=None, n=1, pvals=None,
......
from __future__ import absolute_import, print_function, division from __future__ import absolute_import, print_function, division
import numpy import numpy
import os
from theano import config, function, tensor from theano import config, function, tensor
from theano.compat import PY3
from theano.misc.pkl_utils import CompatUnpickler
from theano.sandbox import multinomial from theano.sandbox import multinomial
from theano.sandbox.rng_mrg import MRG_RandomStreams as RandomStreams from theano.sandbox.rng_mrg import MRG_RandomStreams as RandomStreams
import unittest import unittest
...@@ -10,12 +13,12 @@ class test_OP(unittest.TestCase): ...@@ -10,12 +13,12 @@ class test_OP(unittest.TestCase):
def test_select_distinct(self): def test_select_distinct(self):
""" """
Tests that MultinomialWOReplacementFromUniform always selects distinct elements Tests that ChoiceFromUniform always selects distinct elements
""" """
p = tensor.fmatrix() p = tensor.fmatrix()
u = tensor.fvector() u = tensor.fvector()
n = tensor.iscalar() n = tensor.iscalar()
m = multinomial.MultinomialWOReplacementFromUniform('auto')(p, u, n) m = multinomial.ChoiceFromUniform('auto')(p, u, n)
f = function([p, u, n], m, allow_input_downcast=True) f = function([p, u, n], m, allow_input_downcast=True)
...@@ -43,13 +46,13 @@ class test_OP(unittest.TestCase): ...@@ -43,13 +46,13 @@ class test_OP(unittest.TestCase):
def test_fail_select_alot(self): def test_fail_select_alot(self):
""" """
Tests that MultinomialWOReplacementFromUniform fails when asked to sample more Tests that ChoiceFromUniform fails when asked to sample more
elements than the actual number of elements elements than the actual number of elements
""" """
p = tensor.fmatrix() p = tensor.fmatrix()
u = tensor.fvector() u = tensor.fvector()
n = tensor.iscalar() n = tensor.iscalar()
m = multinomial.MultinomialWOReplacementFromUniform('auto')(p, u, n) m = multinomial.ChoiceFromUniform('auto')(p, u, n)
f = function([p, u, n], m, allow_input_downcast=True) f = function([p, u, n], m, allow_input_downcast=True)
...@@ -63,13 +66,13 @@ class test_OP(unittest.TestCase): ...@@ -63,13 +66,13 @@ class test_OP(unittest.TestCase):
def test_select_proportional_to_weight(self): def test_select_proportional_to_weight(self):
""" """
Tests that MultinomialWOReplacementFromUniform selects elements, on average, Tests that ChoiceFromUniform selects elements, on average,
proportional to the their probabilities proportional to the their probabilities
""" """
p = tensor.fmatrix() p = tensor.fmatrix()
u = tensor.fvector() u = tensor.fvector()
n = tensor.iscalar() n = tensor.iscalar()
m = multinomial.MultinomialWOReplacementFromUniform('auto')(p, u, n) m = multinomial.ChoiceFromUniform('auto')(p, u, n)
f = function([p, u, n], m, allow_input_downcast=True) f = function([p, u, n], m, allow_input_downcast=True)
...@@ -164,3 +167,14 @@ class test_function(unittest.TestCase): ...@@ -164,3 +167,14 @@ class test_function(unittest.TestCase):
avg_pvals /= avg_pvals.sum() avg_pvals /= avg_pvals.sum()
avg_diff = numpy.mean(abs(avg_pvals - pvals)) avg_diff = numpy.mean(abs(avg_pvals - pvals))
assert avg_diff < mean_rtol assert avg_diff < mean_rtol
def test_unpickle_legacy_op(self):
testfile_dir = os.path.dirname(os.path.realpath(__file__))
fname = 'test_sandbox_multinomial_wo_replacement.pkl'
if not PY3:
with open(os.path.join(testfile_dir, fname), 'r') as fp:
u = CompatUnpickler(fp)
m = u.load()
print(m)
assert isinstance(m, multinomial.ChoiceFromUniform)
ccopy_reg
_reconstructor
p1
(ctheano.sandbox.multinomial
MultinomialWOReplacementFromUniform
p2
c__builtin__
object
p3
NtRp4
(dp5
S'odtype'
p6
S'auto'
p7
sb.
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论