<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>gauneg</title>
<link>https://gauneg.github.io/blogs.html</link>
<atom:link href="https://gauneg.github.io/blogs.xml" rel="self" type="application/rss+xml"/>
<description>Notes</description>
<generator>quarto-1.8.26</generator>
<lastBuildDate>Sun, 02 Aug 2026 23:00:00 GMT</lastBuildDate>
<item>
  <title>On Ontologies and their use</title>
  <dc:creator>gauneg </dc:creator>
  <link>https://gauneg.github.io/posts/thesis-excerpts/on_ontologies.html</link>
  <description><![CDATA[ 





<section id="ontology" class="level1">
<h1>Ontology</h1>
<p>The term <em>ontology</em> has its origins in philosophy, where it refers to a particular system of categories that accounts for a certain vision of the world. However, we limit our discussion to knowledge engineering, describing it in both theoretical and practical terms.</p>
<p>An ontology is an engineering artefact constituted by a specific vocabulary used to conceptualise a certain reality and a set of explicit assumptions about the intended meaning of the vocabulary.</p>
<section id="definitions-terminologies" class="level2">
<h2 class="anchored" data-anchor-id="definitions-terminologies">Definitions &amp; Terminologies</h2>
<p>We now introduce the essential terminology as formulated by <span class="citation" data-cites="guarino_1998">Guarino (1998)</span>. By establishing this rigorous theoretical foundation first, we can then smoothly transition to the practical frameworks required for applied ontology engineering.</p>
<section id="conceptualisation" class="level3">
<h3 class="anchored" data-anchor-id="conceptualisation">Conceptualisation</h3>
<p>The process of conceptualisation can be represented as the following ordered triple:</p>
<p><img src="https://latex.codecogs.com/png.latex?C=%5Clangle%20D,%20W,%20%5CRe%5Crangle"></p>
<p>where:</p>
<ul>
<li><img src="https://latex.codecogs.com/png.latex?D"> is the domain space, which is the set of all the elements.</li>
<li><img src="https://latex.codecogs.com/png.latex?W"> is a maximum set of states possible for all n-ary relations in <img src="https://latex.codecogs.com/png.latex?D">.</li>
<li><img src="https://latex.codecogs.com/png.latex?%5CRe"> conceptual relations on the domain space <img src="https://latex.codecogs.com/png.latex?%5Clangle%20D,W%20%5Crangle">.</li>
</ul>
</section>
<section id="ontological-commitment" class="level3">
<h3 class="anchored" data-anchor-id="ontological-commitment">Ontological Commitment</h3>
<p>In a logical language <img src="https://latex.codecogs.com/png.latex?L">, with a vocabulary <img src="https://latex.codecogs.com/png.latex?V">, we fix an intensional interpretation by means of a structure <img src="https://latex.codecogs.com/png.latex?%5Clangle%20C,%20%5CIm%5Crangle">, where <img src="https://latex.codecogs.com/png.latex?C=%5Clangle%20D,%20W,%20%5CRe%5Crangle"> is the conceptualisation and <img src="https://latex.codecogs.com/png.latex?%5CIm:V%5Crightarrow%20D%20%5Ccup%20%5CRe"> is a function assigning the elements of <img src="https://latex.codecogs.com/png.latex?D"> to constant symbols of <img src="https://latex.codecogs.com/png.latex?V">, and elements of <img src="https://latex.codecogs.com/png.latex?%5CRe"> to predicate symbols of <img src="https://latex.codecogs.com/png.latex?V">. This is the intensional interpretation of ontological commitment for <img src="https://latex.codecogs.com/png.latex?L">. We use <img src="https://latex.codecogs.com/png.latex?%5Ccup"> here, because <img src="https://latex.codecogs.com/png.latex?V"> is assigned to either <img src="https://latex.codecogs.com/png.latex?D"> or <img src="https://latex.codecogs.com/png.latex?%5CRe"> with function <img src="https://latex.codecogs.com/png.latex?%5CIm">. The function <img src="https://latex.codecogs.com/png.latex?%5CIm"> assigns meanings to vocabulary symbols by mapping constants to domain entities and predicate symbols to conceptual relations of the conceptualisation.</p>
<p>If <img src="https://latex.codecogs.com/png.latex?K=%5Clangle%20C,%20%5CIm%5Crangle"> is an ontological commitment for <img src="https://latex.codecogs.com/png.latex?L">, then <img src="https://latex.codecogs.com/png.latex?L"> commits to <img src="https://latex.codecogs.com/png.latex?C"> by means of <img src="https://latex.codecogs.com/png.latex?K">, while <img src="https://latex.codecogs.com/png.latex?C"> is the underlying conceptualisation of <img src="https://latex.codecogs.com/png.latex?K">.</p>
<section id="ontology-1" class="level4">
<h4 class="anchored" data-anchor-id="ontology-1">Ontology</h4>
<p>Given a language <img src="https://latex.codecogs.com/png.latex?L"> with ontological commitment <img src="https://latex.codecogs.com/png.latex?K">, an ontology for <img src="https://latex.codecogs.com/png.latex?L"> is a set of axioms designed in such a way that the set of its models approximates as best as possible the set of intended models of <img src="https://latex.codecogs.com/png.latex?L"> according to <img src="https://latex.codecogs.com/png.latex?K">. An ontology <img src="https://latex.codecogs.com/png.latex?O"> commits to <img src="https://latex.codecogs.com/png.latex?C"> if:</p>
<ol type="1">
<li><img src="https://latex.codecogs.com/png.latex?O"> has been designed to characterize <img src="https://latex.codecogs.com/png.latex?C">.</li>
<li><img src="https://latex.codecogs.com/png.latex?O"> approximates <img src="https://latex.codecogs.com/png.latex?C">.</li>
</ol>
<div id="fig-ontology-itself" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ontology-itself-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://gauneg.github.io/posts/thesis-excerpts/images/ontology_conceptualisation.png" class="img-fluid figure-img" style="width:100.0%">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ontology-itself-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Figure by <span class="citation" data-cites="guarino_1998">(Guarino 1998)</span>: The models <img src="https://latex.codecogs.com/png.latex?M(L)"> reflect its commitment to a conceptualisation and the ontology indirectly reflects this commitment by approximating this set of intended models
</figcaption>
</figure>
</div>
<p>With this framework an ontology is a formal, explicit description of concepts in a domain of discourse. It is a set of logical axioms that accounts for the intended meaning of a formal vocabulary.</p>
<p>While Guarino provides a rigorous theoretical framework, <span class="citation" data-cites="onto_101">Noy and Mcguinness (2001)</span> introduce a complementary vocabulary for practical, scalable ontology development. They state that an ontology defines a common vocabulary to facilitate information exchange within a domain. It includes machine-interpretable definitions of basic domain concepts and their relations. This practical description relies on the following foundational elements:</p>
<ul>
<li><strong>Concepts</strong>: These are the formal descriptions of the concepts in the domain of discourse. They are modelled in the ontology as classes.</li>
<li><strong>Properties</strong>: They describe various features and attributes of a concept; they are also called slots or roles.</li>
<li><strong>Facets</strong>: These are the role restrictions on the properties. The facet may apply these restrictions on either Value Type, Range of Values or Cardinality.</li>
<li><strong>Instances</strong>: The extensional realisations based on the intensional structures are called instances. For example, an ontology may define the class Car as an intensional concept that specifies the properties and structural characteristics that constitute cars. Individual vehicles, such as a particular <em>Kia Sportage</em>, correspond to instances that instantiate this class.</li>
<li><strong>Knowledge Base</strong>: The ontology, along with the instances of classes, forms a knowledge base.</li>
</ul>
</section>
</section>
</section>
<section id="types-of-ontologies" class="level2">
<h2 class="anchored" data-anchor-id="types-of-ontologies">Types of Ontologies</h2>
<p>Ontologies can be classified according to the accuracy with which they characterise the conceptualisation they commit to, existing along a continuum defined by:</p>
<ul>
<li><strong>Fine-grained Ontologies</strong>: A fine-grained ontology aims for maximum precision in describing the conceptualisation using a formal language. This is achieved by using more axioms, which limits the number of unintended models. It can also be achieved by adding more domains and relations, thereby increasing the complexity of the extensional structures that can accommodate such a dense ontological formulation.</li>
<li><strong>Coarse Ontologies</strong>: An ontology that opts for a minimal set of axioms and a simplified vocabulary. It allows for many unintended models and is built for efficiency, as fewer axioms or fewer domains and relations exist.</li>
</ul>
<p>Based on the level of generalisability, the ontologies can be classified into the following types:</p>
<ul>
<li><strong>Top-level ontologies</strong>: They describe general concepts which are independent of a particular problem or domain, space, time, matter, objects, events and actions. Basic Formal Ontology (<a href="https://basic-formal-ontology.org">BFO</a>), Descriptive Ontology for Linguistic and Cognitive Engineering (DOLCE) <span class="citation" data-cites="dolce_2022">(Borgo et al. 2022)</span> are examples of top-level ontologies.</li>
<li><strong>Domain ontologies</strong> and <strong>task ontologies</strong> describe the vocabulary related to a generic domain (like medicine, or automobiles) or a generic task or activity (like extracting, or selling). They do so by specialising the terms introduced in the top-level ontology.</li>
<li><strong>Application Ontologies</strong> utilise both domain and task ontologies to describe roles played by domain entities while performing a particular task.</li>
</ul>
</section>
<section id="ontology-development-using-knowledge-engineering-methodology" class="level2">
<h2 class="anchored" data-anchor-id="ontology-development-using-knowledge-engineering-methodology">Ontology Development using Knowledge Engineering Methodology</h2>
<p>There is no one correct method for modelling a domain. Among the viable alternatives, the suitability for the application and anticipated extensions determine the best solution. Getting to the optimal ontology is necessarily an iterative process.</p>
<p>The key decisions that drive the ontology development processes are: (i) Where will the ontology be applied, (ii) The level of granularity, which reflects the flexibility in the commitment to the conceptualisation required for ontology design, and (iii) Assessing the initial version against different conceptualisations in the field. The following steps form the basis of recommended steps for ontology development:</p>
<section id="step-1.-determine-the-domain-and-the-scope-of-the-ontology" class="level4">
<h4 class="anchored" data-anchor-id="step-1.-determine-the-domain-and-the-scope-of-the-ontology">STEP 1. Determine the domain and the scope of the ontology</h4>
<p>In this step, we determine: (i) the domain covered by the ontology, (ii) the purpose of the ontology, (iii) the types of questions to which the information in the ontology should provide an answer, and (iv) the users and maintainers of the ontology. One way to determine the scope of the ontology is to use competency questions <span class="citation" data-cites="survey_cq_2023">(Monfardini, Salamon, and Barcellos 2023)</span>. This is a set of questions that a knowledge base based on the ontology should be able to answer. Once defined, it can also be used to test the adequacy of a designed ontology.</p>
</section>
<section id="step-2.-accessing-existing-ontologies-for-suitability" class="level4">
<h4 class="anchored" data-anchor-id="step-2.-accessing-existing-ontologies-for-suitability">STEP 2. Accessing existing ontologies for suitability</h4>
<p>One should always consider using the existing ontology that can address the requirements. Only in the cases where no ontology exists should one be developed from scratch. If the existing ontology has addressable shortcomings, then it should be modified.</p>
</section>
<section id="step-3.-enumerate-important-terms-in-the-ontology" class="level4">
<h4 class="anchored" data-anchor-id="step-3.-enumerate-important-terms-in-the-ontology">STEP 3. Enumerate important terms in the ontology</h4>
<p>Initially, it is important to get a comprehensive list of terms without worrying about the overlap between the concepts they represent, relations among the terms or any properties of the concepts.</p>
</section>
<section id="step-4.-define-and-organise-classes-hierarchically" class="level4">
<h4 class="anchored" data-anchor-id="step-4.-define-and-organise-classes-hierarchically">STEP 4. Define and organise classes hierarchically</h4>
<p>The process of defining classes and organising the classes hierarchically during the ontology development can be executed using the following approaches:</p>
<ul>
<li><strong>Top-Down Development</strong>: It starts with the definition of the most general concepts first and then subsequently describes more specialised concepts. For example, if the goal is to develop classes for an ontology of wine and food, one would start with general concepts of <em>Wine</em> and <em>Food</em>, then move on to specialisation. The class <em>Wine</em> would be specialised by first creating its subclasses: <em>White Wine</em>, <em>Red wine</em> and <em>Rose Wine</em>. We can further categorise the <em>Red wine</em> class, for example, into <em>Syrah</em>, <em>Red Burgundy</em>, <em>Cabernet Sauvignon</em>, and so on, thereby moving toward even more specialised concepts.</li>
<li><strong>Bottom-Up Development</strong>: This approach starts with defining the specific classes as the leaves, then groups them and defines a general class. It is methodologically inverse to Top-Down Development, i.e., we would first define <em>Syrah</em>, <em>Red Burgundy</em>, and <em>Cabernet Sauvignon</em>, and then group them under a common superclass <em>Red Wine</em>.</li>
<li><strong>Combination Development</strong>: This approach integrates elements of both the bottom-up and top-down approaches by identifying the most important concepts first—whether general or specific—and then either specialising or generalising as necessary. For instance, one might start by defining key concepts such as <em>Cabernet Sauvignon</em> and <em>Wine</em>, and then expand into subclasses or generalise them, grouping related concepts as appropriate to create a more versatile structure.</li>
</ul>
</section>
<section id="step-5.-assign-properties-to-the-class-and-define-the-facets" class="level4">
<h4 class="anchored" data-anchor-id="step-5.-assign-properties-to-the-class-and-define-the-facets">STEP 5. Assign properties to the class and define the facets</h4>
<p>Once the classes are defined, the next step is to populate the slots or the properties of these classes. For the <em>Wine and Food</em> example the properties associated with the classes might represent <em>color</em>, <em>body</em>, <em>flavour</em>, <em>sugar</em>, <em>content</em>, etc. Once the properties are listed, they must be assigned to the relevant classes. There are two types of properties: (i) Data Property, which describes the intrinsic property of the class, and (ii) Object Property, which describes the relationship between two objects of different classes. The facets represent the specification of the values that can be used to populate the Data Properties. They can be one or all of the following:</p>
<ul>
<li><strong>Cardinality</strong>: It defines the number of values a property can have. It may be described by minimum (N) and maximum (M) cardinality to describe the number of slot values more precisely. Minimum cardinality of N means that a slot must have at least N values. For example, the grape slot of a Wine has a minimum cardinality of 1: each wine is made of at least one variety of grape.</li>
<li><strong>Value Type</strong>: It describes the type of data type of values the properties can take.</li>
<li><strong>Domain &amp; Range</strong>: Domain describes the classes that can use the data property, and range describes the restrictions in the property values.</li>
</ul>
</section>
</section>
<section id="applications-of-ontologies" class="level2">
<h2 class="anchored" data-anchor-id="applications-of-ontologies">Applications of Ontologies</h2>
<p>The scope and maturity of ontological applications vary considerably across fields, from large-scale biomedical terminologies to tightly scoped domain constructs, and understanding this landscape contextualises the role of more targeted ontological contributions such as the one developed in this thesis.</p>
<section id="large-scale-ontologies-with-multi-decade-maintenance" class="level3">
<h3 class="anchored" data-anchor-id="large-scale-ontologies-with-multi-decade-maintenance">Large Scale Ontologies with Multi-Decade Maintenance</h3>
<p>One of the most extensively developed families of applied ontologies is found in the biomedical sciences. The Open Biological and Biomedical Ontology (OBO) Foundry <span class="citation" data-cites="smithOBOFoundryCoordinated2007">(Smith et al. 2007)</span> provides a coordinated suite of interoperable ontologies, of which the Gene Ontology (GO) <span class="citation" data-cites="ashburnerGeneOntologyTool2000">(Ashburner et al. 2000)</span> is among the most widely used, providing a controlled vocabulary for biological processes, molecular functions, and cellular components across organisms. These biomedical ontologies are notable for both their scale (GO alone contains over 40,000 terms) and their institutional maintenance infrastructure, features that are rare outside the life sciences and that few domain-specific ontologies can be expected to replicate.</p>
<p>In the financial and legal domains, ontologies have attracted growing interest as a means of formalising regulatory and contractual knowledge. The Financial Industry Business Ontology (FIBO), developed by the Enterprise Data Management Council and standardised through the Object Management Group, provides a modular OWL-based representation of financial instruments, legal entities, and market processes <span class="citation" data-cites="bennettFinancialIndustryBusiness2013">(Bennett 2013)</span>. FIBO has been adopted by major financial institutions as a data governance framework, enabling cross-system interoperability and regulatory reporting. In the legal domain, efforts such as LegalRuleML <span class="citation" data-cites="athanLegalRuleMLDesignPrinciples2015">(Athan et al. 2015)</span> and the Legal Knowledge Interchange Format have sought to represent normative reasoning and deontic logic within formal ontological structures, though full-scale deployment in live legal systems remains limited. These applications underscore a common motivation: in high-stakes, highly structured domains, informal or purely statistical representations of knowledge are insufficient, and ontological precision serves a governance function as much as a scientific one.</p>
</section>
<section id="semantic-web-ontologies" class="level3">
<h3 class="anchored" data-anchor-id="semantic-web-ontologies">Semantic Web Ontologies</h3>
<p>The Semantic Web tradition has produced a third influential strand of ontological application, centred on the OWL and RDF standards <span class="citation" data-cites="debo_2004">(Mcguinness et al. 2004)</span> and realised at scale in projects such as DBpedia <span class="citation" data-cites="auerDBpediaNucleusWeb2007">(Auer et al. 2007)</span> and Wikidata. DBpedia, by extracting structured information from Wikipedia infoboxes and encoding it in RDF, made available a large, interlinked knowledge graph that has been used extensively in entity linking, question answering, and information retrieval research.</p>
</section>
<section id="natural-language-processing" class="level3">
<h3 class="anchored" data-anchor-id="natural-language-processing">Natural Language Processing</h3>
<p>In natural language processing and affective computing, ontological resources have played a similarly enabling role, though somewhat more modestly. SentiWordNet <span class="citation" data-cites="esuli2006sentiwordnet">(Esuli, Sebastiani, et al. 2006)</span> extended the WordNet lexical database with sentiment polarity scores, providing a structured resource for opinion mining that predated the widespread use of neural approaches. More recent work has sought to formalise opinion and affect at a structural level, moving beyond lexicons toward relational representations of the components of subjective language, a trajectory that informs the construction of the UOC ontology developed in this thesis.</p>
<p>It is important to acknowledge, however, that the utility of an ontology is not straightforwardly proportional to its scale. The large ontologies described above (GO, FIBO, DBpedia) are the products of decades of coordinated community effort, sustained institutional investment, and, in many cases, regulatory mandate. As opposed to these multi-decade domain-specific ontology infrastructures, the ontology developed in this thesis is a domain ontology of a modest scale. Its usefulness is intended for conceptual precision, which involves structural coherence within a targeted scope of opinion analysis.</p>
</section>
<section id="ontology-in-the-era-of-llms" class="level3">
<h3 class="anchored" data-anchor-id="ontology-in-the-era-of-llms">Ontology in the Era of LLMs</h3>
<p>This distinction has become particularly salient in the context of large language models and contemporary AI systems. LLMs, trained on vast corpora, have demonstrated remarkable capacity for implicit knowledge representation, raising the question of whether formal ontologies retain utility in an era of such models. The emerging consensus in the research literature suggests that they do, though the nature of that utility has shifted. Ontologies have been shown to improve LLM performance through structured prompting and retrieval-augmented generation, to provide interpretable scaffolding for knowledge graph construction and verification <span class="citation" data-cites="kommineniHumanExpertsMachines2024">(Kommineni, König-Ries, and Samuel 2024)</span>, and to serve as evaluation frameworks against which the implicit knowledge of language models can be assessed <span class="citation" data-cites="alivanistosPromptingProbingUsing2022">(Alivanistos et al. 2022)</span>. Rather than being supplanted by neural approaches, formal ontological representations increasingly function as complementary structures providing the explicit, verifiable semantics that distributional models alone cannot guarantee.</p>
<p>In NLP tasks specifically, where the boundaries between sentiment, opinion, and emotion are conceptually contested, ontological grounding offers a principled means of disambiguating constructs that might otherwise be conflated in purely data-driven frameworks.</p>



</section>
</section>
</section>

<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">References</h2><div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0">
<div id="ref-alivanistosPromptingProbingUsing2022" class="csl-entry">
Alivanistos, Dimitrios, Selene Báez Santamaría, Michael Cochez, Jan-Christoph Kalo, Emile van Krieken, and Thiviyan Thanapalasingam. 2022. <span>“Prompting as <span>Probing</span>: <span>Using</span> <span>Language</span> <span>Models</span> for <span>Knowledge</span> <span>Base</span> <span>Construction</span>.”</span> arXiv. <a href="https://doi.org/10.48550/ARXIV.2208.11057">https://doi.org/10.48550/ARXIV.2208.11057</a>.
</div>
<div id="ref-ashburnerGeneOntologyTool2000" class="csl-entry">
Ashburner, Michael, Catherine A. Ball, Judith A. Blake, David Botstein, Heather Butler, J. Michael Cherry, Allan P. Davis, et al. 2000. <span>“Gene <span>Ontology</span>: Tool for the Unification of Biology.”</span> <em>Nature Genetics</em> 25 (1): 25–29. <a href="https://doi.org/10.1038/75556">https://doi.org/10.1038/75556</a>.
</div>
<div id="ref-athanLegalRuleMLDesignPrinciples2015" class="csl-entry">
Athan, Tara, Guido Governatori, Monica Palmirani, Adrian Paschke, and Adam Wyner. 2015. <span>“<span>LegalRuleML</span>: <span>Design</span> <span>Principles</span> and <span>Foundations</span>.”</span> In <em>Reasoning <span>Web</span>. <span>Web</span> <span>Logic</span> <span>Rules</span></em>, edited by Wolfgang Faber and Adrian Paschke, 9203:151–88. Cham: Springer International Publishing. <a href="https://doi.org/10.1007/978-3-319-21768-0_6">https://doi.org/10.1007/978-3-319-21768-0_6</a>.
</div>
<div id="ref-auerDBpediaNucleusWeb2007" class="csl-entry">
Auer, Sören, Christian Bizer, Georgi Kobilarov, Jens Lehmann, Richard Cyganiak, and Zachary Ives. 2007. <span>“<span>DBpedia</span>: <span>A</span> <span>Nucleus</span> for a <span>Web</span> of <span>Open</span> <span>Data</span>.”</span> In <em>The <span>Semantic</span> <span>Web</span></em>, edited by David Hutchison, Takeo Kanade, Josef Kittler, Jon M. Kleinberg, Friedemann Mattern, John C. Mitchell, Moni Naor, et al., 4825:722–35. Berlin, Heidelberg: Springer Berlin Heidelberg. <a href="https://doi.org/10.1007/978-3-540-76298-0_52">https://doi.org/10.1007/978-3-540-76298-0_52</a>.
</div>
<div id="ref-bennettFinancialIndustryBusiness2013" class="csl-entry">
Bennett, Mike. 2013. <span>“The Financial Industry Business Ontology: <span>Best</span> Practice for Big Data.”</span> <em>Journal of Banking Regulation</em> 14 (3-4): 255–68. <a href="https://doi.org/10.1057/jbr.2013.13">https://doi.org/10.1057/jbr.2013.13</a>.
</div>
<div id="ref-dolce_2022" class="csl-entry">
Borgo, Stefano, Roberta Ferrario, Aldo Gangemi, Nicola Guarino, Claudio Masolo, Daniele Porello, Emilio M. Sanfilippo, and Laure Vieu. 2022. <span>“DOLCE: A Descriptive Ontology for Linguistic and Cognitive Engineering1.”</span> <em>Applied Ontology</em> 17 (1): 45–69. <a href="https://doi.org/10.3233/AO-210259">https://doi.org/10.3233/AO-210259</a>.
</div>
<div id="ref-esuli2006sentiwordnet" class="csl-entry">
Esuli, Andrea, Fabrizio Sebastiani, et al. 2006. <span>“Sentiwordnet: A Publicly Available Lexical Resource for Opinion Mining.”</span> In <em>LREC</em>, 6:417–22.
</div>
<div id="ref-guarino_1998" class="csl-entry">
Guarino, N. 1998. <em>Formal Ontology in Information Systems: Proceedings of the 1st International Conference June 6-8, 1998, Trento, Italy</em>. 1st ed. NLD: IOS Press.
</div>
<div id="ref-kommineniHumanExpertsMachines2024" class="csl-entry">
Kommineni, Vamsi Krishna, Birgitta König-Ries, and Sheeba Samuel. 2024. <span>“From Human Experts to Machines: <span>An</span> <span>LLM</span> Supported Approach to Ontology and Knowledge Graph Construction.”</span> arXiv. <a href="https://doi.org/10.48550/ARXIV.2403.08345">https://doi.org/10.48550/ARXIV.2403.08345</a>.
</div>
<div id="ref-debo_2004" class="csl-entry">
Mcguinness, Deborah, Deborah L, Frank Harmelen, and Frank. 2004. <span>“<span>OWL</span> Web Ontology Language—Overview,”</span> January.
</div>
<div id="ref-survey_cq_2023" class="csl-entry">
Monfardini, Glaice Kelly Q., Jordana S. Salamon, and Monalessa P. Barcellos. 2023. <span>“Use of Competency Questions in Ontology Engineering: A Survey.”</span> In <em>Conceptual Modeling</em>, edited by João Paulo A. Almeida, José Borbinha, Giancarlo Guizzardi, Sebastian Link, and Jelena Zdravkovic, 45–64. Cham: Springer Nature Switzerland.
</div>
<div id="ref-onto_101" class="csl-entry">
Noy, N., and Deborah Mcguinness. 2001. <span>“Ontology Development 101: A Guide to Creating Your First Ontology.”</span> <em>Knowledge Systems Laboratory</em> 32 (January).
</div>
<div id="ref-smithOBOFoundryCoordinated2007" class="csl-entry">
Smith, Barry, Michael Ashburner, Cornelius Rosse, Jonathan Bard, William Bug, Werner Ceusters, Louis J Goldberg, et al. 2007. <span>“The <span>OBO</span> <span>Foundry</span>: Coordinated Evolution of Ontologies to Support Biomedical Data Integration.”</span> <em>Nature Biotechnology</em> 25 (11): 1251–55. <a href="https://doi.org/10.1038/nbt1346">https://doi.org/10.1038/nbt1346</a>.
</div>
</div></section></div> ]]></description>
  <category>thesis-excerpts</category>
  <category>background</category>
  <category>ontology</category>
  <guid>https://gauneg.github.io/posts/thesis-excerpts/on_ontologies.html</guid>
  <pubDate>Sun, 02 Aug 2026 23:00:00 GMT</pubDate>
