本文继续围绕工业级业务对话平台和框架Rasa的Fallback Classifier的相关代码进行解析。对于一些用户输入信息,对话机器人可能会获得一个很低的classification confidence,使用Fallbacks可以帮助优雅地处理这些具有低的confidence的消息,为了处理低的NLU confidence,需要使用FallbackClassifier,这是Rasa DAG图中的一个组件。
一、关于Rasa FallbackClassifier源码解析
- FallbackClassifier使用的包及初始化源码解析
导入日志,类型等:
导入Rasa框架中所有组件的顶级接口GraphComponent;导入ExecutionContext,如上面DAG图所示,每一个graph component在图中都有上下文的依赖关系:
导入DefaultV1Recipe,它相当于程序运行时的配置,譬如在开发时需要使用哪些机器学习组件会配置在一个yml文件里:
导入Resource,它用于表示图中一个持久化的graph component,通过Resource的name从ModelStorage中定位到这个graph component的数据:
导入ModelStorage,它用于为需要进行持久化操作的graph component提供存储服务,对于Rasa以图的框架来进行流式计算来说,状态的管理是非常重要的,无论对于训练还是推理,通过这种持久化机制,可以极大地加速训练:
导入默认NLU Fallback intent name,这是定义的常量即:
导入两个thresholds,它们都是定义的常量:
e.g.
导入接口IntentClassifier,FallbackClassifier继承自这个接口:
导入数据封装类Message,它是描述一个对话turn的数据的容器,譬如描述一个用户utterance时,会用”TEXT”,”INTENT”等属性来描述,而描述对话机器人的action时会使用”ACTION_NAME”,这个容器包括每个属性(attribute)的原始数据(self.data)以及features (self.features):
从特征提取器中获取某个属性的所有sparse features:
从特征提取器中获取某个属性的所有dense features:
导入intent和confidence的常量定义:
e.g.
使用decorator对这个FallbackClassifier组件进行注册,设置ComponentType和is_trainable,由于这个组件是直接使用NLU的输出,所以不需要训练:
2. 核心方法process源码逐行解析
这个方法用于处理传入的messages,FallbackClassifier组件可以依赖任何通过调用其它组件的create方法创建的context attribute,也可以依赖通过任何调用在pipeline中当前这个组件之前的其它组件的process方法创建的context attribute:
调用方法_should_fallback来判断是否需要做fallback处理,过滤出需要进行处理的messages,从配置中取得fallback intent来覆盖message中原有的intent,并把这个intent插入intent排序后获得的列表中的第一个位置(一般做分类预测后会有多个候选intents,按照confidence从高到低进行排序):
这个方法返回默认fallback intent名称和对应的confidence,即threshold的值:
下面方法检查传入的message的confidence来判断是否需要进行fallback处理,如果返回True,表示需要处理:
根据intent name key获取message的intent name:
下面方法先获取message的confidence,然后再和组件配置里的threshold进行比较,来判断是否低于threshold(返回bool值):
判断如果低于threshold,返回True:
如果高于threshold,还需要判断排名前2位的intents的confidence的差值是否小于设定的ambiguity threshold,如果是,也需要进行fallback处理,这是因为这两个intents的区分度过小,导致模型困惑度太大,所以也需要处理:
在下面的方法中,首先检查intents的数量是否大于2,如果是则把排名前2位的intents的confidence取出来,进行差值计算,然后与AMBIGUITY_THRESHOLD_KEY设定的值进行比较,返回False或True,以及这个差值;如果只有一个intent,则直接返回False,None:
下面方法检查FallbackClassifier预测的intent是否是默认fallback intent,即"nlu_fallback":
下面方法用来撤销fallback intent的预测,使对话恢复到进行fallback处理之前的状态:
3. FallbackClassifier与GraphComponent、IntentClassifier关系源码
FallbackClassifier继承自所有graph component的顶级接口GraphComponent和它自己的接口IntentClassifier:
下面方法返回在pipeline中所依赖的组件,这里指DIETClassifier:
下面方法返回组件默认配置信息,可以看到针对这个组件只返回这两个thresholds:
DEFAULT_NLU_FALLBACK_THRESHOLD
DEFAULT_NLU_FALLBACK_AMBIGUITY_THRESHOLD
由于这个组件不需要训练,所以在下面的初始化方法中仅进行config赋值:
使用create方法创建组件的实例: