Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .idea/blis.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The first implementation utilizes numpy to compute the scattering moments and wr
## Installation

Create a conda environment

ss
~~~
conda create -n blis python=3.9`
conda activate blis
Expand Down
4 changes: 2 additions & 2 deletions blis/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import os
DATA_DIR = os.path.join(os.path.dirname(__file__), '..', 'data')
LOG_DIR = os.path.join(os.path.dirname(__file__), '..', 'logs')
DATA_DIR = os.path.join(os.path.dirname(__file__), 'data')
LOG_DIR = os.path.join(os.path.dirname(__file__), 'logs')
Binary file added blis/data/.DS_Store
Binary file not shown.
6 changes: 6 additions & 0 deletions blis/data/synthetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ def synthetic_data_loader(seed, subdata_type, task_type, batch_size, transform=N
label_path = os.path.join(DATA_DIR,"synthetic",subdata_type,task_type,"label.npy")
graph_path = os.path.join(DATA_DIR,"synthetic",subdata_type,"adjacency_matrix.npy")
signal_path = os.path.join(DATA_DIR,"synthetic",subdata_type,"graph_signals.npy")


#print(f'This is the label path {label_path}')

# Load data
X = np.load(signal_path, allow_pickle=True)
Expand Down Expand Up @@ -65,7 +68,10 @@ def synthetic_scattering_data_loader(seed, subdata_type, task_type, batch_size=0

moments = []
for layer_path in layer_paths:
print(os.path.exists(layer_path))
print(f'this is layer path {layer_path}')
for moment in scattering_dict["moments"]:
print(f'monent is {moment}')
moments.append(np.load(os.path.join(layer_path, "moment_{}.npy".format(moment))))

X = np.concatenate(moments,1)
Expand Down
2 changes: 1 addition & 1 deletion blis/models/GCN.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import torch.nn as nn
import torch.nn.functional as F
from torch_geometric.data import Data, DataLoader
from torch_geometric.nn import GCNConv
from torch_geometric.nn import GCNConv, global_mean_pool

class GCN(nn.Module):
def __init__(self, in_features,hidden_channels, num_classes):
Expand Down
9 changes: 5 additions & 4 deletions blis/models/GPS.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@
Sequential,
)

from torch_geometric.nn import GINEConv, GPSConv, global_add_pool
#from torch_geometric.nn.attention import PerformerAttention
from torch_geometric.nn import GINEConv, GPSConv,GCN, global_add_pool,global_mean_pool
from torch_geometric.nn.attention import PerformerAttention
from torch_geometric.nn import GCNConv
from typing import Any, Dict, Optional



class RedrawProjection:
def __init__(self, model: torch.nn.Module,
redraw_interval: Optional[int] = None):
Expand Down Expand Up @@ -54,8 +56,7 @@ def __init__(self, in_features: int, channels: int, pe_dim: int, num_layers: int
ReLU(),
Linear(channels, channels),
)
conv = GPSConv(channels = channels, conv = GINEConv(nn), heads=4,
attn_dropout=attn_dropout)
conv = GPSConv(channels = channels, conv = GINEConv(nn), heads=4)
self.convs.append(conv)

self.mlp = Sequential(
Expand Down
76 changes: 57 additions & 19 deletions blis/models/scattering_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
from itertools import product
import os

print('Started running the scattering transform file')
def relu(x):
return x * (x > 0)

def reverse_relu(x):
return relu(-x)

def scattering_transform(x, scattering_type, wavelets, num_layers, highest_moment, save_dir):
def scattering_transform(x, scattering_type, input_wavelets, num_layers, highest_moment, save_dir,wavelet_type):
'''
Computes the graph scattering transform

Expand All @@ -23,34 +24,45 @@ def scattering_transform(x, scattering_type, wavelets, num_layers, highest_momen
raise ValueError("Invalid scattering type. Accepted values are 'blis' or 'modulus'.")

if len(x.shape) == 3:
num_signals, N ,num_features = x.shape
num_signals, N ,num_features = x.shape
if len(x.shape) == 2:
num_signals, N = x.shape
num_signals, N = x.shape
num_features= 1

J = len(wavelets)


#print(f'this is x at the beginning : {x[0]}')

print('The number of signals is', num_signals)
print('The number of features is', num_features)
print('The number of wavelets is', N)
print(f'this is the shape of x initially in scattering transform: {x.shape}')

print(f'this is the shape of wavelets in scattering transform initially: {input_wavelets.shape}')
J = len(input_wavelets)
print(f'this is J = {J}')

# save the zero order scattering coefficients:
zero_save_dir = os.path.join(save_dir, f'layer_0')
print(f'This is the zero save dir: {zero_save_dir}')
if not os.path.exists(zero_save_dir):
os.makedirs(zero_save_dir)
for moment_ind in range(highest_moment):
full_path = os.path.join(zero_save_dir, f"moment_{moment_ind + 1}.npy")
coeffs_zero = np.zeros((num_signals, 1, num_features, highest_moment))

for moment in range(1, highest_moment + 1):
coeffs_zero[:, 0, :, moment-1] = np.sum(np.power(x, moment), axis = 1)
coeffs_zero[:, 0, :, moment-1] = np.sum(np.power(x, moment), axis = 1)

np.save(full_path, coeffs_zero[:,:,:,moment_ind])

# num_layers is the LARGEST layer size
# layer_num is the largest layer size within the loop
# layer is the layer number looping up to layer_num
# layer is the layer number looping up to layer_num

for layer_num in range(1, num_layers+1):

if save_dir is not None:
layer_dir = os.path.join(save_dir, f'layer_{layer_num}')
print(f'this is the layer dir: {layer_dir}')

if os.path.exists(layer_dir):
# pass over this iteration of the for loop
Expand All @@ -60,36 +72,62 @@ def scattering_transform(x, scattering_type, wavelets, num_layers, highest_momen
if scattering_type == 'blis':
combinations = list(product(range(J), [relu, reverse_relu], repeat = layer_num))
num_activation = 2
print(f'this is the number of combinations: {len(combinations)}')
else:
combinations = list(product(range(J), [np.abs], repeat = layer_num))
num_activation = 1

# store the output
coeffs = np.zeros((num_signals, (J*num_activation)**layer_num, num_features, highest_moment))
print(f'This is the shape of coeffs: {coeffs.shape}')


for ind, comb in enumerate(combinations):
layer_out = x
print(f'this is the number of iterations: {ind+1} out of {len(combinations)}')
layer_out = x
#print(f'this is the shape of layer out: {layer_out.shape}')
for layer in range(layer_num):
wavelet_index = comb[layer * 2]
print(f'This is the wavelet index: {wavelet_index}')
#print(f'this is the shape of wavelets in scattering transform initially: {wavelets.shape}')
activation = comb[layer * 2 + 1]
wavelet = wavelets[wavelet_index]
wavelet_transform = np.einsum('ik, nkf->nif', wavelet, layer_out)
print(f'This is the activation function: {activation}')
if wavelet_type == 'W2':
wavelet=input_wavelets[wavelet_index]
#wavelet_transform=input_wavelets
#print(f'this is the shape of wavelet in scattering transform: {wavelet.shape}')
#print(f'this is the shape of layer out right before einstein summation: {layer_out.shape}')
wavelet_transform=np.einsum('ik, nkf->nif', wavelet, layer_out)
print(f"this is the dimension of the wavelet transform:{wavelet_transform.shape}")
else:
wavelet = input_wavelets[wavelet_index]
#print(f'this is the shape of wavelet in scattering transform: {wavelet.shape}')
wavelet_transform = np.einsum('ik, nkf->nif', wavelet, layer_out)
#print(f'this is the shape of wavelet transform: {wavelet_transform.shape}')

layer_out = activation(wavelet_transform)

# the scattering transform along one path has now been calculated for all signals
# layer_out has shape [num_signals, num_vertices, num_features]
print(f'this is the shape of layer out after transform: {layer_out.shape}')

# the scattering transform along one path has now been calculated for all signals
# layer_out has shape [num_signals, num_vertices, num_features]
for moment in range(1, highest_moment + 1):
coeffs[:, ind, :, moment-1] = np.sum(np.power(layer_out, moment), axis = 1)


print(moment)
print(f'this is the layer out dimension in moment: {layer_out.shape}')
coeffs[:, ind, :, moment-1] = np.sum(np.power(layer_out, moment), axis=1)
print(f'this is the shape of coeffs after moment: {coeffs.shape}')


# all of the coeffs have been calculated for a given layer and number of moments
# write them to memory

#create a directory for each layer
#create a directory for each layer
if save_dir is not None:
if not os.path.exists(layer_dir):
os.makedirs(layer_dir)
for moment_ind in range(highest_moment):
full_path = os.path.join(layer_dir, f"moment_{moment_ind + 1}.npy")
print(f'This is the full path {full_path}')
np.save(full_path, coeffs[:,:,:, moment_ind])

#return coeffs
#return coeffs
19 changes: 13 additions & 6 deletions blis/models/torch_geo_blis_module.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -22,7 +22,14 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
Expand Down Expand Up @@ -357,7 +364,7 @@
},
{
"cell_type": "code",
"execution_count": 97,
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
Expand Down Expand Up @@ -1847,9 +1854,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python (blis)",
"display_name": "base",
"language": "python",
"name": "blis"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
Expand All @@ -1861,7 +1868,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.18"
"version": "3.12.4"
},
"orig_nbformat": 4
},
Expand Down
Loading