Skip to content

Commit 984a07f

Browse files
authored
Merge pull request RasaHQ#5709 from RasaHQ/revert-5565-mask-vs-sequence
Revert model breaking changes in 1.9.x
2 parents 23a5137 + c0b3065 commit 984a07f

File tree

4 files changed

+43
-58
lines changed

4 files changed

+43
-58
lines changed

changelog/5709.bugfix.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Reverted changes in 1.9.6 that led to model incompatibility. Upgrade to 1.9.7 to fix
2+
``self.sequence_lengths_for(tf_batch_data[TEXT_SEQ_LENGTH][0]) IndexError: list index out of range``
3+
error without needing to retrain earlier 1.9 models.
4+
5+
Therefore, all 1.9 models `except for 1.9.6` will be compatible; a model trained on 1.9.6 will need
6+
to be retrained on 1.9.7.

rasa/nlu/classifiers/diet_classifier.py

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@
8787

8888
TEXT_FEATURES = f"{TEXT}_features"
8989
LABEL_FEATURES = f"{LABEL}_features"
90+
TEXT_MASK = f"{TEXT}_mask"
91+
LABEL_MASK = f"{LABEL}_mask"
9092
LABEL_IDS = f"{LABEL}_ids"
9193
TAG_IDS = "tag_ids"
92-
TEXT_SEQ_LENGTH = f"{TEXT}_lengths"
93-
LABEL_SEQ_LENGTH = f"{LABEL}_lengths"
9494

9595

