हुड के तहत ग्राफ ध्यान नेटवर्क

स्रोत नोड: 769288

ग्राफ़ ध्यान नेटवर्क

ग्राफ न्यूरल नेटवर्क (जीएनएन) ग्राफ डेटा से सीखने के लिए मानक टूलबॉक्स के रूप में उभरे हैं। जीएनएन विभिन्न क्षेत्रों में उच्च प्रभाव वाली समस्याओं, जैसे सामग्री अनुशंसा या दवा खोज, में सुधार लाने में सक्षम हैं। छवियों जैसे अन्य प्रकार के डेटा के विपरीत, ग्राफ़ डेटा से सीखने के लिए विशिष्ट तरीकों की आवश्यकता होती है। जैसा कि परिभाषित किया गया है माइकल ब्रोंस्टीन:

[..] ये विधियां ग्राफ़ पर गुजरने वाले कुछ प्रकार के संदेश पर आधारित हैं जो विभिन्न नोड्स को जानकारी का आदान-प्रदान करने की अनुमति देती हैं।

ग्राफ़ (नोड वर्गीकरण, लिंक भविष्यवाणी इत्यादि) पर विशिष्ट कार्यों को पूरा करने के लिए, एक जीएनएन परत तथाकथित के माध्यम से नोड और किनारे प्रतिनिधित्व की गणना करती है पुनरावर्ती पड़ोस प्रसार (या संदेश देना). इस सिद्धांत के अनुसार, प्रत्येक ग्राफ़ नोड स्थानीय ग्राफ़ संरचना का प्रतिनिधित्व करने के लिए अपने पड़ोसियों से सुविधाएँ प्राप्त करता है और एकत्र करता है: विभिन्न प्रकार की GNN परतें विविध एकत्रीकरण रणनीतियों का प्रदर्शन करती हैं।

जीएनएन परत के सबसे सरल फॉर्मूलेशन, जैसे कि ग्राफ कन्वोल्यूशनल नेटवर्क (जीसीएन) या ग्राफसेज, एक आइसोट्रोपिक एकत्रीकरण निष्पादित करते हैं, जहां प्रत्येक पड़ोसी केंद्रीय नोड के प्रतिनिधित्व को अद्यतन करने के लिए समान रूप से योगदान देता है। यह ब्लॉग पोस्ट ग्राफ़ अटेंशन नेटवर्क (जीएटी) के विश्लेषण के लिए समर्पित एक लघु-श्रृंखला (2 लेख) प्रस्तुत करता है, जो पुनरावर्ती पड़ोस प्रसार में अनिसोट्रॉपी ऑपरेशन को परिभाषित करता है। अनिसोट्रॉपी प्रतिमान का फायदा उठाते हुए, ध्यान तंत्र द्वारा सीखने की क्षमता में सुधार किया जाता है, जो प्रत्येक पड़ोसी के योगदान को अलग-अलग महत्व देता है।

यदि आप जीएनएन और संबंधित अवधारणाओं में पूरी तरह से नए हैं, तो मैं आपको निम्नलिखित परिचयात्मक लेख पढ़ने के लिए आमंत्रित करता हूं: ग्राफ न्यूरल नेटवर्क्स (इंट्रो) के बिल्डिंग ब्लॉक्स को समझना.

यदि यह गहन शैक्षिक सामग्री आपके लिए उपयोगी है, हमारी AI रिसर्च मेलिंग लिस्ट को सब्सक्राइब करें जब हम नई सामग्री जारी करते हैं तो सतर्क रहें। 

जीसीएन बनाम जीएटी - गणित वार्म-अप

यह वार्म-अप डीप ग्राफ़ लाइब्रेरी द्वारा रिपोर्ट किए गए GAT विवरण पर आधारित है वेबसाइट .

GAT परत के व्यवहार को समझने से पहले, आइए GCN परत द्वारा किए गए एकत्रीकरण के पीछे के गणित को दोबारा समझें।

जीसीएन परत - एकत्रीकरण कार्य
  • नोड के वन-हॉप पड़ोसियों का सेट है i. इस नोड को सेल्फ-लूप जोड़कर पड़ोसियों के बीच भी शामिल किया जा सकता है।
  • ग्राफ़ संरचना के आधार पर एक सामान्यीकरण स्थिरांक है, जो एक आइसोट्रोपिक औसत गणना को परिभाषित करता है।
  • σ एक सक्रियण फ़ंक्शन है, जो परिवर्तन में गैर-रैखिकता का परिचय देता है।
  • सुविधा परिवर्तन के लिए अपनाए गए सीखने योग्य मापदंडों का भार मैट्रिक्स है।