</item>
<item>
  <title>Message Passing Neural Network (GIN &amp; PNA)</title>
  <dc:creator>gauneg </dc:creator>
  <link>https://gauneg.github.io/posts/graph-neural-networks-(first-steps)/agg_graph.html</link>
  <description><![CDATA[ 





<div id="7a9a8f1e" class="cell" data-execution_count="1">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> torch_scatter <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> scatter</span>
<span id="cb1-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> functools <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> partial</span>
<span id="cb1-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> typing <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Optional, Dict, List</span>
<span id="cb1-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> torch_geometric.datasets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Planetoid</span>
<span id="cb1-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> torch.nn.functional <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> F</span>
<span id="cb1-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb1-7"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> seaborn <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> sns</span>
<span id="cb1-8"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> time</span>
<span id="cb1-9"></span>
<span id="cb1-10"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> datetime</span></code></pre></div></div>
</div>
<div id="6b93da0b" class="cell" data-execution_count="2">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1">dataset <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Planetoid(root<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tutorial1"</span>, name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Cora"</span>)</span>
<span id="cb2-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Cora Graphs, </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(dataset)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb2-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Classes: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>dataset<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>num_classes<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb2-4"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Features: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>dataset<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>num_features<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Cora Graphs, 1
Classes: 7
Features: 1433</code></pre>
</div>
</div>
<section id="isomorphism-topologically-identical" class="level2">
<h2 class="anchored" data-anchor-id="isomorphism-topologically-identical">Isomorphism: Topologically Identical</h2>
<section id="weisfeiler-lehman-isomorphism-test" class="level3">
<h3 class="anchored" data-anchor-id="weisfeiler-lehman-isomorphism-test">Weisfeiler-Lehman Isomorphism Test:</h3>
<p>A test to investigate isomorphism in graphs.</p>
<p><img src="https://latex.codecogs.com/png.latex?c_i%5E%7B(k)%7D%20=%20h%20%5Cbig(c_i%5E%7B(k-1)%7D,%20%5C%7Bc_j%5E%7B(k-1)%7D:j%5Cin%5Cmathcal%7BN%7D(i)%5C%7D%20%5Cbig)"></p>
<p>Note: ### <img src="https://latex.codecogs.com/png.latex?h">: injective function An injective function is also called a one-to-one function.</p>
<p><strong>Definition</strong>: A function <img src="https://latex.codecogs.com/png.latex?f"> is injective if it maps distinct inputs to distinct outputs.</p>
<p>i.e.&nbsp;If <img src="https://latex.codecogs.com/png.latex?x%20%5Cne%20y">, then <img src="https://latex.codecogs.com/png.latex?f(x)%20%5Cne%20f(y)"></p>
<hr>
</section>
</section>
<section id="graph-isomorphism-network-gin" class="level2">
<h2 class="anchored" data-anchor-id="graph-isomorphism-network-gin">Graph Isomorphism Network (GIN)</h2>
<p><a href="https://arxiv.org/pdf/1810.00826">paper</a></p>
<p>It is an attempt to answer whether we can construct a GNN as powerful as the WL Isomorphism test.</p>
<p><img src="https://latex.codecogs.com/png.latex?h_i%5E%7B(k)%7D%20=%20%5Cphi(h_i%5E%7B(k-1)%7D,%20f(%7Bh_j%5E%7B(k-1)%7D:%20j%20%5Cin%20%5Cmathcal%7BN%7D(i)%7D))%5Ctag%7Bi%7D"></p>
<p><img src="https://latex.codecogs.com/png.latex?k">: Hop-Counter and represents iterative steps or layer number. What it means intuitively is:</p>
<p><img src="https://latex.codecogs.com/png.latex?k=0">: Input features we start with</p>
<p><img src="https://latex.codecogs.com/png.latex?k=1">: The model looks at immediate neighbours</p>
<p><img src="https://latex.codecogs.com/png.latex?k=2">: The model looks at neighbours of neighbours.</p>
<p>The goal remains to select <img src="https://latex.codecogs.com/png.latex?%5Cphi"> and <img src="https://latex.codecogs.com/png.latex?f"> for are injective</p>
<p><a href="https://arxiv.org/pdf/1703.06114">Zaheer et al., (2017)</a> proved that an injective function on multisets can be decomposed as:</p>
<p><img src="https://latex.codecogs.com/png.latex?g(X)%20=%20%5Cphi(%5Csum_%7Bx%20%5Cin%20X%7D%20f(x))%5Ctag%7Bii%7D"></p>
<p>using (ii), (i) can be expressed as:</p>
<p><img src="https://latex.codecogs.com/png.latex?g(h,%20X)%20=%20%5Cphi%5Cbigg(%20(1+%5Cepsilon)%5Ccdot%20f(h)%20+%20%5Csum_%7Bx%20%5Cin%20X%7D%20f(x)%5Cbigg)"></p>
<p>we use <img src="https://latex.codecogs.com/png.latex?%5Ctext%7BMLP%7D"> to represent <img src="https://latex.codecogs.com/png.latex?%5Cphi%5Ccirc%20f">:</p>
<p><img src="https://latex.codecogs.com/png.latex?h_i%5E%7B(k)%7D%20=%20%5Ctext%7BMLP%7D%5E%7B(k)%7D%20%5Cbigg((1+%5Cepsilon%5E%7B(k)%7D)%5Ccdot%20h_i%5E%7B(k-1)%7D%20+%20%5Csum_%7Bj%5Cin%20%5Cmathcal%7BN%7D(i)%7Dh_j%7B(k-1)%7D%5Cbigg)"></p>
<p>The authors prove (in the GIN paper) that because MLPs are Universal Approximators, they can model the composition of functions.</p>
<p>MLP=(Linear + ActivationFunct + Linear)</p>
<section id="cons" class="level3">
<h3 class="anchored">Cons:</h3>
<ul>
<li>Highly discontinuous function.</li>
<li><h2 id="no-guarantee-to-find-the-right-function." class="anchored" data-anchor-id="cons">No guarantee to find the right function.</h2></li>
</ul>
</section>
</section>
<section id="principal-neighborhood-aggregation-pna" class="level2">
<h2 class="anchored" data-anchor-id="principal-neighborhood-aggregation-pna">Principal Neighborhood Aggregation (PNA)</h2>
<section id="primary-idea" class="level3">
<h3 class="anchored" data-anchor-id="primary-idea">Primary Idea:</h3>
<p>GNNs like Graph Convolution Network (GCN), Graph ATtention GAT, MPNN and GIN use only a single aggregation method with mean, sum and max aggregators being the most used. A limitation of this method is that aggregators fail to discriminate among messages when using a single GNN layer.</p>
<p>To address this, <a href="https://arxiv.org/pdf/2004.05718">Corso et al.&nbsp;(2020)</a> propose aggregators as continuous functions of multisets. These compute statistics—such as mean, max, or standard deviation—on neighboring nodes. The continuity of input spaces is emphasized: small input changes should yield small output changes for the aggregator.</p>
<p>They used the following aggregators: - Mean Aggregation <img src="https://latex.codecogs.com/png.latex?%5Cmu(X%5E%7Bl%7D)">: The most common message aggregator in the literature, wherein each node computes a weighted average or sum of its incoming messages. This can be calculated as: <img src="https://latex.codecogs.com/png.latex?%5Cmu(X%5E%7Bl%7D)%20=%20%5Cfrac%7B1%7D%7Bd_i%7D%20%5Csum_%7Bj%5Cin%20N(i)%7D%20X_j%5E%7Bl%7D"></p>
<pre><code>Where $i$: target node, $d_i$: Degree of $i$ node, $j \in N(i)$: all the neighbours of $ i$, $X^{l}$: features vector of a neighbour node $j$ at current layer l.</code></pre>
<ul>
<li><p>Maximum and Minimum Aggregations: <img src="https://latex.codecogs.com/png.latex?%5Ctext%7Bmax%7D_i(X%5El)%20=%20max_%7Bj%20%5Cin%20N(i)%7D%20X_j%5El">, <img src="https://latex.codecogs.com/png.latex?%5C;%5C;%5Ctext%7Bmin%7D_i(X%5El)%20=%20min_%7Bj%20%5Cin%20N(i)%7D%20X_j%5El"></p></li>
<li><p>Standard Deviation Aggregation: This is calculated as follows:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Csigma_i(X%5El)%20=%20%5Csqrt%7B%5Ctext%7BReLU%7D%20%5Cbig(%5Cmu_i(X%5E%7Bl%5E%7B2%7D%7D)%20-%20%5Cmu_i(X%5E%7Bl%7D)%20%5Cbig)%7D"></p>
<p>Here, mean and standard deviation describe the neighborhood by measuring the average and spread of node features. Higher moments, such as skewness (3rd) and kurtosis (4th), can provide more detail about the neighborhood’s shape. <img src="https://latex.codecogs.com/png.latex?%5Csqrt%5Bn%5D%7B%5Cmathbb%7BE%7D(X-M)%5En%7D,%20%5C;%5C;%20n%5Cgt1"></p></li>
</ul>
</section>
<section id="degree-based-scalers" class="level3">
<h3 class="anchored" data-anchor-id="degree-based-scalers">Degree-based scalers</h3>
<p>They also use scalers as functions of the number of messages being aggregated (usually the node degree), which are multiplied by the aggregated value to amplify or attenuate the incoming messages.</p>
<p><img src="https://latex.codecogs.com/png.latex?S%20=%20%5Cbigg(%20%5Cfrac%7Blog(d+1)%7D%7B%5Cdelta%7D%20%5Cbigg)%5E%7B%5Calpha%7D"></p>
<p>where, <img src="https://latex.codecogs.com/png.latex?%5Cdelta%20=%20%5Cfrac%7B1%7D%7B%7Ctrain%7C%7D%20%5Csum_%7Bi%20%5Cin%20train%7D%20log%20(d_i%20+%201)"> <img src="https://latex.codecogs.com/png.latex?%5Cdelta"> is a constant value</p>
<p><img src="https://latex.codecogs.com/png.latex?d"> -&gt; Nodes in the neighbourhood, <img src="https://latex.codecogs.com/png.latex?d_i">: Degree of incoming nodes of the neighbours.</p>
<p><img src="https://latex.codecogs.com/png.latex?S_%7Bamp%7D,%20%5Calpha=1">, <img src="https://latex.codecogs.com/png.latex?S_%7Batt%7D,%20%5Calpha=-1">, <img src="https://latex.codecogs.com/png.latex?S_%7Bidentity%7D"></p>
<!-- ```python
src * (torch.log(deg + 1) / avg_deg['log'])
``` -->
<p>Summation aggregation doesn’t generalise well to unseen graphs, as a small change in degree can amplify or attenuate the message and gradients exponentially. In PNA, using a logarithmic amplification <img src="https://latex.codecogs.com/png.latex?S%20%5Cpropto%20log(d+1)"> is proposed to reduce this effect.</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cbigoplus%20=%20%5Cbegin%7Bbmatrix%7D%20I%20%5C%5C%5C%20S(D,%20%5Calpha=1)%20%5C%5C%5C%20S(D,%20%5Calpha=-1)%20%5Cend%7Bbmatrix%7D%20%5Cotimes%20%5Cbegin%7Bbmatrix%7D%20%5Cmu%20%5C%5C%20%5Csigma%20%5C%5C%20%5Ctext%7Bmax%7D%20%5C%5C%20%5Ctext%7Bmin%7D%20%5Cend%7Bbmatrix%7D"></p>
<p>The PNA operator can then be realised in the framework of message passing, which includes edge features also:</p>
<p><img src="https://latex.codecogs.com/png.latex?X_i%5E%7Bt+1%7D%20=%20U%20%5Cbigg(X_i%5E%7B(t)%7D,%20%5Cbigoplus_%7B(j,i)%5Cin%20E%7D%20(X_i%5E%7B(t)%7D,%20E_%7Bj%20%5Crightarrow%20i%7D,%20X_j%5E%7B(t)%7D)%5Cbigg)"></p>
<p><img src="https://latex.codecogs.com/png.latex?E_%7Bj%20%5Crightarrow%20i%7D">: is the features of the edge <img src="https://latex.codecogs.com/png.latex?(j,%20i)">, <img src="https://latex.codecogs.com/png.latex?M"> and <img src="https://latex.codecogs.com/png.latex?U"> are neural networks. <img src="https://latex.codecogs.com/png.latex?U">: reduces the size of concatenated messages back to <img src="https://latex.codecogs.com/png.latex?%5Cmathbb%7BR%7D%5EF"> where <img src="https://latex.codecogs.com/png.latex?F"> is the dimension of the hidden features in the network.</p>
<figure class="figure">
<img src="https://gauneg.github.io/posts/graph-neural-networks-(first-steps)/pna_diag.png" alt="PNA Diagram" style="width:75%" class="figure-img">
<figcaption align="centre">
<b>Architecture Diagram of PNA from <a href="https://arxiv.org/pdf/2004.05718">Corso et al., (2020) </a> </b>
</figcaption>
</figure>
<div id="8f00b5e2" class="cell" data-execution_count="3">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb5-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb5-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> torch</span>
<span id="cb5-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> torch_geometric.typing <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Adj, OptTensor</span>
<span id="cb5-4"></span>
<span id="cb5-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> torch</span>
<span id="cb5-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> torch <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Tensor</span>
<span id="cb5-7"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> torch.nn <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> ModuleList, Sequential, Linear, ReLU</span>
<span id="cb5-8"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> torch_geometric.nn.conv <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> MessagePassing</span>
<span id="cb5-9"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> torch_geometric.nn.inits <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> reset</span>
<span id="cb5-10"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> torch_geometric.utils <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> degree, add_self_loops</span></code></pre></div></div>
</div>
<div id="1441130a" class="cell" data-execution_count="4">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb6-1">src_arr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.tensor(np.random.randint(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>))</span>
<span id="cb6-2">indexes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.tensor(np.random.randint(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>))</span></code></pre></div></div>
</div>
<div id="9d1aebe4" class="cell" data-execution_count="5">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb7-1"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'index:'</span>, indexes)</span>
<span id="cb7-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'src arr:'</span>, src_arr)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>index: tensor([1, 0, 0, 1, 2, 0, 0, 0, 1, 1])
src arr: tensor([33, 74, 81, 91, 41, 45, 68, 96, 76, 78])</code></pre>
</div>
</div>
<div id="9a6e5db2" class="cell" data-execution_count="6">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb9-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># we use torch_scatter as a mechanism to apply index-wise reduce operation.</span></span>
<span id="cb9-2">reduced_output <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> scatter(src<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>src_arr, index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>indexes, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">reduce</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sum"</span>)</span>
<span id="cb9-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(reduced_output)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>tensor([364, 278,  41])</code></pre>
</div>
</div>
</section>
</section>
<section id="implementation-from-pna-repository." class="level2">
<h2 class="anchored" data-anchor-id="implementation-from-pna-repository.">Implementation from <a href="https://github.com/lukecavabarrett/pna">PNA Repository</a>.</h2>
<ul>
<li>Aggregators And Scalars using <code>torch_scatter.scatter</code></li>
</ul>
<div id="b1a74bd7" class="cell" data-execution_count="7">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb11-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> aggregate_sum(src: Tensor, index: Tensor, dim_size: Optional[<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>]):</span>
<span id="cb11-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> scatter(src, index, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>, dim_size, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">reduce</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sum'</span>)</span>
<span id="cb11-3"></span>
<span id="cb11-4"></span>
<span id="cb11-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> aggregate_mean(src: Tensor, index: Tensor, dim_size: Optional[<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>]):</span>
<span id="cb11-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> scatter(src, index, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>, dim_size, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">reduce</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mean'</span>)</span>
<span id="cb11-7"></span>
<span id="cb11-8"></span>
<span id="cb11-9"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> aggregate_min(src: Tensor, index: Tensor, dim_size: Optional[<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>]):</span>
<span id="cb11-10">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> scatter(src, index, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>, dim_size, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">reduce</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'min'</span>)</span>
<span id="cb11-11"></span>
<span id="cb11-12"></span>
<span id="cb11-13"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> aggregate_max(src: Tensor, index: Tensor, dim_size: Optional[<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>]):</span>
<span id="cb11-14">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> scatter(src, index, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>, dim_size, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">reduce</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'max'</span>)</span>
<span id="cb11-15"></span>
<span id="cb11-16"></span>
<span id="cb11-17"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> aggregate_var(src, index, dim_size):</span>
<span id="cb11-18">    mean <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> aggregate_mean(src, index, dim_size)</span>
<span id="cb11-19">    mean_squares <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> aggregate_mean(src <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> src, index, dim_size)</span>
<span id="cb11-20">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> mean_squares <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> mean <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> mean</span>
<span id="cb11-21"></span>
<span id="cb11-22"></span>
<span id="cb11-23"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> aggregate_std(src, index, dim_size):</span>
<span id="cb11-24">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> torch.sqrt(torch.relu(aggregate_var(src, index, dim_size)) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1e-5</span>)</span>
<span id="cb11-25"></span>
<span id="cb11-26"></span>
<span id="cb11-27">AGGREGATORS <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb11-28">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sum'</span>: aggregate_sum,</span>
<span id="cb11-29">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mean'</span>: aggregate_mean,</span>
<span id="cb11-30">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'min'</span>: aggregate_min,</span>
<span id="cb11-31">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'max'</span>: aggregate_max,</span>
<span id="cb11-32">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'var'</span>: aggregate_var,</span>
<span id="cb11-33">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'std'</span>: aggregate_std,</span>
<span id="cb11-34">}</span>
<span id="cb11-35"></span>
<span id="cb11-36"></span>
<span id="cb11-37"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> scale_identity(src: torch.Tensor, deg: torch.Tensor, avg_deg: Dict[<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>]):</span>
<span id="cb11-38">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> src</span>
<span id="cb11-39"></span>
<span id="cb11-40"></span>
<span id="cb11-41"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> scale_amplification(src: torch.Tensor, deg: torch.Tensor, avg_deg: Dict[<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>]):</span>
<span id="cb11-42">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> src <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (torch.log(deg <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> avg_deg[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'log'</span>])</span>
<span id="cb11-43"></span>
<span id="cb11-44"></span>
<span id="cb11-45"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> scale_attenuation(src: torch.Tensor, deg: torch.Tensor, avg_deg: Dict[<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>]):</span>
<span id="cb11-46">    scale <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> avg_deg[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'log'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> torch.log(deg <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb11-47">    scale[deg <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb11-48">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> src <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> scale</span>
<span id="cb11-49"></span>
<span id="cb11-50"></span>
<span id="cb11-51"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> scale_linear(src: torch.Tensor, deg: torch.Tensor, avg_deg: Dict[<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>]):</span>
<span id="cb11-52">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> src <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (deg <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> avg_deg[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'lin'</span>])</span>
<span id="cb11-53"></span>
<span id="cb11-54"></span>
<span id="cb11-55"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> scale_inverse_linear(src: torch.Tensor, deg: torch.Tensor, avg_deg: Dict[<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>]):</span>
<span id="cb11-56">    scale <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> avg_deg[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'lin'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> deg</span>
<span id="cb11-57">    scale[deg <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb11-58">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> src <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> scale</span>
<span id="cb11-59"></span>
<span id="cb11-60"></span>
<span id="cb11-61">SCALERS <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb11-62">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'identity'</span>: scale_identity,</span>
<span id="cb11-63">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'amplification'</span>: scale_amplification,</span>
<span id="cb11-64">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'attenuation'</span>: scale_attenuation,</span>
<span id="cb11-65">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'linear'</span>: scale_linear,</span>
<span id="cb11-66">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'inverse_linear'</span>: scale_inverse_linear</span>
<span id="cb11-67">}</span></code></pre></div></div>
</div>
<ul>
<li>PNAConv Layer Implementation by inheriting <code>torch_geometric.nn.conv.MessagePassing</code></li>
</ul>
<div id="c7e2ee1e" class="cell" data-execution_count="8">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb12-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> PNAConvSimple(MessagePassing):</span>
<span id="cb12-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, in_channels: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>, out_channels: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>,</span>
<span id="cb12-3">                 aggregators: List[<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>], scalers: List[<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>], deg: Tensor,</span>
<span id="cb12-4">                 post_layers: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">**</span>kwargs):</span>
<span id="cb12-5">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">super</span>(PNAConvSimple, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>).<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(aggr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>, node_dim<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">**</span>kwargs)</span>
<span id="cb12-6">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.in_channels <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> in_channels <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#no of input channels</span></span>
<span id="cb12-7">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.out_channels <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> out_channels <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#no</span></span>
<span id="cb12-8">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.aggregators <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [AGGREGATORS[aggr] <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> aggr <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> aggregators]</span>
<span id="cb12-9">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.scalars <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [SCALERS[scale] <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> scale <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> scalers]</span>
<span id="cb12-10"></span>
<span id="cb12-11"></span>
<span id="cb12-12">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">## see what it does</span></span>
<span id="cb12-13">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.F_in <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> in_channels</span>
<span id="cb12-14">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.F_out <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> out_channels</span>
<span id="cb12-15"></span>
<span id="cb12-16">        deg <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> deg.to(torch.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>)</span>
<span id="cb12-17">        total_vertices <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> deg.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>()</span>
<span id="cb12-18">        bin_degrees <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.arange(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(deg)) <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># array of size deg</span></span>
<span id="cb12-19">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.avg_degrees <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb12-20">            <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"lin"</span> : (bin_degrees <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> deg).<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>total_vertices,</span>
<span id="cb12-21">            <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"log"</span> : (((bin_degrees <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>).log()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>deg).<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>total_vertices).item(), <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># this is the delta formula in the paper others are generalised versions of it</span></span>
<span id="cb12-22">            <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"exp"</span> : ((bin_degrees.exp()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>deg).<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>total_vertices).item()</span>
<span id="cb12-23">        }</span>
<span id="cb12-24">        in_channels <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(aggregators) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(scalers)) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.F_in <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 6 * 5 * in_channel</span></span>
<span id="cb12-25">        </span>
<span id="cb12-26">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">## this just stacks MLPs</span></span>
<span id="cb12-27">        modules <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [Linear(in_channels, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.F_out)] <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># just a linear layer</span></span>
<span id="cb12-28">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> _ <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(post_layers<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>):</span>
<span id="cb12-29">            modules <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> [ReLU()]</span>
<span id="cb12-30">            modules <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> [Linear(in_channels, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.F_out)]</span>
<span id="cb12-31">        </span>
<span id="cb12-32">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.post_nn <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Sequential(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>modules)</span>
<span id="cb12-33">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.reset_parameters()</span>
<span id="cb12-34"></span>
<span id="cb12-35">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> reset_parameters(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb12-36">        reset(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.post_nn)</span>
<span id="cb12-37"></span>
<span id="cb12-38">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> forward(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, x: Tensor, edge_index: Adj, edge_attr: OptTensor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> Tensor:</span>
<span id="cb12-39"></span>
<span id="cb12-40">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># propagate_type: (x: Tensor)</span></span>
<span id="cb12-41">        out <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.propagate(edge_index, x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>x, size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>)</span>
<span id="cb12-42">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.post_nn(out)</span>
<span id="cb12-43"></span>
<span id="cb12-44">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> message(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, x_j):</span>
<span id="cb12-45">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> x_j</span>
<span id="cb12-46"></span>
<span id="cb12-47">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> aggregate(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, inputs, index, dim_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>):</span>
<span id="cb12-48">        outs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [aggr(inputs, index, dim_size) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> aggr <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.aggregators]</span>
<span id="cb12-49">        out <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.cat(outs, dim<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb12-50">        deg <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> degree(index, dim_size, dtype<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>inputs.dtype).view(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb12-51">        outs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [sclr(out, deg, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.avg_degrees) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> sclr <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.scalars]</span>
<span id="cb12-52">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> torch.cat(outs, dim<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span></code></pre></div></div>
</div>
<ul>
<li>Using <code>PNAConvSimple</code> in a simple neural network for Node Classification</li>
</ul>
<div id="9d896d04" class="cell" data-execution_count="9">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb13-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">## Model using GCNN </span></span>
<span id="cb13-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> PNA_Network(torch.nn.Module):</span>
<span id="cb13-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, deg_histogram):</span>
<span id="cb13-4">        SCALERS <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'identity'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'amplification'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'attenuation'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'linear'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'inverse_linear'</span>]</span>
<span id="cb13-5">        AGGREGATORS <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sum'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mean'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'min'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'max'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'var'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'std'</span>]</span>
<span id="cb13-6">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">super</span>(PNA_Network, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>).<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>()</span>
<span id="cb13-7">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hid <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">32</span></span>
<span id="cb13-8">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.pna_layer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> PNAConvSimple(dataset.num_features, dataset.num_classes, AGGREGATORS, SCALERS, deg_histogram)</span>
<span id="cb13-9"></span>
<span id="cb13-10">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> forward(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, data):</span>
<span id="cb13-11">        x, edge_index <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data.x, data.edge_index</span>
<span id="cb13-12">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.dropout(x, p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6</span>, training<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.training)</span>
<span id="cb13-13">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># print(f"Input shape Conv1: {x.shape}")</span></span>
<span id="cb13-14">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.pna_layer(x, edge_index)</span>
<span id="cb13-15">        </span>
<span id="cb13-16">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> F.log_softmax(x, dim<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span></code></pre></div></div>
</div>
<div id="18cd4436" class="cell" data-execution_count="10">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb14-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># calculating deg histogram</span></span>
<span id="cb14-2">all_degrees <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb14-3"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> data <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> dataset:</span>
<span id="cb14-4">    all_degrees.append(degree(data.edge_index[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], dtype<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>torch.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">long</span>))</span>
<span id="cb14-5"></span>
<span id="cb14-6">all_degrees <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.cat(all_degrees)</span>
<span id="cb14-7">max_degree <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> all_degrees.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>().item()</span>
<span id="cb14-8">degree_hist <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.zeros(max_degree<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, dtype<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>torch.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">long</span>)</span>
<span id="cb14-9"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> deg <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> all_degrees:</span>
<span id="cb14-10">    degree_hist[deg] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb14-11"></span></code></pre></div></div>
</div>
<section id="degree-histogram" class="level3">
<h3 class="anchored" data-anchor-id="degree-histogram">Degree Histogram</h3>
<p>We require degree histogram when using PNA layer for calculating scalars.</p>
<div id="9ecaab4d" class="cell" data-execution_count="11">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb15-1">sns.set_style(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'whitegrid'</span>)</span>
<span id="cb15-2">fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots()</span>
<span id="cb15-3">x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.arange(degree_hist.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>])</span>
<span id="cb15-4">ax.bar(x, degree_hist)</span>
<span id="cb15-5">ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Node Degree"</span>)</span>
<span id="cb15-6">ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"No. of nodes"</span>)</span>
<span id="cb15-7">ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Degree Histogram'</span>)</span>
<span id="cb15-8">plt.show()</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://gauneg.github.io/posts/graph-neural-networks-(first-steps)/agg_graph_files/figure-html/cell-12-output-1.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
</div>
<div id="04472c79" class="cell" data-execution_count="12">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb16-1">model <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> PNA_Network(degree_hist)</span>
<span id="cb16-2">optimizer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.optim.Adam(model.parameters(), lr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.005</span>, weight_decay<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5e-4</span>)</span>
<span id="cb16-3">data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dataset[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span></code></pre></div></div>
</div>
<div id="6f2aae7c" class="cell" data-execution_count="14">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb17-1">start <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> time.process_time()</span>
<span id="cb17-2"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> epoch <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span>):</span>
<span id="cb17-3">    model.train()</span>
<span id="cb17-4">    optimizer.zero_grad()</span>
<span id="cb17-5">    out <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model(data)</span>
<span id="cb17-6">    loss <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.nll_loss(out[data.train_mask], data.y[data.train_mask])</span>
<span id="cb17-7">    </span>
<span id="cb17-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> epoch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>:</span>
<span id="cb17-9">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Time Elapsed: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>time<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>process_time() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> start<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">, Epoch: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>epoch<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">, loss: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>loss<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>item()<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb17-10">    loss.backward()</span>
<span id="cb17-11">    optimizer.step()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Time Elapsed: 2.681476000000001, Epoch: 0, loss: 1.9427117109298706
Time Elapsed: 483.15815299999997, Epoch: 200, loss: 0.012473355047404766
Time Elapsed: 965.493997, Epoch: 400, loss: 0.011228213086724281
Time Elapsed: 1449.137884, Epoch: 600, loss: 0.06128396838903427
Time Elapsed: 1929.509851, Epoch: 800, loss: 0.001116628060117364</code></pre>
</div>
</div>
</section>
<section id="gin-implementation" class="level3">
<h3 class="anchored" data-anchor-id="gin-implementation">GIN Implementation</h3>
<p>If all Aggregators except sum are removed and the central node is added using self loops. The PNA implementation can be reduced to an instance of GIN layer.</p>
<div id="1c283b1e" class="cell" data-execution_count="15">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb19-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> GINConvSimple(MessagePassing):</span>
<span id="cb19-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, in_channels: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>, out_channels: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>,                  </span>
<span id="cb19-3">                 post_layers: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">**</span>kwargs):</span>
<span id="cb19-4">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">super</span>(GINConvSimple, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>).<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(aggr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>, node_dim<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">**</span>kwargs)</span>
<span id="cb19-5">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.in_channels <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> in_channels <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#no of input channels</span></span>
<span id="cb19-6">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.out_channels <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> out_channels <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#no</span></span>
<span id="cb19-7"></span>
<span id="cb19-8">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># reducing aggregators to sum</span></span>
<span id="cb19-9">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.aggregators <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [AGGREGATORS[aggr] <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> aggr <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sum'</span>]]</span>
<span id="cb19-10"></span>
<span id="cb19-11">      </span>
<span id="cb19-12">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">## see what it does</span></span>
<span id="cb19-13">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.F_in <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> in_channels</span>
<span id="cb19-14">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.F_out <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> out_channels</span>
<span id="cb19-15"></span>
<span id="cb19-16">      </span>
<span id="cb19-17">        in_channels <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.F_in <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 6 * 5 * in_channel #adjustment based on scalars</span></span>
<span id="cb19-18">        </span>
<span id="cb19-19">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">## this just stacks MLPs</span></span>
<span id="cb19-20">        modules <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [Linear(in_channels, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.F_out)] <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># just a linear layer</span></span>
<span id="cb19-21">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> _ <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(post_layers<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>):</span>
<span id="cb19-22">            modules <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> [ReLU()]</span>
<span id="cb19-23">            modules <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> [Linear(in_channels, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.F_out)]</span>
<span id="cb19-24">        </span>
<span id="cb19-25">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.post_nn <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Sequential(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>modules)</span>
<span id="cb19-26">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.reset_parameters()</span>
<span id="cb19-27"></span>
<span id="cb19-28">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> reset_parameters(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb19-29">        reset(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.post_nn)</span>
<span id="cb19-30"></span>
<span id="cb19-31">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> forward(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, x: Tensor, edge_index: Adj, edge_attr: OptTensor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> Tensor:</span>
<span id="cb19-32"></span>
<span id="cb19-33">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># propagate_type: (x: Tensor)</span></span>
<span id="cb19-34">        edge_index, _ <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> add_self_loops(edge_index)</span>
<span id="cb19-35">        out <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.propagate(edge_index, x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>x, size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>)</span>
<span id="cb19-36">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.post_nn(out)</span>
<span id="cb19-37"></span>
<span id="cb19-38">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> message(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, x_j):</span>
<span id="cb19-39">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> x_j</span>
<span id="cb19-40"></span>
<span id="cb19-41">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> aggregate(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, inputs, index, dim_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>):</span>
<span id="cb19-42">        outs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [aggr(inputs, index, dim_size) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> aggr <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.aggregators]</span>
<span id="cb19-43">        </span>
<span id="cb19-44">        out <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.cat(outs, dim<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb19-45">        </span>
<span id="cb19-46">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># deg = degree(index, dim_size, dtype=inputs.dtype).view(-1, 1)</span></span>
<span id="cb19-47">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># outs = [sclr(out, deg, self.avg_degrees) for sclr in self.scalars]</span></span>
<span id="cb19-48">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> out</span>
<span id="cb19-49">    </span>
<span id="cb19-50"></span>
<span id="cb19-51"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> GIN_Network(torch.nn.Module):</span>
<span id="cb19-52">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb19-53">        </span>
<span id="cb19-54">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">super</span>(GIN_Network, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>).<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>()</span>
<span id="cb19-55">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hid <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">32</span></span>
<span id="cb19-56">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.pna_layer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> GINConvSimple(dataset.num_features, dataset.num_classes)</span>
<span id="cb19-57"></span>
<span id="cb19-58">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> forward(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, data):</span>
<span id="cb19-59">        x, edge_index <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data.x, data.edge_index</span>
<span id="cb19-60">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.dropout(x, p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6</span>, training<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.training)</span>
<span id="cb19-61">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># print(f"Input shape Conv1: {x.shape}")</span></span>
<span id="cb19-62">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.pna_layer(x, edge_index)</span>
<span id="cb19-63">        </span>
<span id="cb19-64">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> F.log_softmax(x, dim<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span></code></pre></div></div>
</div>
<div id="5419d903" class="cell" data-execution_count="16">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb20-1">model <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> GIN_Network()</span>
<span id="cb20-2">optimizer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.optim.Adam(model.parameters(), lr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.005</span>, weight_decay<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5e-4</span>)</span>
<span id="cb20-3">data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dataset[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span></code></pre></div></div>
</div>
<div id="df25c9af" class="cell" data-execution_count="17">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb21-1">start <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> time.process_time()</span>
<span id="cb21-2"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> epoch <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span>):</span>
<span id="cb21-3">    model.train()</span>
<span id="cb21-4">    optimizer.zero_grad()</span>
<span id="cb21-5">    out <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model(data)</span>
<span id="cb21-6">    loss <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.nll_loss(out[data.train_mask], data.y[data.train_mask])</span>
<span id="cb21-7">    </span>
<span id="cb21-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> epoch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>:</span>
<span id="cb21-9">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Time Elapsed: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>time<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>process_time() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> start<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">, Epoch: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>epoch<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">, loss: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>loss<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>item()<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb21-10">    loss.backward()</span>
<span id="cb21-11">    optimizer.step()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Time Elapsed: 0.2294729999998708, Epoch: 0, loss: 1.9651533365249634
Time Elapsed: 62.08905800000002, Epoch: 200, loss: 0.02035176381468773
Time Elapsed: 124.28675900000007, Epoch: 400, loss: 0.012289958074688911
Time Elapsed: 186.90790199999992, Epoch: 600, loss: 0.011557257734239101
Time Elapsed: 248.96050700000023, Epoch: 800, loss: 0.01037731021642685</code></pre>
</div>
</div>
</section>
</section>
<section id="note" class="level2">
<h2 class="anchored" data-anchor-id="note">NOTE</h2>
<p>The layers discussed are simplistic implementations for ease of understanding. In real-world scenarios, the use of PyTorch geometric implementation is recommended.</p>
<p>Pytorch Geometric Implementations - <a href="https://pytorch-geometric.readthedocs.io/en/latest/modules/nn.html#convolutional-layers">LINK</a></p>


</section>

 ]]></description>
  <category>graph-nn</category>
  <guid>https://gauneg.github.io/posts/graph-neural-networks-(first-steps)/agg_graph.html</guid>
  <pubDate>Mon, 15 Dec 2025 00:00:00 GMT</pubDate>
  <media:content url="https://gauneg.github.io/posts/graph-neural-networks-(first-steps)/pna_diag.png" medium="image" type="image/png" height="44" width="144"/>
</item>
<item>
  <title>Graph Convolution Network</title>
  <dc:creator>gauneg </dc:creator>
  <link>https://gauneg.github.io/posts/graph-neural-networks-(first-steps)/graphconv.html</link>
  <description><![CDATA[ 





<div id="1b5a841d" class="cell" data-execution_count="1">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> os</span>
<span id="cb1-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> torch</span>
<span id="cb1-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb1-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb1-5">plt.rcParams.update({<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'font.size'</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16</span>})</span>
<span id="cb1-6">N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span></span>
<span id="cb1-7"></span>
<span id="cb1-8"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> torch_geometric.nn <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> GCNConv, ChebConv</span>
<span id="cb1-9"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> torch_geometric.datasets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Planetoid</span>
<span id="cb1-10"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> torch.nn.functional <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> F</span></code></pre></div></div>
</div>
<section id="spectral-graph-convolutions" class="level1">
<h1>Spectral Graph Convolutions</h1>
<p>In a non-graph setting, we would apply a CNN (Convolutional Neural Network) to a 2- or 3-D matrix. Those would be Spatial Methods (Grids).</p>
<p>Applying the CNN grid methods is not possible on the Graphs by default; therefore, we turn to the Spectral Methods, which deal with frequencies and waves.</p>
<p><strong>The convolution theorem</strong> The convolution operation (<img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7Bv%7D%20*%20%5Cmathcal%7Bw%7D">) from the time domain can be transformed to a multiplication operation in the frequency domain. We can then invert it back to the original time domain, resulting in the convolution output. Based on this, we use: 1. Laplacian to transform the graph to the frequency domain. 2. The Laplacian of the graph has multiple components; we separate the wave components, which are the eigenvectors and use them for transforming the graph features to the frequency domain. 3. This proves to be a slow operation, so for computational efficiency, we use Chebyshev polynomials that allow us to perform an approximate equivalent of convolution directly in the spatial domain without ever calculating <img src="https://latex.codecogs.com/png.latex?U">, with just the Laplacian.</p>
<section id="fourier-transform" class="level2">
<h2 class="anchored" data-anchor-id="fourier-transform">Fourier Transform</h2>
<p>It is a mathematical function <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BF%7D">, that decomposes a function into its constituent frequencies.</p>
<p>Transformation <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BF%7D:%20%5Cmathbb%7BR%7D%5EN%20%5Crightarrow%20%5Cmathbb%7BR%7D%5EN">. It has the following property that makes it desirable to us:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BF%7D%5E%7B-1%7D(%5Cmathcal%7BF(%5Cnu)%7D)%20=%20%5Cmathcal%7Bv%7D">, i.e.&nbsp;<img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BF%7D"> is an Invertible function.</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BF%7D(%5Cmathcal%7Bv%7D%20*%20%5Cmathcal%7Bw%7D)%20=%20%5Cmathcal%7BF%7D(%5Cmathcal%7Bv%7D)%20%5Ccdot%20%5Cmathcal%7BF%7D(%5Cmathcal%7Bw%7D)">, i.e.&nbsp;It transforms convolution function into matrix multiplication function.</p>
<p>This implies <img src="https://latex.codecogs.com/png.latex?%5Cbegin%7Balign*%7D%0Av%20*%20w%20&amp;=%20%5Cmathcal%20F%5E%7B-1%7D(%5Cmathcal%20F%20(v%20*%20w))%5C%5C%0A&amp;=%20%5Cmathcal%20F%5E%7B-1%7D(%5Cmathcal%20F(v)%20%5Ccdot%20%5Cmathcal%20F(w))%0A%5Cend%7Balign*%7D"></p>
<section id="computing-fourier-transform" class="level3">
<h3 class="anchored" data-anchor-id="computing-fourier-transform">Computing Fourier Transform:</h3>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BF%7D(%5Cmathcal%7Bv%7D)%20=%20U%20%5Ccdot%5Cmathcal%7Bv%7D,%5C;%5C;%20%5Cmathcal%7BF%7D%5E%7B-1%7D%20=%20%5Cfrac%7B1%7D%7BN%7D%20U%5E%7BH%7D%20%5Ccdot%20%5Cmathcal%7Bv%7D%20%5Ctag%7Bi%7D"></p>
<p>where the <img src="https://latex.codecogs.com/png.latex?N%5Ctimes%20N"> matrix <img src="https://latex.codecogs.com/png.latex?U"> is defined as <img src="https://latex.codecogs.com/png.latex?%0A%5Cbegin%7Balign*%7D%0A%5C%5C%0AU%20=%0A%5Cbegin%7Bbmatrix%7D%0Au_0(0)%20&amp;%20u_1(0)%20&amp;%20%5Cdots%20&amp;%20u_%7BN-1%7D(0)%5C%5C%0Au_0(1)%20&amp;%20u_1(1)%20&amp;%20%5Cdots%20&amp;%20u_%7BN-1%7D(1)%5C%5C%0A%5Cvdots%20&amp;%20%5Cvdots&amp;%20&amp;%20%5Cvdots%5C%5C%0Au_0(N-1)%20&amp;%20u_1(N-1)%20&amp;%20%5Cdots%20&amp;%20u_%7BN-1%7D(N-1)%5C%5C%0A%5Cend%7Bbmatrix%7D%0A%5Cend%7Balign*%7D%20%5Ctag%7Bii%7D%0A"></p>
<p>And <img src="https://latex.codecogs.com/png.latex?u_n"> is calculated as:</p>
<p><img src="https://latex.codecogs.com/png.latex?u_n(x)=%20%5Ccos%5Cleft(2%20%5Cpi%20%5Cfrac%7Bn%7D%7BN%7D%20x%5Cright)%20-%20i%20%5Csin%5Cleft(2%20%5Cpi%20%5Cfrac%7Bn%7D%7BN%7D%20x%5Cright),%20%5Ctag%7Biii%7D"></p>
<div id="d9833a8b" class="cell" data-execution_count="2">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># implementation of u_{n} and the function to generate U i.e. eq ii</span></span>
<span id="cb2-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> matrix_U(N):</span>
<span id="cb2-3">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># generates tensors for x in 0 to N-1 for eq (iii), </span></span>
<span id="cb2-4">    u <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> n, N: np.cos(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.pi<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>N <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.arange(N)) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">1j</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.sin(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.pi<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>N <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> np.arange(N)) </span>
<span id="cb2-5">    U <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.empty((N, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>))</span>
<span id="cb2-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> n <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(N):</span>
<span id="cb2-7">        U <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.c_[U, u(n, N)] <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#stack each u as a column in U</span></span>
<span id="cb2-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> U</span>
<span id="cb2-9"></span>
<span id="cb2-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># implementing </span></span>
<span id="cb2-11"></span>
<span id="cb2-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> fourier_transform(v):</span>
<span id="cb2-13">    N <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> v.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb2-14">    U <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> matrix_U(N)</span>
<span id="cb2-15">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> U <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> v</span>
<span id="cb2-16"></span>
<span id="cb2-17"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> inverse_fourier_transform(v):</span>
<span id="cb2-18">    N <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> v.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb2-19">    U <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> matrix_U(N)</span>
<span id="cb2-20">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> (U.conj().transpose() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> v) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> N</span></code></pre></div></div>
</div>
</section>
</section>
<section id="graph-laplacian" class="level2">
<h2 class="anchored" data-anchor-id="graph-laplacian">Graph Laplacian</h2>
<p>It is computed as: <img src="https://latex.codecogs.com/png.latex?L%20=%20D%20-%20%20A"></p>
<p>where, <img src="https://latex.codecogs.com/png.latex?D">: The Degree Matrix, <img src="https://latex.codecogs.com/png.latex?A">: Adjacency Matrix</p>
<p>Laplacian is a measure of <em>“smoothness”</em>. When applied to a graph signal, it informs how much a node differs from the average of its neighbours. - Low Frequency: The signal changes slowly across the graph. (neighbors have very similar values) - High Frequency: The signal changes rapidly. (neighbors have very different values)</p>
</section>
<section id="convolution-on-a-graph" class="level2">
<h2 class="anchored" data-anchor-id="convolution-on-a-graph">Convolution on a Graph</h2>
<p>We using the graph’s <em>“waves”</em> (the matrix <img src="https://latex.codecogs.com/png.latex?U">), we can define convolution as: <img src="https://latex.codecogs.com/png.latex?%20%5Cmathcal%7Bv%7D%20*%20%5Cmathcal%7Bw%7D%20=%20U%20((U%5E%7BT%7D%5Cmathcal%7Bw%7D)%20%5Codot%20(U%5E%7BT%7D%5Cmathcal%7Bv%7D))"></p>
<p><strong>The Major Problem</strong>: Calculating <img src="https://latex.codecogs.com/png.latex?U"> (eigenvectors) requires decomposing a huge matrix <img src="https://latex.codecogs.com/png.latex?(N%C3%97N)">. For a graph with millions of nodes, this is computationally impossible.</p>
<section id="chebyshev-filters" class="level3">
<h3 class="anchored" data-anchor-id="chebyshev-filters">Chebyshev Filters</h3>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7Bv%7D%20*%20%5Cmathcal%7Bw%7D%20%5Capprox%20%5Csum_%7Bk=0%7D%5E%7BK%7D%20%5Ctheta_k%20%5Ccdot%20T_k(%5Ctilde%7BL%7D)x"></p>
<p><img src="https://latex.codecogs.com/png.latex?T_%7Bk+1%7D(x)%20+%20T_%7Bk-1%7D(x)%20=%202x%20%5Ccdot%20T_k(x)"></p>
<p><img src="https://latex.codecogs.com/png.latex?T_%7Bk+1%7D(x)%20=%202x%20%5Ccdot%20T_k(x)%20+%20T_%7Bk-1%7D(x)"></p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cimplies%20T_%7Bk%7D(x)%20=%202x%20%5Ccdot%20T_%7Bk-1%7D(x)%20-%20T_%7Bk-2%7D(x)"></p>
<p><strong>Using the first order Approximation i.e.&nbsp;K=1</strong></p>
<div id="75b35f50" class="cell" data-execution_count="3">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1">dataset <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Planetoid(root<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tutorial1"</span>, name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Cora"</span>)</span>
<span id="cb3-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Cora Graphs, </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(dataset)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb3-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Classes: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>dataset<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>num_classes<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb3-4"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Features: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>dataset<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>num_features<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Cora Graphs, 1
Classes: 7
Features: 1433</code></pre>
</div>
</div>
</section>
<section id="gcn-using-k1" class="level3">
<h3 class="anchored" data-anchor-id="gcn-using-k1">GCN (Using K=1)</h3>
<p>This type of GCN uses the following propagation proposed by <a href="https://arxiv.org/pdf/1609.02907">(Kipf &amp; Welling, 2017)</a>.</p>
<p><img src="https://latex.codecogs.com/png.latex?H%5E%7B(l+1)%7D%20=%20%5Csigma%20%5Cbigg(%20%5Ctilde%7BD%7D%5E%7B-%5Cfrac%7B1%7D%7B2%7D%7D%20%5Ctilde%7BA%7D%5Ctilde%7BD%7D%5E%7B-%5Cfrac%7B1%7D%7B2%7D%7D%20H%5E%7B(l)%7D%20W%5E%7B(l)%7D%5Cbigg)"></p>
<p>We get this by:</p>
<p><img src="https://latex.codecogs.com/png.latex?g_%7B%5Ctheta%7D%20*%20x%20%5Capprox%20%5Csum_%7Bk=0%7D%5E%7BK%7D%20%5Ctheta_k%20%5Ccdot%20T_k(%5Ctilde%7BL%7D)x"></p>
<p>at <img src="https://latex.codecogs.com/png.latex?k=0">, <img src="https://latex.codecogs.com/png.latex?g_%7B%5Ctheta%7D%20*%20x%20%5Capprox%20%5Ctheta_%7B0%7D%20%5Ccdot%20T_%7B0%7D(%5Ctilde%7BL%7D)%20=%20I"></p>
<p>at <img src="https://latex.codecogs.com/png.latex?k=1">, <img src="https://latex.codecogs.com/png.latex?g_%7B%5Ctheta%7D%20*%20x%20%5Capprox%20%5Ctheta_%7B1%7D%20%5Ccdot%20T_%7B1%7D(%5Ctilde%7BL%7D)%20=%20%5Ctilde%7BL%7D"></p>
<p>The equation becomes:</p>
<p><img src="https://latex.codecogs.com/png.latex?g_%7B%5Ctheta%7D%20*%20x%20%5Capprox%20%5Ctheta_%7B0%7D%20%5Ccdot%20I%20%5Ccdot%20x%20+%20%5Ctheta_%7B1%7D%5Ccdot%5Ctilde%7BL%7D%5Ccdot%20x%20%5Ctag%7Bi%7D"></p>
<p><img src="https://latex.codecogs.com/png.latex?%5Clambda"> represents the Eigenvalues (frequencies) of the Laplacian: - <img src="https://latex.codecogs.com/png.latex?%5Clambda_%7Bmin%7D"> = 0: (Lowest frequency, i.e.&nbsp;constant signal) - <img src="https://latex.codecogs.com/png.latex?%5Clambda_%7Bmax%7D%20=">: Highest frequency (sharpest changes between neighbours)</p>
<p>The Chebyshev polynomials are only valid and stable if the input <img src="https://latex.codecogs.com/png.latex?x"> is between -1 and 1. However, eigenvalues are between 0 to <img src="https://latex.codecogs.com/png.latex?%5Clambda_%7Bmax%7D">. We fix it by <img src="https://latex.codecogs.com/png.latex?%5Cfrac%7B1%7D%7B%5Clambda_%7Bmax%7D%7D">.</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Ctilde%7BL%7D%20=%20%5Cfrac%7B2%7D%7B%5Clambda_%7Bmax%7D%7D%20L%20-%20I">, It was shown by (Kipf &amp; Welling, 2017) that <img src="https://latex.codecogs.com/png.latex?%5Clambda_%7Bmax%7D%20%5Capprox%202">.</p>
<p>substituting in <img src="https://latex.codecogs.com/png.latex?(%5Ctext%7Bi%7D)"></p>
<p><img src="https://latex.codecogs.com/png.latex?g_%7B%5Ctheta%7D%20*%20x%20%5Capprox%20%5Ctheta_%7B0%7D%20%5Ccdot%20x%20+%20%5Ctheta_%7B1%7D%5Ccdot%20(L%20-%20I)%20%5Ccdot%20x"></p>
<p>since, <img src="https://latex.codecogs.com/png.latex?L%20=%20I%20-%20D%5E%7B-%5Cfrac%7B1%7D%7B2%7D%7D%20A%20D%5E%7B-%5Cfrac%7B1%7D%7B2%7D%7D"></p>
<p><img src="https://latex.codecogs.com/png.latex?g_%7B%5Ctheta%7D%20*%20x%20%5Capprox%20%5Ctheta_%7B0%7D%20%5Ccdot%20x%20+%20%5Ctheta_%7B1%7D%5Ccdot%20(I%20-%20D%5E%7B-%5Cfrac%7B1%7D%7B2%7D%7D%20A%20D%5E%7B-%5Cfrac%7B1%7D%7B2%7D%7D%20-%20I)%20%5Ccdot%20x"></p>
<p><img src="https://latex.codecogs.com/png.latex?g_%7B%5Ctheta%7D%20*%20x%20%5Capprox%20%5Ctheta_%7B0%7D%20%5Ccdot%20x%20-%20%5Ctheta_%7B1%7D%5Ccdot%20(%20D%5E%7B-%5Cfrac%7B1%7D%7B2%7D%7D%20A%20D%5E%7B-%5Cfrac%7B1%7D%7B2%7D%7D)%20%5Ccdot%20x"></p>
<p>sharing the weight parameters <img src="https://latex.codecogs.com/png.latex?%5Ctheta%20=%20%5Ctheta_0%20=%20-%5Ctheta_1"></p>
<p><img src="https://latex.codecogs.com/png.latex?g_%7B%5Ctheta%7D%20*%20x%20%5Capprox%20%5Ctheta(I%20+%20D%5E%7B-%5Cfrac%7B1%7D%7B2%7D%7D%20A%20D%5E%7B-%5Cfrac%7B1%7D%7B2%7D%7D)%20%5Ccdot%20x"></p>
<p>We add the Identity matrix before normalisation instead of adding identity marix <img src="https://latex.codecogs.com/png.latex?I"> separately we add the self-loop as just another edge in the graph. <img src="https://latex.codecogs.com/png.latex?%5Ctilde%7BA%7D">: New adjacency matrix with self loop and <img src="https://latex.codecogs.com/png.latex?%5Ctilde%7BD%7D">: New diagonal matrix.</p>
<p>The final propagation becomes:</p>
<p><img src="https://latex.codecogs.com/png.latex?%20H(l+1)%20=%20%5Csigma%5Cbigg(%20%5Ctilde%7BD%7D%5E%7B-%5Cfrac%7B1%7D%7B2%7D%7D%20%5Ctilde%7BA%7D%20%5Ctilde%7BD%7D%5E%7B-%5Cfrac%7B1%7D%7B2%7D%7D%20H%5E%7Bl%7D%20W%5E%7Bl%7D%5Cbigg)"></p>
<div id="63d868a7" class="cell" data-execution_count="4">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb5-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">## Model using GCNN </span></span>
<span id="cb5-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> GCNN_Network(torch.nn.Module):</span>
<span id="cb5-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb5-4">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">super</span>(GCNN_Network, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>).<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>()</span>
<span id="cb5-5">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hid <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">32</span></span>
<span id="cb5-6">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.conv1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> GCNConv(dataset.num_features, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hid)</span>
<span id="cb5-7">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.conv2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> GCNConv(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hid, dataset.num_classes)</span>
<span id="cb5-8"></span>
<span id="cb5-9">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> forward(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, data):</span>
<span id="cb5-10">        x, edge_index <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data.x, data.edge_index</span>
<span id="cb5-11">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.dropout(x, p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6</span>, training<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.training)</span>
<span id="cb5-12">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># print(f"Input shape Conv1: {x.shape}")</span></span>
<span id="cb5-13">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.conv1(x, edge_index)</span>
<span id="cb5-14">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># print(f"Output shape Conv1, hidden-&gt;{self.hid} : output-&gt;{x.shape}")</span></span>
<span id="cb5-15">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.elu(x)</span>
<span id="cb5-16">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.dropout(x, p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6</span>, training<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.training)</span>
<span id="cb5-17">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.conv2(x, edge_index)</span>
<span id="cb5-18">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># print(f"Output shape Conv2, heads : {x.shape}")</span></span>
<span id="cb5-19">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> F.log_softmax(x, dim<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span></code></pre></div></div>
</div>
<div id="ab2a6fce" class="cell" data-execution_count="5">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb6-1">model <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> GCNN_Network()</span>
<span id="cb6-2">optimizer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.optim.Adam(model.parameters(), lr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.005</span>, weight_decay<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5e-4</span>)</span>
<span id="cb6-3">data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dataset[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span></code></pre></div></div>
</div>
<div id="b08505cb" class="cell" data-execution_count="6">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb7-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> epoch <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span>):</span>
<span id="cb7-2">    model.train()</span>
<span id="cb7-3">    optimizer.zero_grad()</span>
<span id="cb7-4">    out <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model(data)</span>
<span id="cb7-5">    loss <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.nll_loss(out[data.train_mask], data.y[data.train_mask])</span>
<span id="cb7-6">    </span>
<span id="cb7-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> epoch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>:</span>
<span id="cb7-8">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(loss)</span>
<span id="cb7-9">    loss.backward()</span>
<span id="cb7-10">    optimizer.step()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>tensor(1.9614, grad_fn=&lt;NllLossBackward0&gt;)
tensor(0.0526, grad_fn=&lt;NllLossBackward0&gt;)
tensor(0.0276, grad_fn=&lt;NllLossBackward0&gt;)
tensor(0.0156, grad_fn=&lt;NllLossBackward0&gt;)
tensor(0.0157, grad_fn=&lt;NllLossBackward0&gt;)</code></pre>
</div>
</div>
</section>
<section id="chebyshev-conv-using-k1" class="level3">
<h3 class="anchored" data-anchor-id="chebyshev-conv-using-k1">Chebyshev Conv (using K&gt;1)</h3>
<p>It considers more neighbours, as K&gt;1.</p>
<div id="eed9773b" class="cell" data-execution_count="11">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb9-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">## Model using GCNN </span></span>
<span id="cb9-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> ChebConv_Network(torch.nn.Module):</span>
<span id="cb9-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb9-4">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">super</span>(ChebConv_Network, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>).<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>()</span>
<span id="cb9-5">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hid <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">32</span></span>
<span id="cb9-6">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.conv1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ChebConv(dataset.num_features, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hid, K<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb9-7">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.conv2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ChebConv(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hid, dataset.num_classes, K<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="cb9-8"></span>
<span id="cb9-9">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> forward(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, data):</span>
<span id="cb9-10">        x, edge_index <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data.x, data.edge_index</span>
<span id="cb9-11">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.dropout(x, p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6</span>, training<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.training)</span>
<span id="cb9-12">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># print(f"Input shape Conv1: {x.shape}")</span></span>
<span id="cb9-13">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.conv1(x, edge_index)</span>
<span id="cb9-14">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># print(f"Output shape Conv1, hidden-&gt;{self.hid} : output-&gt;{x.shape}")</span></span>
<span id="cb9-15">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.elu(x)</span>
<span id="cb9-16">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.dropout(x, p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6</span>, training<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.training)</span>
<span id="cb9-17">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.conv2(x, edge_index)</span>
<span id="cb9-18">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># print(f"Output shape Conv2, heads : {x.shape}")</span></span>
<span id="cb9-19">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> F.log_softmax(x, dim<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span></code></pre></div></div>
</div>
<div id="4a1488cf" class="cell" data-execution_count="12">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb10-1">model <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ChebConv_Network()</span>
<span id="cb10-2">optimizer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.optim.Adam(model.parameters(), lr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.005</span>, weight_decay<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5e-4</span>)</span>
<span id="cb10-3">data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dataset[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span></code></pre></div></div>
</div>
<div id="7d920960" class="cell" data-execution_count="13">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb11-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> epoch <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span>):</span>
<span id="cb11-2">    model.train()</span>
<span id="cb11-3">    optimizer.zero_grad()</span>
<span id="cb11-4">    out <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model(data)</span>
<span id="cb11-5">    loss <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.nll_loss(out[data.train_mask], data.y[data.train_mask])</span>
<span id="cb11-6">    </span>
<span id="cb11-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> epoch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>:</span>
<span id="cb11-8">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(loss)</span>
<span id="cb11-9">    loss.backward()</span>
<span id="cb11-10">    optimizer.step()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>tensor(2.1998, grad_fn=&lt;NllLossBackward0&gt;)
tensor(0.0090, grad_fn=&lt;NllLossBackward0&gt;)
tensor(0.0222, grad_fn=&lt;NllLossBackward0&gt;)
tensor(0.0101, grad_fn=&lt;NllLossBackward0&gt;)
tensor(0.0084, grad_fn=&lt;NllLossBackward0&gt;)</code></pre>
</div>
</div>


</section>
</section>
</section>

 ]]></description>
  <category>graph-nn</category>
  <guid>https://gauneg.github.io/posts/graph-neural-networks-(first-steps)/graphconv.html</guid>
  <pubDate>Mon, 08 Dec 2025 00:00:00 GMT</pubDate>
  <media:content url="https://gauneg.github.io/posts/graph-neural-networks-(first-steps)/gcn.png" medium="image" type="image/png" height="71" width="144"/>
</item>
<item>
  <title>Introduction to Graph Neural Networks (GNN)</title>
  <dc:creator>gauneg </dc:creator>
  <link>https://gauneg.github.io/posts/graph-neural-networks-(first-steps)/dataproc_for_graphs.html</link>
  <description><![CDATA[ 





<section id="essential-components" class="level1">
<h1>Essential Components</h1>
<p>The two essential components required for GNNs are:</p>
<ol type="1">
<li>Node Features</li>
<li>Adjacency Matrix (Relationships between Nodes)</li>
</ol>
</section>
<section id="minimal-terminologies" class="level1">
<h1>Minimal Terminologies</h1>
<ul>
<li><p>Node Degree: No of edges on a node. (In-Degree, Out-Degree)</p></li>
<li><p>Centrality: Measure of node’s structural importance. It has multiple types:</p>
<ul>
<li>Betweenness Centrality: How often does the node acts as a bridge along the shortest path between two other nodes.</li>
<li>Closeness Centrality: Average Distance from the node to all other reachable nodes in the graph.</li>
<li>Eigenvector Centrality: Measure of influence. A node connected to many high-degree nodes has high eigenvector centrality than a node connected to many low-degree nodes.</li>
</ul></li>
<li><p>Graph Density: Undirected Graph <img src="https://latex.codecogs.com/png.latex?%5Ctext%7BDensity%7D%20=%20%5Cfrac%7B2%20%7CE%7C%7D%7B%7CV%7C%5Ctimes(%7CV%7C-1)%7D"> if Density is approx ~1.0 it is dense, ~0 spase.</p></li>
</ul>
<div id="9e8e00d1" class="cell" data-execution_count="1">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> torch_geometric</span>
<span id="cb1-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> torch_geometric.datasets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Planetoid</span>
<span id="cb1-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> torch_geometric.nn <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> SAGEConv, GATConv</span>
<span id="cb1-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> torch.nn.functional <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> F</span>
<span id="cb1-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> torch</span></code></pre></div></div>
</div>
<div id="0e569ff3" class="cell" data-execution_count="2">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1">dataset <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Planetoid(root<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tutorial1"</span>, name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Cora"</span>)</span>
<span id="cb2-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Cora Graphs, </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(dataset)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb2-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Classes: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>dataset<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>num_classes<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb2-4"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Features: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>dataset<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>num_features<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>Cora Graphs, 1
Classes: 7
Features: 1433</code></pre>
</div>
</div>
</section>
<section id="graph-attention-network-gat" class="level1">
<h1>Graph Attention Network (GAT)</h1>
<section id="implementing-steps-of-gat-simple" class="level2">
<h2 class="anchored" data-anchor-id="implementing-steps-of-gat-simple">Implementing steps of GAT (simple)</h2>
<p>STEPS:</p>
<ol type="1">
<li>Linear Transformation</li>
<li>Attention Calculation</li>
<li>Weighing input with attention weight</li>
</ol>
<section id="step-1" class="level3">
<h3 class="anchored" data-anchor-id="step-1">STEP 1</h3>
<p><img src="https://latex.codecogs.com/png.latex?W"> is initialized for linear projections</p>
<p><img src="https://latex.codecogs.com/png.latex?h"> here is <img src="https://latex.codecogs.com/png.latex?h_i"> -&gt; Linear projections obtained by <img src="https://latex.codecogs.com/png.latex?h_i%20=%20W%20%5Ctimes%20I"></p>
<div id="18b68b26" class="cell" data-execution_count="3">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1">in_features <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span></span>
<span id="cb4-2">out_features <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb4-3">nb_nodes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span>
<span id="cb4-4"></span>
<span id="cb4-5">W <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.nn.Parameter(torch.zeros(size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(in_features, out_features)))</span>
<span id="cb4-6">torch.nn.init.xavier_uniform(W.data, gain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.414</span>)</span>
<span id="cb4-7">inpx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.rand(nb_nodes, in_features)</span>
<span id="cb4-8">h <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.mm(inpx, W)</span>
<span id="cb4-9"></span>
<span id="cb4-10">N <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> h.size()[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span></code></pre></div></div>
<div class="cell-output cell-output-stderr">
<pre><code>/var/folders/kr/021dhy4100546918_56lpp4m0000gn/T/ipykernel_14371/2968647810.py:6: UserWarning: nn.init.xavier_uniform is now deprecated in favor of nn.init.xavier_uniform_.
  torch.nn.init.xavier_uniform(W.data, gain=1.414)</code></pre>
</div>
</div>
</section>
<section id="step-2-attention-implementation" class="level3">
<h3 class="anchored" data-anchor-id="step-2-attention-implementation">STEP 2 : Attention Implementation</h3>
<section id="initialising-parameters" class="level4">
<h4 class="anchored" data-anchor-id="initialising-parameters">2.1 Initialising Parameters</h4>
<p><img src="https://latex.codecogs.com/png.latex?a">: Parameters for attention calculation</p>
<p><img src="https://latex.codecogs.com/png.latex?a_%7B%5Ctext%7Binput%7D%7D">: Cartesian of the graph nodes, i.e.&nbsp;The connection of every node to every other node. I think, how the attention will be used to express the relationships between the node is by modifying the weights of these connection matrix (sort of adjacency matrix) but with the properties of relationship learnt in these numbers.</p>
<div id="58f47d22" class="cell" data-execution_count="4">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb6-1">a <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.nn.Parameter(torch.zeros(size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>out_features, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)))</span>
<span id="cb6-2">torch.nn.init.xavier_normal(a.data, gain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.414</span>)</span>
<span id="cb6-3"></span>
<span id="cb6-4">leaky_relu <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.nn.LeakyReLU(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2</span>)</span>
<span id="cb6-5">a_input <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.cat([h.repeat(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, N).view(N <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> N, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>), h.repeat(N, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)], dim<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>).view(N, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> out_features)</span>
<span id="cb6-6"></span>
<span id="cb6-7">e <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> leaky_relu(torch.matmul(a_input, a).squeeze(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>))</span></code></pre></div></div>
<div class="cell-output cell-output-stderr">
<pre><code>/var/folders/kr/021dhy4100546918_56lpp4m0000gn/T/ipykernel_14371/732829903.py:2: UserWarning: nn.init.xavier_normal is now deprecated in favor of nn.init.xavier_normal_.
  torch.nn.init.xavier_normal(a.data, gain=1.414)</code></pre>
</div>
</div>
</section>
<section id="calculating-attention-values" class="level4">
<h4 class="anchored" data-anchor-id="calculating-attention-values">2.2 Calculating attention values</h4>
<ol type="1">
<li><p><img src="https://latex.codecogs.com/png.latex?a_%7B%5Ctext%7Blogit%7D%7D%20=%20a_%7B%5Ctext%7Binput%7D%7D%5Ctimes%20a"></p></li>
<li><p>Leaky Relu activation (E), <img src="https://latex.codecogs.com/png.latex?E%20=%20ReLU_%7B%5Ctext%7Bleaky%7D%7D(a_%7B%5Ctext%7Blogit%7D%7D)"></p></li>
</ol>
<div id="2ef42de0" class="cell" data-execution_count="5">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb8-1">e.shape, inpx.shape</span></code></pre></div></div>
<div class="cell-output cell-output-display" data-execution_count="5">
<pre><code>(torch.Size([3, 3]), torch.Size([3, 5]))</code></pre>
</div>
</div>
<div id="a6a82c70" class="cell" data-execution_count="6">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb10-1"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(a_input.shape, a.shape)</span>
<span id="cb10-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>)</span>
<span id="cb10-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(torch.matmul(a_input, a).shape)</span>
<span id="cb10-4"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>)</span>
<span id="cb10-5"></span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>torch.Size([3, 3, 4]) torch.Size([4, 1])

torch.Size([3, 3, 1])
</code></pre>
</div>
</div>
</section>
<section id="masked-attention" class="level4">
<h4 class="anchored" data-anchor-id="masked-attention">2.3 Masked Attention</h4>
<p>It is different than the mask in Bert, here masking is not continuous tokens, for mostly padding, but here it is used for marking connections using Adjacency Matrix.</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Ctilde%7BE%7D%20=%20E%20%5Codot%20A%20+%20(-%5Cinfty)%20%5Ccdot%20(1-A)"></p>
<p>The following snippet implements it:</p>
<ul>
<li>Generates a matrix with size <img src="https://latex.codecogs.com/png.latex?E">, with a very large negative (<img src="https://latex.codecogs.com/png.latex?-%5Cinfty">) value</li>
<li>Flip the mask and populate it with <img src="https://latex.codecogs.com/png.latex?-%5Cinfty"> values i.e.&nbsp;replace (<img src="https://latex.codecogs.com/png.latex?0%20%5Crightarrow%20-%5Cinfty">)</li>
</ul>
<div id="b2312f0c" class="cell" data-execution_count="7">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb12-1">adj <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.randint(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>))</span>
<span id="cb12-2">zero_vec  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9e15</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>torch.ones_like(e)</span>
<span id="cb12-3">e</span>
<span id="cb12-4">attention <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.where(adj<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, e, zero_vec)</span></code></pre></div></div>
</div>
</section>
</section>
<section id="step-3.-applying-attention" class="level3">
<h3 class="anchored" data-anchor-id="step-3.-applying-attention">STEP 3. Applying attention</h3>
<p><img src="https://latex.codecogs.com/png.latex?%5Calpha%20=%20%5Ctext%7Bsoftmax%7D(%5Ctilde%7BE%7D)"></p>
<p><img src="https://latex.codecogs.com/png.latex?h'%20=%20%5Calpha%20%5Ctimes%20h"></p>
<div id="2a12a4df" class="cell" data-execution_count="8">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb13-1">attention <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.softmax(attention, dim<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb13-2">h_prime <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.matmul(attention, h)</span></code></pre></div></div>
</div>
<div id="893f7233" class="cell" data-execution_count="9">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb14-1">h</span></code></pre></div></div>
<div class="cell-output cell-output-display" data-execution_count="9">
<pre><code>tensor([[ 0.7161, -0.3945],
        [ 0.5494, -0.4554],
        [-0.1075, -0.5380]], grad_fn=&lt;MmBackward0&gt;)</code></pre>
</div>
</div>
<div id="dc95a6e8" class="cell" data-execution_count="10">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb16-1">h_prime</span></code></pre></div></div>
<div class="cell-output cell-output-display" data-execution_count="10">
<pre><code>tensor([[ 0.2763, -0.4898],
        [-0.1075, -0.5380],
        [ 0.7161, -0.3945]], grad_fn=&lt;MmBackward0&gt;)</code></pre>
</div>
</div>
<div id="7bfa83a7" class="cell" data-execution_count="11">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb18-1">test_arr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.tensor([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>])</span></code></pre></div></div>
</div>
</section>
</section>
<section id="exponential-linear-unit-elu" class="level2">
<h2 class="anchored" data-anchor-id="exponential-linear-unit-elu">Exponential Linear Unit (ELU)</h2>
<p><img src="https://latex.codecogs.com/png.latex?ELU(x)%20=%20%5Cbegin%7Bcases%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%20&amp;,%20if%20&amp;%20%20x%20%5Cgt%200%20%5C%5C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5Calpha(e%5Ex%20-11)%20&amp;,%20if%20&amp;%20x%20%5Cleq%200%0A%20%20%20%20%20%20%20%20%20%20%20%20%5Cend%7Bcases%7D%0A"> By default, <img src="https://latex.codecogs.com/png.latex?%5Calpha=1.0"></p>
<section id="advantages-over-relu" class="level3">
<h3 class="anchored" data-anchor-id="advantages-over-relu">Advantages over ReLU</h3>
<ol type="1">
<li>Mitigation of “dying ReLU” problem: <img src="https://latex.codecogs.com/png.latex?ReLU(x)%20=%200%20%5Ctext%7B%20,%7D%20%5Cforall%20x%5Clt0">. It stops learning with negative pre-activation (“dies”). This preserves learning signal for negative inputs.</li>
<li>Pushes mean activation closer to 0: ELU’s negative saturation counterbalances positive activations. Potentially reducing the need for batch normalization resulting in accelerated learning.</li>
<li>Smoother Gradient Flow: It is continuously differentiable (when <img src="https://latex.codecogs.com/png.latex?%5Calpha=0">), avoiding abrupt changes in gradient at 0, which could lead to more stable training.</li>
</ol>
<p><strong>Q. Why not just use leakyReLU instead?</strong></p>
<p>Leaky ReLU is simple, cheap, and often sufficient for many tasks (e.g., GANs, where it remains popular). ELU tends to perform better in deep feedforward or convolutional networks without batch normalization, as its saturation helps control activation statistics. However, when batch normalization is used, the advantage often diminishes.</p>
</section>
</section>
<section id="gatlayer" class="level2">
<h2 class="anchored" data-anchor-id="gatlayer">GATLayer</h2>
<p><strong>Building GAT as a custorm pytorch Layer</strong></p>
<p>There is no implementation of Multi-headed Attention (MHA) in this case. It is made for node classification problem.</p>
<section id="problem-statement" class="level3">
<h3 class="anchored" data-anchor-id="problem-statement">Problem Statement</h3>
<p>Given an undirected Graph, <img src="https://latex.codecogs.com/png.latex?G=(%5Cmathcal%7BV%7D,%20%5Cmathcal%7BE%7D)">, where <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BV%7D"> is a set of <img src="https://latex.codecogs.com/png.latex?N=2708"> nodes.</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BE%7D%20%5Csubset%20%5Cmathcal%7BV%7D%20%5Ctimes%20%5Cmathcal%7BV%7D"> is a set of <img src="https://latex.codecogs.com/png.latex?%7C%5Cmathcal%7BE%7D%7C=10556"> edges, represented by an edge index tensor <img src="https://latex.codecogs.com/png.latex?E%20%5Cin%20%5Cmathbb%7BN%7D%5E%7B2%20%5Ctimes%2010556%7D"></p>
<p>Each node <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7Bv%7D_i%20%5Cin%20%5Cmathcal%7BV%7D"> is associated with a feature vector <img src="https://latex.codecogs.com/png.latex?x_i%20%5Cin%20%5Cmathbb%7BR%7D%5E%7B1433%7D">, collectively forming node feature matrix <img src="https://latex.codecogs.com/png.latex?X%20%5Cin%20%5Cmathbb%7BR%7D%5E%7B2708%20%5Ctimes%201433%7D">.</p>
<p>Each node has a label with class assigned <img src="https://latex.codecogs.com/png.latex?y_i%20%5Cin%20%5C%7B1,%202,%20...,%207%5C%7D">.</p>
<p>The task is to learn a function <img src="https://latex.codecogs.com/png.latex?f_%7B%5Ctheta%7D:%20%5Cmathbb%7BR%7D%5E%7BN%20%5Ctimes%20D%7D%20%5Ctimes%20%5Cmathbb%7BN%7D%5E%7B2%20%5Ctimes%20%7C%5Cmathcal%7BE%7D%7C%7D%20%5Crightarrow%20%5C%7B1,%202,%20...,%207%5C%7D%5E%7BN%7D"></p>
<p>In this eq:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmathbb%7BR%7D%5E%7BN%20%5Ctimes%20D%7D">: Node features (2708 <img src="https://latex.codecogs.com/png.latex?%5Ctimes"> 1433)</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmathbb%7BN%7D%5E%7B2%20%5Ctimes%20%7C%5Cmathcal%7BE%7D%7C%7D">: Edge index</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Ctheta">: learned parameters</p>
<div id="9aeab7d6" class="cell" data-execution_count="12">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb19-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> GATLayer(torch.nn.Module):</span>
<span id="cb19-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, in_features, out_features, dropout, concat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>):</span>
<span id="cb19-3">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">super</span>(GATLayer, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>).<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>()</span>
<span id="cb19-4">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.n_in_features <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> in_features</span>
<span id="cb19-5">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.n_out_features <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> out_features</span>
<span id="cb19-6">        </span>
<span id="cb19-7">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.W <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.nn.Parameter(torch.zeros(size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(in_features, out_features)))</span>
<span id="cb19-8">        torch.nn.init.xavier_uniform(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.W.data, gain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.414</span>)</span>
<span id="cb19-9">        </span>
<span id="cb19-10">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.a <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.nn.Parameter(torch.zeros(size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>out_features, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)))</span>
<span id="cb19-11">        torch.nn.init.xavier_normal(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.a.data, gain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.414</span>)</span>
<span id="cb19-12">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.leakyrelu <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.nn.LeakyReLU(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.2</span>)</span>
<span id="cb19-13"></span>
<span id="cb19-14">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> forward(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, input_tensor, adj):</span>
<span id="cb19-15">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">assert</span> input_tensor.shape[<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.n_in_features, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"number of features is different"</span></span>
<span id="cb19-16">        h <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.mm(input_tensor, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.W)</span>
<span id="cb19-17">        N <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> h.size()[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb19-18">        a_input <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.cat([h.repeat(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, N).view(N <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> N, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>), h.repeat(N, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)], dim<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>).view(N, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> out_features)</span>
<span id="cb19-19">        e <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.leakyrelu(torch.matmul(a_input, a).squeeze(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>))</span>
<span id="cb19-20">        </span>
<span id="cb19-21">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># adj = torch.randint(2, (3, 3))</span></span>
<span id="cb19-22">        zero_vec  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">9e15</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>torch.ones_like(e)</span>
<span id="cb19-23">        attention <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.where(adj <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, e, zero_vec)</span>
<span id="cb19-24">        attention <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.softmax(attention, dim<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb19-25">        attention <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.dropout(attention, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.dropout, training<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.training)</span>
<span id="cb19-26">        h_prime   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.matmul(attention, h)</span>
<span id="cb19-27">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.concat:</span>
<span id="cb19-28">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> F.elu(h_prime)</span>
<span id="cb19-29">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb19-30">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> h_prime</span></code></pre></div></div>
</div>
</section>
<section id="torch_geometric-implementation-of-gat" class="level3">
<h3 class="anchored" data-anchor-id="torch_geometric-implementation-of-gat"><code>torch_geometric</code> implementation of GAT</h3>
<p>It has MHA, efficient implementation and ease of use.</p>
<div id="9ab9d547" class="cell" data-execution_count="13">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb20-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> GAT(torch.nn.Module):</span>
<span id="cb20-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb20-3">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">super</span>(GAT, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>).<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">__init__</span>()</span>
<span id="cb20-4"></span>
<span id="cb20-5">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hid <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span></span>
<span id="cb20-6">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.in_head <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span></span>
<span id="cb20-7">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.out_head <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb20-8"></span>
<span id="cb20-9">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.conv1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> GATConv(dataset.num_features, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hid, heads<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.in_head, dropout<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6</span>)</span>
<span id="cb20-10">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.conv2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> GATConv(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.hid<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.in_head, dataset.num_classes, concat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>, heads<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.out_head, dropout<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6</span>)</span>
<span id="cb20-11"></span>
<span id="cb20-12">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> forward(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>, data):</span>
<span id="cb20-13">        x, edge_index <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data.x, data.edge_index</span>
<span id="cb20-14">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.dropout(x, p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6</span>, training<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.training)</span>
<span id="cb20-15">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># print(f"Input shape Conv1: {x.shape}")</span></span>
<span id="cb20-16">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.conv1(x, edge_index)</span>
<span id="cb20-17">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># print(f"Output shape Conv1, heads {self.in_head}: {x.shape}")</span></span>
<span id="cb20-18">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.elu(x)</span>
<span id="cb20-19">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.dropout(x, p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.6</span>, training<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.training)</span>
<span id="cb20-20">        x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>.conv2(x, edge_index)</span>
<span id="cb20-21">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># print(f"Output shape Conv2, heads {self.out_head}: {x.shape}")</span></span>
<span id="cb20-22">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> F.log_softmax(x, dim<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span></code></pre></div></div>
</div>
<div id="410250ed" class="cell" data-execution_count="14">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb21-1">data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dataset[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span></code></pre></div></div>
</div>
<div id="7d2c45d3" class="cell" data-execution_count="15">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb22-1">model <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> GAT()</span>
<span id="cb22-2">optimizer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> torch.optim.Adam(model.parameters(), lr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.005</span>, weight_decay<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5e-4</span>)</span>
<span id="cb22-3"></span>
<span id="cb22-4"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> epoch <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span>):</span>
<span id="cb22-5">    model.train()</span>
<span id="cb22-6">    optimizer.zero_grad()</span>
<span id="cb22-7">    out <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model(data)</span>
<span id="cb22-8">    loss <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> F.nll_loss(out[data.train_mask], data.y[data.train_mask])</span>
<span id="cb22-9">    </span>
<span id="cb22-10">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> epoch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>:</span>
<span id="cb22-11">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(loss)</span>
<span id="cb22-12">    loss.backward()</span>
<span id="cb22-13">    optimizer.step()</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>tensor(2.0154, grad_fn=&lt;NllLossBackward0&gt;)
tensor(0.4505, grad_fn=&lt;NllLossBackward0&gt;)
tensor(0.2827, grad_fn=&lt;NllLossBackward0&gt;)
tensor(0.3186, grad_fn=&lt;NllLossBackward0&gt;)
tensor(0.3924, grad_fn=&lt;NllLossBackward0&gt;)</code></pre>
</div>
</div>


</section>
</section>
</section>

 ]]></description>
  <category>graph-nn</category>
  <guid>https://gauneg.github.io/posts/graph-neural-networks-(first-steps)/dataproc_for_graphs.html</guid>
  <pubDate>Fri, 28 Nov 2025 00:00:00 GMT</pubDate>
  <media:content url="https://gauneg.github.io/posts/graph-neural-networks-(first-steps)/gat0.png" medium="image" type="image/png" height="71" width="144"/>
</item>
</channel>
</rss>
