Santosh Gupta,Alex Sheng和Junpeng Ye之间的合作
在此处下载训练有素的模型和嵌入文件。
获胜者的前6名#PoweredByTF 2.0挑战的决赛入围者! https://devpost.com/software/nlp-doctor。 DOC产品将展示给TensorFlow Connect的Tensorflow工程团队。请继续关注详细信息。
我们想使用Tensorflow 2.0来探索诸如BERT和GPT-2(GPT-2)的最先进的自然语言处理模型如何通过检索和调理相关的医疗数据来回答医疗问题,这就是结果。
该项目的目的是探索深度学习语言模型进行科学编码和检索的能力,不应将其用于可行的医疗建议。
作为一群具有不同背景的朋友,从破产的本科到数据科学家再到顶级NLP研究人员,我们从机器学习的各个不同领域汲取了灵感。通过结合变压器体系结构的力量,潜在的向量搜索,负面抽样以及Tensorflow 2.0的灵活深度学习框架中的生成预训练,我们能够提出一个新颖的解决方案,以解决一个困难的问题,这似乎像是一项艰巨的任务。
如果您对我们如何构建Doc产品的整个故事以及架构的细节感兴趣,请查看我们的Github Readme!
从压缩天文学大型数据集的压缩到重新实施Tensorflow 2.0中的BERT到以1.17亿个参数进行GPT-2进行,我们的项目构成了太多挑战,从压缩天文学大型数据集进行了重新实现,到在共同代表的情况下运行GPT-2,再到急于将项目的最后一部分准备好,并剩下几个小时才能准备好几个小时,直到提交截止日期为止。奇怪的是,最大的挑战通常是当我们对项目应采取的方向分歧时。但是,尽管我们不同意最好的行动是什么,但最终,我们所有人都有相同的最终目标,即为许多人建立有意义的东西和潜在有价值的东西。话虽这么说,我们始终将始终能够坐下来达成协议,并在彼此的支持和深夜为Google聚会场面进行谈判,并面临挑战并共同克服它们。
尽管DOC产品还没有准备好用于广泛的商业用途,但其出乎意料的良好性能表明,诸如BERT和GPT-2之类的通用语言模型中的进步已经导致了以前棘手的问题,例如基于Deep NLP的方法可以访问医疗信息处理。因此,我们希望我们的工作能够激发他人解决这些问题并探索新开放的NLP边境。
尽管如此,我们仍然计划继续开发DOC产品,特别是将其扩展,以利用GPT-2的345m,762m和1.5b参数版本,因为OpenAI将其作为上演发布程序的一部分发布。我们还打算继续训练该模型,因为我们还有更多数据需要通过。
注意:我们正在研究科学/医学NLP和信息检索的研究。如果您有兴趣合作,请通过[email protected]向我们发送电子邮件!
您可以直接从PIP安装DOC产品并在本地计算机上运行。这是安装DOC产品的代码,以及TensorFlow 2.0和Faiss:
!wget https://anaconda.org/pytorch/faiss-cpu/1.2.1/download/linux-64/faiss-cpu-1.2.1-py36_cuda9.0.176_1.tar.bz2
#To use GPU FAISS use
# !wget https://anaconda.org/pytorch/faiss-gpu/1.2.1/download/linux-64/faiss-gpu-1.2.1-py36_cuda9.0.176_1.tar.bz2
!tar xvjf faiss-cpu-1.2.1-py36_cuda9.0.176_1.tar.bz2
!cp -r lib/python3.6/site-packages/* /usr/local/lib/python3.6/dist-packages/
!pip install mkl
!pip install tensorflow-gpu==2.0.0-alpha0
import tensorflow as tf
!pip install https://github.com/Santosh-Gupta/DocProduct/archive/master.zip
我们的存储库包含用于生成.tfrefords数据,根据您自己的问答数据培训DOC产品的脚本,并运行DOC产品以获取医疗问题的答案。请参阅下面的Google合同演示部分,以获取加载数据/权重的代码样本并运行我们的模型。
看看我们的COLAB演示!我们计划随着时间的流逝添加更多演示,使用户可以探索更多DOC产品的功能。所有新的演示将添加到同一Google驱动器文件夹中。
演示包括用于通过PIP安装DOC产品的代码,下载/加载预训练的权重,并运行Doc Product的检索功能以及在您自己的Q&A数据上进行微调。
https://colab.research.google.com/drive/11har1qo7vcsmijwrefwytfblu2lveh1r
https://colab.research.google.com/drive/1rz2rzkkwwrvexcjiqqtxhxhxzlcw5cxi7xa
端到端的DOC产品演示仍然是实验性的,但请随时尝试! https://colab.research.google.com/drive/1bv7bppxiimsmg4wb_lwjdrguhvi7pxx
我们的BERT经过培训,可以编码医疗问题和医疗信息。用户可以输入医疗问题,我们的模型将检索到该问题的最相关的医疗信息。
我们从几个医学问题和回答论坛中创建了数据集。论坛是WebMD,HealthTap,Ehealthforums,ICLINIC,问题医生和Reddit.com/R/askdocs
该体系结构由一个微调的生物Biobert(对于问题和答案而言相同),将文本输入转换为嵌入表示形式。然后将嵌入到FCNN中(对于问题和答案而言是不同的),以开发用于相似性查找的嵌入。然后,GPT-2使用顶级类似的问题和答案来产生答案。完整的体系结构如下所示。
让我们详细查看上面图的前半部分,即Bert和FCNN的训练。该部分的详细图形如下所示
在培训期间,我们采取了一批医疗问题及其相应的医疗答案,并将其转换为生物植物的嵌入。相同的BERT权重用于问题和答案。
然后将这些嵌入输入到FCNN层中。问题和答案嵌入都有单独的FCNN层。回顾一下,我们在Bert层中使用相同的权重,但是问题和答案每个都有自己的单独的FCNN层。
现在这是事情变得有些棘手的地方。通常,嵌入相似性训练涉及负样本,例如Word2Vec如何使用NCE损失。但是,由于在每个步骤中生成嵌入,并且在每个训练步骤中都会改变权重,因此我们无法使用NCE损失。
因此,我们所做的不是NECE的损失,而是在批处理中计算问题和答案嵌入的每种组合。这在下图中显示
然后,在整行上取一个软磁性。对于每个问题,所有答案组合都是软及。
最后,所使用的损失是跨熵损失。将软矩阵与地面真相矩阵进行了比较。问题和答案的正确组合用“ 1”标记,所有其他组合都标有“ 0”。
数据收集很棘手,因为所有不同医疗场所的格式都大不相同。为了从HTML标签的正确部分提取问题和答案,需要为每个站点完成自定义工作。其中一些网站还有可能对一个问题回答多个医生,因此我们需要一种收集对个别问题的多种回答的方法。为了解决这个问题,我们为每个提问对生成了多行。从这里开始,我们需要通过BERT运行模型,并将输出从一个末端层之一存储,以使生物Biobert嵌入我们可以通过馈电神经网络(FFNN)的密集层。为问题和答案存储了768个尺寸向量,并与CSV文件中的相应文本串联。我们尝试了各种不同的格式,以实现更紧凑,更快的加载和共享,但是CSV最终是最简单,最灵活的方法。在创建生物Biobert嵌入并存储了相似性训练过程之后,创建了FFNN嵌入,以捕获问题与答案的相似性。这些也与生物嵌入和源文本一起存储,以供以后的可视化和查询。
嵌入模型构建在TF 2.0中,该模型利用了渴望执行TF 2.0的灵活性。但是,我们使用的GPT2模型是在TF 1.X中构建的。幸运的是,我们可以分别训练两种型号。在推断时,我们需要使用tf.compat.v1.disable_eager_execution维护禁用的急切执行,并维护两个单独的会话。我们还需要照顾两个会话的GPU记忆,以避免OOM。
根据用户问题检索答案的一种明显的方法是,我们使用功能强大的编码器(BERT)来编码数据库中的输入问题和问题,并进行相似性搜索。没有培训涉及,这种方法的性能完全取决于编码器。取而代之的是,我们使用单独的馈送网络来解决问题和答案,并计算它们之间的余弦相似性。受Word2Vec纸的负抽样的启发,我们将其他答案与负样品相同的其他答案处理,并计算横熵损失。这种方法使问题的嵌入和答案嵌入一对中,就欧几里得距离而言尽可能近。事实证明,这种方法比使用BERT嵌入向量直接进行相似性搜索可以产生更强的结果。
BERT的预处理很复杂,我们完全拥有约333K QA对和超过3000万个令牌。考虑到混车在我们的培训中非常重要,我们需要足够大的洗牌缓冲液以适当训练我们的模型。在每个时期开始训练模型之前,预处理数据花费了10分钟以上。因此,我们使用TF.DATA和TFRECORD来构建高性能输入管道。优化之后,只需20秒即可开始训练,而没有GPU空闲时间。
BERT预处理的另一个问题是将所有数据粘贴到固定的长度。因此,对于简短的序列,大量的计算和GPU存储器浪费了。这非常重要,尤其是在伯特(Bert)等大型模型中。因此,我们将BERT预处理代码重写,并使用tf.data.experiment.bucket_by_sequence_length将其转换为具有不同长度和动态填充序列的存储序列。通过这样做,我们实现了更长的最大序列长度和更快的训练。
经过一些修改后,Keras-Bert能够在TF 2.0环境中运行。但是,当我们尝试将Keras-Bert用作嵌入模型中的子模型时,我们发现了以下两个问题。
结果,我们决定重新实现BERT的命令式版本。我们使用了Keras-Bert(多头注意,检查点重量加载等)的一些组件,并写下BERT的呼叫方法。我们的实现更容易进行调试,并且与灵活的急切模式和高性能静态图模式兼容。
用户可能会在各种情况下遇到多种症状,这使得完美的答案可能是多个答案的组合。为了解决这个问题,我们利用功能强大的GPT2模型,并为用户提供的问题以及我们从数据中检索到的顶级K辅助答案。 GPT2模型将基于问题和顶部K答案,并产生更好的答案。要适当训练GPT2模型,我们创建的培训数据如下:我们在数据集中提取每个问题,进行相似性搜索以获取顶级K+1答案,将原始答案用作目标,将其他答案作为辅助输入。通过这样做,我们获得了与嵌入模型培训数据相同的GPT2培训数据。
伯特(Bert)非常适合编码医疗问题和答案,并开发这些问题/答案的强大矢量表示。
我们培训了模型的微调版本,该版本是用Naver的Biobert初始化的。我们还训练了一个版本,其中生物重物被冷冻,并且仅培训了两个FCNN的问题和答案。虽然我们希望微调版本运行良好,但我们对以后的强劲性感到惊讶。这表明生物伯特在能够编码医疗问题和答案的手段方面具有天生的能力。
探索在研究/探索目的之外是否有任何实际使用该项目。这样的模型不应在公众中用于获取医疗信息。但是,也许训练有素/有执照的医疗专业人员可以使用它来收集审查信息。
探索将相同的方法应用于其他域(即历史信息检索,工程信息检索等)。
探索最近发布的Scibert(来自Allen AI)与Naver的Biobert进行了比较。
我们感谢Tensorflow团队提供#PoweredBytf2.0挑战作为一个平台,我们可以与他人分享我们的工作,并特别感谢Llion Jones博士,他的见解和指导对我们项目的方向产生了重要影响。