Embedding 的理解

Reference: https://zhuanlan.zhihu.com/p/46016518

近年来,从计算机视觉到自然语言处理再到时间序列预测,神经网络、深度学习的应用越来越广泛。在深度学习的应用过程中,Embedding 这样一种将离散变量转变为连续向量的方式为神经网络在各方面的应用带来了极大的扩展。该技术目前主要有两种应用,NLP 中常用的 word embedding 以及用于类别数据的 entity embedding。

此篇文章内容主要源自于 Neural Network Embeddings Explained ,起初未在文章开头标明,谢谢 @Michael Tan 的提醒 。

本篇文章主要介绍以下内容:

  • 什么是 neural network embedding ?
  • 我们为什么需要使用 neural network embedding?
  • 以及 embedding 是如何自学习的?

本文中,将谈到这样一个例子,使用 neural network embedding 来表示所有维基百科上的书籍,可以通过这里访问到原作者的推荐系统项目。

Figure 1: Neural Network Embedding of all books on Wikipedia.

Embedding 和 One Hot 编码

上面说了,Embedding 是一个将离散变量转为连续向量表示的一个方式。在神经网络中,embedding 是非常有用的,因为它不光可以减少离散变量的空间维数,同时还可以有意义的表示该变量。

我们可以总结一下,embedding 有以下 3 个主要目的:

  1. 在 embedding 空间中查找最近邻,这可以很好的用于根据用户的兴趣来进行推荐。
  2. 作为监督性学习任务的输入。
  3. 用于可视化不同离散变量之间的关系。

这也就意味对于上面我们所说的维基百科书籍表示而言,使用 Neural Network Embedding,我们可以在维基百科上获取到的所有 37,000 本书,对于每一篇,仅仅用一个包含 50 个数字的向量即可表示。此外,因为 embedding 是可学习的,因此在不断的训练过程中,更相似的书籍的表示在 embedding space 中将彼此更接近。

要了解 embedding 的优点,我们可以对应 One-hot 编码来观察。One-hot 编码是一种最普通常见的表示离散数据的表示,首先我们计算出需要表示的离散或类别变量的总个数 N,然后对于每个变量,我们就可以用 N-1 个 0 和单个 1 组成的 vector 来表示每个类别。这样做有两个很明显的缺点:

  1. 对于具有非常多类型的类别变量,变换后的向量维数过于巨大,且过于稀疏。
  2. 映射之间完全独立,并不能表示出不同类别之间的关系。
# One Hot Encoding Categoricals
books = ["War and Peace", "Anna Karenina", 
          "The Hitchhiker's Guide to the Galaxy"]
books_encoded = [[1, 0, 0],
                 [0, 1, 0],
                 [0, 0, 1]]
Similarity (dot product) between First and Second = 0
Similarity (dot product) between Second and Third = 0
Similarity (dot product) between First and Third = 0

因此,考虑到这两个问题,表示类别变量的理想解决方案则是我们是否可以通过较少的维度表示出每个类别,并且还可以一定的表现出不同类别变量之间的关系,这也就是 embedding 出现的目的。

# Idealized Representation of Embedding
books = ["War and Peace", "Anna Karenina", 
          "The Hitchhiker's Guide to the Galaxy"]
books_encoded_ideal = [[0.53,  0.85],
                       [0.60,  0.80],
                       [-0.78, -0.62]]
Similarity (dot product) between First and Second = 0.99
Similarity (dot product) between Second and Third = -0.94
Similarity (dot product) between First and Third = -0.97

而为了更好的表示类别实体,我们还可以是用一个 embedding neural network 和 supervised 任务来进行学习训练,以找到最适合的表示以及挖掘其内在联系。

One-hot 编码的最大问题在于其转换不依赖于任何的内在关系,而通过一个监督性学习任务的网络,我们可以通过优化网络的参数和权重来减少 loss 以改善我们的 embedding 表示,loss 越小,则表示最终的向量表示中,越相关的类别,它们的表示越相近。

上面给出维基百科的例子中,可能有这样的一个 supervised 任务,“预测这本书是否是 Leo Tolstoy 写的”,而我们最终产生的 embedding 则会让 Tolstory 写的书之间的表示更接近。因此弄清楚如何创建监督学习任务和产生相关表示是 embedding 表示的关键。

Embedding 可视化

Embedding 最酷的一个地方在于它们可以用来可视化出表示的数据的相关性,当然要我们能够观察,需要通过降维技术来达到 2 维或 3 维。最流行的降维技术是:t-Distributed Stochastic Neighbor Embedding (TSNE)。

我们可以定义维基百科上所有书籍为原始 37,000 维,使用 neural network embedding 将它们映射到 50 维,然后使用 TSNE 将它们映射到 2 维,其结果如下:

Figure 2: Embedding of all 37,000 books on Wikipedia

这样看好像并不能看出什么,但是如果我们根据不同书籍的特征着色,我们将可以很明显的看出结果。

Figure 3: Embeddings Colored by Genre

我们可以清楚地看到属于同一类型的书籍的分组。虽然它并不完美,但惊奇的是,我们只用 2 个数字就代表维基百科上的所有书籍,而在这些数字中仍能捕捉到不同类型之间的差异。这代表着 embedding 的价值。

静态图的问题在于我们无法真正探索数据并调查变量之间的分组或关系。 为了解决这个问题,TensorFlow开发了 projector,这是一个在线应用程序,可以让我们可视化并与 embedding 交互。 结果如下:

Figure 4: Interactive Exploration of Book Embeddings using projector

总结

Embedding 的基本内容如前面介绍所示,然而我想说的是它的价值并不仅仅在于 word embedding 或者 entity embedding,这种将类别数据用低维表示且可自学习的思想更存在价值。通过这种方式,我们可以将神经网络,深度学习用于更广泛的领域,Embedding 可以表示更多的东西,而这其中的关键在于要想清楚我们需要解决的问题和应用 Embedding 表示我们得到的是什么。

Reference

  1. Neural Network Embeddings Explained
  2. TensorFlow Guide to Embeddings
  3. Book Recommendation System Using Embeddings

药物设计的深度学习

Reference: https://blog.csdn.net/u012325865/article/details/105683670?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_utm_term-0&spm=1001.2101.3001.4242

摘要

过去的十年中,深度学习(deeplearning, DL)方法已经非常成功并广泛用于开发几乎每个领域的人工智能(AI)。与传统的机器学习(machine learning, ML)算法相比,DL方法在小分子药物发现和开发方面还有很长的路要走。对于DL研究的推广和应用,例如小分子药物研究和开发,还有很多工作要做。本综述主要讨论了监督学习和非监督学习等几种最强大和主流的体系结构,包括卷积神经网络(CNN)、递归神经网络(RNN)和深度自动编码器网络(DAENs),总结了小分子药物设计中的大部分代表性应用;并简要介绍了如何在这些应用程序中使用DL方法。还强调了关于DL方法利弊的讨论以及我们需要解决的主要挑战。

一、背景
与深蓝相比,IBM开发的chessplaying计算机第一次在20世纪90年代击败世界冠军,AlphaGo集成了一种被称为卷积神经网络(CNN)的先进创新架构,该架构是在神经网络(NN)中的深度学习(DL)算法最成功的实现之一。受益于大数据分析的兴起以及大规模计算能力的发展,特别是图形处理单元(GPU)计算的发展,使用深度学习体系结构已成为应对AI挑战的首要尝试技术。

 深度学习被称为人工神经网络(ANN)的传统机器学习(ML)算法的重新命名,其是为了模仿人类中枢神经系统(CNS)而由连接的人造神经元组成的网络系统。早期,人工神经网络不是“深”而是“浅”的;这些ANN由一个输入层,一个输出层和一个隐藏层组成。输入层直接通过将特征放入每个节点来接收输入数据。然后,隐层中的每个节点接收一个加权线性组合作为来自输入层中所有单元的输入,然后使用激活函数执行非线性变换。输出层做了与隐藏层类似的工作。它从隐藏层接收信号,然后使用激活函数产生结果。在这个过程之后的数据流中,那些ANN可以被认为是前馈神经网络(FNN)。这些Bshallow ^ NNs系统的优化是通过一个过程实现的,该过程首先使用反向传播(BP)算法计算输出结果与实际值之间的误差,然后修改内部可调参数(权重)以通过梯度下降 。通用逼近定理表明,浅层神经网络,只有一个隐含层包含有限数量的节点,可以近似任何连续函数。当可调节参数的数量时,具有这种体系结构的模型可能容易过度拟合。通过仔细培训浅层网络,特别是在应用正则化时,过度拟合可以最小化。尽管如此,可以设计更多的隐藏层来识别来自输入数据的更多抽象模式,其中较低层学习基本模式并且上层学习较高层模式。但是,增加更多的隐藏层和节点可以大大增加计算任务。而那些隐含层数较多的多层神经网络可能会遇到梯度消失问题,导致改变权重以优化模型训练的难度。为了克服这些情况,在DL模型的开发中,GPU加速通常被应用于极大地提高计算能力。同时,对网络架构进行了修改以优化权重的初始化和更新,并采用不同的传递函数和正则化技术来使过度拟合最小化。这些体系结构的例子包括深度置信网络(DBN),CNN和递归神经网络(RNN)。而且,在大数据时代,与其他传统的浅层ML算法相比,DL具有主要优势,如线性回归,逻辑回归,支持向量机(SVM),朴素贝叶斯方法,决策树或随机森林算法。与DL算法相比,这些算法在学习能力上也被认为是很浅的。这些传统算法难以处理原始形式的自然数据,因此必须提取手工设计的特征来表示输入数据,这些数据是至关重要的,但往往难以处理,并且需要输入数据特定领域的专业知识。另一方面,深度学习算法属于表示学习类,它具有处理原始数据的能力,并能够自动提取有用的特征作为进一步检测或分类所需的表示。

现代计算机辅助小分子药物发现和开发中,ML方法,特别是传统学习方法被广泛用于构建预测模型,如定量结构-活性关系(QSAR)模型和定量结构-性质关系(QSPR)模型 等等。 近年来,新的DL技术已被用于药物发现和开发,为制药科学的计算决策打开了新的大门。 DL技术的成功得益于DL算法的快速发展以及高性能计算技术的发展,以及化学数据库中化学信息的爆炸。

本文的目的是帮助读者深入了解计算化学和化学信息学领域的DL应用,以便他们可以在他们的研究中使用DL。因此,本文主要总结了如何构建这些DL应用程序,深度神经网络(DNN)模型的体系结构以及它们采用的输入功能。还将DL与传统的ML算法进行了比较,并讨论了DL的未来视角。尽管数学模型的预测性能非常重要,但由于以下原因,对这些DL应用程序的验证和并行比较在本评价中未被强调。一个是准确度和精度因数据集、模型架构、超参数配置和评估方法而异。 

