在这个学习中,我们先把所有的数据提供给这个初始分类器,这个初始分类器就会猜出一个结果,比方说红色的可能是1等等。然后得到这个结果之后,我们就会把它转化成一个知识推理系统它能够接受的符号表示。比如说从这些label里面,得到了A,非B,非C等等。
那么接下来这一步,我们就要根据知识库里面的知识来发现有没有什么东西是不一致的?刚才在玛雅历法的故事里,第一轮就一致了,但在一般的任务中未必那么早就能发现一致的结果。如果有不一致,我们能不能找到某一个东西,一旦修改之后它就能变成一致?这就是我们要去找最小的不一致。假设我们现在找到,只要把这个非C改成C,那么你得到的事实就和知识都一致了。我们就把它改过来,这就是红色的这个部分。那这就是一个反绎的结果。而反绎出来的这个C,我们现在会回到原来的label中,把这个label把它改掉,接下来我们就用修改过的label和原来的数据一起来训练一个新分类器。这个过程可以不断地迭代下去。这个分类器可以代替掉老的分类器。这个过程一直到分类器不发生变化,或者我们得到的事实和知识库完全一致,这时候就停止了。
可以看到,左边这一半就是在做机器学习,而右边这一半是在做逻辑推理。而且,它不是说一头重一头轻,而是这两者互相依赖,一直这样循环处理下去,这么一个过程。反绎学习的形式化描述,我们今天就不展开了。
反绎学习的讨论与案例
有几点内容我们来讨论一下。首先我们看这个数据部分。在反绎学习中,这个数据只需要有instance,不需要有label。那么我们靠什么来做监督学习呢?主要就是靠初始分类器以及知识库中的知识。可以认为这个监督信息是来自于数据之外的地方,所以从这个角度上说,反绎学习可以看成是一个很广义的弱监督学习。但另一方面,如果初始数据中确实是有label的,那这个学习过程,label信息完全可以用上去。比方说,我们把真的label和反绎出来的label一起用来对分类器做更新等等。
第二个方面,初始的分类器从哪来?这可以有很多的办法,比方说类似于深度学习的预训练或者迁移学习,做一个任务时可以用另外一个任务的结果做初步模型。甚至把数据聚类的结果作为粗糙的起点,有时也可以。这里的关键是,初始分类器未必要准确可靠,只不过用它把过程启动起来。当初始模型非常粗糙时,如果知识库的知识靠谱,那就能通过知识库的信息来修正分类器,能进行下去。如果知识不太精准,而初始模型比较好,也能往下学。如果两者都好,当然可以做得更好。也就是说,至少有一个好就能往下做。当然,如果数据没有label、初始分类器不靠谱、知识也不靠谱,那这样的任务本身就没法做。
那接下来,这个知识库从哪来?这个目前还是需要人类专家来提供。最近一些关于知识图谱的工作能提供很多帮助。另外,有可能初始的知识并不是完美的,那么这个过程中,也可以通过对数据的学习来对知识做精化,所以反绎学习本身也可以认为是一个对知识精化的过程。
接下来这个过程中涉及到怎么样具体地去做学习,去做推理等等,这些具体算法机制的设计。反绎学习本身是一个框架,对里面这些机制细节做不同的设计,可以产生出不同特点的反绎学习模型和算法。
下面就介绍一个简单的例子,面对的这个任务是破译长代码。
例如上面三行代码,这个代码是以图像形式呈现,比方说第一行是正例,第二行是反例,能不能判断第三行是正例还是反例?这里训练数据的长度和测试数据所用的长度不一样。而且,数据的语义是什么事先也不知道。这和破译密码有点像。现在考虑简单的XNOR问题。
第一个是DBA任务,左边是训练数据,每个数据都是由5个图像组成,可以认为它是5位,0 0=0是正例,1 0=0是反例。我们对这5位图像组成的数据学习之后,测试数据是右边这样,长度要比训练数据长得多,而且有些数据特点也不同,例如训练数据中的等号总在倒数第二位,而测试数据中的等号可以出现在很不一样的位置。第二个RBA任务更困难,连图像的含义都看不出来,图像都是随机生成的。
我们用了一个简单的实现。机器学习部分就是用卷积神经网络,逻辑推理部分用ALP,都有开源代码可以直接用。把两者衔接起来,中间的优化求解过程跟一般机器学习里不太一样,我们在神经网络、统计学习里的优化一般用到的是数值优化,通常用梯度下降来做,但现在是面对符号优化,不能求导、梯度下降。这里就用到我们研究团队近五六年一直在做的零阶优化方法,不用求梯度地做优化。把这几个技术结合起来,就是这个简单的实现。