Code Monkey home page Code Monkey logo

bayer-science-for-a-better-life / phc-gnn Goto Github PK

View Code? Open in Web Editor NEW
30.0 7.0 6.0 7.09 MB

Implementation of the Paper: "Parameterized Hypercomplex Graph Neural Networks for Graph Classification" by Tuan Le, Marco Bertolini, Frank Noé and Djork-Arné Clevert

License: GNU General Public License v3.0

Jupyter Notebook 2.71% Shell 0.86% Python 96.44%
graph-neural-networks graph-classification neural-message-passing deep-learning graph-representation-learning hypercomplex quaternion

phc-gnn's People

Contributors

tuanle618 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

phc-gnn's Issues

initialization of PHM layers

Hi

I would like to initialize phm_rule and weights in a way that the final weight matrix of PHM layers is initialized with normal(mean=0, std=0.01), could you kindly provide me with some suggestions on how this can be achieved? So which initialization I can use for phm_rules and weight variables.

thanks

Use cached version of PHM-weight matrix after training.

General idea: When training is finished, the PHM-weight matrix does not have to be constructed by a sum of Kronecker products in every forward pass. One could check for self.train and then use a cached version, e.g. saved in self._cached_weight of the final weight matrix for the linear transformation.
Using torch.nn.functional.linear function with inserting the self._cached_weight parameter.

Advantage: speedup gain in inference, as trainable parameters for PHM-layer are not updated, when running inference, we could just the final weight matrix, which is constructed by the optimized contribution and sub-weight matrices {C_i}_{i=1}^{n} and {W_i}_{i=1}^{n} , respectively.

assert x_j.size(-1) == edge_attr.size(-1)

Hi,

when I run this code via bash run_script_pcba_phm4.sh

I got the following error:

Traceback (most recent call last):
File "train_pcba.py", line 634, in
main()
File "train_pcba.py", line 610, in main
ogb_bestEpoch_test_metrics, ogb_lastEpoch_test_metric, ogb_val_metrics = do_run(i, model, args,
File "train_pcba.py", line 327, in do_run
train_metrics = train(epoch=epoch, model=model, device=device, transform=transform,
File "train_pcba.py", line 174, in train
logits = model(data)
File "/root/miniconda3/envs/phc-gnn/lib/python3.8/site-packages/torch/nn/modules/module.py", line 727, in _call_impl
result = self.forward(*input, **kwargs)
File "/ogb/phc-gnn-master/phc/hypercomplex/undirectional/models.py", line 243, in forward
x = self.compute_hidden_layer_embedding(conv=self.convs[i], norm=self.norms[i],
File "/ogb/phc-gnn-master/phc/hypercomplex/undirectional/models.py", line 208, in compute_hidden_layer_embedding
x = conv(x=tmp[0], edge_index=edge_index, edge_attr=edge_attr, size=size)
File "/root/miniconda3/envs/phc-gnn/lib/python3.8/site-packages/torch/nn/modules/module.py", line 727, in _call_impl
result = self.forward(*input, **kwargs)
File "/ogb/phc-gnn-master/phc/hypercomplex/undirectional/messagepassing.py", line 519, in forward
return self.transform(x, edge_index, edge_attr, size)
File "/root/miniconda3/envs/phc-gnn/lib/python3.8/site-packages/torch/nn/modules/module.py", line 727, in _call_impl
result = self.forward(*input, **kwargs)
File "/phc-gnn-master/phc/hypercomplex/undirectional/messagepassing.py", line 60, in forward
x = self.propagate(edge_index=edge_index, x=x, edge_attr=edge_attr, size=size)
File "/root/miniconda3/envs/phc-gnn/lib/python3.8/site-packages/torch_geometric/nn/conv/message_passing.py", line 236, in propagate
out = self.message(**msg_kwargs)
File "/ogb/phc-gnn-master/phc/hypercomplex/undirectional/messagepassing.py", line 74, in message
assert x_j.size(-1) == edge_attr.size(-1)
AssertionError

Then, I print the shape of both x_j and edge_attr,
x_j : [28302, 512]
edge_attr : [28302, 2048]

what caused this error?

making PHM layers faster

Hi
I observe speed difference between the PHM layers and linear layers, while in the original paper they clarim the running time should be the same, could you kindly let me know if you might know a way I could make the running time faster? greatly appreciated.

serious reproducibility issue with PHMLinear layers

Hi there,

I am using PHMLinear here [1], then I set all the seeds (torch/torch cuda/numpy/random) once before making a model, and then I use this layer inside the model, I am getting each time a different results, could you guide me please how I can fix this issue with this layer?

thank you

[1]

class PHMLinear(torch.nn.Module):
def __init__(self, in_features: int, out_features: int,
phm_dim: int, phm_rule: Union[None, nn.Parameter, nn.ParameterList, list, torch.Tensor] = None,
bias: bool = True, w_init: str = "phm", c_init: str = "standard",
learn_phm: bool = True) -> None:
super(PHMLinear, self).__init__()
assert w_init in ["phm", "glorot-normal", "glorot-uniform"]
assert c_init in ["standard", "random"]
self.in_features = in_features
self.out_features = out_features
self.learn_phm = learn_phm
self.phm_dim = phm_dim
self.shared_phm = False
if phm_rule is not None:
self.shared_phm = True
self.phm_rule = phm_rule
if not isinstance(phm_rule, nn.ParameterList) and learn_phm:
self.phm_rule = nn.ParameterList([nn.Parameter(mat, requires_grad=learn_phm) for mat in self.phm_rule])
else:
self.phm_rule = get_multiplication_matrices(phm_dim, type=c_init)
self.phm_rule = nn.ParameterList([nn.Parameter(mat, requires_grad=learn_phm) for mat in self.phm_rule])
self.bias_flag = bias
self.w_init = w_init
self.c_init = c_init
self.W = nn.ParameterList([nn.Parameter(torch.Tensor(out_features, in_features),
requires_grad=True)
for _ in range(phm_dim)])
if self.bias_flag:
self.b = nn.ParameterList(
[nn.Parameter(torch.Tensor(out_features), requires_grad=True) for _ in range(phm_dim)]
)
else:
self.register_parameter("b", None)
self.reset_parameters()
def reset_parameters(self):
if self.w_init == "phm":
W_init = phm_init(phm_dim=self.phm_dim, in_features=self.in_features, out_features=self.out_features)
for W_param, W_i in zip(self.W, W_init):
W_param.data = W_i.data
elif self.w_init == "glorot-normal":
for i in range(self.phm_dim):
self.W[i] = glorot_normal(self.W[i])
elif self.w_init == "glorot-uniform":
for i in range(self.phm_dim):
self.W[i] = glorot_uniform(self.W[i])
else:
raise ValueError
if self.bias_flag:
self.b[0].data.fill_(0.0)
for bias in self.b[1:]:
bias.data.fill_(0.2)
if not self.shared_phm:
phm_rule = get_multiplication_matrices(phm_dim=self.phm_dim, type=self.c_init)
for i, init_data in enumerate(phm_rule):
self.phm_rule[i].data = init_data
def forward(self, x: torch.Tensor, phm_rule: Union[None, nn.ParameterList] = None) -> torch.Tensor:
# #ToDo modify forward() functional so it can handle shared phm-rule contribution matrices.
return matvec_product(W=self.W, x=x, bias=self.b, phm_rule=self.phm_rule)
def __repr__(self):
return '{}(in_features={}, out_features={}, ' \
'phm_dim={}, ' \
'bias={}, w_init={}, c_init={}, ' \
'learn_phm={})'.format(self.__class__.__name__,
self.in_features,
self.out_features,
self.phm_dim,
self.bias_flag,
self.w_init,
self.c_init,
self.learn_phm)

implementing linear layer with PHM-layer

Hi
thanks for sharing your codes. I am a bit confused on finding the implementation of PHM-layer and how I can turn a linear layer to the more efficient one using the method in the paper to train the models, could you kindly guide me?
I found this line

self.W_r = nn.Parameter(torch.Tensor(self.out_features, self.in_features), requires_grad=True)
not sure if this is the correct one I am looking for, but this seems that linear layer has 4 matrices of size of the original linear layer, then this is even more parameters, could you kindly comment on this?
thanks

AssertionError: Argument `in_features`=50 is not divisble be `phm_dim`4

Hi,

When I run the code via bash run_script_hiv_phm4.sh

I get the following error:

Traceback (most recent call last):
File "train_hiv.py", line 636, in
main()
File "train_hiv.py", line 569, in main
model = UPH_SC_ADD(phm_dim=phm_dim, learn_phm=learn_phm, phm_rule=phm_rule,
File "/ogb/phc-gnn-master/phc/hypercomplex/undirectional/models.py", line 134, in init
self.convs[i] = PHMMessagePassing(in_features=in_dim, out_features=out_dim, bias=bias,
File "/ogb/phc-gnn-master/phc/hypercomplex/undirectional/messagepassing.py", line 494, in init
self.transform = PHMGINEConvSoftmax(in_features, out_features, phm_dim, phm_rule, learn_phm,
File "/ogb/phc-gnn-master/phc/hypercomplex/undirectional/messagepassing.py", line 277, in init
self.transform = PHMMLP(in_features=in_features, out_features=out_features, phm_dim=phm_dim,
File "/phc-gnn-master/phc/hypercomplex/layers.py", line 324, in init
self.linear1 = PHMLinear(in_features=in_features, out_features=int(factor*out_features),
File "/ogb/phc-gnn-master/phc/hypercomplex/layers.py", line 231, in init
assert in_features % phm_dim == 0, f"Argument in_features={in_features} is not divisble be phm_dim{phm_dim}"
AssertionError: Argument in_features=50 is not divisble be phm_dim4

The default embedding dimension is 200. Does this cause this error?

kronecker product implementation and difference with torch.kron

Hi
I tried to test your kronecker product implementation and compare it with torch implementation, for the matrices of the dimension on the example you provided in #1 :

def kronecker_product1(a, b):
    siz1 = torch.Size(torch.tensor(a.shape[-2:]) * torch.tensor(b.shape[-2:]))
    res = a.unsqueeze(-1).unsqueeze(-3) * b.unsqueeze(-2).unsqueeze(-4)
    siz0 = res.shape[:-4]
    out = res.reshape(siz0 + siz1)
    return out

def kronecker_product2(a, b):
   return torch.kron(a, b)

Now lets test the two versions:

a = torch.rand((4, 4, 4))
b = torch.rand((4, 64, 32))
result1 = kronecker_product1(a, b)
print("result 1 ", result1.shape)
result2 = kronecker_product2(a, b)
print("result 2 ", result2.shape)

The results are not the same and even dimension-wise they differ:

result 1  torch.Size([4, 256, 128])
result 2  torch.Size([16, 256, 128])

Could you kindly assist me how I can use the torch.kron implementation and which modifications are needed?

thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.