二、深度学习的应用
1.深度学习的发展
DL的起源可以追溯到Warren McCulloch和Walter Pitts在20世纪40年代提出的神经网络(NN)模型,以及Frank Rosenblatt发明的感知器,两者都被设计用来模拟人类神经元的兴奋通过类比NN中的二进制逻辑门的激活来实现大脑。早期人工神经网络的主要思想是定义一个算法来学习权重向量,它被用作特征值的系数。然后,使用神经元内部的激活函数,例如Heaviside Step Function或Sigmoid Function来确定神经元是否被激活。后来,人工神经网络建模的BP算法的发展带来了这些基于统计的ML方法监督学习的繁荣。DL的实际框架由Geoffrey Hinton,Yann LeCun和其他科学家在2006年提出,它不仅在学术界,而且在工业界开启了DL和新AI的革命浪潮。他们开发了一种多层神经网络的新颖架构,将特征学习引入到DL中,以抽象出数据的要素。通过特征学习,DL方法可以自动从原始格式的输入数据中提取特征,然后转换并将其分布到更抽象的层次。与此同时,并行计算技术和计算硬件的快速发展,特别是针对DL研究而设计的新兴专用集成电路,如张量处理单元(TPU)技术,确保了DNN的巨大计算工作量可能不再是一个无法访问的域名。

2.用于小分子药物发现的通用深度学习体系结构
有不同类型的DL体系结构,每种体系结构都可以根据训练数据的结构以不同的方式识别模式并提取高级特征。本文主要讨论了主流架构,包括CNN,RNN和生成网络。本文简要介绍了它们在DL应用中如何用于小分子药物设计和开发。

2.1卷积神经网络(CNN)
 CNN是DL中最具代表性的体系结构之一,在图像和语音识别以及自然语言处理(NLP)等许多领域被广泛采用。当处理视觉信号时,局部神经元模式负责感知感觉空间中的特定区域,并且CNN通过在卷积层中开发两个主要字符来模拟其特征:稀疏连接和共享权重。 在卷积层k中,有两个特征映射(A和B),其中任何一个具有相同的权重。 隐含层k的每个特征映射中的每个像素来自权重矩阵和层k-1的局部像素簇的卷积。

此外,通过汇集层和通过整合用于正则化的丢失技术实现的提高使得CNN更加复杂。对于那些复杂的信号过程,其中输入数据具有巨大数量的输入特征和极其抽象的连接,CNN的采用可以通过直接将输入数据导入模型来避免特征选择的头痛。在CNN中通常使用三种类型的层:卷积层、共用层和完整连接层。仔细选择和排列这些层以形成多层网络。根据输入数据的形式,可以考虑不同形式的图层。

2.2递归神经网络(RNN)
RNN是DL中另一种代表性的体系结构。 RNN专门针对处理序列数据而被广泛使用,并在NLP中取得了巨大的成功。RNN与前馈架构之后的常规FNN不同。在常规FNN中,同一层中的隐藏节点之间没有连接,但仅在相邻层中的节点之间有连接。FNN的主要缺点之一是它们不能处理序列问题,因为输出不仅与当前的输入信息有关,而且与先前的信息有关。但是,RNN可以通过以下方式处理顺序信息:(1)将有向周期引入其网络;(2)将相邻的隐藏节点相互联系起来;(3)从先前的时间片捕获计算的信息;(4)将其存储用于后续程序。从输入单元到输出单元的单向数据流流经过每个连续的隐藏单元。 St表示步骤t的过渡状态,表示网络中的纪念单元,其包含从序列中先前数据提取的所有信息。该步骤(t)中的输出单元的输出仅与该时刻(St)的过渡状态相关。在RNN中,每个具有有向周期的隐层可以展开并作为传统的NN在每个相同层共享相同的权重矩阵U,V,W进行处理。

有很多RNN的变体,最常见的是门控周期性递归神经网络(GRURNN),长期短期记忆(LSTM)网络和发条RNN(CW-RNN)。在这些RNN体系结构中,LSTM是目前NLP中最受欢迎和广泛使用的一种。在NLP中,LSTM通常结合词嵌入的分布式表示,通过检查语句和词性标注来实现。 使用专门的函数来计算隐藏层中的转换状态,与常规RNN相比,LSTM网络在捕获长期依赖性方面功能强大。另外,LSTM在图像检索领域也与CNN一样流行且成功,并且通常与CNN结合用于AI中的图像描述的自动生成。

2.3生成深度神经网络(DNNs)
DNNs不仅用于处理监督学习中的标记数据,而且还用于分析非监督学习中的非标记数据。深度自动编码器网络(DEAN)是无监督学习中最常见的生成网络架构之一。DEAN由编码器和解码器组成,它们是两个对称的DBN,由希尔顿等人提出的DNN。这两个DBN通常由几个受限玻尔兹曼机器(RBM)组成,这是一个包含一个可见层和一个不可见层的双向网络。在RBM中,来自不同层的每两个节点之间存在对称连接,并且来自同一层的节点之间没有连接。一个简单的自动编码器的功能可以被视为数据的压缩,然后可以基于BP算法进行解压缩和恢复,同时信息损失最小。因此,由于减少冗余的能力,DAEN也被认为是降维方法。在这种情况下,DAEN可以专门用于特征提取,以便使用监督学习算法可以使用简化特征来训练分类模型。这种范例在DL应用的未来发展中可能是有价值的。

最近,生成对抗网络(GAN)是另一种用于无监督学习的DL算法,已经被开发并广泛用于图像合成、图像到图像转换和超分辨率。它受观察数据的潜在概率密度或概率质量函数的驱动。发生器(G)负责从随机向量中制作非真实的图像,以混淆另一个称为鉴别器(D)的网络。当D收到伪造和真实图像时,它会将它们分开。该模块中,G和D彼此竞争并同时训练,直到他们都找到最佳参数。在这些参数下,G最大化了它的分类准确性,D最大化了它的分辨准确性。网络可以通过由完全连接的GAN、卷积GAN、条件GAN、具有推理模型的GAN和对抗自动编码器(AAE)组成的多层网络来实现。

  1. Regularization(正则化)与Dropout
    由于过度拟合是多层DNN中的一个严重问题,因此已经开发了大量的正则化技术来最小化过度拟合问题。Dropout是通过剔除神经网络中的单位(隐藏和可见)来正则化神经网络的常用方法之一。退出的关键思想是随机向其隐藏单元添加噪声;因此,防止过度拟合并改善测试性能。那些采用丢失技术的DNN可以通过随机梯度下降(SGD)来训练,显然与常规DNN类似。同样,神经网络中的每个隐藏单元都必须学会与随机选择的其他单元样本一起工作,这使得它们更加强大,而不是依赖其他隐藏单元来纠正其错误。

贝叶斯正则化人工神经网络(BRANN)是将正则化引入NN体系结构的另一种发展。通过在模型训练的数学过程中使用岭回归,非线性回归可以转化为BRANN中的Bwell-of-statistical统计问题。通过使用BRANN,用于评估模型的交叉验证步骤也可以省略。输入特征的自动相关性确定(ARD)可以在BRANN中应用,以帮助计算几个有效的网络参数或权重,这将导致权重较小的参数被移除。 以这种方式,那些不相关或高度相关的指标被忽略,并且突出了对于建模最重要的变量。 这两个特征对于化学信息学和QSAR / QSPR研究非常有益,因为通常有太多的特征来描述一个分子。

三、用于开发深度学习应用的资源
 随着DL技术的快速发展,用于开发DL框架的许多开源软件包和库可供各个开发人员和小组探讨DL-他们可能不需要开发他们自己的DL平台。大多数这些软件包都有完善的GPU计算内置代码,并附有详细的教程和注释。

除了包和工具之外,数据集,尤其是基准数据集,是构建模型的另一个重要部分。DL的发展受益于CNN在计算机视觉方面的突破,主要是基准数据集ImageNet和年度竞争ImageNet大规模视觉识别挑战(ILSVRC)所促成的。在药物开发领域,使用Merck活性数据集的Merck Kaggle挑战以及使用其基准数据集的Tox21挑战极大地加速了ML方法在QSAR / QSPR研究中的应用。与传统ML方法相比,DL方法具有处理大数据的能力。因此,对于DL建模的大型标准化数据集的需求是非常迫切的。分子ML研究引入了他们的大型基准包MoleculeNet。 MoleculeNet数据集整合了多个公共分子数据集,涵盖量子力学数据,物理化学数据,生物物理数据和生理数据。此外,所有数据集,建立的模型评估指标以及计算分子特征的实现都与DL建模工具包一起打包在他们的称为DeepChem的Python库中。此外,Lenselink等人,发布了由ChEMBL数据库生成的基准生物活性数据集,这可能是开发DL模型的另一种标准化数据集。

四、深度学习在小分子药物设计中的应用
计算化学的三个主要领域已经报道了DL模型预测药物-靶标相互作用,产生新的分子,并预测转化研究的吸收、分布、代谢、排泄和毒性。像其他ML算法一样,DL在构建QSAR / QSPR模型中经历越来越多的成功应用。早在2012年,希尔顿组利用他们的DL模型赢得了默克Kaggle的挑战,开创了使用DL方法预测化合物活性和性质的应用的新篇章。在接下来的一年中,来自希尔顿集团和谷歌公司发表了多篇关于基于DL的QSAR建模的论文。他们使用各种超参数的DNN尝试了多个任务和不同功能,并开始使用GPU进行基准测试。 2014年,使用成对输入神经网络报告了他们的DIT预测模型,提供了将靶标添加到模型中的新理念。为了模拟化合物和蛋白质之间的相互作用,将分开的权重组分配给化合物特征和蛋白质特征,然后分别馈送到第一隐藏层。2015年,Wallach等人推出了他们的DL模型AtomNet,以预测选择用于药物发现的活性化合物的结合亲和力。据称AtomNet是第一个采用CNN进行小分子结合亲和力预测的DL模型。在AtomNet中,使用了结合配体和靶标结构信息的新方法。然而,AtomNet需要配体和靶蛋白的三维结构,这些三维结构包含参与靶标结合位点相互作用的每个原子的位置。最近,Wan和Zeng发表了他们使用DL方法进行复合蛋白质相互作用预测的新模型,他们在NLP研究中采用了一种被广泛使用的称为特征嵌入的技术。在他们的模型中,配体信息(分子指纹)和蛋白质序列都嵌入到多维载体中。在嵌入过程之后,构建了由整流线性单元(ReLU)组成的一系列完全连接的层。

