DeepChem-使用圖卷積神經網路對化學分子建模
阿新 • • 發佈:2020-12-16
技術標籤:圖神經網路藥物設計機器學習tensorflowpython神經網路深度學習
'''
by wufeil
DeepChem-使用圖卷積神經網路對化學分子建模
在深度學習中,圖卷積神經網路特別適合處理化學分子資料,也經常被用於處理分子資料。
這是因為化學分子本身就是一個圖資料。但是如何將分子轉化為圖神經網路可以使用的資料格式呢?
接下來就做簡單的介紹。
首先,標準的卷積網路,最簡單最傳統的就是CNN,convolutional neural network,是處理圖片最常用的神經網路模型。
CNN的輸入是畫素矩陣,每一個畫素都是一個含有三個元素的向量,代表紅黃藍的數值。所以CNN的輸入形狀是;(batch_size, lenght, widht, color(3) )
資料會逐步通過一系列的卷積層。每一層將來自畫素及其相鄰畫素的資料組合在一起,以生成該畫素的新資料向量。
較早的層檢測到小規模的區域性模式,而較後的層則檢測到更大,更抽象的模式。
卷積層通常與執行某些操作(例如在區域性區域上的最大值或最小值)的池化層交替。
圖卷積神經網路也是相似的。
但是圖卷積神經網路是操作在圖上面的。操作的物件是其周圍的節點和邊。
所謂節點就是化學分子中的原子,邊則是源自之間的連線的化學鍵。
所以圖神經網路輸入的是圖中節點的特徵矩陣,在卷積和池化的過程中,不斷的聚合周圍節點和邊的資訊,生成新的節點新的邊特徵。
(如果是圖層面的分類模型,有可能節點和邊的數量都會發生變化)。
關於圖神經網路的知識,有一本書《深入淺出圖神經網路:GNN原理解析》寫的很不錯,有精力的同學可以學習參考。
'''
'''
接下來的關鍵就是如何使用圖神經網路處理為我們的化學分子建模呢?
我們這裡要使用到的資料集是MolNet裡面的Tox21資料集。
之前的部落格有寫道:這些資料集可以很方便的額呼叫,只需要featurizer=‘GraphConv’就可以載入適合圖神經網路的資料集
所以,在這裡如何將化學分子處理成適合圖神經網路的資料集就不做重點介紹,大家可以看我之前的部落格 [《DeepChem的內建資料集及使用方法》](https://editor.csdn.net/md/?articleId=110817827)。
這裡僅介紹圖神經網路的使用方法
'''
'''
匯入資料
'''
import deepchem as dc
tasks, datasets, transformers = dc.molnet.load_tox21(featurizer='GraphConv', splitter='random')
train_set, valid_set, test_set = datasets
'''
使用deepchem內建的圖神經網路模型對資料集進行訓練
(該模型很簡單,並不一定適合真實的資料集!!!真實的資料集需要特殊的資料處理和特殊的模型結構,特殊的損失函式的!!!
這些就是做AI的人在乾的事情)
如果真的要完成某些任務,那就要自己設計模型,編寫自定義的模型,那麼才能有效果。
那麼要在Deepchem中使用自定義模型,但是正如前一篇部落格[《DeepChem-使用自定義Keras\Torch深度學習模型示例》](https://editor.csdn.net/md/?articleId=111171039)所說的,不建議。
最好是直接使用pytorch,tensorflow來寫,來訓練,預測。
因為deepchem的API介面不友好,部分功能還缺失.另外,再執行的時候,有好多的報警,警告,
感覺deepchem呼叫深度學習網路進行訓練的時候不穩定,很有可能崩潰。
更為重要的是,torch, tensorflow現在已經很成熟,很簡單了。python有個一兩年基礎,基本上可以掌握的。
'''
model = dc.models.GraphConvModel(n_tasks=len(tasks), mode='classification')
model.fit(train_set, nb_epoch=50)
'''
評估模型
'''
metric = dc.metrics.Metric(dc.metrics.roc_auc_score)
print('train roc suc score:', model.evaluate(train_set, [metric], transformers))
print('valid roc suc score:', model.evaluate(valid_set, [metric], transformers))
print('test roc suc score:', model.evaluate(test_set, [metric], transformers))
'''
要在Deepchem中使用自定義模型,但是正如前一篇部落格《DeepChem-使用自定義Keras\Torch深度學習模型示例》所說的,不建議。
但是在這裡,還是介紹一些如何使用自定義的圖神經網路模型。
可以結合之前的部落格《DeepChem-使用自定義Keras\Torch深度學習模型示例》
'''
'''
首先來自定義一個圖神經網路模型,使用tensorflow.keras
繼承tf.keras.Model類,定義__init__()和call()函式即可
'''
from deepchem.models.layers import GraphConv, GraphPool, GraphGather
import tensorflow as tf
import tensorflow.keras.layers as layers
batch_size = 100
n_tasks=len(tasks)
class MyGraphConvModel(tf.keras.Model):
def __init__(self):
super(MyGraphConvModel, self).__init__()
self.gc1 = GraphConv(128, activation_fn=tf.nn.tanh)
self.batch_norm1 = layers.BatchNormalization()
self.gp1 = GraphPool()
self.gc2 = GraphConv(128, activation_fn=tf.nn.tanh)
self.batch_norm2 = layers.BatchNormalization()
self.gp2 = GraphPool()
self.dense1 = layers.Dense(256, activation=tf.nn.tanh)
self.batch_norm3 = layers.BatchNormalization()
self.readout = GraphGather(batch_size=batch_size, activation_fn=tf.nn.tanh)
self.dense2 = layers.Dense(n_tasks*2)
self.logits = layers.Reshape((n_tasks, 2))
self.softmax = layers.Softmax()
def call(self, inputs):
gc1_output = self.gc1(inputs)
batch_norm1_output = self.batch_norm1(gc1_output)
gp1_output = self.gp1([batch_norm1_output] + inputs[1:])
gc2_output = self.gc2([gp1_output] + inputs[1:])
batch_norm2_output = self.batch_norm1(gc2_output)
gp2_output = self.gp2([batch_norm2_output] + inputs[1:])
dense1_output = self.dense1(gp2_output)
batch_norm3_output = self.batch_norm3(dense1_output)
readout_output = self.readout([batch_norm3_output] + inputs[1:])
logits_output = self.logits(self.dense2(readout_output))
return self.softmax(logits_output)
'''
接下來就是使用自定義的圖神經網路,例項化一個deepchem的模型。
需要傳遞自定義的圖神經網路和損失函式
'''
model = dc.models.KerasModel(MyGraphConvModel(),loss=dc.models.losses.CategoricalCrossEntropy())
'''
train_set雖然已經使用了featurizer='GraphConv',但是還不能直接作為圖神經網路的輸入。因為圖神經網路的輸入需要的是numpy陣列。
而featurizer='GraphConv'返回的物件是ConvMol,因此還需要將ConvMol轉換為numpy陣列。
(在ConvMol中,並不是直接包含圖神經網路可以使用的鄰接矩陣,度矩陣等,而是:
atom_features (np.ndarray) – Has shape (n_atoms, n_feat),
adj_list (list) – List of length n_atoms, with neighor indices of each atom.
max_deg (int, optional) – Maximum degree of any atom.
min_deg (int, optional) – Minimum degree of any atom.
詳見:https://deepchem.readthedocs.io/en/latest/api_reference/dataclasses.html#graph-convolutions)
詳情請見:文件中關於分子特徵化部分https://deepchem.readthedocs.io/en/latest/api_reference/featurizers.html#
因此,先建立一個數據載入轉換函式data_generator,其輸入是dataset
'''
from deepchem.metrics import to_one_hot
from deepchem.feat.mol_graphs import ConvMol
import numpy as np
import tensorflow as tf
def data_generator(dataset, epochs=1):
for ind, (X_b, y_b, w_b, ids_b) in enumerate(dataset.iterbatches(batch_size, epochs,
deterministic=False, pad_batches=True)):
multiConvMol = ConvMol.agglomerate_mols(X_b)
inputs = [multiConvMol.get_atom_features(), multiConvMol.deg_slice, np.array(multiConvMol.membership)]
for i in range(1, len(multiConvMol.get_deg_adjacency_lists())):
inputs.append(multiConvMol.get_deg_adjacency_lists()[i])
labels = [to_one_hot(y_b.flatten(), 2).reshape(-1, n_tasks, 2)]
weights = [w_b]
yield (inputs, labels, weights)
'''
使用data_generator轉換資料以後直接輸入到model
然後評估驗證集和測試集
注意這裡使用的是model.fit_generator(), 而不是model.fit()
'''
model.fit_generator(data_generator(train_set, epochs=50))
print('Training set score:', model.evaluate_generator(data_generator(train_set), [metric], transformers))
print('Test set score:', model.evaluate_generator(data_generator(test_set), [metric], transformers))
'''
最後總結一下:
1.deepchem裡面有簡單的圖神經網路模型,dc.models.GraphConvModel(),其輸入的是:ConvMol資料型別,因此能與deepchem內建的資料集
和featurizer='GraphConv'無縫對接;
2.deepchem也支援自定義的圖神經網路,僅需要繼承tf.keras.Model/tf.torch.Model,定義__init__()和call()函式。
但是自定義的圖神經網路需要的是numpy的資料型別,因此需要定義一個data_generator,將ConvMol資料型別改變成numpy資料型別,
返回一個數據generator,因此要使用model.fit_generator()
顯然,如果要真的使用這個圖神經網路,那麼真的需要有一些圖神經網路的知識,知道什麼是度,邊,鄰接矩陣等基礎概念。
當然也要知道DeepChem中關於圖神經網路的生成方法。
'''