专栏名称: 桃子说产品
AI产品专家 个人网站:https://ww...
目录
相关文章推荐
今天看啥  ›  专栏  ›  桃子说产品

Rasa 入门教程 Core 系列(五)

桃子说产品  · 简书  ·  · 2019-12-17 21:19
rasa_tutorial_core_background.png

Rasa 入门教程 Core 系列包括十一个部分,前面介绍了 Rasa 框架 Core 系列的第四部分:动作 。本文主要介绍 Rasa 框架 Core 系列的第五部分: 策略

本文的目录结构:

  1. 策略配置
  2. 动作选择
  3. Keras 策略
  4. Embedding 策略
  5. Mapping 策略
  6. Memoization 策略
  7. Augmented Memoization 策略
  8. Fallback 策略
  9. Two-Stage Fallback 策略
  10. Form 策略

1. 策略配置

rasa.core.policies.Policy 决定在对话的每个步骤中应采取的什么动作。有多种策略可供选择,您可以在 rasa.core.agent.Agent 中包含多个策略。

项目中的 config.yml 文件有关键字 policies ,你可以使用该关键字来自定义助手使用的策略。在下面的示例中,最后两行显示了如何使用自定义策略类并将参数传递给它。

policies:
  - name: "KerasPolicy"
    featurizer:
    - name: MaxHistoryTrackerFeaturizer
      max_history: 5
      state_featurizer:
        - name: BinarySingleStateFeaturizer
  - name: "MemoizationPolicy"
    max_history: 5
  - name: "FallbackPolicy"
    nlu_threshold: 0.4
    core_threshold: 0.3
    fallback_action_name: "my_fallback_action"
  - name: "path.to.your.policy.class"
    arg1: "..."

1.1 最长历史记录

Rasa 核心策略的一个重要超参数是 max_history 。这可以控制模型查看多少对话历史记录,以决定下一步应采取什么动作。

你可以在 yaml 文件中的配置策略里通过设置 max_history 值将其传递到 Featurizer

例如:假设你有一个 out_of_scope 表示超纲的意图。如果你的机器人连续多次看到此意图,则可能要告诉用户你可以提供哪些帮助。因此你的 story 可能如下所示:

* out_of_scope
   - utter_default
* out_of_scope
   - utter_default
* out_of_scope
   - utter_help_message

为了使 Rasa Core 学习这种模式, max_history 至少为 4。

如果增加 max_history ,你的模型将变得更大,并且训练将花费更长的时间。如果你有会影响将来对话的一些信息,则应将其作为槽位存储,槽位信息可以用于每个特征提取器。

1.2 数据增强

训练模型时,默认情况下,Rasa Core 随机将 stories 文件中的 stories 粘合在一起来创建更长的 stories。stories 文件如下所示:

# thanks
* thankyou
   - utter_youarewelcome

# bye
* goodbye
   - utter_goodbye

实际上你想教自己的策略在不相关时忽略对话历史记录,而无论以前发生了什么,都只需以相同的动作进行响应即可。

你可以使用 --augmentation 标志更改此行为,允许你设置 augmentation_factor augmentation_factor 决定在训练中有多少增强的 stories 是子采样。增强后的 stories 在训练之前会进行二次抽样,因为它们的数量会很快变得非常大,我们希望对其进行限制。样本 stories 的数量是 augmentation_factor x10。默认情况下,增强设置为 20,最多可生成200个增强 stories。

--augmentation 0 表示禁用所有增强行为。基于 Memoization 策略不受增强影响(与 augmentation_factor 无关),并且会自动忽略所有增强的 stories。

2. 动作选择

在任何时候,配置中定义的每个策略都会以一定的置信度预测下一个动作。有关每个策略如何做出决策的更多信息,请阅读下面的策略说明。然后,该机器人的下一步动作将由具有最高置信度的预测策略决定。

在两个相同的置信度策略进行预测的情况下(例如: Memoization Mapping 策略,始终以 0 或 1 的置信度进行预测),则将考虑策略的优先级。Rasa 策略有默认优先级,这些默认优先级用于在平局时的预期结果。如下所示,数字越高优先级越高:

5. FormPolicy
4. FallbackPolicy and TwoStageFallbackPolicy
3. MemoizationPolicy and AugmentedMemoizationPolicy
2. MappingPolicy
1. EmbeddingPolicy, KerasPolicy, and SklearnPolicy

上述优先级层次结构可确保,在 NLU 的置信度值在 nlu_threshold 之下(例如:如果有一个 mapped 动作),机器人仍将回退。通常,不建议每个优先级使用一个以上的策略,并且某些优先级相同的策略(例如两个 fallback 策略)严格不能一并使用。

如果创建自己的策略,请使用这些优先级作为确定策略优先级的指南。如果你的策略是机器学习策略,则它最有可能具有与 Rasa 机器学习策略相同的优先级 1。

3. Keras 策略

KerasPolicy 策略在 Keras 中使用神经网络实现选择下一个动作。默认体系结构是基于 LSTM,但是你可以重写 KerasPolicy.model_architecture 方法以实现自己的体系结构。

def model_architecture(
    self, input_shape: Tuple[int, int], output_shape: Tuple[int, Optional[int]]
) -> tf.keras.models.Sequential:
    """Build a keras model and return a compiled model."""

    from tensorflow.keras.models import Sequential
    from tensorflow.keras.layers import (
        Masking,
        LSTM,
        Dense,
        TimeDistributed,
        Activation,
    )

    # Build Model
    model = Sequential()

    # the shape of the y vector of the labels,
    # determines which output from rnn will be used
    # to calculate the loss
    if len(output_shape) == 1:
        # y is (num examples, num features) so
        # only the last output from the rnn is used to
        # calculate the loss
        model.add(Masking(mask_value=-1, input_shape=input_shape))
        model.add(LSTM(self.rnn_size, dropout=0.2))
        model.add(Dense(input_dim=self.rnn_size, units=output_shape[-1]))
    elif len(output_shape) == 2:
        # y is (num examples, max_dialogue_len, num features) so
        # all the outputs from the rnn are used to
        # calculate the loss, therefore a sequence is returned and
        # time distributed layer is used

        # the first value in input_shape is max dialogue_len,
        # it is set to None, to allow dynamic_rnn creation
        # during prediction
        model.add(Masking(mask_value=-1, input_shape=(None, input_shape[1])))
        model.add(LSTM(self.rnn_size, return_sequences=True, dropout=0.2))
        model.add(TimeDistributed(Dense(units=output_shape[-1])))
    else:
        raise ValueError(
            "Cannot construct the model because"
            "length of output_shape = {} "
            "should be 1 or 2."
            "".format(len(output_shape))
        )

    model.add(Activation("softmax"))

    model.compile(
        loss="categorical_crossentropy", optimizer="rmsprop", metrics=["accuracy"]
    )

    if obtain_verbosity() > 0:
        model.summary()

    return model

下面是训练部分:

def train(
    self,
    training_trackers: List[DialogueStateTracker],
    domain: Domain,
    **kwargs: Any,
) -> None:

    # set numpy random seed
    np.random.seed(self.random_seed)

    training_data = self.featurize_for_training(training_trackers, domain, **kwargs)
    # noinspection PyPep8Naming
    shuffled_X, shuffled_y = training_data.shuffled_X_y()

    self.graph = tf.Graph()
    with self.graph.as_default():
        # set random seed in tf
        tf.set_random_seed(self.random_seed)
        self.session = tf.compat.v1.Session(config=self._tf_config)

        with self.session.as_default():
            if self.model is None:
                self.model = self.model_architecture(
                    shuffled_X.shape[1:], shuffled_y.shape[1:]
                )

            logger.info(
                "Fitting model with {} total samples and a "
                "validation split of {}"
                "".format(training_data.num_examples(), self.validation_split)
            )

            # filter out kwargs that cannot be passed to fit
            self._train_params = self._get_valid_params(
                self.model.fit, **self._train_params
            )

            self.model.fit(
                shuffled_X,
                shuffled_y,
                epochs=self.epochs,
                batch_size=self.batch_size,
                shuffle=False,
                verbose=obtain_verbosity(),
                **self._train_params,
            )
            # the default parameter for epochs in keras fit is 1
            self.current_epoch = self.defaults.get("epochs", 1)
            logger.info("Done fitting keras policy model")

