මෙයGATV2 ක්රියාකරුගේ PyTorch ක්රියාත්මක කිරීමකි ප්රස්ථාර අවධානය යොමු කරන ජාලයන් කෙතරම් අවධානයෙන් සිටිනවාද? .
GATV2s GATහා සමාන ප්රස්තාර දත්ත මත ක්රියා කරයි. ප්රස්ථාරයක් නෝඩ් සහ දාර සම්බන්ධ කරන නෝඩ් වලින් සමන්විත වේ. උදාහරණයක් ලෙස, කෝරා දත්ත කට්ටලයේ නෝඩ් පර්යේෂණ පත්රිකා වන අතර දාර යනු පත්රිකා සම්බන්ධ කරන උපුටා දැක්වීම් වේ.
GATV2ක්රියාකරු සම්මත GAT හිස්ථිතික අවධානය යොමු කිරීමේ ගැටළුව විසඳයි. ස්ථිතික අවධානය යනු යතුරු නෝඩ් වෙත අවධානය යොමු කිරීම ඕනෑම විමසුම් නෝඩයක් සඳහා එකම ශ්රේණියක් (ඇණවුමක්) ඇති විටය. ගැට් විමසුම node එකක් මතම ඊට අදාල සිට ප්රධාන node එකක් මතම ඊට අදාල අවධානය ගණනය
ඕනෑමවිමසුම් නෝඩයක් සඳහා , යතුරු වල අවධානය ශ්රේණිය () මත පමණක් රඳා පවතින බව සලකන්න . එබැවින් සියලු විමසුම් සඳහා යතුරු වල අවධානය යොමු කිරීම එකම (ස්ථිතික) පවතී.
GATV2අවධානය යොමු කිරීමේ යාන්ත්රණය වෙනස් කිරීමෙන් ගතික අවධානයට ඉඩ දෙයි,
කෘතිමශබ්ද කෝෂ බැලීමේ දත්ත කට්ටලයක් සමඟ සමහර ප්රස්ථාර ගැටළු වලට GATs ස්ථිතික අවධානය යොමු කිරීමේ යාන්ත්රණය අසමත් වන බව පත්රිකාව පෙන්වයි. එය සම්පූර්ණ සම්බන්ධිත ද්විපාර්ශවීය ප්රස්ථාරයක් වන අතර එහිදී එක් නෝඩ් කට්ටලයක් (විමසුම් නෝඩ්) එයට සම්බන්ධ යතුරක් ඇති අතර අනෙක් නෝඩ් කට්ටලයට යතුරක් සහ ඒ හා සම්බන්ධ වටිනාකමක් ඇත. ඉලක්කය වන්නේ විමසුම් නෝඩ් වල අගයන් පුරෝකථනය කිරීමයි. GAT නිසා එහි සීමිත ස්ථිතික අවධානය මෙම කාර්යය සඳහා අසමත්.
කෝරා දත්ත කට්ටලයේ ස්ථර දෙකක GATV2 පුහුණු කිරීම සඳහා පුහුණු කේතය මෙන්න.
59import torch
60from torch import nn
61
62from labml_helpers.module import Moduleමෙයතනි ප්රස්ථාර අවධානය v2 ස්ථරයකි. GATV2 එවැනි ස්ථර කිහිපයකින් සෑදී ඇත. ආදාන සහ ප්රතිදානයන් ලෙස කොතැනද , එය අවශ්ය වේ .
65class GraphAttentionV2Layer(Module):in_features
, , node එකක් මතම ඊට අදාල ආදාන ලක්ෂණ සංඛ්යාව out_features
, , node එකක් මතම ඊට අදාල ප්රතිදානය විශේෂාංග සංඛ්යාව වේ n_heads
, , අවධානය යොමු ප්රධානීන් සංඛ්යාව වේ is_concat
 බහු-හිස ප්රති results ල සංයුක්ත කළ යුතුද නැතහොත් සාමාන්යය විය යුතුද යන්න dropout
 අතහැර දැමීමේ සම්භාවිතාව leaky_relu_negative_slope
 යනු කාන්දු වන රිලූ සක්රිය කිරීම සඳහා negative ණ බෑවුමයි share_weights
 සකසා ඇත්නම් True
, සෑම දාරයකම ප්රභවයට සහ ඉලක්කගත නෝඩයට එකම අනුකෘතිය යොදනු ලැබේ78    def __init__(self, in_features: int, out_features: int, n_heads: int,
79                 is_concat: bool = True,
80                 dropout: float = 0.6,
81                 leaky_relu_negative_slope: float = 0.2,
82                 share_weights: bool = False):92        super().__init__()
93
94        self.is_concat = is_concat
95        self.n_heads = n_heads
96        self.share_weights = share_weightsහිසකටමානයන් ගණන ගණනය කරන්න
99        if is_concat:
100            assert out_features % n_heads == 0අපිබහු හිස් සංකෝචනය කරන්නේ නම්
102            self.n_hidden = out_features // n_heads
103        else:අපිබහු හිස් සාමාන්යය කරන්නේ නම්
105            self.n_hidden = out_featuresආරම්භකප්රභව පරිවර්තනය සඳහා රේඛීය ස්ථරය; එනම් ස්වයං අවධානයට පෙර ප්රභව නෝඩ් කාවැද්දීම් පරිවර්තනය කිරීම
109        self.linear_l = nn.Linear(in_features, self.n_hidden * n_heads, bias=False)share_weights
 නම් True
 ඉලක්කගත නෝඩ් සඳහා එකම රේඛීය ස්ථරය භාවිතා වේ 
