# GeometricFlux: GCNConv but with different graphs

**URL:** <https://discourse.julialang.org/t/geometricflux-gcnconv-but-with-different-graphs/36518>\
**Category:** Machine Learning\
**Tags:** lightgraphs, flux\
**Created:** [March 25, 2020, 8:52pm UTC](https://discourse.julialang.org/t/geometricflux-gcnconv-but-with-different-graphs/36518 "2020-03-25T20:52:34Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![rkurchin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rkurchin/32/16039_2.png) [@rkurchin](https://discourse.julialang.org/u/rkurchin)\
**Post date:** [March 25, 2020, 8:52pm UTC](https://discourse.julialang.org/t/geometricflux-gcnconv-but-with-different-graphs/36518/1 "2020-03-25T20:52:34Z")

</div>

I’m working with GeometricFlux and want to adapt the `GCNConv` layer to allow for different adjacency matrices corresponding to each piece of training data. Since this now requires two separate “streams” of input data (the adjacency matrices and the set of node features corresponding to each graph), I’m wondering about any best practices for dealing with this type of input. Most of the Flux examples I’ve seen have just one vector (or matrix) as the input. Anything particular I should be keeping in mind?

---

<div class="post-metadata">

**Author:** ![tdfalc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tdfalc/32/16665_2.png) [@tdfalc](https://discourse.julialang.org/u/tdfalc)\
**Post date:** [July 24, 2020, 1:08pm UTC](https://discourse.julialang.org/t/geometricflux-gcnconv-but-with-different-graphs/36518/2 "2020-07-24T13:08:53Z")

</div>

Hi, Im working on a similar problem and wondering if you were able to successfully adapt the layer?

---

<div class="post-metadata">

**Author:** ![rkurchin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rkurchin/32/16039_2.png) [@rkurchin](https://discourse.julialang.org/u/rkurchin)\
**Post date:** [July 24, 2020, 4:03pm UTC](https://discourse.julialang.org/t/geometricflux-gcnconv-but-with-different-graphs/36518/3 "2020-07-24T16:03:36Z")

</div>

Yes. Unfortunately the solution I have is currently closed-source because of silly academia funding/IP things, but we plan to open-source it once we publish the paper, hopefully in the next couple months. In the meantime, check out the FeaturedGraph type in GeometricFlux (may be only in master branch currently, not sure); that’s what I’m using as input to the layer.

The main conceptual thing to keep in mind in adapting it (if you want to make your own in the meantime) is that the bias terms will not be able to be trainable per-node since the number of input nodes in the graph can vary, so you can only train it per-feature. If you want to know when it comes out, I’d suggest you keep an eye on this Github org, as this is where it will be published: [https://github.com/aced-differentiate](https://github.com/aced-differentiate)

---

<div class="post-metadata">

**Author:** ![tdfalc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tdfalc/32/16665_2.png) [@tdfalc](https://discourse.julialang.org/u/tdfalc)\
**Post date:** [July 28, 2020, 7:21pm UTC](https://discourse.julialang.org/t/geometricflux-gcnconv-but-with-different-graphs/36518/4 "2020-07-28T19:21:06Z")

</div>

@rkurchin Thanks! This FeaturedGraph type is extremely helpful for my use case. Did you have any trouble computing the gradients when using this type combined with the GCNConv layer? I seem to get the following method error:

```julia
MethodError: no method matching (::GeometricFlux.var"#adjacency_matrix#76")(::FeaturedGraph{Array{Float64,2},Adjoint{Float64,Array{Float64,2}},Array{Float64,2},Array{Float64,1}})

```

---

<div class="post-metadata">

**Author:** ![rkurchin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rkurchin/32/16039_2.png) [@rkurchin](https://discourse.julialang.org/u/rkurchin)\
**Post date:** [July 28, 2020, 11:50pm UTC](https://discourse.julialang.org/t/geometricflux-gcnconv-but-with-different-graphs/36518/5 "2020-07-28T23:50:08Z")

</div>

Yeah, we did end up having to define a custom adjoint for that but I think you may have to wait until our paper comes out to see it. Sorry our funder is so ornery about this! We definitely will open-source it eventually, just have to follow a bunch of rules first…

---

<div class="post-metadata">

**Author:** ![tdfalc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tdfalc/32/16665_2.png) [@tdfalc](https://discourse.julialang.org/u/tdfalc)\
**Post date:** [July 29, 2020, 6:01am UTC](https://discourse.julialang.org/t/geometricflux-gcnconv-but-with-different-graphs/36518/6 "2020-07-29T06:01:14Z")

</div>

@rkurchin Totally understand, thanks! 🙂

---

<div class="post-metadata">

**Author:** ![rkurchin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rkurchin/32/16039_2.png) [@rkurchin](https://discourse.julialang.org/u/rkurchin)\
**Post date:** [September 29, 2020, 6:53pm UTC](https://discourse.julialang.org/t/geometricflux-gcnconv-but-with-different-graphs/36518/7 "2020-09-29T18:53:30Z")

</div>

Psst…took a bit longer than anticipated, but this is finally open: [https://github.com/aced-differentiate/AtomicGraphNets.jl](https://github.com/aced-differentiate/AtomicGraphNets.jl)

We ended up ditching the GeometricFlux dependency entirely and building our own graph type, which is implemented here as AtomGraph: [https://github.com/aced-differentiate/ChemistryFeaturization.jl](https://github.com/aced-differentiate/ChemistryFeaturization.jl)

The adjoints I mentioned earlier are here: [https://github.com/aced-differentiate/AtomicGraphNets.jl/blob/58cc531a331a2132f05f499d14ad8d1e5c0822c1/src/layers.jl#L65](https://github.com/aced-differentiate/AtomicGraphNets.jl/blob/58cc531a331a2132f05f499d14ad8d1e5c0822c1/src/layers.jl#L65)

---

<div class="post-metadata">

**Author:** ![datnamer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datnamer/32/3471_2.png) [@datnamer](https://discourse.julialang.org/u/datnamer)\
**Post date:** [September 30, 2020, 3:03am UTC](https://discourse.julialang.org/t/geometricflux-gcnconv-but-with-different-graphs/36518/8 "2020-09-30T03:03:58Z")

</div>

Why’d you ditch geometric flux ?

---

<div class="post-metadata">

**Author:** ![yuehhua](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuehhua/32/12281_2.png) [@yuehhua](https://discourse.julialang.org/u/yuehhua)\
**Post date:** [September 30, 2020, 3:46am UTC](https://discourse.julialang.org/t/geometricflux-gcnconv-but-with-different-graphs/36518/9 "2020-09-30T03:46:59Z")

</div>

The FeaturedGraph is currently available to put graph and features together.  
If you want graph to be variable, remember to turn off the cache mechanism.

```julia
GCNConv(num_features=>hidden, relu, cache=false)

```

I think that would help.

Any further questions, just tag me.

---

<div class="post-metadata">

**Author:** ![rkurchin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rkurchin/32/16039_2.png) [@rkurchin](https://discourse.julialang.org/u/rkurchin)\
**Post date:** [September 30, 2020, 2:14pm UTC](https://discourse.julialang.org/t/geometricflux-gcnconv-but-with-different-graphs/36518/10 "2020-09-30T14:14:49Z")

</div>

The FeaturedGraph type didn’t have all the checks I wanted (e.g. making sure the dimension of the feature matrix made sense given the dimensions of the graph), and because I’m using this for convolutions, I wanted to store the graph laplacian as well to avoid having to compute it every time. For those reasons and a couple others (mostly related to storing some more specific stuff related to how the featurization is done), I decided to define my own graph type, and then since I wasn’t using the GCNConv layers or the FeaturedGraph type, the GeometricFlux dependency wasn’t really necessary.

@yuehhua, I’d certainly encourage you to take a look at the AtomGraph type I defined in [ChemistryFeaturization](https://github.com/aced-differentiate/ChemistryFeaturization.jl) and think about incorporating some of those checks on feature matrix dimension and potentially also storing the laplacian to speed up convolution…

---

<div class="post-metadata">

**Author:** ![yuehhua](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuehhua/32/12281_2.png) [@yuehhua](https://discourse.julialang.org/u/yuehhua)\
**Post date:** [October 1, 2020, 3:33am UTC](https://discourse.julialang.org/t/geometricflux-gcnconv-but-with-different-graphs/36518/11 "2020-10-01T03:33:31Z")

</div>

Yeah, I have considered to add dimension check between feature matrix and graph. In the other side, I want it to be more general as possible and they maybe don’t consistent with each other during computation. I consider a better way to add dimension check.

As for Laplacian, I still very likely to add this feature but I have some concern about how to put it in FeaturedGraph and have a consistent layout. I want it not to have one copy of matrix to reduce memory allocations.

---

<div class="post-metadata">

**Author:** ![yuehhua](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuehhua/32/12281_2.png) [@yuehhua](https://discourse.julialang.org/u/yuehhua)\
**Post date:** [October 1, 2020, 8:19am UTC](https://discourse.julialang.org/t/geometricflux-gcnconv-but-with-different-graphs/36518/12 "2020-10-01T08:19:23Z")

</div>

I plan to add dimensional check first.  
[https://github.com/yuehhua/GraphSignals.jl/pull/7](https://github.com/yuehhua/GraphSignals.jl/pull/7)

---

<div class="post-metadata">

**Author:** ![yuehhua](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuehhua/32/12281_2.png) [@yuehhua](https://discourse.julialang.org/u/yuehhua)\
**Post date:** [October 2, 2020, 5:08am UTC](https://discourse.julialang.org/t/geometricflux-gcnconv-but-with-different-graphs/36518/13 "2020-10-02T05:08:24Z")

</div>

[https://github.com/yuehhua/GraphSignals.jl/pull/8](https://github.com/yuehhua/GraphSignals.jl/pull/8)