你可以重写这些方法来实现你要的模型,或者使用预定义 keras model 初始化 KerasPolicy

为了在相同输入的情况下,获得可重复训练结果,你可以将 KerasPolicy 的属性 random_seed 设置为任意整数值。

4. Embedding 策略

TEDP(Transformer Embedding Dialogue Policy),该策略的预定义体系结构主要包括以下步骤:

  • 将每个时间步长中的用户输入(用户意图和实体),先前的系统动作,槽位值和动作表单连接到输入矢量中,然后传递给 pre-tranformer 的嵌入层;
  • 喂给 Transformer;
  • 在 Transformer 的输出上增加一个 dense 层,以便在每个时间步长中嵌入对话;
  • 在每个时间步长中使用 dense 层为系统动作创建嵌入;
  • 计算对话嵌入和嵌入式系统动作之间的相似度。这一步是基于 StarSpace 想法。

推荐使用 state_featurizer=LabelTokenizerSingleStateFeaturizer(...) (详见 Featurization )。

4.1 配置

可以将配置参数作为参数传递到 EmbeddingPolicy 策略配置文件中。以下是可调的超参数:

  1. 神经网络的体系架构:

    • hidden_layers_sizes_b 在为系统动作嵌入层之前设置隐藏层大小的列表,隐藏层的数量等于列表的长度;
    • transformer_size 设置 transformer 的单元数;
    • num_transformer_layers 设置 transformer 层数;
    • pos_encoding 设置 transformer 中位置编码的类型,应为 timing emb
    • max_seq_length 如果使用嵌入位置编码,则设置最大序列长度;
    • num_heads 设置多头注意力中的头数;
  2. 训练:

    • batch_size 设置一个前向/后向传播中的训练示例的数量,批次大小越大,需要的存储空间就越大;
    • batch_strategy 设置批处理策略的类型,应为 sequence balanced
    • epochs 设置算法训练数据的次数,其中一个 epoch 表示所有训练示例中一次前向和后向传播;
    • random_seed 如果设置为int,则对于相同的输入将获得可重复的训练结果;
  3. 嵌入:

    • embed_dim 设置嵌入空间的维度;
    • num_neg 设置不正确的意图标签的数量,该算法将在训练过程中将其与用户输入的相似性降至最低;
    • similarity_type 设置相似性的类型,它应该是 auto cosine 或者 inner ,如果 auto 要根据 loss_type inner 就是 softmax cosine 就是 margin
    • loss_type 设置损失函数的类型,应为 softmax margin
    • mu_pos 控制算法应如何尝试为正确的意图标签生成嵌入向量,仅当 loss_type 设置为 margin 时使用;
    • mu_neg 控制最大负相似性为不正确的意图,仅当 loss_type 设置为 margin 时使用;
    • use_max_sim_neg 如果设置为 true ,表示在不正确意图标签上使用最小化最大相似度,仅当 loss_type 被设置为 margin 时使用;
    • scale_loss 如果设置为 true ,会降低损失的比例,例如在高可信度下预测正确标签的示例,仅当 loss_type 设置为 softmax 时使用;
  4. 正则化:

    • C2 设置L2正则化的规模;
    • C_emb 设置最小化不同意图标签的嵌入之间最大相似性的重要性的标度,仅当 loss_type 设置为 margin时使用
    • droprate_a 在用户输入嵌入层之前,设置层之间的丢失率;
    • droprate_b 在系统动作嵌入层之前,设置层之间的丢失率;
  5. 计算训练准确率:

    • evaluate_every_num_epochs 设置计算训练准确率的频率,较小的值可能会损害性能;
    • evaluate_on_num_examples 要使用多少示例来支持验证集以计算验证准确率,较大的值可能会损害性能。

可以在策略配置文件中指定这些参数。默认值定义在 EmbeddingPolicy.defaults 中:

