13from typing import Dict
14
15import numpy as np
16import torch
17from torch import nn
18
19from labml import lab, monit, tracker, experiment
20from labml.configs import BaseConfigs, option, calculate
21from labml.utils import download
22from labml_helpers.device import DeviceConfigs
23from labml_helpers.module import Module
24from labml_nn.graphs.gat import GraphAttentionLayer
25from labml_nn.optimizers.configs import OptimizerConfigs
කෝරා දත්ත කට්ටලය පර්යේෂණ පත්රිකා දත්ත කට්ටලයකි. සෑම කඩදාසි සඳහාම අපට ද්විමය අංග දෛශිකයක් ලබා දී ඇති අතර එය වචන ඇති බව පෙන්නුම් කරයි. සෑම කඩදාසියක්ම පන්ති 7 න් එකකට වර්ගීකරණය කර ඇත. දත්ත කට්ටලයට උපුටා දැක්වීමේ ජාලය ද ඇත.
පත්රිකා යනු ප්රස්ථාරයේ නෝඩ් වන අතර දාර උපුටා දැක්වීම් වේ.
කර්තව්යය වන්නේ නෝඩ් 7 පන්ති වලට විශේෂාංග දෛශික සහ උපුටා දැක්වීමේ ජාලය ආදානය ලෙස වර්ගීකරණය කිරීමයි.
28class CoraDataset:
එක්එක් නෝඩය සඳහා ලේබල
43 labels: torch.Tensor
පන්තිනාම කට්ටලයක් සහ අද්විතීය පූර්ණ සංඛ්යා දර්ශකය
45 classes: Dict[str, int]
සියලුමනෝඩ් සඳහා විශේෂාංග වාහකයන්
47 features: torch.Tensor
දාරයේතොරතුරු සමඟ සම්බන්ධ වීමේ අනුකෘතිය. adj_mat[i][j]
සිට දාරයක් තිබේ True
i
නම් j
.
50 adj_mat: torch.Tensor
දත්තකට්ටලය බාගන්න
52 @staticmethod
53 def _download():
57 if not (lab.get_data_path() / 'cora').exists():
58 download.download_file('https://linqs-data.soe.ucsc.edu/public/lbc/cora.tgz',
59 lab.get_data_path() / 'cora.tgz')
60 download.extract_tar(lab.get_data_path() / 'cora.tgz', lab.get_data_path())
දත්තකට්ටලය පූරණය කරන්න
62 def __init__(self, include_edges: bool = True):
දාරඇතුළත් කළ යුතුද යන්න. මෙම අපි උපුටා දැක්වීමේ ජාලය නොසලකා නම් කොපමණ නිරවද්යතාව අහිමි වේ පරීක්ෂා වේ.
69 self.include_edges = include_edges
බාගතදත්ත කට්ටලය
72 self._download()
කඩදාසිහැඳුනුම්පත්, විශේෂාංග දෛශික සහ ලේබල කියවන්න
75 with monit.section('Read content file'):
76 content = np.genfromtxt(str(lab.get_data_path() / 'cora/cora.content'), dtype=np.dtype(str))
උපුටාදැක්වීම් පූරණය කරන්න, එය නිඛිල යුගල ලැයිස්තුවකි.
78 with monit.section('Read citations file'):
79 citations = np.genfromtxt(str(lab.get_data_path() / 'cora/cora.cites'), dtype=np.int32)
විශේෂාංගදෛශික ලබා ගන්න
82 features = torch.tensor(np.array(content[:, 1:-1], dtype=np.float32))
විශේෂාංගදෛශික සාමාන්යකරණය කරන්න
84 self.features = features / features.sum(dim=1, keepdim=True)
පන්තිනාම ලබා ගන්න සහ ඒ එක් එක් සඳහා අද්විතීය පූර්ණ සංඛ්යාවක් පවරන්න
87 self.classes = {s: i for i, s in enumerate(set(content[:, -1]))}
එමලේබල් එම නිඛිල ලෙස ලබා ගන්න
89 self.labels = torch.tensor([self.classes[i] for i in content[:, -1]], dtype=torch.long)
කඩදාසිහැඳුනුම්පත් ලබා ගන්න
92 paper_ids = np.array(content[:, 0], dtype=np.int32)
කඩදාසිහැඳුනුම්පතේ සිට දර්ශකය දක්වා සිතියම
94 ids_to_idx = {id_: i for i, id_ in enumerate(paper_ids)}
හිස්adjacency න්යාසය - අනන්යතා අනුකෘතියක්
97 self.adj_mat = torch.eye(len(self.labels), dtype=torch.bool)
මෙමadjacency න්යාසය තුළ උපුටා දැක්වීම් සලකුණු
100 if self.include_edges:
101 for e in citations:
කඩදාසිදර්ශක යුගලය
103 e1, e2 = ids_to_idx[e[0]], ids_to_idx[e[1]]
අපිසමමිතික ප්රස්තාරය ඉදි, එහිදී කඩදාසි යොමු කඩදාසි නම් අපි සිට adge තැනින් මෙන්ම සිට අද්දර කිරීමට .
107 self.adj_mat[e1][e2] = True
108 self.adj_mat[e2][e1] = True
111class GAT(Module):
in_features
node එකක් මතම ඊට අදාල විශේෂාංග සංඛ්යාව වේ n_hidden
පළමු ප්රස්තාරය අවධානය ස්ථරය ලක්ෂණ සංඛ්යාව වේ n_classes
යනු පන්ති ගණන n_heads
ප්රස්ථාර අවධානය ස්ථර වල හිස් ගණන dropout
අතහැර දැමීමේ සම්භාවිතාව118 def __init__(self, in_features: int, n_hidden: int, n_classes: int, n_heads: int, dropout: float):
126 super().__init__()
අපිහිස් concatenate එහිදී පළමු ප්රස්තාරය අවධානය ස්ථරය
129 self.layer1 = GraphAttentionLayer(in_features, n_hidden, n_heads, is_concat=True, dropout=dropout)
පළමුප්රස්ථාර අවධානය ස්ථරයෙන් පසු සක්රිය කිරීමේ කාර්යය
131 self.activation = nn.ELU()
අපිහිස් සාමාන්යය එහිදී අවසන් ප්රස්තාරය අවධානය ස්ථරය
133 self.output = GraphAttentionLayer(n_hidden, n_classes, 1, is_concat=False, dropout=dropout)
හැලීම
135 self.dropout = nn.Dropout(dropout)
x
හැඩයේ ලක්ෂණ දෛශික වේ [n_nodes, in_features]
adj_mat
යනු ආකෘතියේ අනුකෘතියේ අනුකෘතිය [n_nodes, n_nodes, n_heads]
හෝ [n_nodes, n_nodes, 1]
137 def forward(self, x: torch.Tensor, adj_mat: torch.Tensor):
ආදානයටඅතහැර දැමීම යොදන්න
144 x = self.dropout(x)
පළමුප්රස්ථාර අවධානය ස්ථරය
146 x = self.layer1(x, adj_mat)
සක්රියකිරීමේ කාර්යය
148 x = self.activation(x)
හැලීම
150 x = self.dropout(x)
පිවිසුම්සඳහා ප්රතිදාන ස්ථරය (සක්රිය කිරීමකින් තොරව)
152 return self.output(x, adj_mat)
නිරවද්යතාවගණනය කිරීම සඳහා සරල ශ්රිතයක්
155def accuracy(output: torch.Tensor, labels: torch.Tensor):
159 return output.argmax(dim=-1).eq(labels).sum().item() / len(labels)
162class Configs(BaseConfigs):
ආකෘතිය
168 model: GAT
පුහුණුකිරීමට නෝඩ් ගණන
170 training_samples: int = 500
ආදානයේනෝඩයකට විශේෂාංග ගණන
172 in_features: int
පළමුප්රස්තාරයේ අවධානය ස්ථරයේ විශේෂාංග ගණන
174 n_hidden: int = 64
හිස්ගණන
176 n_heads: int = 8
වර්ගීකරණයසඳහා පන්ති ගණන
178 n_classes: int
අතහැරදැමීමේ සම්භාවිතාව
180 dropout: float = 0.6
උපුටාදැක්වීමේ ජාලය ඇතුළත් කළ යුතුද යන්න
182 include_edges: bool = True
දත්තකට්ටලය
184 dataset: CoraDataset
පුහුණුපුනරාවර්තන ගණන
186 epochs: int = 1_000
පාඩුශ්රිතය
188 loss_func = nn.CrossEntropyLoss()
පුහුණුකිරීමට උපාංගය
මෙයඋපාංගය සඳහා වින්යාස නිර්මාණය කරයි, එවිට අපට වින්යාස අගයක් පසු කිරීමෙන් උපාංගය වෙනස් කළ හැකිය
193 device: torch.device = DeviceConfigs()
ප්රශස්තකරණය
195 optimizer: torch.optim.Adam
දත්තසමුදාය කුඩා බැවින් අපි පූර්ණ කණ්ඩායම් පුහුණුව කරන්නෙමු. අප නියැදිය හා පුහුණු කිරීමට නම්, එක් එක් පුහුණු පියවර සඳහා නෝඩ් කට්ටලයක් සාම්පල ලබා ගත යුතු අතර එම තෝරාගත් නෝඩ් හරහා විහිදෙන දාර සමඟ.
197 def run(self):
විශේෂාංගදෛශික උපාංගයට ගෙනයන්න
207 features = self.dataset.features.to(self.device)
ලේබලඋපාංගයට ගෙනයන්න
209 labels = self.dataset.labels.to(self.device)
උපකරණයටඅනුකෘතිය ගෙන යන්න
211 edges_adj = self.dataset.adj_mat.to(self.device)
හිස්සඳහා හිස් තෙවන මානයක් එක් කරන්න
213 edges_adj = edges_adj.unsqueeze(-1)
අහඹුදර්ශක
216 idx_rand = torch.randperm(len(labels))
පුහුණුවසඳහා නෝඩ්
218 idx_train = idx_rand[:self.training_samples]
වලංගුකිරීම සඳහා නෝඩ්
220 idx_valid = idx_rand[self.training_samples:]
පුහුණුලූපය
223 for epoch in monit.loop(self.epochs):
පුහුණුමාදිලියට ආකෘතිය සකසන්න
225 self.model.train()
සියලුමඅනුක්රමික ශුන්ය කරන්න
227 self.optimizer.zero_grad()
ආකෘතියතක්සේරු කරන්න
229 output = self.model(features, edges_adj)
පුහුණුනෝඩ් සඳහා අලාභය ලබා ගන්න
231 loss = self.loss_func(output[idx_train], labels[idx_train])
අනුක්රමිකගණනය කරන්න
233 loss.backward()
ප්රශස්තිකරණපියවර ගන්න
235 self.optimizer.step()
අලාභයලොග් කරන්න
237 tracker.add('loss.train', loss)
නිරවද්යතාවයලොග් කරන්න
239 tracker.add('accuracy.train', accuracy(output[idx_train], labels[idx_train]))
වලංගුකිරීම සඳහා ඇගයීමේ ප්රකාරයට සකසන්න
242 self.model.eval()
අනුක්රමිකගණනය කිරීමට අවශ්ය නැත
245 with torch.no_grad():
ආකෘතියනැවත ඇගයීමට ලක් කරන්න
247 output = self.model(features, edges_adj)
වලංගුකිරීමේ නෝඩ් සඳහා අලාභය ගණනය කරන්න
249 loss = self.loss_func(output[idx_valid], labels[idx_valid])
අලාභයලොග් කරන්න
251 tracker.add('loss.valid', loss)
නිරවද්යතාවයලොග් කරන්න
253 tracker.add('accuracy.valid', accuracy(output[idx_valid], labels[idx_valid]))
ලොග්සුරකින්න
256 tracker.save()
කෝරාදත්ත කට්ටලය සාදන්න
259@option(Configs.dataset)
260def cora_dataset(c: Configs):
264 return CoraDataset(c.include_edges)
පන්තිගණන ලබා ගන්න
268calculate(Configs.n_classes, lambda c: len(c.dataset.classes))
ආදානයේවිශේෂාංග ගණන
270calculate(Configs.in_features, lambda c: c.dataset.features.shape[1])
GATආකෘතිය සාදන්න
273@option(Configs.model)
274def gat_model(c: Configs):
278 return GAT(c.in_features, c.n_hidden, c.n_classes, c.n_heads, c.dropout).to(c.device)
වින්යාසගතකළ හැකි ප්රශස්තකරණය
281@option(Configs.optimizer)
282def _optimizer(c: Configs):
286 opt_conf = OptimizerConfigs()
287 opt_conf.parameters = c.model.parameters()
288 return opt_conf
291def main():
වින්යාසයන්සාදන්න
293 conf = Configs()
අත්හදාබැලීමක් සාදන්න
295 experiment.create(name='gat')
වින්යාසයන්ගණනය කරන්න.
297 experiment.configs(conf, {
ආදම්ප්රශස්තකරණය
299 'optimizer.optimizer': 'Adam',
300 'optimizer.learning_rate': 5e-3,
301 'optimizer.weight_decay': 5e-4,
302 })
අත්හදාබැලීම ආරම්භ කර නරඹන්න
305 with experiment.start():
පුහුණුවක්රියාත්මක කරන්න
307 conf.run()
311if __name__ == '__main__':
312 main()