Skip to content

Commit 8326820

Browse files
authored
Merge pull request #459 from ufal/decoders_refactor
`@tensor` to non-recurrent decoders
2 parents 436e05a + 9260fc5 commit 8326820

File tree

4 files changed

+112
-218
lines changed

4 files changed

+112
-218
lines changed

neuralmonkey/decoders/ctc_decoder.py

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,33 +32,41 @@ def __init__(self,
3232
self.vocabulary = vocabulary
3333
self.data_id = data_id
3434

35-
self._merge_repeated_targets = merge_repeated_targets
36-
self._merge_repeated_outputs = merge_repeated_outputs
37-
self._beam_width = beam_width
38-
39-
with self.use_scope():
40-
self.train_targets = tf.sparse_placeholder(tf.int32,
41-
name="targets")
42-
43-
self.train_mode = tf.placeholder(tf.bool, name="train_mode")
44-
45-
# encoder.states_mask is batch-major
46-
self._input_lengths = tf.reduce_sum(
47-
tf.to_int32(self.encoder.states_mask), 1)
48-
49-
if beam_width == 1:
50-
decoded, _ = tf.nn.ctc_greedy_decoder(
51-
inputs=self._logits, sequence_length=self._input_lengths,
52-
merge_repeated=self._merge_repeated_outputs)
53-
else:
54-
decoded, _ = tf.nn.ctc_beam_search_decoder(
55-
inputs=self._logits, sequence_length=self._input_lengths,
56-
beam_width=self._beam_width,
57-
merge_repeated=self._merge_repeated_outputs)
58-
59-
self.decoded = tf.sparse_tensor_to_dense(
60-
tf.sparse_transpose(decoded[0]),
61-
default_value=self.vocabulary.get_word_index(END_TOKEN))
35+
self.merge_repeated_targets = merge_repeated_targets
36+
self.merge_repeated_outputs = merge_repeated_outputs
37+
self.beam_width = beam_width
38+
# pylint: enable=too-many-arguments
39+
40+
# pylint: disable=no-self-use
41+
@tensor
42+
def train_targets(self) -> tf.Tensor:
43+
return tf.sparse_placeholder(tf.int32, name="targets")
44+
45+
@tensor
46+
def train_mode(self) -> tf.Tensor:
47+
return tf.placeholder(tf.bool, name="train_mode")
48+
# pylint: disable=no-self-use
49+
50+
@tensor
51+
def input_lengths(self) -> tf.Tensor:
52+
# encoder.states_mask is batch-major
53+
return tf.reduce_sum(tf.to_int32(self.encoder.states_mask), 1)
54+
55+
@tensor
56+
def decoded(self) -> tf.Tensor:
57+
if self.beam_width == 1:
58+
decoded, _ = tf.nn.ctc_greedy_decoder(
59+
inputs=self.logits, sequence_length=self.input_lengths,
60+
merge_repeated=self.merge_repeated_outputs)
61+
else:
62+
decoded, _ = tf.nn.ctc_beam_search_decoder(
63+
inputs=self.logits, sequence_length=self.input_lengths,
64+
beam_width=self.beam_width,
65+
merge_repeated=self.merge_repeated_outputs)
66+
67+
return tf.sparse_tensor_to_dense(
68+
tf.sparse_transpose(decoded[0]),
69+
default_value=self.vocabulary.get_word_index(END_TOKEN))
6270

6371
@property
6472
def train_loss(self) -> tf.Tensor:
@@ -71,15 +79,15 @@ def runtime_loss(self) -> tf.Tensor:
7179
@tensor
7280
def cost(self) -> tf.Tensor:
7381
loss = tf.nn.ctc_loss(
74-
labels=self.train_targets, inputs=self._logits,
75-
sequence_length=self._input_lengths,
76-
preprocess_collapse_repeated=self._merge_repeated_targets,
77-
ctc_merge_repeated=self._merge_repeated_outputs)
82+
labels=self.train_targets, inputs=self.logits,
83+
sequence_length=self.input_lengths,
84+
preprocess_collapse_repeated=self.merge_repeated_targets,
85+
ctc_merge_repeated=self.merge_repeated_outputs)
7886

7987
return tf.reduce_sum(loss)
8088

8189
@tensor
82-
def _logits(self) -> tf.Tensor:
90+
def logits(self) -> tf.Tensor:
8391
vocabulary_size = len(self.vocabulary)
8492

8593
encoder_states = self.encoder.hidden_states

neuralmonkey/decoders/multi_decoder.py

Lines changed: 0 additions & 148 deletions
This file was deleted.

neuralmonkey/decoders/sequence_classifier.py

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@
66
from neuralmonkey.vocabulary import Vocabulary
77
from neuralmonkey.model.model_part import ModelPart, FeedDict
88
from neuralmonkey.nn.mlp import MultilayerPerceptron
9-
10-
11-
# pylint: disable=too-many-instance-attributes
9+
from neuralmonkey.decorators import tensor
1210

1311