除了预测靶标选择性和DTI之外,已经采用DL方法来预测ADMET性质。 2013年,Lusci等人报道了他们使用DL架构预测水溶性的模型。他们将小分子分割成原子和键,通过对这些原子进行排序并使用它们相应的键将它们连接起来,从而构建一个有向图,然后将收缩图放入RNN模型中。2015年,Shin等人发表了他们使用DL方法开发的模型来预测小分子的吸收潜力。将来自人结肠直肠癌细胞系(Caco-2)的663个小分子的体外通透性数据用作训练数据,并且使用基于它们2D结构的CDK工具箱计算209个分子描述符。如果不使用任何专门的体系结构,则会生成四层完全连接的神经网络,以提取和转换输入信息并最终分类输入化合物的吸收电位。DL方法在预测由NIH,EPA和FDA发起的Tox21数据挑战中的小分子毒性方面也是有效的。 Mayr及其同事在2015年报告了他们基于DL的毒性预测模型。在他们的研究中对多种类型的分子特征(如不同的指纹和化学特性)进行了测试和比较。其模型中采用了四万个输入特征和大量隐藏层。他们的基于DL模型的平均性能在多任务测试中表现良好,表明总体而言,DL算法在训练数据、参数和任务方面非常稳健。最近,佩雷拉等人提出了基于DL的协议进行基于对接的虚拟协议。在他们的模型中,他们使用配体信息和来自对接的互动氨基酸来优化对接结果。输入数据是使用嵌入技术产生的复合蛋白化合物的分布式表示,接着是三层卷积神经网络。

药物发现领域,许多较早的DL尝试一直在使用人工设计的特征,如分子描述符和指纹。在这种情况下,DL作为表示学习的特性,使得DL能够直接从数据中自动设计分子特征,这在很大程度上是缺失的。然而,这可能是区分DNN和传统ML算法的最重要的方面。很高兴看到最近的出版物已经证明直接学习Bundescessed化学数据也可能是一个可行的策略。Yao和Parkhill发表了一篇关于卷积神经网络Bundelcessed化学数据的着作。值得注意的是,他们使用3D小分子的电子密度,而不是2D分子指纹或物理化学性质,作为输入数据并开发了一个三维卷积神经网络模型来预测碳氢化合物的Kohn-Sham动能。 Bjerrum报告了他使用基于LSTM细胞的NN生成DL模型的研究。他研究的创新部分是他使用SMILES枚举作为模型中的原始输入数据。Goh等人的另一项研究。试图使用2D分子绘制分子图像作为CNN模型的输入数据来预测化学性质。他们还将它们的方法与使用传统分子特征作为输入特征的CNN模型进行了比较,结果表明使用基于图像的输入特征构建的模型稍微超过了常规分子特征。

最近,随着无监督学习和生成神经网络的发展,使用DL算法的这些生成模型的应用已经取得了进展。卡杜林等人开发了用于筛选化合物的七层生成AAE模型。与使用QSAR模型的常规筛选方法不同,它们的模型从6252个训练分子的输入分子指纹中提取特征,并使用非监督生成模型为潜在选择性化合物产生新的指纹矢量。然后,他们筛选出这些选定的输出载体,对照来自PubChem的7200万种化合物的大型文库,并预测了320种化合物作为潜在化合物,其中69种在实验上被确定为真正的命中。除了使用自动编码器选择新化合物之外,还有几次尝试使用其他深层生成网络来产生新化合物。Segler等人介绍了使用RNNs设计新型聚焦库的生成模型,实现了完成从头药物设计循环的满意性能。Olivecrona等人为从头库设计开发了类似的方法,并在该方法中增加了强化学习(RL)的新颖性。吉马赖斯等采用GANs以及RL建立一个生成模型,利用SMILES数据生成不同类型的分子,给出了使用最先进的无监督DL方法设计新型化合物的新思路。

五、讨论与展望
深度学习VS传统机器学习
 作为最先进的ML算法,DL算法受到与其他浅层ML算法相比的挑战。温克勒等人最近报道了他们的贝叶斯正则化神经网络(BNN)模型与Ma等人生成的DL模型之间的比较。使用来自Merck的相同KAGGLE数据集。他们的研究表明如果在QSAR或QSPR建模中提供了足够的训练数据,那么具有单个隐藏层的浅层NN可以执行以及具有更多隐藏层的DNN。 Capuzzi等人也得出了类似的结论。从使用Tox21数据进行比较,看起来这些结果与通用逼近定理一致,推断出DL算法可能没有优于正则浅NN的优势。这些结果可能会推翻我们的观点,即新颖的DL应该比传统的浅层ML方法更好。实际上,对于具有最终分类或回归目的的监督学习,DL和浅显学习都有自己的位置。

Schmidhuber等人研究表明大多数传统ML方法的主要缺陷是它们对模拟复杂近似函数的能力有限,并推广到一个看不见的实例。神经网络在QSAR / QSPR建模方面取得了进展,通用逼近定理证明了其在逼近方面的先进性。给定足够多样化的数据,浅层神经网络在大多数情况下可以很好地推广到新数据。给定相同的描述符和训练数据,两种类型的NN都会生成相似的质量模型。但是,深度神经网络可以生成复杂的描述符抽象。如前所述,将DL方法与浅层神经网络区分开来的本质特征不仅是对网络深度的重视,而且还强调对特征学习的重视。与需要手工选择特征的浅层神经网络相比,DL方法可以通过构建非线性网络模型来提取大数据的潜在信息,从而从数据中学习特征。在早期的QSAR / QSPR研究中,描述符是手动设计的,没有捕获所有影响QSAR / QSPR响应曲面的特征。因此,这些描述符值的微小变化可能会导致活动发生重大变化。这种现象被称为活动悬崖,这是QSAR建模中非常常见的问题。活动悬崖的存在与用于训练模型的活动响应面的分布高度相关,不仅涉及小分子特征学习,还涉及蛋白质目标特征提取。研究表明蛋白质特征的添加使DL模型表现更好。从DL建模的角度来看,不同的DL体系结构的选择和超参数的配置对于实现良好的性能非常重要。

另外,其他研究人员还探讨了DL方法和传统浅层ML方法之间的其他差异。 Lenselink等人发现DL方法和传统浅层ML方法在随机分割数据上表现相似;然而,当数据被同类化学系列分割时,它们有显着差异。他们认为一起发表的化合物在化学结构上通常非常相似,并且以这种方式分裂可以使验证更符合所进行的实验。

深度学习的局限与未来展望
由于特征学习的推进,在训练集应包含大量数据的前提下,DL可以达到较高的识别准确率。在数据非常有限的情况下,DL技术无法实现泛化的无偏估计,因此它们可能不如一些传统的浅层ML方法那么实用。同时,由于网络架构的复杂性,时间复杂度急剧增加,因此需要更强大的硬件设施和高级编程技能来授予DL方法的可行性和有效性。另外,尽管DL方法在实践中通常具有出色的性能,但在DL建模中调整超参数通常是棘手的。此外,很难知道有多少隐藏层和节点足以建立最佳仿真而没有针对特定DL建模的冗余。最后,DL中无监督学习的策略令人鼓舞,但仍远远落后。在现实世界的应用中,尤其是在药物发现方面,大部分数据都是非标记数据,包含大量信息。使用DL方法探索和开发新的无监督学习方法,以及从这些数据挖掘有用的信息仍然是困难的。

尽管DL方法已经成功应用于许多领域,但对于小分子药物发现中以化学为中心的建模来说,算法的适应仍然是一个问题,尤其是对于RNN和CNN,这些功能是强大的但对输入数据的格式有更高的限制。另一方面,DL系统被认为是B黑盒子系统;因此,他们很难解释,并且参与逻辑推理的权力有限。这些因素限制了DL在许多领域的应用和认可,例如临床数据分析。在这种情况下,从描述角度来看,结构-活性关系(SAR)研究的解释更为实用。然而,传统ML模型在当前化学信息学研究中常用的描述小分子(如分子指纹、物理化学性质、拓扑性质和热力学性质)的常规特征并不完全适用于DL体系结构。因此,更多可解释描述符的发展是可怕的。具体而言,由于DL方法属于表示学习,因此可以自动从原始数据中提取特征,DL建模有两个非常重要的问题:(1)如何优化DL体系结构以抽象有用特征;(2)如何解释这些特征。如上所述,最近的一些研究开始使用原始格式的化学数据来构建他们的DL模型,这表明常规特征工程可能不再是化学所必需的。

 除此之外,与诸如AlphaGo之类的DL模型的大数据量相比,用于DL建模的化学信息学数据库的大小远远落后。尽管主要数据库的规模很大,如ChEMBL已达到100万的规模,但用于构建特定模型的实际可用数据仍然有限。越来越多的研究人员正在将他们的策略从化学中心建模转变为组合方法,这些方法不仅考虑小分子的化学特征,还包括目标蛋白质信息以及其他类型的数据。

总体而言,小分子药物发现将变得越来越复杂。专为复杂的模拟而设计,DL应该有能力处理这种复杂性。此外,对于DL方法,我们不应将自己限制在关于生物活性、ADMET性质或药代动力学模拟的传统预测中,但也可能系统地整合所有数据和信息,并在药物发现中达到新的AI水平。

参考资料:

Jing Y, Bian Y, Hu Z, et al. Deep Learning for Drug Design: an Artificial Intelligence Paradigm for Drug Discovery in the Big Data Era.[J]. Aaps Journal, 2018, 20(3):58.
————————————————
版权声明:本文为CSDN博主「DrugAI」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u012325865/article/details/105683670

RDKit入门教程(1)——RDKit 安装 (Win10)

RDKit简介
RDKit官网:https://www.rdkit.org/
RDKit是干啥的:https://www.rdkit.org/docs/Overview.html#what-is-it
言简意赅的翻译一下:

RDKit是一个化学信息学的开源工具包
主要用于操作化学分子(SMILES和SMARTS)
可生成适合机器学习的化学分子特征
拥有Python 3.x API和C++ API
Win10下RDKit安装使用(Python API)
下载Anaconda 3.x版本的Python:
https://repo.anaconda.com/archive/Anaconda3-2019.07-Windows-x86_64.exe
安装完成后打开Anaconda Prompt: 并在命令行输入以下命令:
conda create -c rdkit -n my-rdkit-env rdkit
等上述命令完成后,接着激活rdkit的使用环境,进入rdkit模式
conda activate my-rdkit-env
如果在rdkit环境中需要使用常见模块,请另行使用pip install xxx安装,如:
pip install numpy
关闭命令行(Anaconda Prompt)窗口。
利用Spyder打开rdkit的文本编辑环境,安装好my-rdkit-env之后,在菜单栏的Anaconda3 (64-bit)文件夹下,应该会出现Spyder (my-rdkit-env)图标,点击即进入有rdkit环境的Spyder,否则会进入base状态的Spyder。
如图所示:

参考资料:https://www.rdkit.org/docs/Install.html
————————————————
版权声明:本文为CSDN博主「慕蒿」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zkchen0420/article/details/97784388

AI提高药物发现效率 |ML,Supercomputers and Big Data

Reference: https://zhuanlan.zhihu.com/p/82386729

摘要

药物研发成本的增加和投资回报率的降低对制药行业构成了巨大的威胁。新兴技术有可能大幅提高药物研发和制造的效率。人工智能(AI)被认为是一种令人难以置信的工具,可以增强医疗保健的多个方面,特别是药物发现。越来越多的制药公司正在投资人工智能。尽管最初持怀疑态度,但医疗人工智能市场据称到2020年将增长到80亿美元,主要受到药物发现应用的推动。

从本质上讲,人工智能由新颖的机器学习算法、计算能力的进步以及不断增加的临床前和临床数据提供支持。机器学习公司的数量激增,专门为制药公司提供服务,包括疾病靶标识别、化合物筛选、从头药物设计、临床疗效,毒性和ADME预测。这些工具现在比以往任何时候都更强大,不仅因为算法设计的进步,还因为可以访问大型超级计算机和基于GPU的新型AI加速器。甚至难以捉摸的量子计算机也开始用于人工智能驱动的药物研发。但是,获取良好的数据是关键,公共和私营公司越来越多地努力汇总和协调可用于药物研发的数据。随着先进研究工具(例如,下一代测序)、医疗保健数字化以及新兴的物联网基础设施的出现,这变得越来越重要。

为了提高药物发现效率和增加药物管线,许多制药公司已经与机器学习、计算和大数据公司合作。例如,强生公司正在进入临床试验IIb阶段的药物由BenevolentAI重新调整。然而,重要的是要了解不同AI系统的优点和缺点,因为它们通常针对特定目的进行优化。投资正确的技术是关键,通过投资一系列不同的系统,制药公司不仅能够将AI用于的大部分的药物研发和从药物发现到临床试验,而且还能找到针对复杂疾病的颠覆性新疗法。

介绍

药物研发变得越来越低效,主要归因于较大的平均研发成本,低临床试验药物成功率和低ROI,医疗支出减少和对罕见疾病的关注。大约15-20%的研发成本处于发现阶段。因此,减少药物发现的成本和时间以及提高临床试验成功率是必要的。

使用计算机模拟进行药物研发,也称为计算机筛选、设计和测试,有可能降低成本并提高药物管线的成功率。然而,这个想法并不新鲜。自90年代以来,已使用如同源模建、分子对接、定量构效关系和分子动力学模拟的方法。但是现代预测分析工具的出现使得计算机技术的力量呈指数级增长。AI常被用作流行语来描述不同的预测分析工具,例如预测建模、机器学习和数据挖掘。

越来越多的制药公司投资于人工智能,以加强疾病靶标识别、化合物筛选、从头药物设计和效力/毒性预测。目前,医疗保健人工智能市场估值约为70亿美元,预计将以惊人的复合年增长率53%增长,到2022年达到80亿美元。药物发现应用占据了该市场的最大部分(超过35%)。其他应用可以在医学图像、诊断、治疗方案和医院工作流程中找到。

这些预测工具的性能依赖于三个关键组件:算法(核心基础设施),计算能力(发动机)和数据(燃料)。除了相互交叉以外,这三个方面都取得了快速进展,从而产生了前所未有的强大工具,可用于了解复杂疾病和发现先进的治疗方法。

机器学习

巨大的计算能力和大量数据不足以进行预测建模。要在强大的计算机中处理所有数据,算法是必要的。算法越复杂,分析能力越好。由于人工智能革命,算法正在快速发展。其核心在于机器学习 – 一种用于发现数据集模式的极其强大的工具。机器学习的前沿是深度学习,它使用复杂的分层人工神经网络。 深度学习非常适合药物发现,因为它具有前所未有的从原始未处理数据、大型或小型数据集中提取关键特征的能力。因此,这对于识别新的疾病靶标,产生新的关联和预测药物结果是非常有利的。机器学习算法有不同的“学习”方式:监督、无监督或强化。无监督机器学习可以在医学和生物学研究数据中找到可用于识别新疾病靶标的隐藏模式。通过建模和量子化学的强化机器学习,可以实现虚拟筛选和从头药物设计。使用现有的药物和临床试验数据,监督学习可用于提高药效,毒性和ADME预测。因此,通过利用正确的AI算法,大部分药物开发可以通过计算机进行,从而节省成本并降低风险。

机器学习(ML):人工智能的一个子集,专注于计算机程序,可以教会自己在暴露于新数据时成长和变化。这种学习或“绩效的逐步提高”可以通过任务训练(监督学习),没有反馈(无监督学习)或性能反馈(强化学习)来实现。因此导致了复杂算法的创建和发展,这些算法对于人类自身发展而言过于复杂。

人工神经网络(ANN):一种信息处理算法,可以极大地提高机器学习性能。这种数据处理方法的灵感来自于生物神经系统如何处理信息。通常,这由节点(或人工神经元)网络组成,这些节点堆叠在不同的层中并一起工作以处理输入,相互调制并生成输出。调制由算法本身发生,以产生最佳输出。虽然这些算法可以在台式计算机上运行,但超级计算机和AI加速器可以增加它们的潜力。

深度学习(DL): ANN的子集仅存在了几年,并且在技术上以节点的多个“隐藏层”为特征。这种层次结构使算法能够基于更简单的下层在更高层中创建更复杂的模式和概念,就像人类视觉的工作方式一样。由于能够通过多个非线性变换对数据中的高级抽象特征进行建模,因此它可以指数级地加速机器学习性能。

迄今为止最先进的机器学习系统之一是Google的 DeepMind。在技术方面,它使用卷积神经网络上的深度学习和一种无模型强化学习的形式。实际上,这意味着没有提供预定义的环境/数据模型。该算法教会自己面对数据以及如何使用它。谷歌最强大的AI,AlphaGo Zero,已经教会了自己如何在最复杂的棋盘游戏中击败人类大师。谷歌已使用AlphaGo Zero来学习如何预测蛋白质折叠。

越来越多的AI公司为药物开发提供特定的解决方案。此列表概述了最值得注意的内容及其提供的服务:

Atomwise

What:预测小分子的生物活性

How:卷积神经网络(AtomNetTM)进行分子建模

Partners:AbbVie,默克

BenevolentAI

What:产生更好的靶标选择,设计新分子和优化化合物

How:深度学习从临床试验数据到学术论文挖掘和分析生物医学信息

Partners:强生公司

Berg

What:患者特异性的精确医学解决方案,以预测药物疗效和毒性

How:深度学习评估患者适应性 – 生物学数据

Partners:AstraZeneca,Sanofi

Exscientia

What:小分子药物设计和效力,选择性和ADME的预评估

How:机器学习使用各种实验、结构和临床数据库

Partners:GlaxoSmithKline(针对10种疾病相关目标的小分子),Sanofi(代谢性疾病的小分子),Sumitomo Dainippon Pharma(针对两种GPCR受体的小分子),Evotec合作伙伴关系,包括拜耳,赛诺菲,罗氏/基因泰克,强生公司和UCB(用于免疫肿瘤治疗的小分子)

Insilico Medicine

What:药物发现和再利用、生物标志物鉴定和临床试验设计

How:生成对抗网络来评估大量的多组学数据

Partners:GlaxoSmithKline(生物目标和途径)。

Numerate

What:小分子药物的发现和优化,包括活性和毒性预测

How:可以同时使用小型和大型数据库的机器学习(商业秘密)

Partners:Boehringer Ingelheim(传染病的主要负责人),Merck(心血管疾病的主要负责人),Servier(心血管疾病的小分子调节剂设计目标),Takeda(肿瘤学,胃肠病学和中枢神经系统疾病的主要负责人)

Recursion Pharmaceuticals

What:用于靶标发现和活性/毒性预测的细胞疾病模型

How:深深度学习来分析内部实验生物学数据

Partners:武田,赛诺菲

twoXAR

What:发现、筛选和优先考虑候选药物

How:机器学习与基因表达测量,蛋白质相互作用网络和临床记录

Partners:斯坦福大学亚洲肝脏中心,Santen

其他有价值的包括(1)Roche / Genentech和GNS Healthcare(癌症药物靶标),(2)加速GlaxoSmithKline医学机会治疗(ATOM)联盟(从药物目标到患者就绪治疗不到一年), (3)Deep Genomics,Johnson&Johnson Innovation的创业公司(用于操纵细胞生物学和治疗疾病的反义寡核苷酸),以及(4)Turbine,Bayer Open Innovation的初创公司(癌症生物学的分子模型,用于更好的生物标记)。

超级计算机

算法需要一个平台才能运行。虽然简单的机器学习算法可以在台式计算机上运行,但更强大的处理器可以执行更复杂的算法并处理更大的数据集,在频谱的最远端是令人难以置信的数字运算机,称为超级计算机,它可以大规模提升机器学习算法的功能。

计算能力不断提高,从而不断加速预测建模和人工智能的深度。据预测,2018年计算性能将达到1 exaFLOPS(每秒10亿亿次计算)。这种计算水平被认为是人类大脑的处理能力,并且可以实现令人难以置信的强大功能,数据分析和预测建模。

目前,中国的神威·太湖之光是最强的超级计算机,拥有惊人的93 petaFLOPS。它在石油勘探,生命科学,天气预报,工业设计和药物研究方面具有商业应用,但消耗大量15,371千瓦的电力。更著名的IBM Watson是一个由90台超级计算机组成的集群,即IBM Power 750,可以产生80 teraFLOPS的处理能力。IBM通过将沃森开放给商业应用程序,包括医疗保健和生命科学,推动了这一趋势。从药物发现到临床开发和疾病诊断。例如,辉瑞公司正在加速其与IBM Watson进行药物发现的免疫肿瘤学研究。IBM目前最强大的超级计算机是Sequoia(Blue Gene / Q),运行速度为20 petaFLOPS。

Nvidia通过引入新的计算模型完全改变了这种模式,这些模型大大加速了人工智能和高性能计算(HPC)。导致他们的股票在去年飙升了81.3%。他们采用异构计算,使用多个GPU作为协处理器,作为快速动作节点。2017年,Nvidia发布了其Volta处理器,该处理器使用所谓的张量微体系结构,也被谷歌的AlphaGo Zero使用,该处理器针对深度学习进行了优化。这种微体系结构用于他们的消费者GPU“Titan V”,它在经典基准测试中提供大约15 teraFLOPS,在张量基准测试上提供120 teraFLOPS。而功耗低于600 W。Nvidia还将他们的Volta处理器用于他们的GPU云,他们的数据中心GPU’Tesla V100’和他们的桌面AI超级计算机’DGX-1’。凭借新的张量核心,DGX-1系统可提供惊人的960 teraFLOPS,据说可以极大地促进机器学习。BenevolentAI已经使用先前版本的DGX-1(170 teraFLOPS)作为他们的判断增强认知系统TM,使计算机药物发现比以往更快更有效。

计算的下一个前沿是量子计算。目前公司之间存在竞赛,以生产稳定且适用于应用的系统。量子计算机使用单个粒子或量子位来编码信息。这使得能够在具有低功耗的小型设备中实现指数计算能力。例如,一个只有50个量子比特的系统理论上可以胜过当前的超级计算机。然而,保持量子比特稳定是一项重大的工程挑战。

大数据

所有这些超级计算机和深度学习算法都只是倾注于其中的数据“智能”。通常不是关于谁拥有最好的算法或最强大的处理器,而是关于谁有权访问最佳数据。真实的现代机器学习算法可以分析非结构化数据,例如PubMed上同行评审的生命科学文章的大量数据库。

我们生活在所谓的“信息爆炸”时代。仅在过去两年中就创造了90%的数据,我们目前每天产生大约2.5艾字节或2.5×1018字节。然而,大部分数据是分散的,不可访问的和未经证实的。不同的私人和公共组织专注于聚合数据,以便更有效地使用它。具体而言,对于药物发现,有许多可以开采的公共数据库,通常可分为3类:

分子生物学数据库:用于识别疾病靶标,包括组学数据(基因组学,转录组学,蛋白质组学,代谢组学),分子相互作用,功能获得和丧失,以及显微镜图像。数据库:dbSNP,dbVar,COSMIC,1000 Genomes Project,TCGA,Gene Expression Omnibus,ArrayExpress,Cancer Genome Atlas,GTEx Portal,Encode,Human Protein Atlas,Human Proteome Map,Cancer Cell Line Encyclopaedia,Project Achilles等。

结构-功能数据库创建新的药物线索,包括分子结构,药物-靶标相互作用和结构-功能关系。数据库:LINCS,连通图,ChEMBL,PubChem等

临床试验数据库用于预测药物反应,包括药物疗效,毒性和ADME。数据库:Cancer Therapeutics Response Portal,ImmPort,http://ClinicalTrials.gov,PharmaGKB等。

还有许多私营公司在数据聚合和结构上货币化。这些公司通常使用机器学习来挖掘和管理数据。例如,Innoplexus和NuMedii都利用分子、生物和临床数据库来提供可用于药物发现的注释、策划和标准化数据。其他公司正在应对来自下一代测序的数据激增。需要做出更多努力来集中和协调各种生物和医学研究机构所产生的大量数据。在这方面,欧盟的Corbel等共享服务正处于领先地位。

有许多患者数据可用,例如保险数据、公共卫生数据、移动健康数据、患者报告数据、组学数据、EHR数据、家庭数据和环境数据。这些数据不仅可以洞察疾病和治疗,还可以支持新的医疗保健模式,如基于结果的模式和面向患者的服务。数据挖掘通常是必要的,因为大约80%的医疗保健数据是非结构化的。然而,主要问题之一是数据保护和隐私。例如,谷歌DeepMind与英国国家健康服务(NHS)就获取肾功能衰竭数据达成的协议导致了由于隐私法问题引起的强烈反对。像IQVIA这样的公司通过使用强有力的隐私和安全措施来解决这个问题。IQVIA从药房供应商和EHR系统购买和管理数据。

随着物联网(IoT)的出现,患者特定数据的数量将以加速的速度增长。虽然数据挖掘将具有挑战性,但这可以使人们更好地了解健康和疾病。物联网健康解决方案,如临床级生物识别传感器,家用监视器和健身可穿戴设备,将增加可用于预测新疾病靶标和重新利用药物的大量数据。例如,Proteus Digital Health在药片上使用可摄入的传感器,不仅可以追踪依从性,还可以追踪症状。Quantus和MC10等公司生产临床级可穿戴生物识别传感器,可跟踪各种生命体征。

结论

近年来人们对人工智能能否兑现其提高药物开发效率的承诺持怀疑态度。现在公平地说,使用这些计算工具确实存在令人难以置信的疾病靶标识别、化合物筛选、从头药物设计和临床预测的潜力。这不仅体现在技术提供商数量的增加,而且还包括制药行业的大量采用和测试。值得注意的是,BenevolentAI和Johnson&Johnson正在通过机器学习进入IIb期临床试验,服用一种可以改善帕金森病嗜睡状态的药物。虽然许多其他制药和生物技术公司已经开始与几家人工智能公司合作,旨在通过机器学习和超级计算的进步获利,但公司投资正确的机器学习技术非常重要。每种算法都有其优点和缺点,并且通常针对特定目的进行优化。随着超级计算机创新,新型基于GPU的AI加速器和难以捉摸的量子计算的不断增加的计算能力,AI对药物开发的影响只会增加。此外,我们只处于数据时代的开端。随着越来越多的数据从先进的研究(如新一代测序)、医疗保健数字化和物联网涌入,随着时间的推移将获得更多的见解。

作者:

Dr Jeroen Verheyen

Dr Michal Wlodarski

深度学习在小分子药物研发中的应用

Reference: https://zhuanlan.zhihu.com/p/82404883

一、深度学习在小分子药物研发中的应用


二、深度学习工具


参考资料
Jing Y, Bian Y, Hu Z, et al. Deep Learning for Drug Design: an Artificial Intelligence Paradigm for Drug Discovery in the Big Data Era.[J]. Aaps Journal, 2018, 20(3):58.

深度学习在药物发现领域的兴起

reference: https://zhuanlan.zhihu.com/p/82405133

摘要

过去的十年中,深度学习(DeepLearning,DL)在各种人工智能研究领域取得了显着的成功。从以前对人工神经网络的研究演变而来,该技术在诸如图像和语音识别,自然语言处理等领域表现出优于其他机器学习(Machine Learning,ML)算法的性能。近年来,深度学习在医药研究中的第一波应用出现了,它的用途超出了生物活性预测的范围,并且在解决药物发现中的各种问题方面显示出了前景。

一、介绍

各种形状和大小的数字数据呈指数级增长。据美国国家安全局称,互联网每天处理1826PB的数据。在2011年,数字信息在短短五年内增长了9倍;到2020年,其在全球的数量预计将达到35万亿千兆字节。探索和分析大数据的高需求鼓励使用像深度学习(DL)这样的数据挖掘的机器学习算法。DL在计算机游戏、语音识别、计算机视觉、自然语言处理和自动驾驶汽车等广泛的应用领域取得了巨大的成功。可以说,DL正在改变我们的日常生活。在Gartner选择的2018年前十大技术趋势中,DL代表的AI技术位居榜首。

过去的十年里,已经在可用的化合物的活性和生物医学数据的量显着增加。如何有效地挖掘大规模的化学数据成为药物发现的关键问题。更大的数据量与更多的自动化技术相结合促进了机器学习的进一步应用。除了支持向量机(SVM)、神经网络(NN)和随机森林(RF)等已建立的方法,这些方法已被用于开发QSAR模型很长一段时间,矩阵分解和DL等方法已经开始被使用。DL利用了数据量的增加和可用计算机功率的不断增加。大多数其他机器学习方法和DL之间的区别在于DL中NN体系结构的灵活性。将在本问中讨论的架构是卷积神经网络(CNN),递归神经网络(RNN)和完全连接的前馈网络。单层神经网络已经用于QSAR建模很长一段时间;随着数据尺寸和计算能力的增加,自然而然地应用多层前馈网络进行生物活性预测。随着高通量成像设备的采用,CNN在计算机视觉领域取得了显着的成功,并成为生物图像处理的自然选择。在药物研发领域应用DL的领域正在迅速发展,几乎每周都有新的文章发表。最近,有关计算化学和生命科学领域的DL应用的一些评论已经发表。这里,我们更关注药物开发中的DL应用,特别是化学信息学和生物图像分析领域,并强调目前在药物开发中使用的DL结构。

二、深度学习的原理

DL是一类机器学习算法,其使用具有用于学习数据表示的多层非线性处理单元的人工神经网络(ANN)。最早的ANN可以追溯到1943年,当时Warren McCulloch和Walter Pitts基于数学和算法为阈值逻辑开发了神经网络的计算模型。现代ANN的基本结构受到人脑结构的启发。ANN中有三个基本层:输入层、隐藏层和输出层。根据ANN的类型,相邻层中的节点(也称为神经元)可以完全连接或部分连接。输入变量由输入节点进行,变量通过隐藏节点进行变换,最终输出值在输出节点进行计算。

ANN的训练是通过迭代修改网络中的权重值来完成的,通常通过反向传播方法来优化预测值和真值之间的误差。现代人工神经网络算法是在20世纪60年代至80年代期间开发的,并且自那时起就出现了应用。但传统的人工神经网络方法存在诸如过拟合、递减梯度等问题,并且在很大程度上被其他机器学习算法取代。DL的最近发展使ANN得以复兴。DL与传统ANN之间的主要区别在于神经网络的规模和复杂性。由于计算机硬件在早期的局限性,DL使用大量的隐藏层,而传统的ANN通常只能提供一个或两个隐藏层。由于更强大的CPU和GPU硬件的出现,DL可以承担在每层中使用更多的节点。DL中还有许多算法改进,例如使用丢失和DropConnect方法来解决过度拟合问题,应用整型线性单元(ReLU)以避免消除梯度并将卷积层和池层引入新颖的网络体系结构,以便使用大量的输入变量。大多数DL软件包都是开源的。这里简要介绍DL中使用的几种流行的NN架构。首先是完全连接的深度神经网络(DNN),它包含多个隐藏层,每层包含数百个非线性处理单元。DNN可以采用大量的输入特征,并且DNN的不同层中的神经元可以自动提取不同层级的特征。

(a)完全连接的深度神经网络(DNN),(b)卷积神经网络(CNN),(c)递归神经网络(RNN)和(d)自动编码器(AE)

另一种非常流行的NN是CNN,它被广泛用于图像识别。它通常包含几个卷积层和子采样层。卷积层由一组具有较小感受域和可学习参数的过滤器组成。在正向过程中,每个过滤器在输入体积的宽度和高度上进行卷积,计算过滤器条目与输入体积中的接受域之间的点积,并生成该过滤器的2D特征映射,子采样层用于减小特征映射的大小。最后,特征映射被连接成完全连接的层,相邻层中的神经元全部连接,就像在传统的ANN中一样,以提供最终的输出值。由于每个滤波器共享相同的参数,CNN在很大程度上减少了所学习的自由参数的数量,从而降低了消耗的内存并提高了学习速度。它在图像识别中胜过了其他类型的机器学习算法。

ANN的另一个变体是RNN。与前馈神经网络不同,它允许同一隐藏层中的神经元之间的连接形成有向循环。RNN可以将顺序数据作为输入特征,这非常适合于时间相关的任务,如语言建模。使用称为长期短期记忆(LSTM)的技术,RNN可以减少消失梯度问题。

第四种ANN结构称为自动编码器(AE)。AE是用于无监督学习的NN。它包含一个编码器部分,它是一个NN,用于将从输入层接收的信息转换为有限数量的隐藏单元,然后将解码器NN与具有与输入层相同数量的节点的输出层耦合。代替预测输入实例的标签,解码器NN的目的是从较少数量的隐藏单元重建其自己的输入。通常,AE的目的是为了降低非线性维数。最近,AE概念已经越来越广泛地用于从数据学习生成模型。

三、深度学习在化合物性质和活性预测中的应用

包括ANN在内的机器学习方法已经应用于化合物活性预测中。DL方法被用来首先解决活性预测问题。当通过相同数量的分子描述符呈现化合物时,直接的方法是使用完全连接的DNN来构建模型。达尔等人使用大量的2D拓扑描述符在默克Kaggle挑战数据集上应用DNN;并且DNN在15个靶标中的13个中显示比标准RF方法略好的性能。这项研究的一些关键知识是:(i)DNN可以处理数千个描述符而不需要特征选择;(2)Dropout可以避免传统人工神经网络面临的过度拟合问题;(iii)超参数(层数、每层节点的数量、激活函数的类型等)优化可以最大化DNN性能;(iv)多任务DNN模型比单任务模型执行得更好。迈尔等人报告他们的多任务DNN模型在包含12的数据集上赢得了Tox21挑战12000种化合物用于12种高通量毒性分析。他们使用具有静态描述符(3D、2D描述符,预定义的毒素)的大型特征集以及动态生成的扩展连接指纹描述符(ECFP)来使DNN在训练过程中进行自我特征推导。更有意思的是,专门使用ECFP的 DNN模型进行统计学关联分析,并且与已知的毒性基因显着相关的子结构在每个隐藏层都可以被识别。这些基准测试结果证明了与单任务DNN和传统机器学习方法相比,多任务DNN的优势。

Ramsundar等进行了一项系统研究,以构建多任务DNN并将其性能与单任务DNN模型进行比较。他们的研究结果表明,多任务模型比单任务模型和射频模型表现更好。Koutsoukas 等将DNN模型与一些常用的机器学习方法(如SVM,RF等)相比较,选择了ChEMBL中的七个数据集。发现DNN在统计学上优于其他(基于Wilcoxon统计检验的P值<0.01)机器学习方法。Lenselink 等报道了另一项比较DNN与常规机器学习方法RF、SVM、朴素贝叶斯和逻辑回归方法考虑蛋白质描述符的基准研究。他们研究了包含314 767个靶标化合物相互作用的数据集上的各种分类模型的性能。DNN模型在BEDROC(Boltzmann增强的接收机工作特性鉴别)方面证明是最好的模型,并且多任务和PCM实现被证明可以提高单任务DNN的性能。

此外有人报告了使用DNN二维拓扑描述来制作预测研究BACE活性模型和实现0.82的分类精度和PIC的标准误差50 ~0.53所述验证集。Aliper 等人建立了DNN模型,用于预测药物的药理学特性以及利用来自LINCS项目的转录组数据的药物再利用,以及路径信息。已经表明,使用途径和基因水平的信息,DNN模型在预测药物适应症方面实现了高精度,因此它们可用于药物再利用。

即使NN能够直接从分子结构中学习,而不是使用预定义的分子描述符。这个想法最初是由Merkwirth等人探索的。2005年几年后,开发了两种不同的方法来解决这个问题。Lusci 等报道了一种采用称为UGRNN的RNN变体的方法,该方法首先将分子结构转换为与分子表示相同长度的矢量,然后将它们传递到完全连接的NN层以建立模型。向量中的位值是从数据集中学习的。显示UGRNN方法能够建立预测溶解度模型,其准确性与用分子描述符建立的模型相当。徐等人应用相同的方法模拟药物性肝损伤(DILI),DL模型是基于475种药物构建的,并在198种药物的外部数据集上进行验证。最好的模型达到了0.955的AUC,超过了先前报道的DILI模型的精确度。

另一种方法称为图形卷积模型,其基本思想类似于UGRNN方法,该方法使用NN来自动生成分子描述向量,并通过训练NN来学习向量值。由摩根圆形指纹法启发,Duvenaud 等提出了神经指纹方法作为创建图形卷积模型。

该方法的工作流程:首先,读取2D分子结构以形成状态矩阵,其包含每个原子的原子和键信息。状态矩阵然后通过单层神经网络进行卷积运算以生成固定长度的矢量作为分子表示。通过考虑相邻原子的贡献,卷积操作可以在不同的级别运行,这相当于不同邻近级别的圆形指纹。由不同卷积运算产生的载体首先经历softmax变换,然后被总结以形成化合物的最终载体,该化合物是编码分子水平信息的神经指纹。神经指纹通过另一个完全连接的NN层来生成最终输出。神经指纹中的比特值通过训练学习并且是可微分的。在Duvenaud的三个测试案例中,使用神经指纹获得比Morgan指纹更好的结果,更重要的是,图形卷积模型中的影响性子结构可以被可视化以解释模型。图卷积模型的优点是描述符在训练过程中自动生成,并且不需要任何预定义的分子描述符。这样的描述符不是一般的描述符,而是特定任务和完全可区分的,因此可以提供更好的预测。其他分子图卷积方法由Kearnes报道使用神经指纹比使用摩根指纹获得更好的结果,更重要的是,图形卷积模型中的影响性子结构可以被可视化以解释模型。

除了基于图的表示学习方法外,还探索了基于其他类型分子表示的DL方法。Bjerrum使用SMILES字符串作为LSTM RNN的输入来构建预测模型,而不需要生成分子描述符。更有趣的是,有人观察到通过使用多个SMILES字符串来表示相同的化合物来扩大数据集比使用规范的SMILES获得更好的结果。吴作栋等将CNN应用于分子2D图形的图像,并获得令人惊讶的与ECFP培训的DNN模型相当的结果。而且当图像增加了一些基本的化学信息时,模型性能得到进一步改善。直接从结构中学习表示的能力不需要使用任何预定义的结构描述符,这是将DL与其他机器学习方法区分开来的一个重要特征,它基本上不需要传统的特征选择和缩减过程。

四、利用深度学习进行全新设计

DL在化学信息学中另一个有趣的应用是通过神经网络产生新的化学结构。Gómez-Bombarelli等提出了一种使用变分自动编码器(VAE)生成化学结构的新方法。第一步是使用VAE进行无监督学习,将ZINC数据库中的化学结构(SMILES字符串)映射到潜在空间。一旦VAE训练完成,潜在空间中的潜在载体就成为分子结构的连续表示,并且可以通过训练好的VAE可逆地转化为SMILES字符串。通过任何优化方法搜索连续潜在空间中的最优潜在解,然后将搜索到的潜在解解码为SMILES,可以实现具有期望特性的新结构的生成。继Gómez-Bombarelli的作品之后,Kadurin 等人使用VAE作为分子描述符发生器与生成敌对网络(GAN)耦合,一种特殊的神经网络架构以产生新的结构。布拉施克等利用VAE产生具有预测的抗多巴胺受体 2型活性的新型结构。



RNN在自然语言处理领域一直非常成功。Segler 等人报道他们的研究使用RNNs来产生新的化学结构。在大量SMILES字符串上训练RNN之后,RNN方法在生成未包含在训练集中的新有效SMILES字符串方面出人意料地发挥了非常好的作用。RNN通过学习SMILES字符串中字符的潜在概率分布来写结构上有效的SMILES ,在这种情况下,RNN可以被看作是分子结构的生成模型。Segler 等还探讨了使用RNN生成特定目标文库的可能性,方法是首先通过对一小部分特定目标活性化合物进行转移学习,首先训练一般先验模型,然后进行精细调整的重点模型。在对两种抗生素靶标进行回顾性分析的研究中,他们的重点模型能够产生金黄色葡萄球菌 18%看不见的真正活性物和恶性疟原虫28%。

Jaques等人将一种名为Deep Q-learning的强化学习技术与RNN一起应用,生成具有理想分子特性的SMILES。然而,他们的方法需要一种奖励功能,其结合手写规则来惩罚不良类型的结构,否则将导致对奖励的利用,从而导致不现实的简单分子。为了克服这个缺点,Olivecrona等提出了一种基于策略的强化学习方法来调整预先训练的RNN,以产生具有给定用户定义属性的分子。在一个测试实例中,将模型调整为产生预测对多巴胺受体2型有活性的化合物,该模型产生的结构中> 95%被预测为活性的。

五、深度学习在预测反应和逆合成分析中的应用


综合预测的历史可以追溯到20世纪60年代的基于规则的方法。最近在使用DL方法的反应预测中报告了一些有希望的结果。尽管没有与其他机器学习方法进行明确比较,但结果表明,DL可以实现与基于规则的方法相媲美的性能或优于基于规则的方法。概括地说,机器学习可以解决两类问题:一种类型是正向反应预测,其中产物预测给定一组反应物,而另一种类型是反向合成预测,其中给出最终产物,预测产物的反应步骤。Coley 等人根据美国专利的15 000个反应的训练集,利用NN对一组反应的候选产品进行排序。将反应分类为模板,并且训练后的模型正确地将主要产品等级为1 分配为71.8%,等级≤3分别为86.7%和等级≤5分别为90.8%。为了克服基于模板的反应预测方法所面临的覆盖率和效率问题,在同一研究组的后续研究中提出了无模板方法。他们使用Weisfeiler-Lehman差异网络对生成的候选反应进行评分,并且与基于反应模板的方法相比,实现了卓越的性能。Segler 等人使用350万个反应作为DNN的训练集。反应预测的前十位准确率为97%,逆合成分析的准确率为95%。另一项研究中,他们将策略网络和蒙特卡罗树搜索结合起来,利用由科学文献中的1200万反应组成的训练集进行逆合成预测。他们的系统可以像基于规则的方法那样解决两倍于分子的重新合成计划。

六、卷积神经网络在预测配体-蛋白质相互作用中的应用

评估蛋白质和配体之间的相互作用是分子对接计划的关键部分,并且基于力场或现有蛋白质-配体复合物结构的知识开发了许多评分函数。受到CNN在图像分析中成功的启发,最近发表了几篇关于应用CNN评分蛋白质-配体相互作用的研究。一个典型的例子是由Ragoza等人进行的研究蛋白质-配体结构被离散成分辨率为0.5的网格。栅格的每边都是24 埃,并以结合位点为中心。用一个函数描述每个原子,并且生成网格上的原子密度以形成输入矩阵。使用Caffe DL框架定义和训练多层CNN模型。CNN评分在CSAR靶标间姿势预测数据集 上优于AutoDock Vina,但对姿势的靶标内部排名表现更差。虽然卷积网络已经取得了一些令人鼓舞的结果,但与目前使用的评分函数相比,他们是否能持续改进结果还不清楚。

七、化学信息学中的基准数据集

图像识别领域的快速发展不仅可以归因于新算法的出现,而且可以归因于典型和大型数据集的存在。标准化数据集将使社区能够方便地对开发的机器学习方法进行基准测试或评估。每年ImageNet大规模视觉识别竞赛(ILSVRC)已经见证了许多有影响力的CNN体系结构的诞生。