defaults = {
    # nn architecture
    # a list of hidden layers sizes before user embed layer
    # number of hidden layers is equal to the length of this list
    "hidden_layers_sizes_pre_dial": [],
    # a list of hidden layers sizes before bot embed layer
    # number of hidden layers is equal to the length of this list
    "hidden_layers_sizes_bot": [],
    # number of units in transformer
    "transformer_size": 128,
    # number of transformer layers
    "num_transformer_layers": 1,
    # type of positional encoding in transformer
    "pos_encoding": "timing",  # string 'timing' or 'emb'
    # max sequence length if pos_encoding='emb'
    "max_seq_length": 256,
    # number of attention heads in transformer
    "num_heads": 4,
    # training parameters
    # initial and final batch sizes:
    # batch size will be linearly increased for each epoch
    "batch_size": [8, 32],
    # how to create batches
    "batch_strategy": "balanced",  # string 'sequence' or 'balanced'
    # number of epochs
    "epochs": 1,
    # set random seed to any int to get reproducible results
    "random_seed": None,
    # embedding parameters
    # dimension size of embedding vectors
    "embed_dim": 20,
    # the type of the similarity
    "num_neg": 20,
    # flag if minimize only maximum similarity over incorrect labels
    "similarity_type": "auto",  # string 'auto' or 'cosine' or 'inner'
    # the type of the loss function
    "loss_type": "softmax",  # string 'softmax' or 'margin'
    # how similar the algorithm should try
    # to make embedding vectors for correct labels
    "mu_pos": 0.8,  # should be 0.0 < ... < 1.0 for 'cosine'
    # maximum negative similarity for incorrect labels
    "mu_neg": -0.2,  # should be -1.0 < ... < 1.0 for 'cosine'
    # the number of incorrect labels, the algorithm will minimize
    # their similarity to the user input during training
    "use_max_sim_neg": True,  # flag which loss function to use
    # scale loss inverse proportionally to confidence of correct prediction
    "scale_loss": True,
    # regularization
    # the scale of L2 regularization
    "C2": 0.001,
    # the scale of how important is to minimize the maximum similarity
    # between embeddings of different labels
    "C_emb": 0.8,
    # dropout rate for dial nn
    "droprate_a": 0.1,
    # dropout rate for bot nn
    "droprate_b": 0.0,
    # visualization of accuracy
    # how often calculate validation accuracy
    "evaluate_every_num_epochs": 20,  # small values may hurt performance
    # how many examples to use for hold out validation set
    "evaluate_on_num_examples": 0,  # large values may hurt performance
}

5. Mapping 策略

MappingPolicy 策略可直接映射到意图动作。通过给意图属性 triggers 来分配映射,例如:

intents:
 - ask_is_bot:
     triggers: action_is_bot

一个意图最多只能映射到一个动作。机器人在收到触发意图消息后将运行映射的动作。之后,它将监听下一条消息。随着下一条用户消息,将恢复正常预测。

如果你不希望意图动作映射影响对话历史记录,则映射动作必须返回一个 UserUtteranceReverted() 事件。这将从对话历史记录中删除用户的最新消息及其后面发生的任何事件。这意味着你不应该将意图-动作交互包括在 stories 中。

例如:如果用户在对话流程中询问“你是机器人吗?”,你可能想回答用户后,该交互不要影响到下一个动作预测。自定义动作可以做任何事,下面是一个简单的示例,调度机器人的话语,然后恢复原交互:

class ActionIsBot(Action):
"""Revertible mapped action for utter_is_bot"""

def name(self):
    return "action_is_bot"

def run(self, dispatcher, tracker, domain):
    dispatcher.utter_template(template="utter_is_bot")
    return [UserUtteranceReverted()]

6. Memoization 策略

MemoizationPolicy 策略是记住训练数据中的会话。如果训练数据中存在正确的对话,它会将置信度设置为 1.0 并预测下一个动作,否则置信度为 0.0 预测为 None

7. Augmented Memoization 策略

AugmentedMemoizationPolicy 策略记得从训练的故事长达例子 max_history 转弯,就像 MemoizationPolicy 。此外,它具有遗忘机制,可以遗忘对话历史记录中的某些步骤,并尝试在历史记录短的情况下找到匹配项。它预测有信心下一个动作 1.0 ,如果发现匹配,否则就预测 None 有信心 0.0

