38
38
from rasa .shared .nlu .interpreter import NaturalLanguageInterpreter
39
39
from rasa .core .policies .policy import Policy , PolicyPrediction
40
40
from rasa .core .constants import DEFAULT_POLICY_PRIORITY , DIALOGUE
41
+ from rasa .shared .constants import DIAGNOSTIC_DATA
41
42
from rasa .shared .core .constants import ACTIVE_LOOP , SLOTS , ACTION_LISTEN_NAME
42
43
from rasa .shared .core .trackers import DialogueStateTracker
43
44
from rasa .shared .core .generator import TrackerWithCachedStates
50
51
Data ,
51
52
)
52
53
from rasa .utils .tensorflow .model_data_utils import convert_to_data_format
54
+ import rasa .utils .tensorflow .numpy
53
55
from rasa .utils .tensorflow .constants import (
54
56
LABEL ,
55
57
IDS ,
@@ -632,6 +634,9 @@ def predict_action_probabilities(
632
634
confidence .tolist (),
633
635
is_end_to_end_prediction = is_e2e_prediction ,
634
636
optional_events = optional_events ,
637
+ diagnostic_data = rasa .utils .tensorflow .numpy .values_to_numpy (
638
+ output .get (DIAGNOSTIC_DATA )
639
+ ),
635
640
)
636
641
637
642
def _create_optional_event_for_entities (
@@ -1050,14 +1055,23 @@ def _embed_dialogue(
1050
1055
self ,
1051
1056
dialogue_in : tf .Tensor ,
1052
1057
tf_batch_data : Dict [Text , Dict [Text , List [tf .Tensor ]]],
1053
- ) -> Tuple [tf .Tensor , tf .Tensor , tf .Tensor ]:
1054
- """Create dialogue level embedding and mask."""
1058
+ ) -> Tuple [tf .Tensor , tf .Tensor , tf .Tensor , Optional [tf .Tensor ]]:
1059
+ """Creates dialogue level embedding and mask.
1060
+
1061
+ Args:
1062
+ dialogue_in: The encoded dialogue.
1063
+ tf_batch_data: Batch in model data format.
1064
+
1065
+ Returns:
1066
+ The dialogue embedding, the mask, and (for diagnostic purposes)
1067
+ also the attention weights.
1068
+ """
1055
1069
dialogue_lengths = tf .cast (tf_batch_data [DIALOGUE ][LENGTH ][0 ], tf .int32 )
1056
1070
mask = self ._compute_mask (dialogue_lengths )
1057
1071
1058
- dialogue_transformed = self ._tf_layers [f"transformer. { DIALOGUE } " ](
1059
- dialogue_in , 1 - mask , self . _training
1060
- )
1072
+ dialogue_transformed , attention_weights = self ._tf_layers [
1073
+ f"transformer. { DIALOGUE } "
1074
+ ]( dialogue_in , 1 - mask , self . _training )
1061
1075
dialogue_transformed = tfa .activations .gelu (dialogue_transformed )
1062
1076
1063
1077
if self .use_only_last_dialogue_turns :
@@ -1069,7 +1083,7 @@ def _embed_dialogue(
1069
1083
1070
1084
dialogue_embed = self ._tf_layers [f"embed.{ DIALOGUE } " ](dialogue_transformed )
1071
1085
1072
- return dialogue_embed , mask , dialogue_transformed
1086
+ return dialogue_embed , mask , dialogue_transformed , attention_weights
1073
1087
1074
1088
def _encode_features_per_attribute (
1075
1089
self , tf_batch_data : Dict [Text , Dict [Text , List [tf .Tensor ]]], attribute : Text
@@ -1615,6 +1629,7 @@ def batch_loss(
1615
1629
dialogue_embed ,
1616
1630
dialogue_mask ,
1617
1631
dialogue_transformer_output ,
1632
+ _ ,
1618
1633
) = self ._embed_dialogue (dialogue_in , tf_batch_data )
1619
1634
dialogue_mask = tf .squeeze (dialogue_mask , axis = - 1 )
1620
1635
@@ -1686,6 +1701,7 @@ def batch_predict(
1686
1701
dialogue_embed ,
1687
1702
dialogue_mask ,
1688
1703
dialogue_transformer_output ,
1704
+ attention_weights ,
1689
1705
) = self ._embed_dialogue (dialogue_in , tf_batch_data )
1690
1706
dialogue_mask = tf .squeeze (dialogue_mask , axis = - 1 )
1691
1707
@@ -1698,7 +1714,11 @@ def batch_predict(
1698
1714
scores = self ._tf_layers [f"loss.{ LABEL } " ].confidence_from_sim (
1699
1715
sim_all , self .config [SIMILARITY_TYPE ]
1700
1716
)
1701
- predictions = {"action_scores" : scores , "similarities" : sim_all }
1717
+ predictions = {
1718
+ "action_scores" : scores ,
1719
+ "similarities" : sim_all ,
1720
+ DIAGNOSTIC_DATA : {"attention_weights" : attention_weights },
1721
+ }
1702
1722
1703
1723
if (
1704
1724
self .config [ENTITY_RECOGNITION ]
0 commit comments