Adding the self-loop before normalising keeps the eigenvalues of the propagation operator inside [-1, 1], which is what stops repeated application from exploding.
Examples
set.seed(1)
A <- matrix(c(0, 1, 0, 1, 0, 1, 0, 1, 0), 3, 3, byrow = TRUE)
X <- matrix(rnorm(6), 3, 2)
W <- matrix(rnorm(4), 2, 2)
GcnL(A, X, W)
#> $estimate
#> [1] 0.1042731
#>
#> $H
#> [,1] [,2]
#> [1,] 0.57210545 0
#> [2,] 0.05353326 0
#> [3,] 0.00000000 0
#>
#> $preactivation
#> [,1] [,2]
#> [1,] 0.57210545 -0.4218540
#> [2,] 0.05353326 -0.4385753
#> [3,] -0.37067714 -0.1132026
#>
#> $n
#> [1] 3
#>
#> $method
#> [1] "H' = relu(Dt^{-1/2}(A+I)Dt^{-1/2} X W), Kipf & Welling (2017) eq. (8)"
#>
#> attr(,"class")
#> [1] "morie_rich_result" "list"