GAT परत ध्यान गुणांक के माध्यम से प्रत्येक किनारे को अलग-अलग महत्व प्रदान करते हुए, GCN परत के मूल एकत्रीकरण फ़ंक्शन का विस्तार करती है।

GAT परत समीकरण
  • समीकरण (1) निचली परत एम्बेडिंग का एक रैखिक परिवर्तन है नमस्ते, और W इसका सीखने योग्य वजन मैट्रिक्स है। यह परिवर्तन इनपुट सुविधाओं को उच्च-स्तरीय और सघन सुविधाओं में बदलने के लिए पर्याप्त अभिव्यंजक शक्ति प्राप्त करने में मदद करता है।
  • समीकरण (2) दो पड़ोसियों के बीच जोड़ी-वार अ-सामान्यीकृत ध्यान स्कोर की गणना करता है। यहाँ, यह सबसे पहले संयोजित होता है z दो नोड्स की एम्बेडिंग, जहां || संयोजन को दर्शाता है. फिर, यह इस तरह के संयोजन का एक डॉट उत्पाद और एक सीखने योग्य वजन वेक्टर लेता है a. अंत में, डॉट उत्पाद के परिणाम पर एक LeakyReLU लागू किया जाता है। ध्यान स्कोर संदेश भेजने के ढांचे में पड़ोसी नोड के महत्व को इंगित करता है।
  • समीकरण (3) प्रत्येक नोड के आने वाले किनारों पर ध्यान स्कोर को सामान्य करने के लिए सॉफ्टमैक्स लागू करता है। सॉफ्टमैक्स संभाव्यता वितरण में पिछले चरण के आउटपुट को एन्कोड करता है। परिणामस्वरूप, विभिन्न नोड्स में ध्यान स्कोर बहुत अधिक तुलनीय हैं।
  • समीकरण (4) जीसीएन एकत्रीकरण के समान है (अनुभाग की शुरुआत में समीकरण देखें)। पड़ोसियों के एम्बेडिंग को एक साथ एकत्रित किया जाता है, ध्यान स्कोर के आधार पर मापा जाता है। इस स्केलिंग प्रक्रिया का मुख्य परिणाम प्रत्येक पड़ोस नोड से एक अलग योगदान सीखना है।

न्यूमपी कार्यान्वयन

पहला कदम एक साधारण ग्राफ का प्रतिनिधित्व करने और रैखिक परिवर्तन करने के लिए सामग्री (मैट्रिसेस) तैयार करना है।

NumPy कोड

print('nn----- One-hot vector representation of nodes. Shape(n,n)n')
X = np.eye(5, 5)
n = X.shape[0]
np.random.shuffle(X)
print(X) print('nn----- Embedding dimensionn')
emb = 3
print(emb) print('nn----- Weight Matrix. Shape(emb, n)n')
W = np.random.uniform(-np.sqrt(1. / emb), np.sqrt(1. / emb), (emb, n))
print(W) print('nn----- Adjacency Matrix (undirected graph). Shape(n,n)n')
A = np.random.randint(2, size=(n, n))
np.fill_diagonal(A, 1) A = (A + A.T)
A[A > 1] = 1
print(A)

उत्पादन

