'''
by wufeil
Tutorial Part 5: Creating Models with TensorFlow and PyTorch
DeepChem支持大量的机器学习模型,包括:scikit-learn, xgboost, TensorFlow, and PyTorch
详情可以看下表:
'''
'''
除了标准化的模型,DeepChem也支持自定义模型。
DeepChem提供与TensorFlow(Keras)和PyTorch的集成
实际上,在DeepChem中使用TensorFlow或PyTorch模型可以采用两种不同的方法。
这取决于您是否要使用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不能便捷。
所以,如果是自定义深度模型最好是直接使用tensorflow或者Pytorch, 使用DeepChem作为数据处理,转换。
即使是deepchem内置的深度学习模型,也不建议使用,因为模型内部不具备调优的可能性,全部封闭。
虽然提供了许多API接口,但是还要重新学习,熟悉,得不偿失。那还不如直接使用torch或者tensorflow。
[链接]
所以这里仅做一个简单的介绍。
'''
'''
一、KerasModel
KerasModel是DeepChem的Model类的子类。
它充当tensorflow.keras.Model的包装器。
让我们看一个使用它的例子。
对于此示例,我们创建了一个由两个密集层组成的简单顺序模型。
'''
import deepchem as dc
import tensorflow as tf
'''
自定义一个keras模型
'''
keras_model = tf.keras.Sequential([
tf.keras.layers.Dense(1000, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(10, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(1)
])
'''
deepchem调用自定义的keras模型
dc.models.KerasModel(自定义模型, 损失函数)
'''
model = dc.models.KerasModel(keras_model, dc.models.losses.L2Loss())
'''
加载数据
'''
tasks, datasets, transformers = dc.molnet.load_toxcast(featurizer='ECFP', splitter='random')
train_dataset, valid_dataset, test_dataset = datasets
'''
训练模型
'''
model.fit(train_dataset)
metric = dc.metrics.Metric(dc.metrics.pearson_r2_score)
print('valid dataset R2 :', model.evaluate(valid_dataset, [metric]))
print('test dataset R2:', model.evaluate(test_dataset, [metric]))
'''
二、TorchModel
使用dc.models.TorchModel()
'''
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()) #可能会报错: module 'deepchem.models' has no attribute 'TorchModel'
#
# 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]))
'''
三、计算损失
在上述模型中,损失是直接从模型的输出中计算得出的。
通常这很好,但并非总是如此。 考虑一个输出概率分布的分类模型。
尽管可以从概率中计算损失,但从对数中计算损失在数值上更稳定。
为此,我们创建一个返回多个输出(概率和对数)的模型。
KerasModel和TorchModel可让您指定“输出类型”列表。
如果特定输出的类型为“ prediction”,则表示它是正常输出,应在调用predict()时返回。
如果类型为“loss”,则意味着应将其传递给损失函数以代替正常输出。
'''
class ClassificationModel(tf.keras.Model):
def __init__(self):
super(ClassificationModel, self).__init__()
self.dense1 = tf.keras.layers.Dense(1000, activation='relu')
self.dense2 = tf.keras.layers.Dense(1)
def call(self, inputs, training=False):
y = self.dense1(inputs)
if training:
y = tf.nn.dropout(y, 0.5)
logits = self.dense2(y)
output = tf.nn.sigmoid(logits)
return output, logits
keras_model = ClassificationModel()
output_types = ['prediction', 'loss']
model = dc.models.KerasModel(keras_model, dc.models.losses.SigmoidCrossEntropy(), output_types=output_types)
tasks, datasets, transformers = dc.molnet.load_bace_classification(feturizer='ECFP', split='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]))