Skip to content

Instantly share code, notes, and snippets.

@iwatobipen
Last active February 18, 2020 07:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iwatobipen/6b05b849dce18a187308987799402da3 to your computer and use it in GitHub Desktop.
Save iwatobipen/6b05b849dce18a187308987799402da3 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"RDKit WARNING: [16:00:50] Enabling RDKit 2019.09.3 jupyter extensions\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"use GPU\n"
]
}
],
"source": [
"import os\n",
"from rdkit import Chem\n",
"from rdkit import RDPaths\n",
"import numpy as np\n",
"\n",
"import torch\n",
"import dgl\n",
"if torch.cuda.is_available():\n",
" print('use GPU')\n",
" device='cuda'\n",
"else:\n",
" print('use CPU')\n",
" device='cpu'\n",
"\n",
"from dgl.model_zoo.chem import GCNClassifier\n",
"from dgl.data.chem.utils import mol_to_graph\n",
"from dgl.data.chem.utils import mol_to_complete_graph\n",
"from dgl.data.chem import CanonicalAtomFeaturizer\n",
"from dgl.data.chem import CanonicalBondFeaturizer\n",
"from torch import nn\n",
"\n",
"import torch.nn.functional as F\n",
"from torch.utils.data import DataLoader\n",
"from torch.utils.data import Dataset\n",
"from torch.nn import CrossEntropyLoss"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"trainsdf = os.path.join(RDPaths.RDDocsDir, 'Book/data/solubility.train.sdf')\n",
"testsdf = os.path.join(RDPaths.RDDocsDir, 'Book/data/solubility.test.sdf')\n",
"\n",
"trainmols = [m for m in Chem.SDMolSupplier(trainsdf)]\n",
"testmols = [m for m in Chem.SDMolSupplier(testsdf)]\n",
"\n",
"prop_dict = {\n",
" \"(A) low\": 0,\n",
" \"(B) medium\": 1,\n",
" \"(C) high\": 2\n",
"}\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"atom_featurizer = CanonicalAtomFeaturizer()\n",
"bond_featurizer = CanonicalBondFeaturizer()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"g = mol_to_complete_graph(trainmols[0], \n",
" add_self_loop=False, \n",
" node_featurizer=atom_featurizer,\n",
" #edge_featurizer= bond_featurizer\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"74\n"
]
}
],
"source": [
"# check feature size\n",
"n_feats = atom_featurizer.feat_size('h')\n",
"print(n_feats)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"ncls = 3\n",
"\n",
"\n",
"train_g = [mol_to_complete_graph(m, node_featurizer=atom_featurizer) for m in trainmols]\n",
"train_y = np.array([prop_dict[m.GetProp('SOL_classification')] for m in trainmols])\n",
"train_y = np.array(train_y, dtype=np.int64)\n",
"\n",
"test_g = [mol_to_complete_graph(m, node_featurizer=atom_featurizer) for m in testmols]\n",
"test_y = np.array([prop_dict[m.GetProp('SOL_classification')] for m in testmols])\n",
"test_y = np.array(test_y, dtype=np.int64)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# define GCN NET with 2 GCN layers\n",
"gcn_net = GCNClassifier(in_feats=n_feats,\n",
" gcn_hidden_feats=[60,20],\n",
" n_tasks=ncls,\n",
" classifier_hidden_feats=10,\n",
" dropout=0.5,)\n",
"gcn_net = gcn_net.to(device)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"def collate(sample):\n",
" graphs, labels = map(list,zip(*sample))\n",
" batched_graph = dgl.batch(graphs)\n",
" batched_graph.set_n_initializer(dgl.init.zero_initializer)\n",
" batched_graph.set_e_initializer(dgl.init.zero_initializer)\n",
" return batched_graph, torch.tensor(labels)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"train_data = list(zip(train_g, train_y))\n",
"train_loader = DataLoader(train_data, batch_size=128, shuffle=True, collate_fn=collate, drop_last=True)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"GCNClassifier(\n",
" (gnn_layers): ModuleList(\n",
" (0): GCNLayer(\n",
" (graph_conv): GraphConv(in=74, out=60, normalization=False, activation=<function relu at 0x7efbaf93f1e0>)\n",
" (dropout): Dropout(p=0.0, inplace=False)\n",
" (res_connection): Linear(in_features=74, out_features=60, bias=True)\n",
" (bn_layer): BatchNorm1d(60, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
" )\n",
" (1): GCNLayer(\n",
" (graph_conv): GraphConv(in=60, out=20, normalization=False, activation=<function relu at 0x7efbaf93f1e0>)\n",
" (dropout): Dropout(p=0.0, inplace=False)\n",
" (res_connection): Linear(in_features=60, out_features=20, bias=True)\n",
" (bn_layer): BatchNorm1d(20, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
" )\n",
" )\n",
" (weighted_sum_readout): WeightAndSum(\n",
" (atom_weighting): Sequential(\n",
" (0): Linear(in_features=20, out_features=1, bias=True)\n",
" (1): Sigmoid()\n",
" )\n",
" )\n",
" (soft_classifier): MLPBinaryClassifier(\n",
" (predict): Sequential(\n",
" (0): Dropout(p=0.5, inplace=False)\n",
" (1): Linear(in_features=40, out_features=10, bias=True)\n",
" (2): ReLU()\n",
" (3): BatchNorm1d(10, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
" (4): Linear(in_features=10, out_features=3, bias=True)\n",
" )\n",
" )\n",
")"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"loss_fn = CrossEntropyLoss()\n",
"optimizer = torch.optim.Adam(gcn_net.parameters(), lr=0.01)\n",
"gcn_net.train()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"epoch: 20, LOSS: 0.384, ACC: 0.834\n",
"epoch: 40, LOSS: 0.327, ACC: 0.842\n",
"epoch: 60, LOSS: 0.290, ACC: 0.874\n",
"epoch: 80, LOSS: 0.257, ACC: 0.893\n",
"epoch: 100, LOSS: 0.244, ACC: 0.896\n",
"epoch: 120, LOSS: 0.249, ACC: 0.899\n",
"epoch: 140, LOSS: 0.222, ACC: 0.903\n",
"epoch: 160, LOSS: 0.186, ACC: 0.928\n",
"epoch: 180, LOSS: 0.158, ACC: 0.941\n",
"epoch: 200, LOSS: 0.178, ACC: 0.928\n"
]
}
],
"source": [
"epoch_losses = []\n",
"epoch_accuracies = []\n",
"for epoch in range(1,201):\n",
" epoch_loss = 0\n",
" epoch_acc = 0\n",
" for i, (bg, labels) in enumerate(train_loader):\n",
" labels = labels.to(device)\n",
" atom_feats = bg.ndata.pop('h').to(device)\n",
" atom_feats, labels = atom_feats.to(device), labels.to(device)\n",
" pred = gcn_net(bg, atom_feats)\n",
" loss = loss_fn(pred, labels)\n",
" optimizer.zero_grad()\n",
" loss.backward()\n",
" optimizer.step()\n",
" epoch_loss += loss.detach().item()\n",
" pred_cls = pred.argmax(-1).detach().to('cpu').numpy()\n",
" true_label = labels.to('cpu').numpy()\n",
" epoch_acc += sum(true_label==pred_cls) / true_label.shape[0]\n",
" epoch_acc /= (i + 1)\n",
" epoch_loss /= (i + 1)\n",
" if epoch % 20 == 0:\n",
" print(f\"epoch: {epoch}, LOSS: {epoch_loss:.3f}, ACC: {epoch_acc:.3f}\")\n",
" epoch_accuracies.append(epoch_acc)\n",
" epoch_losses.append(epoch_loss)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Text(0, 0.5, 'loss/acc')"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"import matplotlib.pyplot as plt\n",
"plt.style.use('ggplot')\n",
"plt.plot([i for i in range(1, 201)], epoch_losses, c='b', alpha=0.6, label='loss')\n",
"plt.legend()\n",
"plt.plot([i for i in range(1, 201)], epoch_accuracies, c='r', alpha=0.6, label='acc')\n",
"plt.legend()\n",
"plt.xlabel('epoch')\n",
"plt.ylabel('loss/acc')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment