提交 ec57ef26 authored 作者: James Bergstra's avatar James Bergstra

merge

...@@ -12,9 +12,9 @@ Type's contract ...@@ -12,9 +12,9 @@ Type's contract
In Theano's framework, a Type is any object which defines the following In Theano's framework, a Type is any object which defines the following
methods. To obtain the default methods described below, the Type should methods. To obtain the default methods described below, the Type should
be an instance of :api:``theano.gof.Type`` or should be an instance of a be an instance of :api:`theano.gof.Type` or should be an instance of a
subclass of :api:``theano.gof.Type``. If you will write all methods yourself, subclass of :api:`theano.gof.Type`. If you will write all methods yourself,
you need not use an instance of :api:``theano.gof.Type``. you need not use an instance of :api:`theano.gof.Type`.
Methods with default arguments must be defined with the same signature, Methods with default arguments must be defined with the same signature,
i.e. the same default argument names and values. If you wish to add i.e. the same default argument names and values. If you wish to add
...@@ -73,9 +73,9 @@ default values. ...@@ -73,9 +73,9 @@ default values.
- *Default*: ``make_variable`` - *Default*: ``make_variable``
For each method, the *default* is what :api:``theano.gof.Type`` defines For each method, the *default* is what :api:`theano.gof.Type` defines
for you. So, if you create an instance of :api:``theano.gof.Type`` or an for you. So, if you create an instance of :api:`theano.gof.Type` or an
instance of a subclass of :api:``theano.gof.Type``, you instance of a subclass of :api:`theano.gof.Type`, you
must define ``filter``. You might want to override ``values_eq_approx``, must define ``filter``. You might want to override ``values_eq_approx``,
as well as ``values_eq``. The other defaults generally need not be as well as ``values_eq``. The other defaults generally need not be
overridden. overridden.
...@@ -135,7 +135,7 @@ chose to be 1e-4. ...@@ -135,7 +135,7 @@ chose to be 1e-4.
.. note:: .. note::
``values_eq`` is never actually used by Theano, but it might be used ``values_eq`` is never actually used by Theano, but it might be used
internally in the future. Currently, all equality testing is done internally in the future. Equality testing in DebugMode is done
using ``values_eq_approx``. using ``values_eq_approx``.
**Putting them together** **Putting them together**
...@@ -185,15 +185,15 @@ instances of ``Double`` are technically the same Type. However, different ...@@ -185,15 +185,15 @@ instances of ``Double`` are technically the same Type. However, different
>>> double1 == double2 >>> double1 == double2
False False
Theano often compares Types using ``==`` to see if they are the same. If Theano compares Types using ``==`` to see if they are the same. If
the inputs of two different :ref:`Applies <apply>` have the same Type the inputs of two different :ref:`Applies <apply>` are the same
and the :ref:`op` applied on them is the same, they can be :term:`merged and two :ref:`op`s applied to them compare equal, then only one of those ops
<merge>`. must be evaluated. (This is sometimes called a :term:`merging <merge>` and it
is done by the :api:`MergeOptimizer`.)
There are several ways to make it that instances of Type ``Double`` There are several ways to make sure graphs are merged properly:
compare equal:
#. Define ``Double.__eq__`` so that all instances of type Double #. Define ``Double.__eq__`` so that instances of type Double
are equal. For example: are equal. For example:
.. code-block:: python .. code-block:: python
...@@ -202,9 +202,10 @@ compare equal: ...@@ -202,9 +202,10 @@ compare equal:
return type(self) is Double and type(other) is Double return type(self) is Double and type(other) is Double
#. Override ``Double.__new__`` to always return the same instance. #. Override ``Double.__new__`` to always return the same instance.
#. Hide Double and only publish a single instance of it. #. Hide the Double class and only advertise a single instance of it.
We prefer the final option, because it's the simplest. Here we will prefer the final option, because it's the simplest.
Often Ops in the theano code define the ``__eq__`` function though.
Untangling some concepts Untangling some concepts
......
...@@ -8,7 +8,7 @@ Graph Structures ...@@ -8,7 +8,7 @@ Graph Structures
Theano represents symbolic mathematical computations as graphs. These Theano represents symbolic mathematical computations as graphs. These
graphs are composed of interconnected :ref:`apply` and :ref:`variable` graphs are composed of interconnected :ref:`apply` and :ref:`variable`
nodes. They are associated to *function application* and *data*, nodes. They are associated to *function application* and *data*,
respectively. Operations are represented :ref:`op` instances and data respectively. Operations are represented by :ref:`op` instances and data
types are represented by :ref:`type` instances. Here is a piece of code types are represented by :ref:`type` instances. Here is a piece of code
and a diagram showing the structure built by that piece of code. This and a diagram showing the structure built by that piece of code. This
should help you understand how these pieces fit together: should help you understand how these pieces fit together:
...@@ -40,24 +40,26 @@ bi-partite, directed, acyclic graph. Variables point to the Apply nodes ...@@ -40,24 +40,26 @@ bi-partite, directed, acyclic graph. Variables point to the Apply nodes
representing the function application producing them via their representing the function application producing them via their
``owner`` field. These Apply nodes point in turn to their input and ``owner`` field. These Apply nodes point in turn to their input and
output Variables via their ``inputs`` and ``outputs`` fields. output Variables via their ``inputs`` and ``outputs`` fields.
(Apply instances also contain a list of references to their ``outputs``, but
those pointers don't count in this graph.)
The ``owner`` field of both ``x`` and ``y`` point to ``None`` because The ``owner`` field of both ``x`` and ``y`` point to ``None`` because
they are not the variable of another computation. If they were the they are not the result of another computation. If one of them was the
variable of another computation, they would point to another blue box result of another computation, it's ``owner`` field would point to another
like ``z`` does, and so on. blue box like ``z`` does, and so on.
Note that the ``Apply`` instance's outputs points to Note that the ``Apply`` instance's outputs points to
``z``. ``z.owner`` points to the ``Apply`` instance. ``z``, and ``z.owner`` points back to the ``Apply`` instance.
An explicit example An explicit example
=================== ===================
In this example we will see in turn a short example in which the In this example we will compare two ways of defining the same graph.
graph construction is hidden behind the standard interface's syntactic First, a short bit of code will build an expression (graph) the *normal* way, with most of the
shortcuts. We will then see the same example but rolled out so that the graph construction being done automatically.
graph construction is made explicit. Second, we will walk through a longer re-coding of the same thing
without any shortcuts that will make the graph construction very explicit.
**Short example** **Short example**
...@@ -332,5 +334,5 @@ eligible to participate in numerous optimizations: constant inlining ...@@ -332,5 +334,5 @@ eligible to participate in numerous optimizations: constant inlining
in C code, constant folding, etc. in C code, constant folding, etc.
A constant does not need to be specified in a :ref:`function`'s list A constant does not need to be specified in a :ref:`function`'s list
of inputs. of inputs. In fact, doing so will raise an exception.
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论