提交 6ff2fca5 authored 作者: Razvan Pascanu's avatar Razvan Pascanu

merge

......@@ -656,49 +656,36 @@ computations. If you would like to update the value of a
Elementwise
===========
.. _libdoc_tensor_broadcastable:
Broadcasting in Theano vs. Numpy
--------------------------------
Broadcasting is a mechanism which allows tensors with
different numbers of dimensions to be added or multiplied
together by (virtually) replicating the smaller tensor along
the dimensions that it is lacking.
Broadcasting is the mechanism by which a scalar
may be added to a matrix, a vector to a matrix or a scalar to
a vector.
Casting
-------
.. figure:: bcast.png
.. function:: cast(x, dtype)
Broadcasting a row matrix. T and F respectively stand for
True and False and indicate along which dimensions we allow
broadcasting.
Cast any tensor `x` to a Tensor of the same shape, but with a different
numerical type `dtype`.
If the second argument were a vector, its shape would be
``(2,)`` and its broadcastable pattern ``(F,)``. They would
be automatically expanded to the **left** to match the
dimensions of the matrix (adding ``1`` to the shape and ``T``
to the pattern), resulting in ``(1, 2)`` and ``(T, F)``.
It would then behave just like the example above.
This is not a reinterpret cast, but a coersion cast, similar to
``numpy.asarray(x, dtype=dtype)``.
.. code-block:: python
Unlike numpy which does broadcasting dynamically, Theano needs
to know, for any operation which supports broadcasting, which
dimensions will need to be broadcasted. When applicable, this
information is given in the :ref:`type` of a *Variable*.
import theano.tensor as T
x_as_float = T.matrix()
x_as_int = T.cast(x, 'int32')
See also:
* `SciPy documentation about numpy's broadcasting <http://www.scipy.org/EricsBroadcastingDoc>`_
Attempting to casting a complex value to a real value is ambiguous and
will raise an exception. Use `real()`, `imag()`, `abs()`, or `angle()`.
* `OnLamp article about numpy's broadcasting <http://www.onlamp.com/pub/a/python/2000/09/27/numerically.html>`_
.. function:: real(x)
Return the real (not imaginary) components of Tensor x.
For non-complex `x` this function returns x.
.. function:: imag(x)
Casting
-------
Return the imaginary components of Tensor x.
For non-complex `x` this function returns zeros_like(x).
Comparisons
------------
......@@ -774,6 +761,13 @@ Condition
x,y = T.dmatrices('x','y')
z = T.switch(T.lt(a,b), x, y)
.. function:: clip(x, min, max)
Return a variable representing x, but with all elements greater than
`max` clipped to `max` and all elements less than `min` clipped to `min.
Normal broadcasting rules apply to each of `x`, `min`, and `max`.
Bit-wise
--------
......@@ -824,6 +818,10 @@ Mathematical
.. note:: Can also be accessed with ``abs(a)``.
.. function:: angle(a)
Returns a variable representing angular component of complex-valued Tensor `a`.
.. function:: exp(a)
Returns a variable representing the exponential of a, ie e^a.
......@@ -873,6 +871,48 @@ Mathematical
Returns a variable representing the hyperbolic trigonometric functions of a (hyperbolic cosine, sine and tangent).
.. _libdoc_tensor_broadcastable:
Broadcasting in Theano vs. Numpy
--------------------------------
Broadcasting is a mechanism which allows tensors with
different numbers of dimensions to be added or multiplied
together by (virtually) replicating the smaller tensor along
the dimensions that it is lacking.
Broadcasting is the mechanism by which a scalar
may be added to a matrix, a vector to a matrix or a scalar to
a vector.
.. figure:: bcast.png
Broadcasting a row matrix. T and F respectively stand for
True and False and indicate along which dimensions we allow
broadcasting.
If the second argument were a vector, its shape would be
``(2,)`` and its broadcastable pattern ``(F,)``. They would
be automatically expanded to the **left** to match the
dimensions of the matrix (adding ``1`` to the shape and ``T``
to the pattern), resulting in ``(1, 2)`` and ``(T, F)``.
It would then behave just like the example above.
Unlike numpy which does broadcasting dynamically, Theano needs
to know, for any operation which supports broadcasting, which
dimensions will need to be broadcasted. When applicable, this
information is given in the :ref:`type` of a *Variable*.
See also:
* `SciPy documentation about numpy's broadcasting <http://www.scipy.org/EricsBroadcastingDoc>`_
* `OnLamp article about numpy's broadcasting <http://www.onlamp.com/pub/a/python/2000/09/27/numerically.html>`_
Linear Algebra
==============
......@@ -939,7 +979,4 @@ Gradient / Differentiation
Full Constructor List
======================
......@@ -896,9 +896,6 @@ class Clip(ScalarOp):
return max
else:
return x
#backport
#return min if x < min else max if x > max else x
def c_code(self, node, name, (x, min, max), (z, ), sub):
return "%(z)s = %(x)s < %(min)s ? %(min)s : %(x)s > %(max)s ? %(max)s : %(x)s;" % locals()
def grad(self, (x, min, max), (gz, )):
......@@ -907,9 +904,7 @@ class Clip(ScalarOp):
return gx, None, None
else:
return None, None, None
#return gx if x.type in grad_types else None, None, None
clip = Clip(transfer_type(0), name = 'clip')
clip = Clip(upcast_out, name = 'clip')
class First(BinaryScalarOp):
def impl(self, x, y):
......
......@@ -1633,6 +1633,11 @@ def imag(x):
else:
return zeros_like(x)
@constructor
def angle(x):
"""Return the angular component of complex-valued `x`"""
raise NotImplementedError()
##########################
# Misc
......@@ -1738,8 +1743,36 @@ def prod(input, axis = None):
"""WRITEME"""
return elemwise.Prod(axis)(input)
class Mean(elemwise.CAReduce):
def __init__(self, axis = None):
elemwise.CAReduce.__init__(self, scal.add, axis)
def __str__(self):
if self.axis is not None:
return "Mean{%s}" % (", ".join(str(x) for x in self.axis))
else:
return "Mean"
def _output_dtype(self, idtype):
# we want to protect against overflow
return 'float64'
def perform(self, node, (input, ), (output, )):
ret = elemwise.CAReduce.perform(self,node,(input,),(output,))
output[0]=numpy.asarray(output[0]/len(input))
def c_code(self, node, name, inames, onames, sub):
ret = elemwise.CAReduce.c_code(self, node, name, inames, onames, sub)
return ret + """
*((double *)PyArray_DATA(%s)) /= PyArray_SIZE(%s);
"""%(onames[0],inames[0])
#TODO: implement the grad. When done and tested, you can make this the default version.
# def grad(self, (x,), (gout,)):
# import pdb;pdb.set_trace()
# return grad(mean(x, self.axis, op=False),[x])
@constructor
def mean(input, axis = None):
def mean(input, axis = None, op = False):
"""Compute the mean value along the given axis of a tensor `input`
:param axis: compute the mean along this axis of the tensor. None means all axes (like
......@@ -1747,6 +1780,9 @@ def mean(input, axis = None):
:type axis: None or int or (list of int) (see `Sum`)
"""
if op:
return Mean(axis)(input)
if str(input.dtype).startswith('int'):
# we need to cast eventually anyway, and this helps
# to prevents overflow
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论