4
4
import numpy as np
5
5
import tensorflow as tf
6
6
7
- from neuralmonkey .logging import notice
8
7
from neuralmonkey .model .model_part import GenericModelPart
9
8
from neuralmonkey .model .feedable import Feedable
10
9
from neuralmonkey .model .parameterized import Parameterized
@@ -25,7 +24,7 @@ class ExecutionResult(NamedTuple(
25
24
("scalar_summaries" , tf .Summary ),
26
25
("histogram_summaries" , tf .Summary ),
27
26
("image_summaries" , tf .Summary )])):
28
- """A data structure that represents a result of a graph execution.
27
+ """A data structure that represents the result of a graph execution.
29
28
30
29
The goal of each runner is to populate this structure and set it as its
31
30
``self._result``.
@@ -40,8 +39,41 @@ class ExecutionResult(NamedTuple(
40
39
41
40
42
41
class GraphExecutor (GenericModelPart ):
42
+ """The abstract parent class of all graph executors.
43
+
44
+ In Neural Monkey, a graph executor is an object that retrieves tensors
45
+ from the computational graph. The two major groups of graph executors are
46
+ trainers and runners.
47
+
48
+ Each graph executor is an instance of `GenericModelPart` class, which means
49
+ it has parameterized and feedable dependencies which reference the model
50
+ part objects needed to be created in order to compute the tensors of
51
+ interest (called "fetches").
52
+
53
+ Every graph executor has a method called `get_executable`, which returns
54
+ an `GraphExecutor.Executable` instance, which specifies what tensors to
55
+ execute and collects results from the session execution.
56
+ """
43
57
44
58
class Executable (Generic [Executor ]):
59
+ """Abstract base class for executables.
60
+
61
+ Executables are objects associated with the graph executors. Each
62
+ executable has two main functions: `next_to_execute` and
63
+ `collect_results`. These functions are called in a loop, until
64
+ the executable's result has been set.
65
+
66
+ To make use of Mypy's type checking, the executables are generic and
67
+ are parameterized by the type of their graph executor. Since Python
68
+ does not know the concept of nested classes, each executable receives
69
+ the instance of the graph executor through its constructor.
70
+
71
+ When subclassing `GraphExecutor`, it is also necessary to subclass
72
+ the `Executable` class and name it `Executable`, so it overrides the
73
+ definition of this class. Following this guideline, the default
74
+ implementation of the `get_executable` function on the graph executor
75
+ will work without the need of overriding it.
76
+ """
45
77
46
78
def __init__ (self ,
47
79
executor : Executor ,
@@ -110,6 +142,12 @@ def parameterizeds(self) -> Set[Parameterized]:
110
142
111
143
112
144
class BaseRunner (GraphExecutor , Generic [MP ]):
145
+ """Base class for runners.
146
+
147
+ Runners are graph executors that retrieve tensors from the model without
148
+ changing the model parameters. Each runner has a top-level model part it
149
+ relates to.
150
+ """
113
151
114
152
# pylint: disable=too-few-public-methods
115
153
# Pylint issue here: https://github.com/PyCQA/pylint/issues/2607
@@ -130,12 +168,9 @@ def __init__(self,
130
168
decoder : MP ) -> None :
131
169
GraphExecutor .__init__ (self , {decoder })
132
170
self .output_series = output_series
171
+ # TODO(tf-data) rename decoder to something more general
133
172
self .decoder = decoder
134
173
135
- if not hasattr (decoder , "data_id" ):
136
- notice ("Top-level decoder {} does not have the 'data_id' attribute"
137
- .format (decoder ))
138
-
139
174
@property
140
175
def decoder_data_id (self ) -> Optional [str ]:
141
176
return getattr (self .decoder , "data_id" , None )
0 commit comments