提交 112b22f6 authored 作者: Ramana.S's avatar Ramana.S

Updated tutorial/extending_theano.txt

上级 48661f10
......@@ -64,6 +64,13 @@ possibilities you may encounter or need. For that refer to
# Properties attribute
__props__ = ()
#itypes and otypes attributes are
#compulsory if make_node method is not defined.
#They're the type of input and output respectively
itypes = []
otypes = []
#Compulsory if itypes and otypes are not defined
def make_node(self, *inputs):
pass
......@@ -98,7 +105,7 @@ possibilities you may encounter or need. For that refer to
.. ../extending/op.txt
An op has to implement some methods defined in the the interface of
:class:`gof.Op`. More specifically, it is mandatory for an op to define the method :func:`make_node` and one of the implementation methods, either :func:`perform`, :meth:`Op.c_code` or :func:`make_thunk`.
:class:`gof.Op`. More specifically, it is mandatory for an op to define either the method :func:`make_node` or :attr:`itypes`, :attr:`otypes` and one of the implementation methods, either :func:`perform`, :meth:`Op.c_code` or :func:`make_thunk`.
:func:`make_node` method creates an Apply node representing the application
of the op on the inputs provided. This method is reponsible for three things:
......@@ -175,6 +182,10 @@ An op has to implement some methods defined in the the interface of
to obtain the op's implementation.
:func:`perform` and :meth:`Op.c_code` will be ignored.
If :func:`make_node` is not defined, the :attr:`itypes` and :attr:`otypes`
are used by the Op's :func:`make_node` method to implement the functionality
of :func:`make_node` method mentioned above.
Other methods can be optionally defined by the op.
The :func:`__str__` method provides a meaningful string representation of
......@@ -286,6 +297,36 @@ Op Example
return eval_points
return self.grad(inputs, eval_points)
.. testcode:: example (using itypes and otypes)
import theano
class DoubleOp(theano.Op):
__props__ = ()
itypes = [theano.tensor.dmatrix]
otypes = [theano.tensor.dmatrix]
def perform(self, node, inputs, output_storage):
x = inputs[0]
z = output_storage[0]
z[0] = x * 2
def infer_shape(self, node, i0_shapes):
return i0_shapes
def grad(self, inputs, output_grads):
return [output_grads[0] * 2]
def R_op(self, inputs, eval_points):
# R_op can receive None as eval_points.
# That mean there is no diferientiable path through that input
# If this imply that you cannot compute some outputs,
# return None for those.
if eval_points[0] is None:
return eval_points
return self.grad(inputs, eval_points)
You can try it as follows:
.. testcode:: example
......
......@@ -836,7 +836,7 @@ class Op(utils.object2, PureOp, CLinkerOp):
def __eq__(self, other):
if hasattr(self, '__props__'):
return (type(self) == type(other)
and self._props() == other._props())
and self._props() == other._props())
else:
return NotImplemented
......
......@@ -9,7 +9,6 @@ from six import string_types
from theano.gof.type import Type, Generic
from theano.gof.graph import Apply, Variable
import theano.tensor as T
from theano.compile import as_op
from theano import scalar
from theano import shared
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论