虽然有几个开源的化学信息学数据集可用,但由于这些数据集的规模有限,缺乏多种分离培训和测试集的方式,它们对机器学习方法开发的影响仍然有限,更重要的是,缺乏提议的新算法的标准评估平台。通过WordNet的启发和ImageNet 等人通过策划许多不同的集合,包括量子力学、物理化学、生物物理学和生理数据集,并开发一套实现许多已知分子表示和机器学习算法的软件,推出了MoleculeNet数据集。MoleculeNet建立在开源软件包DeepChem上,可以轻松访问DeepChem中现有的一些流行的DL算法。这将在很大程度上促进未来新型机器学习算法的比较和开发。

八、深度学习在生物成像分析中的应用

药物发现过程中,生物成像和图像分析广泛应用于从临床前研发到临床试验的各个阶段。成像使科学家能够看到宿主(人或动物)、器官、组织、细胞和亚细胞组分的表型和行为。通过数字图像分析,揭示了隐藏的生物学和病理学以及药物作用机制。成像模式的实例是荧光标记的或未标记的显微图像、计算机断层扫描(CT)、MRI、正电子发射断层扫描(PET)、组织病理学成像和质谱成像(MSI)。DL也在生物图像分析方面取得成功,许多研究报告与经典分类器相比具有优越的性能。

对于显微图像,已使用CNNs对单个荧光标记细胞进行分割和亚型分型,以及来自相位缩小显微镜的未标记图像。临床前设置的其他传统艰巨任务,如细胞追踪和菌落计数,也可以使用DL自动进行。由于组织形态丰富,与荧光标记图像相比,来自组织病理学的图像本质上通常是复杂的。尽管如此,在细胞水平上,用苏木精和曙红(H&E)染色染色的乳腺和结肠组织可以实现单个细胞的分割和分类。在组织区域水平,通过DL鉴定来自H&E染色的乳房组织的肿瘤区域,而白细胞和脂肪组织的额外类别也可以被识别。除了基本的图像分割,DL已经被用于H&E和免疫组织化学染色组织的组织病理学诊断。

DL的应用也用于CT、MRI和PET成像的分析。除了图像分割和分类的流行应用外,其实程序还在基于内容的图像检索中,并且据报道DL方法胜过了流行的ISOMAP和弹性网方法。

对于新兴的MSI,类似于DL在组织病理学中的应用,肿瘤亚型可以通过高分辨率基质辅助激光解吸/电离(MALDI)MSI进行。鉴于MSI可以将组织的代谢信息可视化,已经可以通过DL检测到具有解吸电喷雾电离(DESI)MSI 代谢异质性的肿瘤的亚区域。最后,在一个不寻常的成像领域:流式细胞术,DL使细胞分类实时用于高通量应用。用于成像的DNN训练非常耗时且需要专门的GPU处理。此外,在高通量成像筛查的情况下,高质量的训练集很少见。

九、未来药物发现深度学习的发展

机器学习方法和DL通常需要大数据集来训练;然而,人脑只有几个例子才有学习的能力。如何只用少量的可用数据进行学习是机器学习中最热门的话题之一。利用辅助数据改进仅有少数数据点的模型的DL示例是匹配网络,其被提出作为单次学习的变体。当包括辅助数据时获得改进的结果。像一次性学习这样的方法与药物发现有关,药物化学家通常在可用数据有限的情况下开展新靶点研究。Altae-Tran等在化学信息学数据集上使用LSTM方法来构建具有非常小的训练集的模型,并且报告了有希望的结果。最近,DL在记忆增广神经网络中使用了一种新型架构,用可微分神经计算机(DNC)显着改善了这种结构。已经将DNCs应用于几个问题,如问答系统和查找图表中的最短路径。然而,这些更先进的架构迄今尚未应用于药物研发。

结语

机器学习自20世纪90年代后期以来一直用于药物研发,并已成为药物发现的有用工具。机器学习工具最近的一个扩展是DL;与其他方法相比,DL具有更灵活的架构,因此可以创建针对特定问题量身定制的NN架构。缺点是DL通常需要非常大的训练集。一个相关的问题是:DL是否优于其他机器学习方法?我们认为现在得出任何确定的结论还为时尚早,迄今为止的结果表明,DL对于图像分析等特定任务来说是优越的,对于de novo分子设计和反应预测非常有用。对于具有结构化输入描述符的任务,DL似乎至少与其他方法一样。最相关的例子是生物活性预测,DL似乎通过多任务学习实现了更好的整体表现。但是,其他机器学习方法也在不断改进。因此,实际上用于生物活性预测的方法的选择可能取决于建模者最熟悉的方法。如果不同的机器学习方法达到大致相同的精度,那么使用机器学习模型可以实现的限制可能取决于数据和数据集大小的实验不确定性,而不是所使用的具体算法。


参考资料

Chen H, Engkvist O, Wang Y, et al. The rise of deep learning in drug discovery[J]. Drug Discovery Today, 2018.

Pytorch DataLoader详解

Reference: https://www.zdaiot.com/MLFrameworks/Pytorch/Pytorch%20DataLoader%E8%AF%A6%E8%A7%A3/

因为Few-Shot Learning问题要读取数据组成task,因此如何读取数据组成一个task是一个问题。之前看到好几个Pytorch版本的代码,虽然也实现了读取数据组成task,但是逻辑较为复杂且复杂度较高。最近看到了这个代码,感觉实现的方法特别高级,定制性也很强,但是需要比较深入的理解Pytorch DataLoader的原理。所以便有了这篇文章。

Pytorch读取数据流程

Pytorch读取数据虽然特别灵活,但是还是具有特定的流程的,它的操作顺序为:

  • 创建一个 Dataset 对象,该对象如果现有的 Dataset 不能够满足需求,我们也可以自定义 Dataset,通过继承 torch.utils.data.Dataset。在继承的时候,需要 override 三个方法。
    • __init__: 用来初始化数据集
    • __getitem__:给定索引值,返回该索引值对应的数据;它是python built-in方法,其主要作用是能让该类可以像list一样通过索引值对数据进行访问
    • __len__:用于len(Dataset)时能够返回大小
  • 创建一个 DataLoader 对象
  • 不停的 循环 这个 DataLoader 对象

对我们来说,本篇文章的侧重点在于介绍 DataLoader,因此对于自定义 Dataset,这里不作详细的说明。

DataLoader参数

先介绍一下DataLoader(object)的参数:

  • dataset(Dataset): 传入的数据集
  • batch_size(int, optional): 每个batch有多少个样本
  • shuffle(bool, optional): 在每个epoch开始的时候,对数据进行重新排序
  • sampler(Sampler, optional): 自定义从数据集中取样本的策略,如果指定这个参数,那么shuffle必须为False
  • batch_sampler(Sampler, optional): 与sampler类似,但是一次只返回一个batch的indices(索引),需要注意的是,一旦指定了这个参数,那么batch_size,shuffle,sampler,drop_last就不能再指定了(互斥——Mutually exclusive)
  • num_workers (int, optional): 这个参数决定了有几个进程来处理data loading。0意味着所有的数据都会被load进主进程。(默认为0)
  • collate_fn (callable, optional): 将一个list的sample组成一个mini-batch的函数;通俗来说就是将一个batch的数据进行合并操作。默认的collate_fn是将img和label分别合并成imgs和labels,所以如果你的__getitem__方法只是返回 img, label,那么你可以使用默认的collate_fn方法,但是如果你每次读取的数据有img, box, label等等,那么你就需要自定义collate_fn来将对应的数据合并成一个batch数据,这样方便后续的训练步骤。
  • pin_memory (bool, optional): 如果设置为True,那么data loader将会在返回它们之前,将tensors拷贝到CUDA中的固定内存(CUDA pinned memory)中.
  • drop_last (bool, optional): 如果设置为True:这个是对最后的未完成的batch来说的,比如你的batch_size设置为64,而一个epoch只有100个样本,那么训练的时候后面的36个就被扔掉了…如果为False(默认),那么会继续正常执行,只是最后的batch_size会小一点。
  • timeout(numeric, optional): 如果是正数,表明等待从worker进程中收集一个batch等待的时间,若超出设定的时间还没有收集到,那就不收集这个内容了。这个numeric应总是大于等于0。默认为0
  • worker_init_fn (callable, optional): 每个worker初始化函数 If not None, this will be called on each worker subprocess with the worker id (an int in [0, num_workers – 1]) as input, after seeding and before data loading. (default: None)

这里,我们需要重点关注samplerbatch_sampler这两个参数。在介绍这两个参数之前,我们需要首先了解一下DataLoader,Sampler和Dataset三者关系。

DataLoader,Sampler和Dataset

在介绍该参数之前,我们首先需要知道DataLoader,Sampler和Dataset三者关系。首先我们看一下DataLoader.next的源代码长什么样,为方便理解我只选取了num_works为0的情况(num_works简单理解就是能够并行化地读取数据)。

1
2
3
4
5
6
7
8
9
10
class DataLoader(object):


def __next__(self):
if self.num_workers == 0:
indices = next(self.sample_iter) # Sampler
batch = self.collate_fn([self.dataset[i] for i in indices]) # Dataset
if self.pin_memory:
batch = _utils.pin_memory.pin_memory_batch(batch)
return batch

在阅读上面代码前,我们可以假设我们的数据是一组图像,每一张图像对应一个index,那么如果我们要读取数据就只需要对应的index即可,即上面代码中的indices,而选取index的方式有多种,有按顺序的,也有乱序的,所以这个工作需要Sampler完成,现在你不需要具体的细节,后面会介绍,你只需要知道DataLoader和Sampler在这里产生关系。

那么Dataset和DataLoader在什么时候产生关系呢?没错就是下面一行。我们已经拿到了indices,那么下一步我们只需要根据index对数据进行读取即可了。

再下面的if语句的作用简单理解就是,如果pin_memory=True,那么Pytorch会采取一系列操作把数据拷贝到GPU,总之就是为了加速。

综上可以知道DataLoader,Sampler和Dataset三者关系如下:

img

sampler和batch_sampler

通过上面对DataLoader参数的介绍,发现参数里面有两种sampler:samplerbatch_sampler,都默认为None前者的作用是生成一系列的index,而batch_sampler则是将sampler生成的indices打包分组,得到一个又一个batch的index。例如下面示例中,BatchSamplerSequentialSampler(Sampler的一种)生成的index按照指定的batch size分组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from torch.utils.data import SequentialSampler, BatchSampler

SequentialSampler(range(10))
Out[5]: <torch.utils.data.sampler.SequentialSampler at 0x7fe1631de908>