----- One-hot vector representation of nodes. Shape(n,n)
[[0 0 1 0 0] # node 1 [0 1 0 0 0] # node 2 [0 0 0 0 1] [1 0 0 0 0] [0 0 0 1 0]]
----- Embedding dimension
3
----- Weight Matrix. Shape(emb, n)
[[-0.4294049 0.57624235 -0.3047382 -0.11941829 -0.12942953] [ 0.19600584 0.5029172 0.3998854 -0.21561317 0.02834577] [-0.06529497 -0.31225734 0.03973776 0.47800217 -0.04941563]]
----- Adjacency Matrix (undirected graph). Shape(n,n)
[[1 1 1 0 1] [1 1 1 1 1] [1 1 1 1 0] [0 1 1 1 1] [1 1 0 1 1]]

पहला मैट्रिक्स नोड्स के एक-हॉट एन्कोडेड प्रतिनिधित्व को परिभाषित करता है (नोड 1 को बोल्ड में दिखाया गया है)। फिर, हम परिभाषित एम्बेडिंग आयाम का फायदा उठाते हुए एक वजन मैट्रिक्स को परिभाषित करते हैं। मैंने तीसरे कॉलम वेक्टर पर प्रकाश डाला है W क्योंकि, जैसा कि आप शीघ्र ही देखेंगे, यह वेक्टर नोड 1 के अद्यतन प्रतिनिधित्व को परिभाषित करता है (तीसरे स्थान पर 1-मान प्रारंभ किया गया है)। हम इन सामग्रियों से शुरू करके नोड सुविधाओं के लिए पर्याप्त अभिव्यंजक शक्ति प्राप्त करने के लिए रैखिक परिवर्तन कर सकते हैं। इस कदम का लक्ष्य (एक-हॉट एन्कोडेड) इनपुट सुविधाओं को कम और सघन प्रतिनिधित्व में बदलना है।

GAT परत (समीकरण 1)

NumPy कोड

# equation (1)
print('nn----- Linear Transformation. Shape(n, emb)n')
z1 = X.dot(W.T)
print(z1)

उत्पादन

----- Linear Transformation. Shape(n, emb) [[-0.3047382 0.3998854 0.03973776] [ 0.57624235 0.5029172 -0.31225734] [-0.12942953 0.02834577 -0.04941563] [-0.4294049 0.19600584 -0.06529497] [-0.11941829 -0.21561317 0.47800217]]

अगला ऑपरेशन प्रत्येक किनारे के लिए आत्म-ध्यान गुणांक पेश करना है। हम किनारों का प्रतिनिधित्व करने के लिए स्रोत नोड के प्रतिनिधित्व और गंतव्य नोड के प्रतिनिधित्व को जोड़ते हैं। यह संयोजन प्रक्रिया आसन्न मैट्रिक्स द्वारा सक्षम है A, जो ग्राफ़ में सभी नोड्स के बीच संबंधों को परिभाषित करता है।

GAT परत (समीकरण 2)

NumPy कोड

# equation (2) - First part
print('nn----- Concat hidden features to represent edges. Shape(len(emb.concat(emb)), number of edges)n')
edge_coords = np.where(A==1)
h_src_nodes = z1[edge_coords[0]]
h_dst_nodes = z1[edge_coords[1]]
z2 = np.concatenate((h_src_nodes, h_dst_nodes), axis=1)

उत्पादन

----- Concat hidden features to represent edges. Shape(len(emb.concat(emb)), number of edges) [[-0.3047382 0.3998854 0.03973776 -0.3047382 0.3998854 0.03973776] [-0.3047382 0.3998854 0.03973776 0.57624235 0.5029172 -0.31225734] [-0.3047382 0.3998854 0.03973776 -0.12942953 0.02834577 -0.04941563] [-0.3047382 0.3998854 0.03973776 -0.11941829 -0.21561317 0.47800217] [ 0.57624235 0.5029172 -0.31225734 -0.3047382 0.3998854 0.03973776] [ 0.57624235 0.5029172 -0.31225734 0.57624235 0.5029172 -0.31225734] [ 0.57624235 0.5029172 -0.31225734 -0.12942953 0.02834577 -0.04941563] [ 0.57624235 0.5029172 -0.31225734 -0.4294049 0.19600584 -0.06529497] [ 0.57624235 0.5029172 -0.31225734 -0.11941829 -0.21561317 0.47800217] [-0.12942953 0.02834577 -0.04941563 -0.3047382 0.3998854 0.03973776] [-0.12942953 0.02834577 -0.04941563 0.57624235 0.5029172 -0.31225734] [-0.12942953 0.02834577 -0.04941563 -0.12942953 0.02834577 -0.04941563] [-0.12942953 0.02834577 -0.04941563 -0.4294049 0.19600584 -0.06529497] [-0.4294049 0.19600584 -0.06529497 0.57624235 0.5029172 -0.31225734] [-0.4294049 0.19600584 -0.06529497 -0.12942953 0.02834577 -0.04941563] [-0.4294049 0.19600584 -0.06529497 -0.4294049 0.19600584 -0.06529497] [-0.4294049 0.19600584 -0.06529497 -0.11941829 -0.21561317 0.47800217] [-0.11941829 -0.21561317 0.47800217 -0.3047382 0.3998854 0.03973776] [-0.11941829 -0.21561317 0.47800217 0.57624235 0.5029172 -0.31225734] [-0.11941829 -0.21561317 0.47800217 -0.4294049 0.19600584 -0.06529497] [-0.11941829 -0.21561317 0.47800217 -0.11941829 -0.21561317 0.47800217]]

पिछले ब्लॉक में, मैंने नोड 4 से जुड़े 4 इन-किनारों का प्रतिनिधित्व करने वाली 1 पंक्तियों पर प्रकाश डाला है। प्रत्येक पंक्ति के पहले 3 तत्व नोड 1 पड़ोसियों के एम्बेडिंग प्रतिनिधित्व को परिभाषित करते हैं, जबकि प्रत्येक पंक्ति के अन्य 3 तत्व नोड 1 पड़ोसियों के एम्बेडिंग प्रतिनिधित्व को परिभाषित करते हैं। नोड XNUMX स्वयं (जैसा कि आप देख सकते हैं, पहली पंक्ति एक सेल्फ-लूप को एनकोड करती है)।

इस ऑपरेशन के बाद, हम ध्यान गुणांक पेश कर सकते हैं और उन्हें किनारे के प्रतिनिधित्व के साथ गुणा कर सकते हैं, जो कि संघनन प्रक्रिया के परिणामस्वरूप होता है। अंत में, इस उत्पाद के आउटपुट पर लीकी रेलू फ़ंक्शन लागू किया जाता है।

NumPy कोड

# equation (2) - Second part
print('nn----- Attention coefficients. Shape(1, len(emb.concat(emb)))n')
att = np.random.rand(1, z2.shape[1])
print(att) print('nn----- Edge representations combined with the attention coefficients. Shape(1, number of edges)n')
z2_att = z2.dot(att.T)
print(z2_att) print('nn----- Leaky Relu. Shape(1, number of edges)')
e = leaky_relu(z2_att)
print(e)

उत्पादन

----- Attention coefficients. Shape(1, len(emb.concat(emb))) [[0.09834683 0.42110763 0.95788953 0.53316528 0.69187711 0.31551563]] ----- Edge representations combined with the attention coefficients. Shape(1, number of edges) [[ 0.30322275] [ 0.73315639] [ 0.11150219] [ 0.11445879] [ 0.09607946] [ 0.52601309] [-0.0956411 ] [-0.14458757] [-0.0926845 ] [ 0.07860653] [ 0.50854017] [-0.11311402] [-0.16206049] [ 0.53443082] [-0.08722337] [-0.13616985] [-0.08426678] [ 0.48206613] [ 0.91199976] [ 0.2413991 ] [ 0.29330217]] ----- Leaky Relu. Shape(1, number of edges)
[[ 3.03222751e-01] [ 7.33156386e-01] [ 1.11502195e-01] [ 1.14458791e-01] [ 9.60794571e-02] [ 5.26013092e-01] [-9.56410988e-04] [-1.44587571e-03] [-9.26845030e-04] [ 7.86065337e-02] [ 5.08540169e-01] [-1.13114022e-03] [-1.62060495e-03] [ 5.34430817e-01] [-8.72233739e-04] [-1.36169846e-03] [-8.42667781e-04] [ 4.82066128e-01] [ 9.11999763e-01] [ 2.41399100e-01] [ 2.93302168e-01]]

इस प्रक्रिया के अंत में, हमने ग्राफ़ के प्रत्येक किनारे के लिए एक अलग स्कोर हासिल किया। ऊपरी ब्लॉक में, मैंने पहले किनारे से जुड़े गुणांक के विकास पर प्रकाश डाला है। फिर, विभिन्न नोड्स में गुणांक को आसानी से तुलनीय बनाने के लिए, प्रत्येक गंतव्य नोड के लिए सभी पड़ोसियों के योगदान पर एक सॉफ्टमैक्स फ़ंक्शन लागू किया जाता है।

GAT परत (समीकरण 3)

NumPy कोड

# equation (3)
print('nn----- Edge scores as matrix. Shape(n,n)n')
e_matr = np.zeros(A.shape)
e_matr[edge_coords[0], edge_coords[1]] = e.reshape(-1,)
print(e_matr) print('nn----- For each node, normalize the edge (or neighbor) contributions using softmaxn')
alpha0 = softmax(e_matr[:,0][e_matr[:,0] != 0]) alpha1 = softmax(e_matr[:,1][e_matr[:,1] != 0])
alpha2 = softmax(e_matr[:,2][e_matr[:,2] != 0])
alpha3 = softmax(e_matr[:,3][e_matr[:,3] != 0])
alpha4 = softmax(e_matr[:,4][e_matr[:,4] != 0])
alpha = np.concatenate((alpha0, alpha1, alpha2, alpha3, alpha4))
print(alpha) print('nn----- Normalized edge score matrix. Shape(n,n)n')
A_scaled = np.zeros(A.shape)
A_scaled[edge_coords[0], edge_coords[1]] = alpha.reshape(-1,)
print(A_scaled)

उत्पादन

----- Edge scores as matrix. Shape(n,n) [[ 3.03222751e-01 7.33156386e-01 1.11502195e-01 0.00000000e+00 1.14458791e-01] [ 9.60794571e-02 5.26013092e-01 -9.56410988e-04 -1.44587571e-03 -9.26845030e-04] [ 7.86065337e-02 5.08540169e-01 -1.13114022e-03 -1.62060495e-03 0.00000000e+00] [ 0.00000000e+00 5.34430817e-01 -8.72233739e-04 -1.36169846e-03 -8.42667781e-04] [ 4.82066128e-01 9.11999763e-01 0.00000000e+00 2.41399100e-01 2.93302168e-01]] ----- For each node, normalize the edge (or neighbor) contributions using softmax [0.26263543 0.21349717 0.20979916 0.31406823 0.21610715 0.17567419 0.1726313 0.1771592 0.25842816 0.27167844 0.24278118 0.24273876 0.24280162 0.23393014 0.23388927 0.23394984 0.29823075 0.25138555 0.22399017 0.22400903 0.30061525] ----- Normalized edge score matrix. Shape(n,n) [[0.26263543 0.21349717 0.20979916 0. 0.31406823] [0.21610715 0.17567419 0.1726313 0.1771592 0.25842816] [0.27167844 0.24278118 0.24273876 0.24280162 0. ] [0. 0.23393014 0.23388927 0.23394984 0.29823075] [0.25138555 0.22399017 0. 0.22400903 0.30061525]]

सामान्यीकृत बढ़त स्कोर को परिभाषित करने वाले अंतिम मैट्रिक्स के अर्थ की व्याख्या करने के लिए, आइए आसन्न मैट्रिक्स की सामग्री को दोबारा दोहराएं।

----- Adjacency Matrix (undirected graph). Shape(n,n) [[1 1 1 0 1] [1 1 1 1 1] [1 1 1 1 0] [0 1 1 1 1] [1 1 0 1 1]]

जैसा कि आप देख सकते हैं, किनारों को परिभाषित करने के लिए 1 मान रखने के बजाय, हमने प्रत्येक पड़ोसी के योगदान को फिर से बढ़ाया। अंतिम चरण पड़ोस एकत्रीकरण की गणना करना है: पड़ोसियों से एम्बेडिंग को गंतव्य नोड में शामिल किया जाता है, जिसे ध्यान स्कोर द्वारा बढ़ाया जाता है।

GAT परत (समीकरण 4)

NumPy कोड

# equation (4)
print('nnNeighborhood aggregation (GCN) scaled with attention scores (GAT). Shape(n, emb)n')
ND_GAT = A_scaled.dot(z1)
print(ND_GAT)

उत्पादन

Neighborhood aggregation (GCN) scaled with attention scores (GAT). Shape(n, emb) [[-0.02166863 0.15062515 0.08352843] [-0.09390287 0.15866476 0.05716299] [-0.07856777 0.28521023 -0.09286313] [-0.03154513 0.10583032 0.04267501] [-0.07962369 0.19226439 0.069115 ]]

अगला चरण

भविष्य के लेख में, मैं मल्टी-हेड जीएटी लेयर के पीछे के तंत्र का वर्णन करूंगा, और हम लिंक भविष्यवाणी कार्य के लिए कुछ एप्लिकेशन देखेंगे।

संदर्भ

  • कोड का रनिंग संस्करण निम्नलिखित में उपलब्ध है नोटबुक. आपको एक डीजीएल कार्यान्वयन भी मिलेगा, जो कार्यान्वयन की शुद्धता की जांच करने के लिए उपयोगी है।
  • ग्राफ़ अटेंशन नेटवर्क्स पर पेटार वेलिस्कोविक, गुइलेम कुकुरुल, अरांत्सा कैसानोवा, एड्रियाना रोमेरो, पिएत्रो लीओ, योशुआ बेंगियोइस का मूल पेपर यहां उपलब्ध है। arXiv.
  • विषय की गहन व्याख्या के लिए, मैं वीडियो का भी सुझाव देता हूं अलेक्सा गोर्डिक.

यह आलेख मूलतः पर प्रकाशित हुआ था डेटा साइंस की ओर और लेखक से अनुमति के साथ TOPBOTS में फिर से प्रकाशित।

इस लेख का आनंद लें? अधिक AI अपडेट के लिए साइन अप करें।

जब हम अधिक तकनीकी शिक्षा जारी करते हैं तो हम आपको बताएंगे।

स्रोत: https://www.topbots.com/graph-attention-networks-under-the-hood/

समय टिकट:

से अधिक टॉपबॉट्स