8. Fallback 策略

当出现以下情况就会触发 FallbackPolicy 策略调用 撤销动作

  1. 意图识别的置信度值低于 nlu_threshold
  2. 排名最高意图的置信度与排名第二意图的置信度值相差小于 ambiguity_threshold
  3. 没有一项对话政策预测高于置信度 core_threshold 的行动。

8.1 配置

阈值和撤销动作可以在策略配置文件中作为 FallbackPolicy 参数进行调整:

policies:
  - name: "FallbackPolicy"
    nlu_threshold: 0.3
    ambiguity_threshold: 0.1
    core_threshold: 0.3
    fallback_action_name: 'action_default_fallback'
参数 说明
nlu_threshold 接受 NLU 预测所需的最低置信度
ambiguity_threshold 最高意图的置信度必须超过第二高意图的置信度的最小值
core_threshold 接受 Rasa Core 的动作预测所需的最低置信度
fallback_action_name 如果意图或动作的置信度低于各自的阈值,则调用 撤销动作

您也可以在 python 代码中配置 FallbackPolicy

from rasa.core.policies.fallback import FallbackPolicy
from rasa.core.policies.keras_policy import KerasPolicy
from rasa.core.agent import Agent

fallback = FallbackPolicy(fallback_action_name="action_default_fallback",
                          core_threshold=0.3,
                          nlu_threshold=0.3,
                          ambiguity_threshold=0.1)

agent = Agent("domain.yml", policies=[KerasPolicy(), fallback])

9. Two-Stage Fallback 策略

TwoStageFallbackPolicy 策略用于处理 NLU 置信度值低的情况,试图在多个阶段对用户输入进行消歧。

  1. 如果 NLU 预测的置信度值低或不明显高于排名第二预测的置信度值,则要求用户确认意图的分类。

    • 如果用户确认,那么 story 将继续,就好像从一开始就对意图进行了高置信度的分类。
    • 如果他们拒绝,则要求用户重新表达他们的消息。
  2. 重新表达

    • 如果重新表达的意图分类是确定的,则 story 将继续,就好像用户从一开始就有此意图一样。
    • 如果重新表达的意图经过意图分类的置信度值不高,则要求用户确认意图分类。
  3. 二次确认

    • 如果用户确认了此意图,则 story 将继续,就好像用户从一开始就有此意图一样。
    • 如果用户拒绝,则将原始意图分类为 deny_suggestion_intent_name 指定的意图,并触发最后的回退操作。

<font color='#ff0178'>9.1 配置

要使用 TwoStageFallbackPolicy ,请在策略配置中包括以下内容。

policies:
  - name: TwoStageFallbackPolicy
 nlu_threshold: 0.3
 ambiguity_threshold: 0.1
 core_threshold: 0.3
 fallback_core_action_name: "action_default_fallback"
 fallback_nlu_action_name: "action_default_fallback"
 deny_suggestion_intent_name: "out_of_scope"
参数 说明
nlu_threshold 接受 NLU 预测所需的最低置信度
ambiguity_threshold 最高意图的置信度必须超过第二高意图的置信度的最小值
core_threshold 接受 Rasa Core 的动作预测所需的最低置信度
fallback_core_action_name 如果 Rasa Core 动作预测的置信度值低于 core_threshold ,则调用 撤销动作 。该动作是为了提出建议的可识别意图。
fallback_nlu_action_name 如果 Rasa NLU 意图分类的置信度值低于 nlu_threshold ,则调用的 撤销动作 。当用户第二次拒绝时调用此动作。
deny_suggestion_intent_name 用于用户拒绝后建议的意图分类名称

<font color='#ff0178'>10. Form 策略</font>

FormPolicy 策略是 MemoizationPolicy 的扩展,用来处理表单填充。当 FormAction 被调用时, FormPolicy 策略将不断预测 FormAction ,直到表单中的所有必需的槽位值被填充。有关更多信息,请参见 Forms


作者: 关于我

备注:转载请注明出处。

如发现错误,欢迎留言指正。




原文地址:访问原文地址
快照地址: 访问文章快照