list(BatchSampler(SequentialSampler(range(10)), batch_size=3, drop_last=False))
Out[6]: [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

a = BatchSampler(SequentialSampler(range(10)), batch_size=3, drop_last=False)
b = iter(a)
next(b)
Out[9]: [0, 1, 2]
next(b)
Out[10]: [3, 4, 5]
b = iter(a)
next(b)
Out[12]: [0, 1, 2]

从这个例子中可以看出,当BatchSampler中的数据取完了,再使用iter(a)得到新的迭代器对象即可,不需要再次实例化类。

Pytorch中已经实现的Sampler有如下几种(均在torch.utils.data下):

  • SequentialSampler(若shuffle=False,则若未指定sampler,默认使用)
  • RandomSampler(若shuffle=True,则若未指定sampler,默认使用)
  • WeightedSampler
  • SubsetRandomSampler

Pytorch中已经实现的 batch_samplerBatchSampler(在torch.utils.data下,默认使用)

需要注意的是DataLoader的部分初始化参数之间存在互斥关系,这个你可以通过阅读源码更深地理解,这里只做总结:

  • 如果你自定义了batch_sampler,那么这些参数都必须使用默认值:batch_sizeshuffle,sampler,drop_last
  • 如果你自定义了sampler,那么shuffle需要设置为False
  • 如果samplerbatch_sampler都为None,那么batch_sampler使用Pytorch已经实现好的BatchSampler,而sampler分两种情况:
    • shuffle=True,则sampler=RandomSampler(dataset)
    • shuffle=False,则sampler=SequentialSampler(dataset)

源码解析

首先,大概扫一下DataLoader的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class DataLoader(object):
__initialized = False

def __init__(self, dataset, batch_size=1, shuffle=False, sampler=None, batch_sampler=None,
num_workers=0, collate_fn=default_collate, pin_memory=False, drop_last=False,
timeout=0, worker_init_fn=None):

self.dataset = dataset
self.batch_size = batch_size
self.num_workers = num_workers


if sampler is not None and shuffle:
raise ValueError(‘sampler option is mutually exclusive with “shuffle”‘)

if batch_sampler is None:
if sampler is None:
if shuffle:
sampler = RandomSampler(dataset)
else:
sampler = SequentialSampler(dataset)
batch_sampler = BatchSampler(sampler, batch_size, drop_last)

self.sampler = sampler
self.batch_sampler = batch_sampler
self.__initialized = True

def __iter__(self):
return _DataLoaderIter(self)

这里我们主要看__init__()__iter__()

(1)数据的shuffle和batch处理

  • RandomSampler(dataset)
  • SequentialSampler(dataset)
  • BatchSampler(sampler, batch_size, drop_last)

(2)因为DataLoader只有__iter__()而没有实现__next__()

所以DataLoader是一个iterable而不是iterator。这个iterator的实现在_DataLoaderIter中。

RandomSampler(dataset)、 SequentialSampler(dataset)

这两个类的实现是在dataloader.py的同级目录下的torch/utils/data/sampler.py

sampler.py中实现了一个父类Sampler,以及SequentialSampler,RandomSampler和BatchSampler等五个继承Sampler的子类

这里面的Sampler的实现是用C/C++实现的,这里的细节暂且不表。

我们这里需要知道的是:对每个采样器,都需要提供__iter__方法,这个方法用以表示数据遍历的方式和__len__方法,用以返回数据的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import torch


class Sampler(object):
r”””Base class for all Samplers.
Every Sampler subclass has to provide an __iter__ method, providing a way
to iterate over indices of dataset elements, and a __len__ method that
returns the length of the returned iterators.
“””

def __init__(self, data_source):
pass

def __iter__(self):
raise NotImplementedError

def __len__(self):
raise NotImplementedError


class SequentialSampler(Sampler):
r”””Samples elements sequentially, always in the same order.
Arguments:
data_source (Dataset): dataset to sample from
“””

def __init__(self, data_source):
self.data_source = data_source

def __iter__(self):
return iter(range(len(self.data_source)))

def __len__(self):
return len(self.data_source)


class RandomSampler(Sampler):
r”””Samples elements randomly, without replacement.
Arguments:
data_source (Dataset): dataset to sample from
“””

def __init__(self, data_source):
self.data_source = data_source

def __iter__(self):
return iter(torch.randperm(len(self.data_source)).tolist())

def __len__(self):
return len(self.data_source)


if __name__ == “__main__”:
print(list(RandomSampler(range(10))))
print(list(SequentialSampler(range(10))))

a = SequentialSampler(range(10))

from collections import Iterable
print(isinstance(a, Iterable))
from collections import Iterator
print(isinstance(a, Iterator))

for x in SequentialSampler(range(10)):
print(x)

print(next(a))
print(next(iter(a)))

输出结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[3, 7, 5, 8, 9, 0, 2, 4, 1, 6]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
True
False
0
1
2
3
4
5
6
7
8
9
TypeError: ‘SequentialSampler’ object is not an iterator
0

可以看出RandomSampler等方法返回的就是DataSet中的索引位置(indices),其中,在子类中的__iter__方法中,需要返回的是iter(xxx)(即iterator)的形式:

这里写图片描述
1
2
3
4
5
6
7
8
9
10
#### 以下两个代码是等价的
for data in dataloader:

#### 等价与
iters = iter(dataloader)
while 1:
try:
next(iters)
except StopIteration:
break

此外,torch.randperm()的用法如下:

这里写图片描述

最后,我们再理解一下这些类中间的__iter__函数,该函数的返回值为迭代器对象,可以使用for循环或者next()函数依次访问该迭代器对象中的每一个元素。但是这些类是可迭代类并不是迭代器类,所以上例中的实例对象a只能使用for循环访问__iter__函数返回的迭代器对象,而不能直接使用next()函数,需要使用iter()函数得到__iter__函数返回的迭代器对象。如下所示,可以看到iter(a)后得到的结果为range_iterator,也就是__iter__函数返回的迭代器对象。

1
2
3
4
5
a
Out[74]: <__main__.SequentialSampler at 0x7fa26c1d7898>

iter(a)
Out[75]: <range_iterator at 0x7fa26c1cf960>

BatchSampler(Sampler)

BatchSampler是wrap一个sampler,并生成mini-batch的索引(indices)的方式。代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class BatchSampler(Sampler):
r”””Wraps another sampler to yield a mini-batch of indices.
Args:
sampler (Sampler): Base sampler.
batch_size (int): Size of mini-batch.
drop_last (bool): If “True“, the sampler will drop the last batch if
its size would be less than “batch_size“
Example:
>>> list(BatchSampler(SequentialSampler(range(10)), batch_size=3, drop_last=False))
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
>>> list(BatchSampler(SequentialSampler(range(10)), batch_size=3, drop_last=True))
[[0, 1, 2], [3, 4, 5], [6, 7, 8]]
“””

def __init__(self, sampler, batch_size, drop_last):
if not isinstance(sampler, Sampler):
raise ValueError(“sampler should be an instance of “
“torch.utils.data.Sampler, but got sampler={}”
.format(sampler))
if not isinstance(batch_size, _int_classes) or isinstance(batch_size, bool) or \
batch_size <= 0:
raise ValueError(“batch_size should be a positive integeral value, “
“but got batch_size={}”.format(batch_size))
if not isinstance(drop_last, bool):
raise ValueError(“drop_last should be a boolean value, but got “
“drop_last={}”.format(drop_last))
self.sampler = sampler
self.batch_size = batch_size
self.drop_last = drop_last

def __iter__(self):
batch = []
# 一旦达到batch_size的长度,说明batch被填满,就可以yield出去了
for idx in self.sampler:
batch.append(idx)
if len(batch) == self.batch_size:
yield batch
batch = []
if len(batch) > 0 and not self.drop_last:
yield batch

def __len__(self):
# 比如epoch有100个样本,batch_size选择为64,那么drop_last的结果为1,不drop_last的结果为2
if self.drop_last:
return len(self.sampler) // self.batch_size
else:
return (len(self.sampler) + self.batch_size – 1) // self.batch_size

if __name__ == “__main__”:
print(list(BatchSampler(SequentialSampler(range(10)), batch_size=3, drop_last=False)))
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
print(list(BatchSampler(SequentialSampler(range(10)), batch_size=3, drop_last=True)))
# [[0, 1, 2], [3, 4, 5], [6, 7, 8]]

这里主要看__iter__方法,可以看到,代码的思路很清楚明白的展示了batch indices的是如何取出的。要想理解该方法,最重要的是对于yield关键字的理解。之前我已经有一篇文章解释过yield关键字了。这里只说结论:yield就是return返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后开始;同时包含yield的函数为生成器(生成器是迭代器对象),当直接调用该函数的时候,会返回一个生成器。而生成器是迭代器对象,正好对应于前面所述的Sample对象的__iter__(self)函数,返回值需要是迭代器对象

对于BatchSampler类而言,只含有__iter__含义,但是不含有__next__函数,所以它是一个可迭代类但是不是一个迭代器类。因此只能使用for循环,不能使用next()函数。若想使用next()函数,需要使用iter()函数作用于BatchSampler类的实例,这样就可以得到__iter__函数的返回值即迭代器对象。其实对于含有__iter__的类,使用for循环遍历其数据的时候,内部是内置了__iter__函数了。

总结

假设某个数据集有100个样本,batch size=4时,以SequentialSamplerBatchSampler为例,Pytorch读取数据的时候,主要过程是这样的:

  • SequentialSampler类中的__iter__方法返回iter(range(100))迭代器对象,对其进行遍历时,会依次得到range(100)中的每一个值,也就是100个样本的下标索引。
  • BatchSampler类中__iter__使用for循环访问SequentialSampler类中的__iter__方法返回的迭代器对象,也就是iter(range(100))。当达到batch size大小的时候,就使用yield方法返回。而含有yield方法为生成器也是一个迭代器对象,因此BatchSampler类中__iter__方法返回的也是一个迭代器对象,对其进行遍历时,会依次得到batch size大小的样本的下标索引。
  • DataLoaderIter类会依次遍历类中的BatchSampler类中__iter__方法返回的迭代器对象,得到每个batch的数据下标索引。

自定义Sampler和BatchSampler

仔细查看源代码其实可以发现,所有采样器其实都继承自同一个父类,即Sampler,其代码定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Sampler(object):
r”””Base class for all Samplers.
Every Sampler subclass has to provide an :meth:`__iter__` method, providing a
way to iterate over indices of dataset elements, and a :meth:`__len__` method
that returns the length of the returned iterators.
.. note:: The :meth:`__len__` method isn’t strictly required by
:class:`~torch.utils.data.DataLoader`, but is expected in any
calculation involving the length of a :class:`~torch.utils.data.DataLoader`.
“””

def __init__(self, data_source):
pass

def __iter__(self):
raise NotImplementedError

def __len__(self):
return len(self.data_source)

所以你要做的就是定义好__iter__(self)函数,不过要注意的是该函数的返回值需要是迭代器对象。例如SequentialSampler返回的是iter(range(len(self.data_source)))

另外BatchSampler与其他Sampler的主要区别是它需要将Sampler作为参数,打包Sampler中__iter__方法返回的迭代器对象的迭代值,进而每次迭代返回以batch size为大小的index列表。也就是说在后面的读取数据过程中使用的都是batch sampler