111        if share_weights:
112            self.linear_r = self.linear_l
113        else:
114            self.linear_r = nn.Linear(in_features, self.n_hidden * n_heads, bias=False)අවධානයලකුණු ගණනය කිරීම සඳහා රේඛීය ස්ථරය
116        self.attn = nn.Linear(self.n_hidden, 1, bias=False)අවධානයලකුණු සඳහා සක්රිය
118        self.activation = nn.LeakyReLU(negative_slope=leaky_relu_negative_slope)අවධානයගණනය කිරීමට සොෆ්ට්මැක්ස්
120        self.softmax = nn.Softmax(dim=1)අවධානයසඳහා යෙදිය යුතු ස්තරය
122        self.dropout = nn.Dropout(dropout)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
. 124    def forward(self, h: torch.Tensor, adj_mat: torch.Tensor):නෝඩ්ගණන
134        n_nodes = h.shape[0]එක්එක් හිස සඳහා ආරම්භක පරිවර්තනයන්. අපි රේඛීය පරිවර්තනයන් දෙකක් කර එක් එක් හිස සඳහා එය බෙදන්න.
140        g_l = self.linear_l(h).view(n_nodes, self.n_heads, self.n_hidden)
141        g_r = self.linear_r(h).view(n_nodes, self.n_heads, self.n_hidden)එක්එක් හිස සඳහා අපි මේවා ගණනය කරමු . සරලබව සඳහා අපි මඟ හරවා ඇත්තෙමු.
අවධානය ලකුණු (වැදගත්කම) node එකක් මතම ඊට අදාල සිට node එකක් මතම ඊට අදාල අපි එක් එක් හිස සඳහා මෙය ගණනය කරමු.
අවධානය යොමු කිරීමේ යාන්ත්රණය, එය අවධානය ලකුණු ගණනය කරයි. කඩදාසි සාරාංශ , a විසින් අනුගමනය කරන අතර බර දෛශිකයක් සමඟ රේඛීය පරිවර්තනයක් සිදු කරයි
සටහන: අප මෙහි භාවිතා කරන අර්ථ දැක්වීමට සමාන වන කඩදාසි අවලංගු කරයි .
පළමුවඅපි සියලු යුගල සඳහා ගණනය කරමු .
g_l_repeat
 එක් එක් node එකක් මතම ඊට අදාල කාවැද්දීම නැවත නැවත n_nodes
 වතාවක්  කොහෙද ලැබෙන. 
179        g_l_repeat = g_l.repeat(n_nodes, 1, 1)g_r_repeat_interleave
 එක් එක් node එකක් මතම ඊට අදාල කාවැද්දීම නැවත නැවත n_nodes
 වතාවක්  කොහෙද ලැබෙන. 
184        g_r_repeat_interleave = g_r.repeat_interleave(n_nodes, dim=0)දැන්අපි ලබා ගැනීම සඳහා ටෙන්සර දෙක එකතු කරමු
192        g_sum = g_l_repeat + g_r_repeat_interleaveඒනිසා නැවත g_sum[i, j]
 හැඩගස්වා  
194        g_sum = g_sum.view(n_nodes, n_nodes, self.n_heads, self.n_hidden)ගණනයහැඩයෙන්  e
 යුක්ත වේ [n_nodes, n_nodes, n_heads, 1]
 
202        e = self.attn(self.activation(g_sum))ප්රමාණයේඅවසාන මානය ඉවත් කරන්න 1
 
204        e = e.squeeze(-1)මෙමadjacency න්යාසය හැඩය [n_nodes, n_nodes, n_heads]
 හෝ තිබිය යුතුය[n_nodes, n_nodes, 1]
 
208        assert adj_mat.shape[0] == 1 or adj_mat.shape[0] == n_nodes
209        assert adj_mat.shape[1] == 1 or adj_mat.shape[1] == n_nodes
210        assert adj_mat.shape[2] == 1 or adj_mat.shape[2] == self.n_headsමැස්සිඅනුකෘතිය මත පදනම් වූ මාස්ක්. සිට දාරයක් නොමැති නම් දක්වා සකසා ඇත.
213        e = e.masked_fill(adj_mat == 0, float('-inf'))ඉන්පසුඅපි අවධානය යොමු කිරීමේ ලකුණු සාමාන්යකරණය කරමු (හෝ සංගුණක)
සම්බන්ධවූ නෝඩ් කට්ටලය කොහේද?
අපිමෙය කරන්නේ අසම්බන්ධිත යුගල සඳහා සම්බන්ධ නොවූ සැකසීමෙනි.
223        a = self.softmax(e)අතහැරදැමීමේ විධිමත් කිරීම යොදන්න
226        a = self.dropout(a)එක්එක් හිස සඳහා අවසාන ප්රතිදානය ගණනය කරන්න
230        attn_res = torch.einsum('ijh,jhf->ihf', a, g_r)ප්රධානීන්සංයුක්ත කරන්න
233        if self.is_concat:235            return attn_res.reshape(n_nodes, self.n_heads * self.n_hidden)ප්රධානීන්ගේමධ්යන්යය ගන්න
237        else:239            return attn_res.mean(dim=1)