Commit d87fea82 authored by VoVAllen's avatar VoVAllen
Browse files

add gcn toy case

parent 52203051
{
"cells": [
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Populating the interactive namespace from numpy and matplotlib\n"
]
}
],
"source": [
"%pylab inline\n",
"import networkx as nx\n",
"import scipy as sp\n",
"import scipy"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"edges=np.loadtxt(\"edges.txt\",dtype=np.int32)\n",
"nodes=np.loadtxt(\"nodes.txt\",dtype=np.int32)\n",
"G=nx.Graph()\n",
"\n",
"for i in range(4):\n",
" G.add_nodes_from(nodes[nodes[:,1]==i][:,0],labels=i)\n",
"G.add_edges_from(edges)"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"values= [node[1]['labels'] for node in G.nodes(data=True)]\n",
"\n",
"nx.draw_spring(G, cmap=plt.get_cmap('Set2'), node_color=values)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"def normalized_A(G):\n",
" A = nx.to_scipy_sparse_matrix(G,format='csr')\n",
" I=scipy.sparse.eye(A.shape[0])\n",
" n,m = A.shape\n",
" diags = A.sum(axis=1).flatten()\n",
" D = scipy.sparse.spdiags(diags, [0], m, n, format='csr')\n",
" AH=A+I\n",
" with scipy.errstate(divide='ignore'):\n",
" diags_sqrt = 1.0/scipy.sqrt(diags)\n",
" diags_sqrt[scipy.isinf(diags_sqrt)] = 0\n",
" DH = scipy.sparse.spdiags(diags_sqrt, [0], m, n, format='csr')\n",
" normalized_A=DH.dot(AH.dot(DH))\n",
" return normalized_A"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [],
"source": [
"def ReLU(x):\n",
" return np.maximum(x, 0)\n",
"\n",
"num_input_features=34\n",
"num_output_features=2\n",
"\n",
"hidden_dim=[num_input_features,34,24,num_output_features]\n",
"num_layers=len(hidden_dim)-1\n",
"\n",
"num_nodes=G.number_of_nodes()\n",
"H=[np.random.randn(num_nodes,num_input_features) for i in range(num_layers+1)]\n",
"W=[np.random.randn(hidden_dim[i],hidden_dim[i+1])*3 for i in range(num_layers)]\n"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [],
"source": [
"NA=normalized_A(G)\n",
"H[0]=np.eye(num_input_features)\n",
"for i in range(num_layers):\n",
" H[i+1]=ReLU(NA@H[i]@W[i])"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([330.65527807, 328.33212954, 327.29190903, 334.35929148,\n",
" 254.98186216, 848.1842729 , 367.62767144, 680.85927011,\n",
" 336.21841481, 324.98512806, 257.44082247, 345.22589289,\n",
" 389.92371201, 251.94775242, 262.56207955, 300.10323616,\n",
" 304.4027439 , 169.89019483, 181.95920536, 205.9823762 ,\n",
" 257.33860518, 253.01664177, 216.53126085, 195.03677365,\n",
" 391.22075663, 346.15820503, 196.40311898, 222.7800006 ,\n",
" 180.89261242, 189.85892877, 177.72642253, 212.64308276,\n",
" 185.25827475, 155.83209081])"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"H[3][:,0]"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.collections.PathCollection at 0x7f71f55464a8>"
]
},
"execution_count": 42,
"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": [
"plt.scatter(H[3][:,1],H[3][:,0],c=values,cmap='Set2')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.6",
"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.6.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
# Embedding-the-karate-club-network-
Embedding the karate club network
{
"cells": [
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Populating the interactive namespace from numpy and matplotlib\n"
]
}
],
"source": [
"%pylab inline\n",
"import networkx as nx\n",
"import torch\n",
"\n",
"import torch.nn.functional as F\n",
"import torch_geometric.transforms as T\n",
"from torch_geometric.data import Data\n",
"from torch_geometric.nn import GCNConv"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [],
"source": [
"edges=np.loadtxt(\"edges.txt\",dtype=np.int32)\n",
"nodes=np.loadtxt(\"nodes.txt\",dtype=np.int32)\n",
"G=nx.Graph()\n",
"\n",
"for i in range(4):\n",
" G.add_nodes_from(nodes[nodes[:,1]==i][:,0],labels=i)\n",
"G.add_edges_from(edges)"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [],
"source": [
"nodes=G.nodes(data=True)\n",
"values=[]\n",
"for i in range(1,G.number_of_nodes()+1):\n",
" values.append(nodes[i]['labels'])\n",
"edge_index=torch.from_numpy(np.array(G.edges()))\n",
"y=torch.from_numpy(np.array(values))\n",
"x=torch.eye(G.number_of_nodes())"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [],
"source": [
"data = Data(x=x, edge_index=edge_index,y=y)"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Data(edge_index=[77, 2], x=[34, 34], y=[34])"
]
},
"execution_count": 56,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"tensor([0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,\n",
" 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=torch.uint8)"
]
},
"execution_count": 57,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.y==0"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [],
"source": [
"class Net(torch.nn.Module):\n",
" def __init__(self):\n",
" super(Net, self).__init__()\n",
" self.module=torch.nn.Sequential(\n",
" GCNConv(data.num_features, 16),\n",
" torch.nn.ReLU(),\n",
" GCNConv(16, data.num_classes),\n",
" torch.nn.LogSoftmax(dim=1)\n",
" )\n",
" def forward(self, data):\n",
" return self.module((data.x, data.edge_index)\n"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [],
"source": [
"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"ename": "RuntimeError",
"evalue": "cuda runtime error (59) : device-side assert triggered at /pytorch/aten/src/THC/generic/THCTensorCopy.cpp:20",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-42-b966576db2b6>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdata\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m~/.pyenv/versions/3.6.1/lib/python3.6/site-packages/torch_geometric/data/data.py\u001b[0m in \u001b[0;36mto\u001b[0;34m(self, device, *keys)\u001b[0m\n\u001b[1;32m 102\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 103\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdevice\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 104\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 105\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 106\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__repr__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/.pyenv/versions/3.6.1/lib/python3.6/site-packages/torch_geometric/data/data.py\u001b[0m in \u001b[0;36mapply\u001b[0;34m(self, func, *keys)\u001b[0m\n\u001b[1;32m 95\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 96\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mitem\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 97\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 98\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 99\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/.pyenv/versions/3.6.1/lib/python3.6/site-packages/torch_geometric/data/data.py\u001b[0m in \u001b[0;36m<lambda>\u001b[0;34m(x)\u001b[0m\n\u001b[1;32m 102\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 103\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdevice\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 104\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 105\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 106\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__repr__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mRuntimeError\u001b[0m: cuda runtime error (59) : device-side assert triggered at /pytorch/aten/src/THC/generic/THCTensorCopy.cpp:20"
]
}
],
"source": [
"data.to(device)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"ename": "RuntimeError",
"evalue": "cuda runtime error (59) : device-side assert triggered at /pytorch/aten/src/THC/generic/THCTensorCopy.cpp:20",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-22-57c0fbac8614>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mdevice\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'cuda'\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcuda\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_available\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;34m'cpu'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mmodel\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mNet\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m~/.pyenv/versions/3.6.1/lib/python3.6/site-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36mto\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 377\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_floating_point\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnon_blocking\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 378\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 379\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_apply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mconvert\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 380\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 381\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mregister_backward_hook\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhook\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/.pyenv/versions/3.6.1/lib/python3.6/site-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_apply\u001b[0;34m(self, fn)\u001b[0m\n\u001b[1;32m 183\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_apply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 184\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mmodule\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mchildren\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 185\u001b[0;31m \u001b[0mmodule\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_apply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 186\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 187\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mparam\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_parameters\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/.pyenv/versions/3.6.1/lib/python3.6/site-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_apply\u001b[0;34m(self, fn)\u001b[0m\n\u001b[1;32m 189\u001b[0m \u001b[0;31m# Tensors stored in modules are graph leaves, and we don't\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 190\u001b[0m \u001b[0;31m# want to create copy nodes, so we have to unpack the data.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 191\u001b[0;31m \u001b[0mparam\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparam\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 192\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mparam\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_grad\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 193\u001b[0m \u001b[0mparam\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_grad\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparam\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_grad\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/.pyenv/versions/3.6.1/lib/python3.6/site-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36mconvert\u001b[0;34m(t)\u001b[0m\n\u001b[1;32m 375\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 376\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mconvert\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mt\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 377\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_floating_point\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnon_blocking\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 378\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 379\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_apply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mconvert\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mRuntimeError\u001b[0m: cuda runtime error (59) : device-side assert triggered at /pytorch/aten/src/THC/generic/THCTensorCopy.cpp:20"
]
}
],
"source": [
"model, data = Net().to(device), data.to(device)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"tensor([1, 1, 2, 1, 0, 0, 0, 1, 3, 2, 0, 1, 1, 1, 3, 3, 0, 1, 3, 1, 3, 1, 3, 3,\n",
" 2, 2, 3, 2, 2, 3, 3, 2, 3, 3])"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"ename": "RuntimeError",
"evalue": "Expected object of type torch.FloatTensor but found type torch.cuda.FloatTensor for argument #2 'mat2'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-16-ac68ecf76d96>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0moutput\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m~/.pyenv/versions/3.6.1/lib/python3.6/site-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, *input, **kwargs)\u001b[0m\n\u001b[1;32m 475\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_slow_forward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 476\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 477\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mforward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 478\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mhook\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_forward_hooks\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 479\u001b[0m \u001b[0mhook_result\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mhook\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m<ipython-input-6-6046f23108a0>\u001b[0m in \u001b[0;36mforward\u001b[0;34m(self, data)\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mforward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mF\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrelu\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconv1\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0medge_index\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 9\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconv2\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0medge_index\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mF\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlog_softmax\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdim\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/.pyenv/versions/3.6.1/lib/python3.6/site-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, *input, **kwargs)\u001b[0m\n\u001b[1;32m 475\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_slow_forward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 476\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 477\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mforward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 478\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mhook\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_forward_hooks\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 479\u001b[0m \u001b[0mhook_result\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mhook\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/.pyenv/versions/3.6.1/lib/python3.6/site-packages/torch_geometric/nn/conv/gcn_conv.py\u001b[0m in \u001b[0;36mforward\u001b[0;34m(self, x, edge_index, edge_attr)\u001b[0m\n\u001b[1;32m 41\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 42\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mforward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0medge_index\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0medge_attr\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 43\u001b[0;31m \u001b[0mout\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mweight\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 44\u001b[0m \u001b[0mout\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mout\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0medge_index\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0medge_attr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 45\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mRuntimeError\u001b[0m: Expected object of type torch.FloatTensor but found type torch.cuda.FloatTensor for argument #2 'mat2'"
]
}
],
"source": [
"output=model(data)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for epoch in range(1, 101):\n",
" output=model(data)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.6",
"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.6.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
2692
2532
2050
1715
2362
2609
2622
1975
2081
1767
2263
1725
2588
2259
2357
1998
2574
2179
2291
2382
1812
1751
2422
1937
2631
2510
2378
2589
2345
1943
1850
2298
1825
2035
2507
2313
1906
1797
2023
2159
2495
1886
2122
2369
2461
1925
2565
1858
2234
2000
1846
2318
1723
2559
2258
1763
1991
1922
2003
2662
2250
2064
2529
1888
2499
2454
2320
2287
2203
2018
2002
2632
2554
2314
2537
1760
2088
2086
2218
2605
1953
2403
1920
2015
2335
2535
1837
2009
1905
2636
1942
2193
2576
2373
1873
2463
2509
1954
2656
2455
2494
2295
2114
2561
2176
2275
2635
2442
2704
2127
2085
2214
2487
1739
2543
1783
2485
2262
2472
2326
1738
2170
2100
2384
2152
2647
2693
2376
1775
1726
2476
2195
1773
1793
2194
2581
1854
2524
1945
1781
1987
2599
1744
2225
2300
1928
2042
2202
1958
1816
1916
2679
2190
1733
2034
2643
2177
1883
1917
1996
2491
2268
2231
2471
1919
1909
2012
2522
1865
2466
2469
2087
2584
2563
1924
2143
1736
1966
2533
2490
2630
1973
2568
1978
2664
2633
2312
2178
1754
2307
2480
1960
1742
1962
2160
2070
2553
2433
1768
2659
2379
2271
1776
2153
1877
2027
2028
2155
2196
2483
2026
2158
2407
1821
2131
2676
2277
2489
2424
1963
1808
1859
2597
2548
2368
1817
2405
2413
2603
2350
2118
2329
1969
2577
2475
2467
2425
1769
2092
2044
2586
2608
1983
2109
2649
1964
2144
1902
2411
2508
2360
1721
2005
2014
2308
2646
1949
1830
2212
2596
1832
1735
1866
2695
1941
2546
2498
2686
2665
1784
2613
1970
2021
2211
2516
2185
2479
2699
2150
1990
2063
2075
1979
2094
1787
2571
2690
1926
2341
2566
1957
1709
1955
2570
2387
1811
2025
2447
2696
2052
2366
1857
2273
2245
2672
2133
2421
1929
2125
2319
2641
2167
2418
1765
1761
1828
2188
1972
1997
2419
2289
2296
2587
2051
2440
2053
2191
1923
2164
1861
2339
2333
2523
2670
2121
1921
1724
2253
2374
1940
2545
2301
2244
2156
1849
2551
2011
2279
2572
1757
2400
2569
2072
2526
2173
2069
2036
1819
1734
1880
2137
2408
2226
2604
1771
2698
2187
2060
1756
2201
2066
2439
1844
1772
2383
2398
1708
1992
1959
1794
2426
2702
2444
1944
1829
2660
2497
2607
2343
1730
2624
1790
1935
1967
2401
2255
2355
2348
1931
2183
2161
2701
1948
2501
2192
2404
2209
2331
1810
2363
2334
1887
2393
2557
1719
1732
1986
2037
2056
1867
2126
1932
2117
1807
1801
1743
2041
1843
2388
2221
1833
2677
1778
2661
2306
2394
2106
2430
2371
2606
2353
2269
2317
2645
2372
2550
2043
1968
2165
2310
1985
2446
1982
2377
2207
1818
1913
1766
1722
1894
2020
1881
2621
2409
2261
2458
2096
1712
2594
2293
2048
2359
1839
2392
2254
1911
2101
2367
1889
1753
2555
2246
2264
2010
2336
2651
2017
2140
1842
2019
1890
2525
2134
2492
2652
2040
2145
2575
2166
1999
2434
1711
2276
2450
2389
2669
2595
1814
2039
2502
1896
2168
2344
2637
2031
1977
2380
1936
2047
2460
2102
1745
2650
2046
2514
1980
2352
2113
1713
2058
2558
1718
1864
1876
2338
1879
1891
2186
2451
2181
2638
2644
2103
2591
2266
2468
1869
2582
2674
2361
2462
1748
2215
2615
2236
2248
2493
2342
2449
2274
1824
1852
1870
2441
2356
1835
2694
2602
2685
1893
2544
2536
1994
1853
1838
1786
1930
2539
1892
2265
2618
2486
2583
2061
1796
1806
2084
1933
2095
2136
2078
1884
2438
2286
2138
1750
2184
1799
2278
2410
2642
2435
1956
2399
1774
2129
1898
1823
1938
2299
1862
2420
2673
1984
2204
1717
2074
2213
2436
2297
2592
2667
2703
2511
1779
1782
2625
2365
2315
2381
1788
1714
2302
1927
2325
2506
2169
2328
2629
2128
2655
2282
2073
2395
2247
2521
2260
1868
1988
2324
2705
2541
1731
2681
2707
2465
1785
2149
2045
2505
2611
2217
2180
1904
2453
2484
1871
2309
2349
2482
2004
1965
2406
2162
1805
2654
2007
1947
1981
2112
2141
1720
1758
2080
2330
2030
2432
2089
2547
1820
1815
2675
1840
2658
2370
2251
1908
2029
2068
2513
2549
2267
2580
2327
2351
2111
2022
2321
2614
2252
2104
1822
2552
2243
1798
2396
2663
2564
2148
2562
2684
2001
2151
2706
2240
2474
2303
2634
2680
2055
2090
2503
2347
2402
2238
1950
2054
2016
1872
2233
1710
2032
2540
2628
1795
2616
1903
2531
2567
1946
1897
2222
2227
2627
1856
2464
2241
2481
2130
2311
2083
2223
2284
2235
2097
1752
2515
2527
2385
2189
2283
2182
2079
2375
2174
2437
1993
2517
2443
2224
2648
2171
2290
2542
2038
1855
1831
1759
1848
2445
1827
2429
2205
2598
2657
1728
2065
1918
2427
2573
2620
2292
1777
2008
1875
2288
2256
2033
2470
2585
2610
2082
2230
1915
1847
2337
2512
2386
2006
2653
2346
1951
2110
2639
2520
1939
2683
2139
2220
1910
2237
1900
1836
2197
1716
1860
2077
2519
2538
2323
1914
1971
1845
2132
1802
1907
2640
2496
2281
2198
2416
2285
1755
2431
2071
2249
2123
1727
2459
2304
2199
1791
1809
1780
2210
2417
1874
1878
2116
1961
1863
2579
2477
2228
2332
2578
2457
2024
1934
2316
1841
1764
1737
2322
2239
2294
1729
2488
1974
2473
2098
2612
1834
2340
2423
2175
2280
2617
2208
2560
1741
2600
2059
1747
2242
2700
2232
2057
2147
2682
1792
1826
2120
1895
2364
2163
1851
2391
2414
2452
1803
1989
2623
2200
2528
2415
1804
2146
2619
2687
1762
2172
2270
2678
2593
2448
1882
2257
2500
1899
2478
2412
2107
1746
2428
2115
1800
1901
2397
2530
1912
2108
2206
2091
1740
2219
1976
2099
2142
2671
2668
2216
2272
2229
2666
2456
2534
2697
2688
2062
2691
2689
2154
2590
2626
2390
1813
2067
1952
2518
2358
1789
2076
2049
2119
2013
2124
2556
2105
2093
1885
2305
2354
2135
2601
1770
1995
2504
1749
2157
1 32
1 22
1 20
1 18
1 14
1 13
1 12
1 11
1 9
1 8
1 7
1 6
1 5
1 4
1 3
1 2
2 31
2 22
2 20
2 18
2 14
2 8
2 4
2 3
3 14
3 9
3 10
3 33
3 29
3 28
3 8
3 4
4 14
4 13
4 8
5 11
5 7
6 17
6 11
6 7
7 17
9 34
9 33
9 33
10 34
14 34
15 34
15 33
16 34
16 33
19 34
19 33
20 34
21 34
21 33
23 34
23 33
24 30
24 34
24 33
24 28
24 26
25 32
25 28
25 26
26 32
27 34
27 30
28 34
29 34
29 32
30 34
30 33
31 34
31 33
32 34
32 33
33 34
7 0
5 0
11 0
6 0
17 0
12 1
13 1
1 1
18 1
22 1
8 1
4 1
2 1
20 1
14 1
3 2
32 2
10 2
29 2
28 2
26 2
25 2
9 3
31 3
34 3
33 3
21 3
24 3
15 3
16 3
23 3
19 3
30 3
27 3
import numpy as np
from matplotlib import pyplot as plt
import networkx as nx
import torch
import torch.nn.functional as F
import torch_geometric.transforms as T
from torch_geometric.data import Data
from torch_geometric.nn import GCNConv
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
edges = np.loadtxt("../edges.txt", dtype=np.int32)
nodes = np.loadtxt("../nodes.txt", dtype=np.int32)
G = nx.Graph()
for i in range(4):
G.add_nodes_from(nodes[nodes[:, 1] == i][:, 0], labels=i)
G.add_edges_from(edges)
nodes = G.nodes(data=True)
values = []
for i in range(1, G.number_of_nodes() + 1):
values.append(nodes[i]['labels'])
edge_index = torch.from_numpy(np.array(G.edges())).long().t()
y = torch.from_numpy(np.array(values))
# x = torch.eye(G.number_of_nodes()).float()
x = torch.zeros((34, 2)).float()
train_mask = torch.zeros(G.number_of_nodes())
train_mask.data[0] = 1
train_mask.data[2] = 1
train_mask.data[8] = 1
train_mask.data[4] = 1
val_mask = 1 - train_mask
data = Data(x=x, edge_index=edge_index - 1, y=y)
data.train_mask = train_mask.to(torch.uint8).to(device)
data.val_mask = val_mask.to(torch.uint8).to(device)
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = GCNConv(data.num_features, 16)
self.conv2 = GCNConv(16, data.num_classes)
def forward(self, data):
x = F.relu(self.conv1(data.x, data.edge_index))
x = self.conv2(x, data.edge_index)
return F.log_softmax(x, dim=1)
model, data = Net().to(device), data.to(device).contiguous()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)
EPOCH = 10
for i in range(EPOCH):
output = model(data)
optimizer.zero_grad()
loss = F.nll_loss(output[data.train_mask], data.y[data.train_mask])
loss.backward()
optimizer.step()
# Validation
logits = model()
mask = data.val_mask
pred = logits[mask].max(1)[1]
acc = pred.eq(data.y[mask]).sum().item() / mask.sum().item()
print(f"Validation Accuracy: {acc}")
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment