Skip to content

Commit

Permalink
remove the last softmax activation
Browse files Browse the repository at this point in the history
  • Loading branch information
EdisonLeeeee committed Aug 7, 2020
1 parent 0977e37 commit 3ba050e
Show file tree
Hide file tree
Showing 26 changed files with 230 additions and 177 deletions.
2 changes: 1 addition & 1 deletion graphgallery/nn/layers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
from graphgallery.nn.layers.edgeconv import GraphEdgeConvolution
from graphgallery.nn.layers.mediansage import MedianAggregator, MedianGCNAggregator
from graphgallery.nn.layers.gcnf import GraphConvFeature
from graphgallery.nn.layers.misc import SparseConversion, Scale, Sample
from graphgallery.nn.layers.misc import SparseConversion, Scale, Sample, Gather
21 changes: 21 additions & 0 deletions graphgallery/nn/layers/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,24 @@ def get_config(self):

def compute_output_shape(self, input_shapes):
return tf.TensorShape(input_shapes[0])


class Gather(Layer):
def __init__(self, axis=0, *args, **kwargs):
super().__init__(*args, **kwargs)
self.axis = axis

def call(self, inputs):
params, indices = inputs
output = tf.gather(params, indices, axis=self.axis)
return output

def get_config(self):
base_config = super().get_config()
return base_config

def compute_output_shape(self, input_shapes):
axis = self.axis
params_shape, indices_shape = input_shapes
output_shape = params_shape[:axis] + indices_shape + params_shape[axis + 1:]
return tf.TensorShape(output_shape)
12 changes: 7 additions & 5 deletions graphgallery/nn/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
# (semi-)supervised model
from graphgallery.nn.models.semisupervised.semi_supervised_model import SemiSupervisedModel
from graphgallery.nn.models.semisupervised.gcn import GCN
from graphgallery.nn.models.semisupervised.gcn_mix import GCN_MIX
from graphgallery.nn.models.semisupervised.sgc import SGC
from graphgallery.nn.models.semisupervised.gat import GAT
from graphgallery.nn.models.semisupervised.clustergcn import ClusterGCN
Expand All @@ -17,11 +16,14 @@
from graphgallery.nn.models.semisupervised.lgcn import LGCN
from graphgallery.nn.models.semisupervised.obvat import OBVAT
from graphgallery.nn.models.semisupervised.sbvat import SBVAT
from graphgallery.nn.models.semisupervised.s_obvat import SimplifiedOBVAT
from graphgallery.nn.models.semisupervised.gmnn import GMNN
from graphgallery.nn.models.semisupervised.edgeconv import EdgeGCN
from graphgallery.nn.models.semisupervised.mediansage import MedianSAGE
from graphgallery.nn.models.semisupervised.gcnf import GCNF

# experimental
from graphgallery.nn.models.semisupervised.experimental.gcnf import GCNF
from graphgallery.nn.models.semisupervised.experimental.gcn_mix import GCN_MIX
from graphgallery.nn.models.semisupervised.experimental.s_obvat import SimplifiedOBVAT
from graphgallery.nn.models.semisupervised.experimental.edgeconv import EdgeGCN
from graphgallery.nn.models.semisupervised.experimental.mediansage import MedianSAGE


# unsupervised model
Expand Down
17 changes: 9 additions & 8 deletions graphgallery/nn/models/semisupervised/chebynet.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import tensorflow as tf
from tensorflow.keras import Model, Input
from tensorflow.keras.layers import Dropout, Softmax
from tensorflow.keras.layers import Dropout
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import regularizers
from tensorflow.keras.losses import SparseCategoricalCrossentropy

from graphgallery.nn.layers import ChebyConvolution
from graphgallery.nn.layers import ChebyConvolution, Gather
from graphgallery.sequence import FullBatchNodeSequence
from graphgallery.nn.models import SemiSupervisedModel
from graphgallery.utils.misc import chebyshev_polynomials
Expand Down Expand Up @@ -37,7 +38,7 @@ class ChebyNet(SemiSupervisedModel):
i.e., math:: \hat{A} = D^{-\frac{1}{2}} A D^{-\frac{1}{2}})
norm_x (String, optional):
How to normalize the node feature matrix. See `graphgallery.normalize_x`
(default :str: `l1`)
(default :obj: `None`)
device (String, optional):
The device where the model is running on. You can specified `CPU` or `GPU`
for the model. (default: :str: `CPU:0`, i.e., running on the 0-th `CPU`)
Expand All @@ -51,7 +52,7 @@ class ChebyNet(SemiSupervisedModel):
"""

def __init__(self, adj, x, labels, order=2, norm_adj=-0.5,
norm_x='l1', device='CPU:0', seed=None, name=None, **kwargs):
norm_x=None, device='CPU:0', seed=None, name=None, **kwargs):

super().__init__(adj, x, labels,
device=device, seed=seed, name=name, **kwargs)
Expand Down Expand Up @@ -103,11 +104,11 @@ def build(self, hiddens=[16], activations=['relu'], dropouts=[0.5], l2_norms=[5e
h = Dropout(rate=dropout)(h)

h = ChebyConvolution(self.n_classes, order=self.order, use_bias=use_bias)([h, adj])
h = tf.gather(h, index)
output = Softmax()(h)
h = Gather()([h, index])

model = Model(inputs=[x, *adj, index], outputs=output)
model.compile(loss='sparse_categorical_crossentropy', optimizer=Adam(lr=lr), metrics=['accuracy'])
model = Model(inputs=[x, *adj, index], outputs=h)
model.compile(loss=SparseCategoricalCrossentropy(from_logits=True),
optimizer=Adam(lr=lr), metrics=['accuracy'])
self.model = model

def train_sequence(self, index):
Expand Down
17 changes: 8 additions & 9 deletions graphgallery/nn/models/semisupervised/clustergcn.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
import networkx as nx
import tensorflow as tf
from tensorflow.keras import Model, Input
from tensorflow.keras.layers import Dropout, Softmax
from tensorflow.keras.layers import Dropout
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import regularizers
from tensorflow.keras.losses import SparseCategoricalCrossentropy

from graphgallery.nn.layers import GraphConvolution, SparseConversion
from graphgallery.nn.models import SemiSupervisedModel
Expand Down Expand Up @@ -46,7 +47,7 @@ class ClusterGCN(SemiSupervisedModel):
i.e., math:: \hat{A} = D^{-\frac{1}{2}} A D^{-\frac{1}{2}})
norm_x (String, optional):
How to normalize the node feature matrix. See `graphgallery.normalize_x`
(default :str: `l1`)
(default :obj: `None`)
device (String, optional):
The device where the model is running on. You can specified `CPU` or `GPU`
for the model. (default: :str: `CPU:0`, i.e., running on the 0-th `CPU`)
Expand All @@ -60,7 +61,7 @@ class ClusterGCN(SemiSupervisedModel):
"""

def __init__(self, adj, x, labels, graph=None, n_clusters=None,
norm_adj=-0.5, norm_x='l1', device='CPU:0', seed=None, name=None, **kwargs):
norm_adj=-0.5, norm_x=None, device='CPU:0', seed=None, name=None, **kwargs):

super().__init__(adj, x, labels=labels, device=device, seed=seed, name=name, **kwargs)

