DeepChem内置了很多标准模型供我们使用,但是,如果我们想自定义一个全新的模型,它也提供了与TensorFlow(Keras)和PyTorch的集成,因此我们可以将其与这两个框架中的模型一起使用。 表1 Deepchem内置的标准模型 我们可以使用两种不同的方法将TensorFlow或PyTorch模型与DeepChem一起使用。这取决于您是要在训练和评估模型时使用TensorFlow/PyTorch API还是DeepChem API。当训练模型时,DeepChem的Dataset类包含轻松适应其他框架的方法。make_tf_dataset()会返回一个tensorflow.data.Dataset对象,它可以遍历所有数据。make_pytorch_dataset()返回一个torch.utils.data.IterableDataset,它可以遍历数据。这样,就可以使用DeepChem的数据集、加载器、特征提取器、转换器、分割器等,并将它们轻松集成到您现有的TensorFlow或PyTorch代码中。 DeepChem还提供了许多其他有用的功能。我们可以将模型封装在一个DeepChem的模型对象中,下面我们将用实例代码讲解如何进行封装:
1. Keras Model KerasModel是DeepChem的Model类的子类。它作为tensorflow.keras.Model的封装器。让我们看一个使用示例。对于这个示例,我们创建一个由两个全连接层组成简单的序列模型。 import deepchem as dc import 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())
在这个示例中,我们使用了Keras的Sequential类。我们的模型包含一个具有ReLU激活函数的全连接层,50%的dropout用于提供正则化,并且最后一层生成一个标量输出。我们还需要指定训练模型时要使用的损失函数,这里我们使用L2损失。现在我们可以像使用任何其他DeepChem模型一样训练和评估这个模型。例如,让我们加载Delaney溶解度数据集(DeepChem预测小分子溶解度)。根据分子的扩展连接指纹(ECFPs),我们测试一下模型在预测分子的溶解度方面表现如何。 import deepchem as dc import 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。KerasModel和TorchModel允许我们指定一个"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 = datasets model.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 = datasets model.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 = datasets model.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左右,说明模型存在过拟合。
|