Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add WeightAndSum pooling layer #263

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions src/GraphNeuralNetworks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export
Set2Set,
TopKPool,
topk_index,
WeigthAndSumPool,

# mldatasets
mldataset2gnngraph
Expand Down
41 changes: 41 additions & 0 deletions src/layers/pool.jl
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,47 @@ end

topk_index(y::Adjoint, k::Int) = topk_index(y', k)

"""
WeigthAndSumPool(in_feats)

WeigthAndSum sum pooling layer.
Takes a graph and the node features as inputs, computes the weights for each node and perform a weighted sum.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Takes a graph and the node features as inputs, computes the weights for each node and perform a weighted sum.
In the forward pass, takes a graph and the node features as inputs, computes the weights for each node and performs a weighted sum.

Should also describe how the weights are computed and describe the in_feats constructor argument.


# Example

```julia
n = 3
chin = 5

ws = WeigthAndSumPool(chin)
g = GNNGraph(rand_graph(3, 4), ndata = rand(Float32, chin, 3), graph_type = GRAPH_T)
aurorarossi marked this conversation as resolved.
Show resolved Hide resolved

u = ws(g, g.ndata.x)
```
"""
struct WeigthAndSumPool
in_feats::Int
dense_layer::Dense
end

@functor WeigthAndSumPool

function WeigthAndSumPool(in_feats::Int)
dense_layer = Dense(in_feats, 1, sigmoid; bias = true)
WeigthAndSumPool(in_feats, dense_layer)
end

function (ws::WeigthAndSumPool)(g::GNNGraph, x::AbstractArray)
atom_weighting = ws.dense_layer
return reduce_nodes(+, g, atom_weighting(x) .* x)
end

function (ws::WeigthAndSumPool)(g::GNNGraph, x::CuArray)
atom_weighting = ws.dense_layer |> gpu
return reduce_nodes(+, g, atom_weighting(x) .* x)
end

(ws::WeigthAndSumPool)(g::GNNGraph) = GNNGraph(g, gdata = ws(g, node_features(g)))

@doc raw"""
Set2Set(n_in, n_iters, n_layers = 1)
Expand Down
16 changes: 16 additions & 0 deletions test/layers/pool.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ end
y = p(X)
@test size(y) == (in_channel, k)
end

@testset "WeigthAndSumPool" begin
n = 3
chin = 5
ng = 3

ws = WeigthAndSumPool(chin)
g = GNNGraph(rand_graph(n, 4), ndata = rand(Float32, chin, n), graph_type = GRAPH_T)

test_layer(ws, g, rtol = 1e-5, outtype = :graph,outsize = (chin, 1))
g_batch = Flux.batch([GNNGraph(rand_graph(n, 4),
ndata = rand(Float32, chin, n),
graph_type = GRAPH_T)
for i in 1:ng])
test_layer(ws, g_batch, rtol = 1e-5,outtype = :graph, outsize = (chin, ng))
end
end

@testset "topk_index" begin
Expand Down