1412
class SequenceClassifier(ModelPart):
@@ -53,36 +51,62 @@ def __init__(self,
5351
self.dropout_keep_prob = dropout_keep_prob
5452
self.max_output_len = 1
5553

56-
with self.use_scope():
57-
self.train_mode = tf.placeholder(tf.bool, name="train_mode")
58-
self.learning_step = tf.get_variable(
59-
"learning_step", [], trainable=False,
60-
initializer=tf.constant_initializer(0))
61-
62-
self.gt_inputs = [tf.placeholder(
63-
tf.int32, shape=[None], name="targets")]
64-
mlp_input = tf.concat([enc.encoded for enc in encoders], 1)
65-
mlp = MultilayerPerceptron(
66-
mlp_input, layers, self.dropout_keep_prob, len(vocabulary),
67-
activation_fn=self.activation_fn, train_mode=self.train_mode)
68-
69-
self.loss_with_gt_ins = tf.reduce_mean(
70-
tf.nn.sparse_softmax_cross_entropy_with_logits(
71-
logits=mlp.logits, labels=self.gt_inputs[0]))
72-
self.loss_with_decoded_ins = self.loss_with_gt_ins
73-
self.cost = self.loss_with_gt_ins
74-
75-
self.decoded_seq = [mlp.classification]
76-
self.decoded_logits = [mlp.logits]
77-
self.runtime_logprobs = [tf.nn.log_softmax(mlp.logits)]
78-
79-
tf.summary.scalar(
80-
'val_optimization_cost', self.cost,
81-
collections=["summary_val"])
82-
tf.summary.scalar(
83-
'train_optimization_cost',
84-
self.cost, collections=["summary_train"])
85-
# pylint: enable=too-many-arguments
54+
tf.summary.scalar(
55+
'train_optimization_cost',
56+
self.cost, collections=["summary_train"])
57+
# pylint: enable=too-many-arguments
58+
59+
# pylint: disable=no-self-use
60+
@tensor
61+
def train_mode(self) -> tf.Tensor:
62+
return tf.placeholder(tf.bool, name="train_mode")
63+
64+
@tensor
65+
def gt_inputs(self) -> List[tf.Tensor]:
66+
return [tf.placeholder(tf.int32, shape=[None], name="targets")]
67+
# pylint: enable=no-self-use
68+
69+
@tensor
70+
def _mlp(self) -> MultilayerPerceptron:
71+
mlp_input = tf.concat([enc.encoded for enc in self.encoders], 1)
72+
return MultilayerPerceptron(
73+
mlp_input, self.layers,
74+
self.dropout_keep_prob, len(self.vocabulary),
75+
activation_fn=self.activation_fn, train_mode=self.train_mode)
76+
77+
@tensor
78+
def loss_with_gt_ins(self) -> tf.Tensor:
79+
# pylint: disable=no-member,unsubscriptable-object
80+
return tf.reduce_mean(
81+
tf.nn.sparse_softmax_cross_entropy_with_logits(
82+
logits=self._mlp.logits, labels=self.gt_inputs[0]))
83+
# pylint: enable=no-member,unsubscriptable-object
84+
85+
@property
86+
def loss_with_decoded_ins(self) -> tf.Tensor:
87+
return self.loss_with_gt_ins
88+
89+
@property
90+
def cost(self) -> tf.Tensor:
91+
return self.loss_with_gt_ins
92+
93+
@tensor
94+
def decoded_seq(self) -> List[tf.Tensor]:
95+
# pylint: disable=no-member
96+
return [self._mlp.classification]
97+
# pylint: enable=no-member
98+
99+
@tensor
100+
def decoded_logits(self) -> List[tf.Tensor]:
101+
# pylint: disable=no-member
102+
return [self._mlp.logits]
103+
# pylint: enable=no-member
104+
105+
@tensor
106+
def runtime_logprobs(self) -> List[tf.Tensor]:
107+
# pylint: disable=no-member
108+
return [tf.nn.log_softmax(self._mlp.logits)]
109+
# pylint: enable=no-member
86110

87111
@property
88112
def train_loss(self):
@@ -108,7 +132,9 @@ def feed_dict(self, dataset: Dataset, train: bool = False) -> FeedDict:
108132
label_tensors, _ = self.vocabulary.sentences_to_tensor(
109133
sentences_list, self.max_output_len)
110134

135+
# pylint: disable=unsubscriptable-object
111136
fd[self.gt_inputs[0]] = label_tensors[0]
137+
# pylint: enable=unsubscriptable-object
112138

113139
fd[self.train_mode] = train
114140

neuralmonkey/decoders/sequence_labeler.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,21 @@ def __init__(self,
3030
self.rnn_size = self.encoder.rnn_size * 2
3131
self.max_output_len = self.encoder.max_input_len
3232

33-
self.train_targets = tf.placeholder(tf.int32, shape=[None, None],
34-
name="labeler_targets")
33+
# pylint: disable=no-self-use
34+
@tensor
35+
def train_targets(self) -> tf.Tensor:
36+
return tf.placeholder(tf.int32, shape=[None, None],
37+
name="labeler_targets")
3538

36-
self.train_weights = tf.placeholder(tf.float32, shape=[None, None],
37-
name="labeler_padding_weights")
39+
@tensor
40+
def train_weights(self) -> tf.Tensor:
41+
return tf.placeholder(tf.float32, shape=[None, None],
42+
name="labeler_padding_weights")
3843

39-
self.train_mode = tf.placeholder(tf.bool, name="train_mode")
44+
@tensor
45+
def train_mode(self) -> tf.Tensor:
46+
return tf.placeholder(tf.bool, name="train_mode")
47+
# pylint: enable=no-self-use
4048

4149
@property
4250
def train_loss(self) -> tf.Tensor:

0 commit comments

Comments
 (0)