docs/si/graphs/gatv2/index.html
[View code on Github](https://github.com/labmlai/annotated_deep_learning_paper_implementations/tree/master/labml_nn/graphs/gatv2/ init.py)
මෙයGATV2 ක්රියාකරුගේ PyTorch ක්රියාත්මක කිරීමකි ප්රස්ථාර අවධානය යොමු කරන ජාලයන් කෙතරම් අවධානයෙන් සිටිනවාද?.
GATV2s GATහා සමාන ප්රස්තාර දත්ත මත ක්රියා කරයි. ප්රස්ථාරයක් නෝඩ් සහ දාර සම්බන්ධ කරන නෝඩ් වලින් සමන්විත වේ. උදාහරණයක් ලෙස, කෝරා දත්ත කට්ටලයේ නෝඩ් පර්යේෂණ පත්රිකා වන අතර දාර යනු පත්රිකා සම්බන්ධ කරන උපුටා දැක්වීම් වේ.
GATV2ක්රියාකරු සම්මත GAT හිස්ථිතික අවධානය යොමු කිරීමේ ගැටළුව විසඳයි. ස්ථිතික අවධානය යනු යතුරු නෝඩ් වෙත අවධානය යොමු කිරීම ඕනෑම විමසුම් නෝඩයක් සඳහා එකම ශ්රේණියක් (ඇණවුමක්) ඇති විටය. ගැට් විමසුම node එකක් මතම ඊට අදාල සිට ප්රධාන node i එකක් මතම ඊට අදාල j අවධානය ගණනය
eij=LeakyReLU(a⊤[Whi∥Whj])=LeakyReLU(a1⊤Whi+a2⊤Whj)
ඕනෑමවිමසුම් නෝඩයක් සඳහා i, යතුරු වල අවධානය ශ්රේණිය (argsort) මත පමණක් රඳා පවතින බව සලකන්න a2⊤Whj. එබැවින් සියලු විමසුම් සඳහා යතුරු වල අවධානය යොමු කිරීම එකම (ස්ථිතික) පවතී.
GATV2අවධානය යොමු කිරීමේ යාන්ත්රණය වෙනස් කිරීමෙන් ගතික අවධානයට ඉඩ දෙයි,
eij=a⊤LeakyReLU(W[hi∥hj])=a⊤LeakyReLU(Wlhi+Wrhj)
කෘතිමශබ්ද කෝෂ බැලීමේ දත්ත කට්ටලයක් සමඟ සමහර ප්රස්ථාර ගැටළු වලට GATs ස්ථිතික අවධානය යොමු කිරීමේ යාන්ත්රණය අසමත් වන බව පත්රිකාව පෙන්වයි. එය සම්පූර්ණ සම්බන්ධිත ද්විපාර්ශවීය ප්රස්ථාරයක් වන අතර එහිදී එක් නෝඩ් කට්ටලයක් (විමසුම් නෝඩ්) එයට සම්බන්ධ යතුරක් ඇති අතර අනෙක් නෝඩ් කට්ටලයට යතුරක් සහ ඒ හා සම්බන්ධ වටිනාකමක් ඇත. ඉලක්කය වන්නේ විමසුම් නෝඩ් වල අගයන් පුරෝකථනය කිරීමයි. GAT නිසා එහි සීමිත ස්ථිතික අවධානය මෙම කාර්යය සඳහා අසමත්.
කෝරා දත්ත කට්ටලයේ ස්ථර දෙකක GATV2 පුහුණු කිරීම සඳහා පුහුණු කේතය මෙන්න.
59importtorch60fromtorchimportnn6162fromlabml\_helpers.moduleimportModule
මෙයතනි ප්රස්ථාර අවධානය v2 ස්ථරයකි. GATV2 එවැනි ස්ථර කිහිපයකින් සෑදී ඇත. ආදාන සහ ප්රතිදානයන් hi∈RF ලෙස කොතැනද h′={h1′,h2′,…,hN′}, එය අවශ්ය වේ h={h1,h2,…,hN}hi′∈RF′.
65classGraphAttentionV2Layer(Module):
in_features , F, node එකක් මතම ඊට අදාල ආදාන ලක්ෂණ සංඛ්යාවout_features , F′, node එකක් මතම ඊට අදාල ප්රතිදානය විශේෂාංග සංඛ්යාව වේn_heads , K, අවධානය යොමු ප්රධානීන් සංඛ්යාව වේis_concat බහු-හිස ප්රති results ල සංයුක්ත කළ යුතුද නැතහොත් සාමාන්යය විය යුතුද යන්නdropout අතහැර දැමීමේ සම්භාවිතාවleaky_relu_negative_slope යනු කාන්දු වන රිලූ සක්රිය කිරීම සඳහා negative ණ බෑවුමයිshare_weights සකසා ඇත්නම් True , සෑම දාරයකම ප්රභවයට සහ ඉලක්කගත නෝඩයට එකම අනුකෘතිය යොදනු ලැබේ78def\_\_init\_\_(self,in\_features:int,out\_features:int,n\_heads:int,79is\_concat:bool=True,80dropout:float=0.6,81leaky\_relu\_negative\_slope:float=0.2,82share\_weights:bool=False):
92super().\_\_init\_\_()9394self.is\_concat=is\_concat95self.n\_heads=n\_heads96self.share\_weights=share\_weights
හිසකටමානයන් ගණන ගණනය කරන්න
99ifis\_concat:100assertout\_features%n\_heads==0
අපිබහු හිස් සංකෝචනය කරන්නේ නම්
102self.n\_hidden=out\_features//n\_heads103else:
අපිබහු හිස් සාමාන්යය කරන්නේ නම්
105self.n\_hidden=out\_features
ආරම්භකප්රභව පරිවර්තනය සඳහා රේඛීය ස්ථරය; එනම් ස්වයං අවධානයට පෙර ප්රභව නෝඩ් කාවැද්දීම් පරිවර්තනය කිරීම
109self.linear\_l=nn.Linear(in\_features,self.n\_hidden\*n\_heads,bias=False)
share_weights නම් True ඉලක්කගත නෝඩ් සඳහා එකම රේඛීය ස්ථරය භාවිතා වේ
111ifshare\_weights:112self.linear\_r=self.linear\_l113else:114self.linear\_r=nn.Linear(in\_features,self.n\_hidden\*n\_heads,bias=False)
අවධානයලකුණු ගණනය කිරීම සඳහා රේඛීය ස්ථරය eij
116self.attn=nn.Linear(self.n\_hidden,1,bias=False)
අවධානයලකුණු සඳහා සක්රිය eij
118self.activation=nn.LeakyReLU(negative\_slope=leaky\_relu\_negative\_slope)
අවධානයගණනය කිරීමට සොෆ්ට්මැක්ස් αij
120self.softmax=nn.Softmax(dim=1)
අවධානයසඳහා යෙදිය යුතු ස්තරය
122self.dropout=nn.Dropout(dropout)
h , h හැඩයේ ආදාන නෝඩ් කාවැද්දීම් [n_nodes, in_features] වේ.adj_mat යනු හැඩයේ විඝටන අනුකෘතියකි [n_nodes, n_nodes, n_heads] . එක් එක් හිස සඳහා adjacency එක සමාන [n_nodes, n_nodes, 1] බැවින් අපි හැඩය භාවිතා කරමු. සමපාත අනුකෘතිය නෝඩ් අතර දාර (හෝ සම්බන්ධතා) නියෝජනය කරයි. adj_mat[i][j] නෝඩ් සිට නෝඩ් සිට නෝඩ් i දක්වා දාරයක් තිබේ True නම් j .124defforward(self,h:torch.Tensor,adj\_mat:torch.Tensor):
නෝඩ්ගණන
134n\_nodes=h.shape[0]
එක්එක් හිස glik=Wlkhi grik=Wrkhi සඳහා ආරම්භක පරිවර්තනයන්. අපි රේඛීය පරිවර්තනයන් දෙකක් කර එක් එක් හිස සඳහා එය බෙදන්න.
140g\_l=self.linear\_l(h).view(n\_nodes,self.n\_heads,self.n\_hidden)141g\_r=self.linear\_r(h).view(n\_nodes,self.n\_heads,self.n\_hidden)
එක්එක් හිස සඳහා අපි මේවා ගණනය කරමු k. සරලබව ⋅k සඳහා අපි මඟ හරවා ඇත්තෙමු.
eij=a(Wlhi,Wrhj)=a(gli,grj)
eij අවධානය ලකුණු (වැදගත්කම) node එකක් මතම ඊට අදාල සිට node j එකක් iමතම ඊට අදාල අපි එක් එක් හිස සඳහා මෙය ගණනය කරමු.
a අවධානය යොමු කිරීමේ යාන්ත්රණය, එය අවධානය ලකුණු ගණනය කරයි. කඩදාසි සාරාංශ gli, a විසින් grj අනුගමනය කරන LeakyReLU අතර බර දෛශිකයක් සමඟ රේඛීය පරිවර්තනයක් සිදු කරයි a∈RF′
eij=a⊤LeakyReLU([gli+grj]) සටහන: අප මෙහි භාවිතා කරන අර්ථ දැක්වීමට සමාන eij=a⊤LeakyReLU(W[hi∥hj]) වන කඩදාසි අවලංගු කරයි eij .
පළමුවඅපි සියලු යුගල [gli+grj] සඳහා ගණනය කරමු i,j.
g_l_repeat එක් එක් node එකක් මතම ඊට අදාල කාවැද්දීම නැවත නැවත n_nodes වතාවක් {gl1,gl2,…,glN,gl1,gl2,…,glN,...} කොහෙද ලැබෙන.
179g\_l\_repeat=g\_l.repeat(n\_nodes,1,1)
g_r_repeat_interleave එක් එක් node එකක් මතම ඊට අදාල කාවැද්දීම නැවත නැවත n_nodes වතාවක් {gr1,gr1,…,gr1,gr2,gr2,…,gr2,...} කොහෙද ලැබෙන.
184g\_r\_repeat\_interleave=g\_r.repeat\_interleave(n\_nodes,dim=0)
දැන්අපි ලබා ගැනීම සඳහා ටෙන්සර දෙක එකතු කරමු {gl1+gr1,gl1+gr2,…,gl1+grN,gl2+gr1,gl2+gr2,…,gl2+grN,...}
192g\_sum=g\_l\_repeat+g\_r\_repeat\_interleave
ඒනිසා නැවත g_sum[i, j] හැඩගස්වා gli+grj
194g\_sum=g\_sum.view(n\_nodes,n\_nodes,self.n\_heads,self.n\_hidden)
ගණනයහැඩයෙන් eij=a⊤LeakyReLU([gli+grj]) e යුක්ත වේ [n_nodes, n_nodes, n_heads, 1]
202e=self.attn(self.activation(g\_sum))
ප්රමාණයේඅවසාන මානය ඉවත් කරන්න 1
204e=e.squeeze(-1)
මෙමadjacency න්යාසය හැඩය [n_nodes, n_nodes, n_heads] හෝ තිබිය යුතුය[n_nodes, n_nodes, 1]
208assertadj\_mat.shape[0]==1oradj\_mat.shape[0]==n\_nodes209assertadj\_mat.shape[1]==1oradj\_mat.shape[1]==n\_nodes210assertadj\_mat.shape[2]==1oradj\_mat.shape[2]==self.n\_heads
මැස්සිඅනුකෘතිය මත eij පදනම් වූ මාස්ක්. eij සිට i දාරයක් නොමැති −∞ නම් දක්වා සකසා jඇත.
213e=e.masked\_fill(adj\_mat==0,float('-inf'))
ඉන්පසුඅපි අවධානය යොමු කිරීමේ ලකුණු සාමාන්යකරණය කරමු (හෝ සංගුණක) αij=softmaxj(eij)=∑j′∈Niexp(eij′)exp(eij)
සම්බන්ධවූ නෝඩ් කට්ටලය Ni iකොහේද?
අපිමෙය කරන්නේ අසම්බන්ධිත eij යුගල exp(eij)∼0 සඳහා සම්බන්ධ නොවූ සැකසීමෙනි. −∞
223a=self.softmax(e)
අතහැරදැමීමේ විධිමත් කිරීම යොදන්න
226a=self.dropout(a)
එක්එක් හිස සඳහා අවසාන ප්රතිදානය ගණනය කරන්න hi′k=j∈Ni∑αijkgrj,k
230attn\_res=torch.einsum('ijh,jhf-\>ihf',a,g\_r)
ප්රධානීන්සංයුක්ත කරන්න
233ifself.is\_concat:
hi′=∥∥k=1Khi′k
235returnattn\_res.reshape(n\_nodes,self.n\_heads\*self.n\_hidden)
ප්රධානීන්ගේමධ්යන්යය ගන්න
237else:
hi′=K1k=1∑Khi′k
239returnattn\_res.mean(dim=1)