Expand Down Expand Up @@ -118,7 +119,7 @@ def build(self, hiddens=[32], activations=['relu'], dropouts=[0.5], l2_norms=[1e
mask = Input(batch_shape=[None], dtype=tf.bool, name='mask')

adj = SparseConversion()([edge_index, edge_weight])

h = x
for hid, activation, dropout, l2_norm in zip(hiddens, activations, dropouts, l2_norms):
h = Dropout(rate=dropout)(h)
Expand All @@ -128,12 +129,10 @@ def build(self, hiddens=[32], activations=['relu'], dropouts=[0.5], l2_norms=[1e
h = Dropout(rate=dropout)(h)
h = GraphConvolution(self.n_classes, use_bias=use_bias)([h, adj])
h = tf.boolean_mask(h, mask)
output = Softmax()(h)

model = Model(inputs=[x, edge_index, edge_weight, mask], outputs=output)

model.compile(loss='sparse_categorical_crossentropy', optimizer=Adam(lr=lr),
metrics=['accuracy'])
model = Model(inputs=[x, edge_index, edge_weight, mask], outputs=h)
model.compile(loss=SparseCategoricalCrossentropy(from_logits=True),
optimizer=Adam(lr=lr), metrics=['accuracy'])

self.model = model

Expand Down
15 changes: 8 additions & 7 deletions graphgallery/nn/models/semisupervised/densegcn.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
from tensorflow.keras.layers import Dropout, Softmax
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import regularizers
from tensorflow.keras.losses import SparseCategoricalCrossentropy

from graphgallery.nn.layers import DenseGraphConv
from graphgallery.nn.layers import DenseGraphConv, Gather
from graphgallery.nn.models import SemiSupervisedModel
from graphgallery.sequence import FullBatchNodeSequence
from graphgallery.utils.shape_utils import set_equal_in_length
Expand Down Expand Up @@ -42,7 +43,7 @@ class DenseGCN(SemiSupervisedModel):
i.e., math:: \hat{A} = D^{-\frac{1}{2}} A D^{-\frac{1}{2}})
norm_x (String, optional):
How to normalize the node feature matrix. See `graphgallery.normalize_x`
(default :str: `l1`)
(default :obj: `None`)
device (String, optional):
The device where the model is running on. You can specified `CPU` or `GPU`
for the model. (default: :str: `CPU:0`, i.e., running on the 0-th `CPU`)
Expand All @@ -56,7 +57,7 @@ class DenseGCN(SemiSupervisedModel):
"""

def __init__(self, adj, x, labels, norm_adj=-0.5, norm_x='l1',
def __init__(self, adj, x, labels, norm_adj=-0.5, norm_x=None,
device='CPU:0', seed=None, name=None, **kwargs):

super().__init__(adj, x, labels, device=device, seed=seed, name=name, **kwargs)
Expand Down Expand Up @@ -112,11 +113,11 @@ def build(self, hiddens=[16], activations=['relu'], dropouts=[0.5], l2_norms=[5e
h = Dropout(rate=dropout)(h)

h = DenseGraphConv(self.n_classes, use_bias=use_bias)([h, adj])
h = tf.gather(h, index)
output = Softmax()(h)
h = Gather()([h, index])

model = Model(inputs=[x, adj, index], outputs=output)
model.compile(loss='sparse_categorical_crossentropy', optimizer=Adam(lr=lr), metrics=['accuracy'])
model = Model(inputs=[x, adj, index], outputs=h)
model.compile(loss=SparseCategoricalCrossentropy(from_logits=True),
optimizer=Adam(lr=lr), metrics=['accuracy'])
self.model = model

def train_sequence(self, index):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import numpy as np
import tensorflow as tf
from tensorflow.keras import Model, Input
from tensorflow.keras.layers import Dropout, Softmax
from tensorflow.keras.layers import Dropout
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import regularizers
from tensorflow.keras.losses import SparseCategoricalCrossentropy

from graphgallery.nn.layers import GraphEdgeConvolution
from graphgallery.nn.layers import GraphEdgeConvolution, Gather
from graphgallery.nn.models import SemiSupervisedModel
from graphgallery.sequence import FullBatchNodeSequence
from graphgallery.utils.shape_utils import set_equal_in_length
Expand Down Expand Up @@ -44,7 +45,7 @@ class EdgeGCN(SemiSupervisedModel):
i.e., math:: \hat{A} = D^{-\frac{1}{2}} A D^{-\frac{1}{2}})
norm_x (String, optional):
How to normalize the node feature matrix. See `graphgallery.normalize_x`
(default :str: `l1`)
(default :obj: `None`)
device (String, optional):
The device where the model is running on. You can specified `CPU` or `GPU`
for the model. (default: :str: `CPU:0`, i.e., running on the 0-th `CPU`)
Expand All @@ -57,7 +58,7 @@ class EdgeGCN(SemiSupervisedModel):
"""

def __init__(self, adj, x, labels, norm_adj=-0.5, norm_x='l1',
def __init__(self, adj, x, labels, norm_adj=-0.5, norm_x=None,
device='CPU:0', seed=None, name=None, **kwargs):

super().__init__(adj, x, labels, device=device, seed=seed, name=name, **kwargs)
Expand Down Expand Up @@ -109,11 +110,11 @@ def build(self, hiddens=[16], activations=['relu'], dropouts=[0.5], l2_norms=[5e
h = Dropout(rate=dropout)(h)

h = GraphEdgeConvolution(self.n_classes, use_bias=use_bias)([h, edge_index, edge_weight])
h = tf.gather(h, index)
output = Softmax()(h)

model = Model(inputs=[x, edge_index, edge_weight, index], outputs=output)
model.compile(loss='sparse_categorical_crossentropy', optimizer=Adam(lr=lr), metrics=['accuracy'])
h = Gather()([h, index])

model = Model(inputs=[x, edge_index, edge_weight, index], outputs=h)
model.compile(loss=SparseCategoricalCrossentropy(from_logits=True),
optimizer=Adam(lr=lr), metrics=['accuracy'])
self.model = model

def train_sequence(self, index):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class GCN_MIX(SemiSupervisedModel):
i.e., math:: \hat{A} = D^{-\frac{1}{2}} A D^{-\frac{1}{2}})
norm_x (String, optional):
How to normalize the node feature matrix. See `graphgallery.normalize_x`
(default :str: `l1`)
(default :obj: `None`)
device (String, optional):
The device where the model is running on. You can specified `CPU` or `GPU`
for the model. (default: :str: `CPU:0`, i.e., running on the 0-th `CPU`)
Expand All @@ -49,7 +49,7 @@ class GCN_MIX(SemiSupervisedModel):
"""

def __init__(self, adj, x, labels, norm_adj=-0.5, norm_x='l1',
def __init__(self, adj, x, labels, norm_adj=-0.5, norm_x=None,
device='CPU:0', seed=None, name=None, **kwargs):

super().__init__(adj, x, labels, device=device, seed=seed, name=name, **kwargs)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import tensorflow as tf
from tensorflow.keras import Model, Input
from tensorflow.keras.layers import Dropout, Softmax
from tensorflow.keras.layers import Dropout
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import regularizers
from tensorflow.keras.losses import SparseCategoricalCrossentropy

from graphgallery.nn.layers import GraphConvFeature
from graphgallery.nn.layers import GraphConvFeature, Gather
from graphgallery.nn.models import SemiSupervisedModel
from graphgallery.sequence import FullBatchNodeSequence
from graphgallery.utils.shape_utils import set_equal_in_length
Expand All @@ -17,34 +18,34 @@ class GCNF(SemiSupervisedModel):
Arguments:
----------
adj: shape (N, N), Scipy sparse matrix if `is_adj_sparse=True`,
adj: shape (N, N), Scipy sparse matrix if `is_adj_sparse=True`,
Numpy array-like (or matrix) if `is_adj_sparse=False`.
The input `symmetric` adjacency matrix, where `N` is the number
The input `symmetric` adjacency matrix, where `N` is the number
of nodes in graph.
x: shape (N, F), Scipy sparse matrix if `is_x_sparse=True`,
x: shape (N, F), Scipy sparse matrix if `is_x_sparse=True`,
Numpy array-like (or matrix) if `is_x_sparse=False`.
The input node feature matrix, where `F` is the dimension of features.
labels: Numpy array-like with shape (N,)
The ground-truth labels for all nodes in graph.
norm_adj (Float scalar, optional):
The normalize rate for adjacency matrix `adj`. (default: :obj:`-0.5`,
i.e., math:: \hat{A} = D^{-\frac{1}{2}} A D^{-\frac{1}{2}})
norm_x (Boolean, optional):
Whether to use row-wise normalization for node feature matrix.
(default :bool: `True`)
device (String, optional):
The device where the model is running on. You can specified `CPU` or `GPU`
norm_adj (Float scalar, optional):
The normalize rate for adjacency matrix `adj`. (default: :obj:`-0.5`,
i.e., math:: \hat{A} = D^{-\frac{1}{2}} A D^{-\frac{1}{2}})
norm_x (String, optional):
How to normalize the node feature matrix. See `graphgallery.normalize_x`
(default :obj: `None`)
device (String, optional):
The device where the model is running on. You can specified `CPU` or `GPU`
for the model. (default: :str: `CPU:0`, i.e., running on the 0-th `CPU`)
seed (Positive integer, optional):
Used in combination with `tf.random.set_seed` & `np.random.seed` & `random.seed`
to create a reproducible sequence of tensors across multiple calls.
seed (Positive integer, optional):
Used in combination with `tf.random.set_seed` & `np.random.seed` & `random.seed`
to create a reproducible sequence of tensors across multiple calls.
(default :obj: `None`, i.e., using random seed)
name (String, optional):
name (String, optional):
Specified name for the model. (default: :str: `class.__name__`)
"""

def __init__(self, adj, x, labels, norm_adj=-0.5, norm_x='l1',
def __init__(self, adj, x, labels, norm_adj=-0.5, norm_x=None,
device='CPU:0', seed=None, name=None, **kwargs):

super().__init__(adj, x, labels, device=device, seed=seed, name=name, **kwargs)
Expand Down Expand Up @@ -100,11 +101,11 @@ def build(self, hiddens=[16], activations=['relu'], dropouts=[0.5], l2_norms=[5e
# of the input data to remain the same
# if ensure_shape:
# h = tf.ensure_shape(h, [self.n_nodes, self.n_classes])
h = tf.gather(h, index)
output = Softmax()(h)
h = Gather()([h, index])

model = Model(inputs=[x, adj, index], outputs=output)
model.compile(loss='sparse_categorical_crossentropy', optimizer=Adam(lr=lr), metrics=['accuracy'])
model = Model(inputs=[x, adj, index], outputs=h)
model.compile(loss=SparseCategoricalCrossentropy(from_logits=True),
optimizer=Adam(lr=lr), metrics=['accuracy'])

self.model = model

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import numpy as np
import tensorflow as tf
from tensorflow.keras import Model, Input
from tensorflow.keras.layers import Dropout, Softmax
from tensorflow.keras.layers import Dropout
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import regularizers
from tensorflow.keras.losses import SparseCategoricalCrossentropy

from graphgallery.nn.layers import MedianAggregator, MedianGCNAggregator
from graphgallery.nn.models import SemiSupervisedModel
Expand Down Expand Up @@ -34,7 +35,7 @@ class MedianSAGE(SemiSupervisedModel):
`5` sencond-order neighbors, and the radius for `GraphSAGE` is `2`)
norm_x (String, optional):
How to normalize the node feature matrix. See `graphgallery.normalize_x`
(default :str: `l1`)
(default :obj: `None`)
device (String, optional):
The device where the model is running on. You can specified `CPU` or `GPU`
for the model. (default: :str: `CPU:0`, i.e., running on the 0-th `CPU`)
Expand All @@ -48,7 +49,7 @@ class MedianSAGE(SemiSupervisedModel):
"""

def __init__(self, adj, x, labels, n_samples=[15, 3], norm_x='l1',
def __init__(self, adj, x, labels, n_samples=[15, 3], norm_x=None,
device='CPU:0', seed=None, name=None, **kwargs):

super().__init__(adj, x, labels, device=device, seed=seed, name=name, **kwargs)
Expand Down Expand Up @@ -124,10 +125,10 @@ def build(self, hiddens=[32], activations=['relu'], dropouts=[0.5], l2_norms=[5e
h = h[0]
if output_normalize:
h = tf.nn.l2_normalize(h, axis=1)
output = Softmax()(h)

model = Model(inputs=[x, nodes, *neighbors], outputs=output)
model.compile(loss='sparse_categorical_crossentropy', optimizer=Adam(lr=lr), metrics=['accuracy'])
model = Model(inputs=[x, nodes, *neighbors], outputs=h)
model.compile(loss=SparseCategoricalCrossentropy(from_logits=True),
optimizer=Adam(lr=lr), metrics=['accuracy'])

self.model = model

Expand Down
Loading

0 comments on commit 3ba050e

Please sign in to comment.