提交 eb513f7c authored 作者: Olivier Breuleux's avatar Olivier Breuleux

splitted some topics into advanced, updated advanced tutorial

上级 de95e004
====================
Making the cons type
====================
WRITEME
...@@ -26,22 +26,24 @@ What needs to be defined ...@@ -26,22 +26,24 @@ What needs to be defined
There are less methods to define for an Op than for a Type: There are less methods to define for an Op than for a Type:
- **c_code(node, name, input_names, output_names, sub)** .. function:: c_code(node, name, input_names, output_names, sub)
- This must return C code that carries the computation we want to This must return C code that carries the computation we want to do.
do.
- **c_code_cleanup(node, name, input_names, output_names, sub)** .. function:: c_code_cleanup(node, name, input_names, output_names, sub)
- This must return C code that cleans up whatever c_code allocated This must return C code that cleans up whatever c_code allocated and
and that we must free. that we must free.
- *Default* The default behavior is to do nothing. *Default* The default behavior is to do nothing.
- **c_compile_args(), c_headers(), c_libraries(), c_support_code()** .. function:: c_compile_args()
c_headers()
c_libraries()
c_support_code()
- Allows you to specify headers, libraries, special g++ arguments or Allows you to specify headers, libraries, special g++ arguments or
helper functions/structs that the type needs. See :ref:`op`. helper functions/structs that the type needs. See :ref:`op`.
The ``name`` argument is currently given an invalid value, so steer The ``name`` argument is currently given an invalid value, so steer
......
...@@ -46,38 +46,41 @@ be found in the documentation for :ref:`type`. Here, we'll focus on ...@@ -46,38 +46,41 @@ be found in the documentation for :ref:`type`. Here, we'll focus on
the most important ones: the most important ones:
- **c_declare(name, sub)** .. function:: c_declare(name, sub)
- This must return C code which declares variables. These variables This must return C code which declares variables. These variables
will be available to operations defined in C. You may also write will be available to operations defined in C. You may also write
typedefs. typedefs.
- **c_init(name, sub)** .. function:: c_init(name, sub)
- This must return C code which initializes the variables declared This must return C code which initializes the variables declared in
in c_declare. Either this or c_extract will be called. c_declare. Either this or c_extract will be called.
- **c_extract(name, sub)** .. function:: c_extract(name, sub)
- This must return C code which takes a reference to a Python object This must return C code which takes a reference to a Python object
and initializes the variables declared in c_declare to match the and initializes the variables declared in c_declare to match the
Python object's data. Either this or c_init will be called. Python object's data. Either this or c_init will be called.
- **c_sync(name, sub)** .. function:: c_sync(name, sub)
- When the computations are done, transfer the variables from the C When the computations are done, transfer the variables from the C
structure we put them in to the destination Python object. This structure we put them in to the destination Python object. This will
will only be called for the outputs. only be called for the outputs.
- **c_cleanup(name, sub)** .. function:: c_cleanup(name, sub)
- When we are done using the data, clean up whatever we allocated When we are done using the data, clean up whatever we allocated and
and decrease the appropriate reference counts. decrease the appropriate reference counts.
- **c_compile_args(), c_headers(), c_libraries(), c_support_code()** .. function:: c_compile_args()
c_headers()
c_libraries()
c_support_code()
- Allows you to specify headers, libraries, special g++ arguments or Allows you to specify headers, libraries, special g++ arguments or
helper functions/structs that the type needs. See :ref:`type`. helper functions/structs that the type needs. See :ref:`type`.
Each of these functions take two arguments, ``name`` and ``sub`` which Each of these functions take two arguments, ``name`` and ``sub`` which
......
...@@ -24,7 +24,7 @@ grounding for fundamental Theano concepts. ...@@ -24,7 +24,7 @@ grounding for fundamental Theano concepts.
.. toctree:: .. toctree::
theano_vs_python theano_vs_c
graphstructures graphstructures
type type
op op
......
...@@ -14,44 +14,46 @@ Op's contract ...@@ -14,44 +14,46 @@ Op's contract
An Op (:api:`gof.op.Op`) is any object which defines the following methods: An Op (:api:`gof.op.Op`) is any object which defines the following methods:
- **make_node(*inputs)**
.. function:: make_node(*inputs)
- This method is responsible for creating output Variables of a suitable Type This method is responsible for creating output Variables of a
to serve as the outputs of this Op's application. This method should put these suitable Type to serve as the outputs of this Op's application.
outputs into an Apply instance, and return the Apply instance. This method should put these outputs into an Apply instance, and
return the Apply instance.
- This method creates an Apply node representing the This method creates an Apply node representing the application of
application of the Op on the inputs provided. If the Op cannot be the Op on the inputs provided. If the Op cannot be applied on
applied on these inputs, it must raise an appropriate these inputs, it must raise an appropriate exception.
exception.
- The inputs of the Apply instance returned by this call must be ordered The inputs of the Apply instance returned by this call must be
correctly: a subsequent ``self.make_node(*apply.inputs)`` must produce ordered correctly: a subsequent ``self.make_node(*apply.inputs)``
something equivalent to the first ``apply``. must produce something equivalent to the first ``apply``.
- default_output ``default_output``
- *Default*: None *Default*: None
- If this member variable is an integer, then the default implementation of If this member variable is an integer, then the default
``__call__`` will return `node.outputs[self.default_output]``, where implementation of ``__call__`` will return
`node` was returned by ``make_node``. Otherwise, the entire list of `node.outputs[self.default_output]``, where `node` was returned
outputs will be returned. by ``make_node``. Otherwise, the entire list of outputs will be
returned.
- **__call__(*inputs)** .. function:: __call__(*inputs)
- Syntactic shortcut to make_node which returns the output Variables Syntactic shortcut to make_node which returns the output
of the Op. Variables of the Op.
- *Default*: this is done for you by Op. *Default*: this is done for you by Op.
- **perform(node, inputs, output_storage)** .. function:: perform(node, inputs, output_storage)
- This method computes the function associated to this Op. The This method computes the function associated to this Op. The
``node`` is an Apply node created by the Op's ``make_node`` ``node`` is an Apply node created by the Op's ``make_node``
method, ``inputs`` is a list of references to data to operate on, method, ``inputs`` is a list of references to data to operate on,
and ``output_storage`` is a list of storage cells where the variables of and ``output_storage`` is a list of storage cells where the
the computation must be put. More specifically: variables of the computation must be put. More specifically:
- ``node``: This is a reference to an Apply node which was previously - ``node``: This is a reference to an Apply node which was previously
obtained via ``mul``'s ``make_node`` method. It is typically not obtained via ``mul``'s ``make_node`` method. It is typically not
...@@ -74,108 +76,70 @@ An Op (:api:`gof.op.Op`) is any object which defines the following methods: ...@@ -74,108 +76,70 @@ An Op (:api:`gof.op.Op`) is any object which defines the following methods:
None. This feature can allow perform to reuse memory between calls, for None. This feature can allow perform to reuse memory between calls, for
example. example.
- This method must be determined by the inputs. That is to say, if it is This method must be determined by the inputs. That is to say, if
evaluated once on inputs A and returned B, then if ever inputs C, equal to it is evaluated once on inputs A and returned B, then if ever
A, are presented again, then outputs equal to B must be returned again. inputs C, equal to A, are presented again, then outputs equal to
B must be returned again.
- You must be careful about aliasing outputs to inputs, and making You must be careful about aliasing outputs to inputs, and making
modifications to any of the inputs. See `Views and inplace operations modifications to any of the inputs. See `Views and inplace
<views_and_inplace>`_ operations <views_and_inplace>`_ before writing a ``perform``
before writing a ``perform`` implementation that does either of these implementation that does either of these things.
things.
- **__eq__(self, other)** .. function:: __eq__(other)
- ``other`` is also an Op. ``other`` is also an Op.
- Returning ``True`` here is a promise to the optimization system that the other Returning ``True`` here is a promise to the optimization system
Op will produce exactly the same graph effects (from perform) as this one, that the other Op will produce exactly the same graph effects
given identical inputs. This means it will produce the same output values, (from perform) as this one, given identical inputs. This means it
it will destroy the same inputs (same destroy_map), and will alias outputs will produce the same output values, it will destroy the same
to the same inputs (same view_map). inputs (same destroy_map), and will alias outputs to the same
inputs (same view_map).
- **__hash__(self)** .. function:: __hash__()
- If two Op instances compare equal, then they **must** return the same hash If two Op instances compare equal, then they **must** return the
value. same hash value.
- Equally important, this hash value must not change during the lifetime of Equally important, this hash value must not change during the
self. Op instances should be immutable in this sense. lifetime of self. Op instances should be immutable in this
sense.
- **__ne__(self, other)**
- Recommended .. function:: __ne__(other)
- Default: ``(not (self==other))`` Default: ``(not (self==other))``
- **grad(inputs, output_gradients)** .. function:: grad(inputs, output_gradients)
- Optional. Optional.
- If the Op you are defining is differentiable, you can define its If the Op you are defining is differentiable, you can define its
gradient symbolically in this method. gradient symbolically in this method.
- Both the ``inputs`` and ``output_gradients`` will be Variables. This Both the ``inputs`` and ``output_gradients`` will be
method must return a list containing one Variable (or None) for each Variables. This method must return a list containing one Variable
input. Each returned Variable represents the gradient with respect to (or None) for each input. Each returned Variable represents the
that input given the symbolic gradients with respect to each output. gradient with respect to that input given the symbolic gradients
with respect to each output.
- If the output is not differentiable with respect to any inputs, then this If the output is not differentiable with respect to any inputs,
method should be defined to return [None for i in inputs]. then this method should be defined to return [None for i in
inputs].
- If this method is not defined, then theano assumes it has been forgotten. If this method is not defined, then theano assumes it has been
Symbolic differentiation will fail on a graph that includes this Op. forgotten. Symbolic differentiation will fail on a graph that
includes this Op.
- For more information on the use of this method, see ``grad``. For more information on the use of this method, see ``grad``.
For each method, the *default* is what :api:`theano.gof.op.Op` defines For each method, the *default* is what :api:`theano.gof.op.Op` defines
for you. At a bare minimum, a new Op must define ``make_node`` and for you. At a bare minimum, a new Op must define ``make_node`` and
``perform``, which have no defaults. ``perform``, which have no defaults.
For more details, including the interface for providing a C implementation of For more details, including the interface for providing a C
perform(), refer to the documentation for :ref:`op`. implementation of perform(), refer to the documentation for :ref:`op`.
Checklist
---------
Use this list to make sure that you defined everything you need for your Op:
* Are there parameters that are not inputs but parametrize the behavior of your Op? (see parametrization section below)
* Yes?
* Define ``__init__`` with those parameters. They will be instance variables.
* Override ``__eq__``, ``__ne__`` and ``__hash__`` (optional)
* Consider making pre-made instances for common parameters. This will simplify usage.
* No? (usual case for simple Ops)
* Consider making a singleton of your Op (this can be as simple as
``my_op = MyOp()``). This will save you from having to implement __eq__
and company. The singleton approach does not work when an Op instance
has parameters (Did you pass anything to __init__?)
* Always define *make_node* (see make_node section below).
* Always define *perform* (see perform section below).
* Do you need performance only C can offer?
* Define *c_code* and *c_code_cleanup* (see HowtoMakeCeeOps)
* Remember to use the 'c' or 'c|py' linker on graphs using your Op! [*This is described where?*]
* Is your Op differentiable? Do you want to use it in differentiable
expressions?
* Define *grad* (see grad section below)
* Does your Op modify any of its inputs?
* *IMPORTANT:* read the destroyers and viewers section.
* Does any output from the Op share any sort of state with an input?
* *IMPORTANT:* read the destroyers and viewers section.
* Does your Op have more than one output?
* Consider setting the default_output attribute to the index of that output. (It will make your Op usable in ``PatternOptimizers``, and make user code look like the Op has only that output.)
[*Consider changing the order of the checklist above and the sections below such that the stuff you ALWAYS have to do, which is the most basic stuff anyhow, goes towards the top.*]
Defining an Op: ``mul`` Defining an Op: ``mul``
...@@ -259,28 +223,6 @@ Here, ``z`` is a list of one element. By default, ``z == [None]``. ...@@ -259,28 +223,6 @@ Here, ``z`` is a list of one element. By default, ``z == [None]``.
that a Python ``float`` must be put there. You should not put, say, an that a Python ``float`` must be put there. You should not put, say, an
``int`` in ``z[0]`` because Theano assumes Ops handle typing properly. ``int`` in ``z[0]`` because Theano assumes Ops handle typing properly.
**eq** and **hash**
Correct implementations of eq and hash permit Theano to recognize one
of the most obvious opportunities
for optimization: not repeatedly computing the same thing.
.. code-block:: python
def __eq__(self, other):
return type(self) == type(other) and (self.name == other.name) and (self.fn == other.fn)
def __hash__(self):
return hash(type(self)) ^ hash(self.name) ^ hash(self.fn)
When theano compiles a graph, most Modes first :term:`merge` the graph (this is
done by the :api:`MergeOptimizer`.) The principle of merging is that if the
inputs to two different :ref:`Applies <apply>` are identical and the :ref:`op`s
applied to them compare equal, then those two Apply instances are guaranteed to
produce the same outputs.
So Theano will only compute one of them.
Trying out our new Op Trying out our new Op
===================== =====================
......
...@@ -38,24 +38,24 @@ Global optimization ...@@ -38,24 +38,24 @@ Global optimization
A global optimization (or optimizer) is an object which defines the following A global optimization (or optimizer) is an object which defines the following
methods: methods:
- **apply(env)** .. function:: apply(env)
- This method takes an Env object which contains the computation This method takes an Env object which contains the computation graph
graph and does modifications in line with what the optimization is and does modifications in line with what the optimization is meant
meant to do. This is of the main method of the optimizer. to do. This is of the main method of the optimizer.
- **add_requirements(env)** .. function:: add_requirements(env)
- This method takes an Env object and adds :ref:`features This method takes an Env object and adds :ref:`features
<envfeature>` to it. These features are "plugins" that are needed <envfeature>` to it. These features are "plugins" that are needed
for the apply method to do its job properly. for the apply method to do its job properly.
- **optimize(env)** .. function:: optimize(env)
- This is the interface function called by Theano. This is the interface function called by Theano.
- *Default:* this is defined by Optimizer as ``add_requirement(env); *Default:* this is defined by Optimizer as ``add_requirement(env);
apply(env)``. apply(env)``.
See the section about :ref:`env` to understand how to define these See the section about :ref:`env` to understand how to define these
methods. methods.
...@@ -66,14 +66,14 @@ Local optimization ...@@ -66,14 +66,14 @@ Local optimization
A local optimization is an object which defines the following methods: A local optimization is an object which defines the following methods:
- **transform(node)** .. function:: transform(node)
- This method takes an :ref:`apply` node and returns either False to This method takes an :ref:`apply` node and returns either False to
signify that no changes are to be done or a list of Variables which signify that no changes are to be done or a list of Variables which
matches the length of the node's ``outputs`` list. When the matches the length of the node's ``outputs`` list. When the
LocalOptimizer is applied by a Navigator, the outputs of the node LocalOptimizer is applied by a Navigator, the outputs of the node
passed as argument to the LocalOptimizer will be replaced by the passed as argument to the LocalOptimizer will be replaced by the
list returned. list returned.
...@@ -380,21 +380,21 @@ A Query is built by the following call: ...@@ -380,21 +380,21 @@ A Query is built by the following call:
theano.gof.Query(include, require = None, exclude = None, subquery = None) theano.gof.Query(include, require = None, exclude = None, subquery = None)
* **include**: a set of tags (a tag being a string) such that every **include**: a set of tags (a tag being a string) such that every
optimization obtained through this Query must have **one** of the optimization obtained through this Query must have **one** of the tags
tags listed. This field is required and basically acts as a listed. This field is required and basically acts as a starting point
starting point for the search. for the search.
* **require**: a set of tags such that every optimization obtained **require**: a set of tags such that every optimization obtained
through this Query must have **all** of these tags. through this Query must have **all** of these tags.
* **exclude**: a set of tags such that every optimization obtained **exclude**: a set of tags such that every optimization obtained
through this Query must have **none** of these tags. through this Query must have **none** of these tags.
* **subquery**: optdb can contain sub-databases; subquery is a **subquery**: optdb can contain sub-databases; subquery is a
dictionary mapping the name of a sub-database to a special Query. dictionary mapping the name of a sub-database to a special Query. If
If no subquery is given for a sub-database, the original Query no subquery is given for a sub-database, the original Query will be
will be used again. used again.
Furthermore, a Query object includes three methods, ``including``, Furthermore, a Query object includes three methods, ``including``,
``requiring`` and ``excluding`` which each produce a new Query object ``requiring`` and ``excluding`` which each produce a new Query object
...@@ -454,8 +454,8 @@ Theano defines two EquilibriumDBs where you can put local ...@@ -454,8 +454,8 @@ Theano defines two EquilibriumDBs where you can put local
optimizations: optimizations:
* **canonicalize**: this contains optimizations that aim to *simplify* **canonicalize**: this contains optimizations that aim to *simplify*
the graph: the graph:
* Replace rare or esoterical operations with their equivalents using * Replace rare or esoterical operations with their equivalents using
elementary operations. elementary operations.
...@@ -467,8 +467,8 @@ optimizations: ...@@ -467,8 +467,8 @@ optimizations:
* Fold constants (Constant(2)*Constant(2) becomes Constant(4)) * Fold constants (Constant(2)*Constant(2) becomes Constant(4))
* **specialize**: this contains optimizations that aim to *specialize* **specialize**: this contains optimizations that aim to *specialize*
the graph: the graph:
* Replace a combination of operations with a special operation that * Replace a combination of operations with a special operation that
does the same thing (but better). does the same thing (but better).
......
.. _theano_vs_python: .. _theano_vs_c:
====================== ============
Theano vs. Python Theano vs. C
====================== ============
We describe some of the patterns in Theano, and present their closest We describe some of the patterns in Theano, and present their closest
analogue in Python: analogue in a statically typed language such as C:
=============== =========================================================== =============== ===========================================================
Theano Python Theano C
=============== =========================================================== =============== ===========================================================
Apply function application / function call Apply function application / function call
Variable function data / variable Variable function data / variable
...@@ -17,3 +17,25 @@ Op operations carried out in computation / function definition ...@@ -17,3 +17,25 @@ Op operations carried out in computation / function definition
Type data types Type data types
Module ??? class? Module ??? class?
=============== =========================================================== =============== ===========================================================
For example:
.. code-block:: c
int main(int a) {
int b = 3;
int c = f(b)
return g(a, c);
}
Based on this code snippet, we can relate f and g to Ops, a, b and c
to Variables, g(a, c) and f(b) (taken as meaning the action of
computing f or g on their respective inputs) to Applies. Lastly, int
could be interpreted as the Theano Type of the Variables a and b.
...@@ -22,69 +22,69 @@ i.e. the same default argument names and values. If you wish to add ...@@ -22,69 +22,69 @@ i.e. the same default argument names and values. If you wish to add
extra arguments to any of these methods, these extra arguments must have extra arguments to any of these methods, these extra arguments must have
default values. default values.
- **filter(value, strict=False)** .. function:: filter(value, strict=False)
- This casts a value to match the Type and returns the This casts a value to match the Type and returns the
casted value. If ``value`` is incompatible with the Type, casted value. If ``value`` is incompatible with the Type,
the method must raise an exception. If ``strict`` is True, ``filter`` must return a the method must raise an exception. If ``strict`` is True, ``filter`` must return a
reference to ``value`` (i.e. casting prohibited) reference to ``value`` (i.e. casting prohibited)
We need to define ``filter`` with two arguments. The second argument We need to define ``filter`` with two arguments. The second argument
must be called ``strict`` (Theano often calls it by keyword) and must must be called ``strict`` (Theano often calls it by keyword) and must
have a default value of ``False``. have a default value of ``False``.
- **is_valid_value(value)** .. function:: is_valid_value(value)
- Returns True iff the value is compatible with the Type. If Returns True iff the value is compatible with the Type. If
``filter(value, strict = True)`` does not raise an exception, the ``filter(value, strict = True)`` does not raise an exception, the
value is compatible with the Type. value is compatible with the Type.
- *Default*: True iff ``filter(value, strict = True)`` does not raise an *Default*: True iff ``filter(value, strict = True)`` does not raise
exception. an exception.
- **values_eq(a, b)** .. function:: values_eq(a, b)
- Returns True iff ``a`` and ``b`` are equal. Returns True iff ``a`` and ``b`` are equal.
- *Default*: ``a == b`` *Default*: ``a == b``
- **values_eq_approx(a, b)** .. function:: values_eq_approx(a, b)
- Returns True iff ``a`` and ``b`` Returns True iff ``a`` and ``b`` are approximately equal, for a
are approximately equal, for a definition of "approximately" which definition of "approximately" which varies from Type to Type.
varies from Type to Type.
- *Default*: ``values_eq(a, b)`` *Default*: ``values_eq(a, b)``
- **make_variable(name=None)** .. function:: make_variable(name=None)
- Makes a :term:`Variable` of this Type with the specified name, if Makes a :term:`Variable` of this Type with the specified name, if
``name is not None``. If ``name is ``None``, then the Variable does ``name is not None``. If ``name is ``None``, then the Variable does
not have a name. The Variable will have its ``type`` field set to the not have a name. The Variable will have its ``type`` field set to
Type object. the Type object.
- *Default*: there is a generic definition of this in Type. The Variable's *Default*: there is a generic definition of this in Type. The
``type`` will be the object that defines this method (in other words, Variable's ``type`` will be the object that defines this method (in
``self``). other words, ``self``).
- **__call__(name=None)**: .. function:: __call__(name=None)
- Syntactic shortcut to ``make_variable``. Syntactic shortcut to ``make_variable``.
- *Default*: ``make_variable`` *Default*: ``make_variable``
- **__eq__(self, other)**: .. function:: __eq__(other)
- Used to compare Type instances themselves Used to compare Type instances themselves
- *Default*: ``object.__eq__`` *Default*: ``object.__eq__``
- **__hash__(self)**: .. function:: __hash__()
- Types should not be mutable, so it should be Ok to define a hash function. Types should not be mutable, so it should be Ok to define a hash
Typically this function should hash all of the terms involved in ``__eq__``. function. Typically this function should hash all of the terms
involved in ``__eq__``.
- *Default*: ``id(self)`` *Default*: ``id(self)``
For each method, the *default* is what ``Type`` defines For each method, the *default* is what ``Type`` defines
for you. So, if you create an instance of ``Type`` or an for you. So, if you create an instance of ``Type`` or an
......
...@@ -30,6 +30,5 @@ Now we're ready for the tour: ...@@ -30,6 +30,5 @@ Now we're ready for the tour:
adding adding
examples examples
function
module module
tools tools
...@@ -8,12 +8,14 @@ Contents ...@@ -8,12 +8,14 @@ Contents
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
LICENSE index
introduction introduction
LICENSE
install install
basic_tutorial/index basic_tutorial/index
advanced_tutorial/index advanced_tutorial/index
topics/index topics/index
advanced/index
indexes/index indexes/index
glossary glossary
links links
......
...@@ -144,9 +144,9 @@ Generating the documentation ...@@ -144,9 +144,9 @@ Generating the documentation
---------------------------- ----------------------------
You can read the latest HTML documentation `here You can read the latest HTML documentation `here
<http://pylearn.org/theano/contents.html>`_. <http://pylearn.org/theano/contents.html>`__.
You can download the latest PDF documentation `here You can download the latest PDF documentation `here
<http://pylearn.org/theano/theano.pdf`_. <http://pylearn.org/theano/theano.pdf`__.
We recommend you look at the documentation on the website, since it We recommend you look at the documentation on the website, since it
will be more current than the documentation included with the package. will be more current than the documentation included with the package.
......
.. _function: .. _usingfunction:
=============== =====================
theano.function Using theano.function
=============== =====================
This page is about ``theano.function``, the interface for compiling graphs into callable objects. This page is about ``theano.function``, the interface for compiling graphs into callable objects.
......
.. _advanced: .. _topics:
=============== ======
Advanced Topics Topics
=============== ======
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
function
pipeline pipeline
unittest
profilemode profilemode
debugmode debugmode
debug_faq
module_vs_op module_vs_op
randomstreams randomstreams
.. env
.. features
.. optimization
.. compilation
.. ccodegen
.. function
.. module
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论