分享

DeepChem: 集成Tensorflow及PyTorch深度学习框架

 翌然生物 2023-05-18 发布于广东

      DeepChem内置了很多标准模型供我们使用,但是,如果我们想自定义一个全新的模型,它也提供了与TensorFlow(Keras)PyTorch的集成,因此我们可以将其与这两个框架中的模型一起使用。

表1 Deepchem内置的标准模型

      我们可以使用两种不同的方法将TensorFlowPyTorch模型与DeepChem一起使用。这取决于您是要在训练和评估模型时使用TensorFlow/PyTorch API还是DeepChem API。当训练模型时,DeepChem的Dataset类包含轻松适应其他框架的方法。make_tf_dataset()会返回一个tensorflow.data.Dataset对象,它可以遍历所有数据。make_pytorch_dataset()返回一个torch.utils.data.IterableDataset,它可以遍历数据。这样,就可以使用DeepChem的数据集、加载器、特征提取器、转换器、分割器等,并将它们轻松集成到您现有的TensorFlowPyTorch代码中。

  DeepChem还提供了许多其他有用的功能。我们可以将模型封装在一个DeepChem的模型对象中,下面我们将用实例代码讲解如何进行封装:

1. Keras Model

      KerasModel是DeepChem的Model类的子类。它作为tensorflow.keras.Model的封装器。让我们看一个使用示例。对于这个示例,我们创建一个由两个全连接层组成简单的序列模型。

import deepchem as dcimport tensorflow as tf
keras_model = tf.keras.Sequential([ tf.keras.layers.Dense(1000, activation='relu'), tf.keras.layers.Dropout(rate=0.5), # 生成一个标量输出 tf.keras.layers.Dense(1)])model = dc.models.KerasModel(keras_model, dc.models.losses.L2Loss())

      在这个示例中,我们使用了KerasSequential类。我们的模型包含一个具有ReLU激活函数的全连接层,50%的dropout用于提供正则化,并且最后一层生成一个标量输出。我们还需要指定训练模型时要使用的损失函数,这里我们使用L2损失。现在我们可以像使用任何其他DeepChem模型一样训练和评估这个模型。例如,让我们加载Delaney溶解度数据集(DeepChem预测小分子溶解度)。根据分子的扩展连接指纹(ECFPs),我们测试一下模型在预测分子的溶解度方面表现如何。

import deepchem as dcimport tensorflow as tf
keras_model = tf.keras.Sequential([ tf.keras.layers.Dense(1000, activation='relu'), tf.keras.layers.Dropout(rate=0.5), # 生成一个标量输出 tf.keras.layers.Dense(1)])model = dc.models.KerasModel(keras_model, dc.models.losses.L2Loss())

     从输出结果中可以看出,在训练集上的R2值为0.98,在测试集上R2的结果为0.776,模型的预测性能还算不错。

2. TorchModel

      TorchModel的使用方式与KerasModel类似,只不过它封装在了torch.nn.Module中。我们使用PyTorch创建另一个与之前相同的模型,并在相同的数据上对其进行训练和测试。

import torch
pytorch_model = torch.nn.Sequential( torch.nn.Linear(1024, 1000), torch.nn.ReLU(), torch.nn.Dropout(0.5), torch.nn.Linear(1000, 1))model = dc.models.TorchModel(pytorch_model, dc.models.losses.L2Loss())
model.fit(train_dataset, nb_epoch=50)print('training set score:', model.evaluate(train_dataset, [metric]))print('test set score:', model.evaluate(test_dataset, [metric]))

     对比上面Keras模型的结果可以发现,两者的结果非常接近。

3. 定义计算模型损失

     我们看一个更高级的示例。在上面的模型中,模型损失是直接从模型的输出计算得出的。这种方法通常是可行的,但也有例外。考虑一个输出结果为概率分布的分类模型。虽然我们可以利用概率计算损失,但利用logits计算更具数值稳定性。

    为了实现这一点,我们创建一个返回多个输出的模型,包括概率和logits。KerasModelTorchModel允许我们指定一个"output types"的列表。如果输出类型为'prediction',那意味着它是一个正常输出,在调用predict()时应返回。如果它的类型是'loss',那意味着它应该替代正常输出传递给损失函数。

     Sequential模型不允许多个输出,因此我们定义一个模型的子类。

3.1  KerasModel 子类

import torch
pytorch_model = torch.nn.Sequential( torch.nn.Linear(1024, 1000), torch.nn.ReLU(), torch.nn.Dropout(0.5), torch.nn.Linear(1000, 1))model = dc.models.TorchModel(pytorch_model, dc.models.losses.L2Loss())
model.fit(train_dataset, nb_epoch=50)print('training set score:', model.evaluate(train_dataset, [metric]))print('test set score:', model.evaluate(test_dataset, [metric]))

     我们可以使用BACE数据集对模型进行训练。这是一个二分类任务,旨在预测一种分子是否会抑制BACE-1酶。

tasks, datasets, transformers = dc.molnet.load_bace_classification(feturizer='ECFP', splitter='scaffold')train_dataset, valid_dataset, test_dataset = datasetsmodel.fit(train_dataset, nb_epoch=100)metric = dc.metrics.Metric(dc.metrics.roc_auc_score)print('training set score:', model.evaluate(train_dataset, [metric]))print('test set score:', model.evaluate(test_dataset, [metric]))

3.2 TorchModel 子类

tasks, datasets, transformers = dc.molnet.load_bace_classification(feturizer='ECFP', splitter='scaffold')train_dataset, valid_dataset, test_dataset = datasetsmodel.fit(train_dataset, nb_epoch=100)metric = dc.metrics.Metric(dc.metrics.roc_auc_score)print('training set score:', model.evaluate(train_dataset, [metric]))print('test set score:', model.evaluate(test_dataset, [metric]))

     我们将使用相同的BACE数据集。与之前一样,该模型将尝试进行二分类任务,预测一种分子是否会抑制酶BACE-1

tasks, datasets, transformers = dc.molnet.load_bace_classification(feturizer='ECFP', splitter='scaffold')train_dataset, valid_dataset, test_dataset = datasetsmodel.fit(train_dataset, nb_epoch=100)metric = dc.metrics.Metric(dc.metrics.roc_auc_score)print('training set score:', model.evaluate(train_dataset, [metric]))print('test set score:', model.evaluate(test_dataset, [metric]))

     对比两个模型的输出结果可以发现,在训练集上ROC的数值均较高(接近于1),但在测试集数据上ROC值都在0.76左右,说明模型存在过拟合。


关注我获得

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多