9696
class DIETClassifier(IntentClassifier, EntityExtractor):
@@ -484,7 +484,7 @@ def _create_label_data(
484484
# to track correctly dynamic sequences
485485
label_data.add_features(LABEL_IDS, [np.expand_dims(label_ids, -1)])
486486

487-
label_data.add_lengths(LABEL_SEQ_LENGTH, LABEL_FEATURES)
487+
label_data.add_mask(LABEL_MASK, LABEL_FEATURES)
488488

489489
return label_data
490490

@@ -558,8 +558,8 @@ def _create_model_data(
558558
model_data.add_features(LABEL_IDS, [np.expand_dims(label_ids, -1)])
559559
model_data.add_features(TAG_IDS, [tag_ids])
560560

561-
model_data.add_lengths(TEXT_SEQ_LENGTH, TEXT_FEATURES)
562-
model_data.add_lengths(LABEL_SEQ_LENGTH, LABEL_FEATURES)
561+
model_data.add_mask(TEXT_MASK, TEXT_FEATURES)
562+
model_data.add_mask(LABEL_MASK, LABEL_FEATURES)
563563

564564
return model_data
565565

@@ -1165,6 +1165,10 @@ def _prepare_entity_recognition_layers(self) -> None:
11651165
average="micro",
11661166
)
11671167

1168+
@staticmethod
1169+
def _get_sequence_lengths(mask: tf.Tensor) -> tf.Tensor:
1170+
return tf.cast(tf.reduce_sum(mask[:, :, 0], axis=1), tf.int32)
1171+
11681172
def _combine_sparse_dense_features(
11691173
self,
11701174
features: List[Union[np.ndarray, tf.Tensor, tf.SparseTensor]],
@@ -1246,23 +1250,16 @@ def _create_sequence(
12461250
outputs = self._tf_layers[f"{name}_transformer"](
12471251
transformer_inputs, 1 - mask, self._training
12481252
)
1249-
1250-
if self.config[NUM_TRANSFORMER_LAYERS] > 0:
1251-
# apply activation
1252-
outputs = tfa.activations.gelu(outputs)
1253+
outputs = tfa.activations.gelu(outputs)
12531254

12541255
return outputs, inputs, seq_ids, lm_mask_bool
12551256

12561257
def _create_all_labels(self) -> Tuple[tf.Tensor, tf.Tensor]:
12571258
all_label_ids = self.tf_label_data[LABEL_IDS][0]
1258-
1259-
label_lengths = self.sequence_lengths_for(
1260-
self.tf_label_data[LABEL_SEQ_LENGTH][0]
1261-
)
1262-
mask_label = self._compute_mask(label_lengths)
1263-
12641259
x = self._create_bow(
1265-
self.tf_label_data[LABEL_FEATURES], mask_label, self.label_name,
1260+
self.tf_label_data[LABEL_FEATURES],
1261+
self.tf_label_data[LABEL_MASK][0],
1262+
self.label_name,
12661263
)
12671264
all_labels_embed = self._tf_layers[f"embed.{LABEL}"](x)
12681265

@@ -1356,23 +1353,13 @@ def _calculate_entity_loss(
13561353

13571354
return loss, f1
13581355

1359-
@staticmethod
1360-
def _compute_mask(sequence_lengths: tf.Tensor) -> tf.Tensor:
1361-
mask = tf.sequence_mask(sequence_lengths, dtype=tf.float32)
1362-
# explicitly add last dimension to mask
1363-
# to track correctly dynamic sequences
1364-
return tf.expand_dims(mask, -1)
1365-
1366-
def sequence_lengths_for(self, sequence_lengths: tf.Tensor) -> tf.Tensor:
1367-
return tf.cast(sequence_lengths, dtype=tf.int32)
1368-
13691356
def batch_loss(
13701357
self, batch_in: Union[Tuple[tf.Tensor], Tuple[np.ndarray]]
13711358
) -> tf.Tensor:
13721359
tf_batch_data = self.batch_to_model_data_format(batch_in, self.data_signature)
13731360

1374-
sequence_lengths = self.sequence_lengths_for(tf_batch_data[TEXT_SEQ_LENGTH][0])
1375-
mask_text = self._compute_mask(sequence_lengths)
1361+
mask_text = tf_batch_data[TEXT_MASK][0]
1362+
sequence_lengths = self._get_sequence_lengths(mask_text)
13761363

13771364
(
13781365
text_transformed,
@@ -1401,14 +1388,11 @@ def batch_loss(
14011388
# get _cls_ vector for intent classification
14021389
cls = self._last_token(text_transformed, sequence_lengths)
14031390

1404-
label_lengths = self.sequence_lengths_for(
1405-
tf_batch_data[LABEL_SEQ_LENGTH][0]
1406-
)
1407-
mask_label = self._compute_mask(label_lengths)
1408-
14091391
label_ids = tf_batch_data[LABEL_IDS][0]
14101392
label = self._create_bow(
1411-
tf_batch_data[LABEL_FEATURES], mask_label, self.label_name,
1393+
tf_batch_data[LABEL_FEATURES],
1394+
tf_batch_data[LABEL_MASK][0],
1395+
self.label_name,
14121396
)
14131397
loss, acc = self._calculate_label_loss(cls, label, label_ids)
14141398
self.intent_loss.update_state(loss)
@@ -1434,8 +1418,8 @@ def batch_predict(
14341418
batch_in, self.predict_data_signature
14351419
)
14361420

1437-
sequence_lengths = self.sequence_lengths_for(tf_batch_data[TEXT_SEQ_LENGTH][0])
1438-
mask_text = self._compute_mask(sequence_lengths)
1421+
mask_text = tf_batch_data[TEXT_MASK][0]
1422+
sequence_lengths = self._get_sequence_lengths(mask_text)
14391423

14401424
text_transformed, _, _, _ = self._create_sequence(
14411425
tf_batch_data[TEXT_FEATURES], mask_text, self.text_name

rasa/nlu/selectors/response_selector.py

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
DIET,
1818
TEXT_FEATURES,
1919
LABEL_FEATURES,
20+
TEXT_MASK,
21+
LABEL_MASK,
2022
LABEL_IDS,
21-
TEXT_SEQ_LENGTH,
22-
LABEL_SEQ_LENGTH,
2323
)
2424
from rasa.utils.tensorflow.constants import (
2525
LABEL,
@@ -432,10 +432,8 @@ def _prepare_layers(self) -> None:
432432
def _create_all_labels(self) -> Tuple[tf.Tensor, tf.Tensor]:
433433
all_label_ids = self.tf_label_data[LABEL_IDS][0]
434434

435-
sequence_lengths_label = self.sequence_lengths_for(
436-
self.tf_label_data[LABEL_SEQ_LENGTH][0]
437-
)
438-
mask_label = self._compute_mask(sequence_lengths_label)
435+
mask_label = self.tf_label_data[LABEL_MASK][0]
436+
sequence_lengths_label = self._get_sequence_lengths(mask_label)
439437

440438
label_transformed, _, _, _ = self._create_sequence(
441439
self.tf_label_data[LABEL_FEATURES], mask_label, self.label_name
@@ -451,10 +449,8 @@ def batch_loss(
451449
) -> tf.Tensor:
452450
tf_batch_data = self.batch_to_model_data_format(batch_in, self.data_signature)
453451

454-
sequence_lengths_text = self.sequence_lengths_for(
455-
tf_batch_data[TEXT_SEQ_LENGTH][0]
456-
)
457-
mask_text = self._compute_mask(sequence_lengths_text)
452+
mask_text = tf_batch_data[TEXT_MASK][0]
453+
sequence_lengths_text = self._get_sequence_lengths(mask_text)
458454

459455
(
460456
text_transformed,
@@ -469,10 +465,8 @@ def batch_loss(
469465
sequence_ids=True,
470466
)
471467

472-
sequence_lengths_label = self.sequence_lengths_for(
473-
tf_batch_data[LABEL_SEQ_LENGTH][0]
474-
)
475-
mask_label = self._compute_mask(sequence_lengths_label)
468+
mask_label = tf_batch_data[LABEL_MASK][0]
469+
sequence_lengths_label = self._get_sequence_lengths(mask_label)
476470

477471
label_transformed, _, _, _ = self._create_sequence(
478472
tf_batch_data[LABEL_FEATURES], mask_label, self.label_name
@@ -512,10 +506,8 @@ def batch_predict(
512506
batch_in, self.predict_data_signature
513507
)
514508

515-
sequence_lengths_text = self.sequence_lengths_for(
516-
tf_batch_data[TEXT_SEQ_LENGTH][0]
517-
)
518-
mask_text = self._compute_mask(sequence_lengths_text)
509+
mask_text = tf_batch_data[TEXT_MASK][0]
510+
sequence_lengths_text = self._get_sequence_lengths(mask_text)
519511

520512
text_transformed, _, _, _ = self._create_sequence(
521513
tf_batch_data[TEXT_FEATURES], mask_text, self.text_name

rasa/utils/tensorflow/model_data.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,17 +144,20 @@ def add_features(self, key: Text, features: List[np.ndarray]):
144144
# update number of examples
145145
self.num_examples = self.number_of_examples()
146146

147-
def add_lengths(self, key: Text, from_key: Text) -> None:
148-
"""Adds np.array of lengths of sequences to data under given key."""
147+
def add_mask(self, key: Text, from_key: Text):
148+
"""Calculate mask for given key and put it under specified key."""
149+
149150
if not self.data.get(from_key):
150151
return
151152

152153
self.data[key] = []
153154

154155
for data in self.data[from_key]:
155156
if data.size > 0:
156-
lengths = np.array([x.shape[0] for x in data])
157-
self.data[key].append(lengths)
157+
# explicitly add last dimension to mask
158+
# to track correctly dynamic sequences
159+
mask = np.array([np.ones((x.shape[0], 1)) for x in data])
160+
self.data[key].append(mask)
158161
break
159162

160163
def split(

0 commit comments

Comments
 (0)