Skip to content

Commit

Permalink
added-feedforward-net
Browse files Browse the repository at this point in the history
  • Loading branch information
anna-grim committed Oct 26, 2023
1 parent 5b62912 commit 5a8c606
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 27 deletions.
6 changes: 3 additions & 3 deletions src/deep_neurographs/densegraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ def check_aligned(self, pred_xyz_i, pred_xyz_j):
target_dist = max(target_dist, 1)

ratio = min(pred_dist, target_dist) / max(pred_dist, target_dist)
if ratio < 0.6 and pred_dist > 25:
if ratio < 0.5 and pred_dist > 15:
return False
elif ratio < 0.25:
elif ratio < 0.2:
return False

# Compare projected predicted path
Expand All @@ -94,7 +94,7 @@ def check_aligned(self, pred_xyz_i, pred_xyz_j):

intersection = proj_nodes.intersection(set(target_path))
overlap = len(intersection) / len(target_path)
if overlap < 0.5 and pred_dist > 25:
if overlap < 0.5 and pred_dist > 15:
return False
elif overlap < 0.2:
return False
Expand Down
24 changes: 10 additions & 14 deletions src/deep_neurographs/feature_extraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

from deep_neurographs import geometry_utils, utils

NUM_POINTS = 10
WINDOW_SIZE = [6, 6, 6]
NUM_POINTS = 5
WINDOW_SIZE = [5, 5, 5]

NUM_IMG_FEATURES = NUM_POINTS
NUM_SKEL_FEATURES = 11
Expand Down Expand Up @@ -178,21 +178,17 @@ def build_feature_submatrix(neurograph, feat_dict, shift):


# -- Utils --
def compute_num_features(features):
num_features = 0
for key in features.keys():
num_features += features[key][0]
return num_features
def compute_num_features():
return NUM_SKEL_FEATURES # NUM_IMG_FEATURES +


def combine_feature_vecs(features):
vec = None
for key in features.keys():
if vec is None:
vec = features[key]
else:
vec = np.concatenate((vec, features[key]), axis=1)
return vec
for edge in features["skel"].keys():
for feat_key in [key for key in features.keys() if key != "skel"]:
features["skel"][edge] = np.concatenate(
(features["skel"][edge], features[feat_key][edge])
)
return features["skel"]


"""
Expand Down
2 changes: 1 addition & 1 deletion src/deep_neurographs/geometry_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def get_profile(
for xyz in xyz_arr:
img_chunk = utils.read_img_chunk(img, xyz, window_size)
profile.append(np.max(img_chunk))
return profile
return np.array(profile)


def get_coords(xyz_arr, anisotropy=[1.0, 1.0, 1.0]):
Expand Down
43 changes: 43 additions & 0 deletions src/deep_neurographs/neural_networks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from torch import nn


class FeedFowardNet(nn.Module):
def __init__(self, num_features, depth=3):
nn.Module.__init__(self)

# Parameters
assert depth < num_features
self.depth = depth
self.num_features = num_features

# Layers
print("Network Architecture...")
self.activation = nn.ELU()
self.dropout = nn.Dropout(p=0.2)
for d in range(self.depth):
D_in = num_features // max(d, 1)
D_out = num_features // (d + 1)
self.add_fc_layer(d, D_in, D_out)
self.last_fc = nn.Linear(D_out, 1)
self.sigmoid = nn.Sigmoid()

def forward(self, x):
for d in range(self.depth):
fc_d = getattr(self, "fc{}".format(d))
x = self.activation(self.dropout(fc_d(x)))
x = self.last_fc(x)
return self.sigmoid(x)

def add_fc_layer(self, d, D_in, D_out):
setattr(self, "fc{}".format(d), nn.Linear(D_in, D_out))
print(" {} --> {}".format(D_in, D_out))


class ConvNet(nn.Module):
def __init__(self, input_dims, depth=3):
pass


class MultiModalNet(nn.Module):
def __init__(self, feature_vec_shape, img_patch_shape):
pass
2 changes: 1 addition & 1 deletion src/deep_neurographs/neurograph.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ def init_targets(self, target_neurograph, target_densegraph):
xyz_j = self.nodes[j]["xyz"]
proj_xyz_i, d_i = target_neurograph.get_projection(xyz_i)
proj_xyz_j, d_j = target_neurograph.get_projection(xyz_j)
if d_i > 15 or d_j > 15:
if d_i > 10 or d_j > 10:
continue

# Get corresponding edges on target
Expand Down
88 changes: 81 additions & 7 deletions src/deep_neurographs/train.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,80 @@
import os.path as osp
from random import sample

import torch
import torch_geometric.transforms as T
import lightning.pytorch as pl
import numpy as np
from sklearn.metrics import roc_auc_score
from torch_geometric.datasets import Planetoid
from torch_geometric.nn import GCNConv
import torch
import torch.nn.functional as F
from torch_geometric.utils import negative_sampling
from torch.utils.data import Dataset
from torcheval.metrics.functional import (
binary_accuracy,
binary_f1_score,
binary_precision,
binary_recall,
)


# Cross Validation
def get_kfolds(train_data, k):
folds = []
samples = set(train_data)
num_samples = int(np.floor(len(train_data) / k))
assert num_samples > 0, "Sample size is too small for {}-folds".format(k)
for i in range(k):
if i < k - 1:
samples_i = sample(samples, num_samples)
samples = samples.difference(samples_i)
folds.append(set(samples_i))
else:
folds.append(samples)
return folds


# Neural Network Training
class EdgeDataset(Dataset):
def __init__(self, data, labels):
self.data = data.astype(np.float32)
self.labels = labels.astype(np.float32)

def __len__(self):
return len(self.data)

def __getitem__(self, idx):
return {"data": self.data[idx], "label": self.labels[idx]}


class LitNeuralNet(pl.LightningModule):
def __init__(self, net):
super().__init__()
self.net = net

def configure_optimizers(self):
optimizer = torch.optim.Adam(self.parameters(), lr=1e-3)
return optimizer

def training_step(self, batch, batch_idx):
x = self.get_example(batch, "data")
y = self.get_example(batch, "label")
y_hat = self.net(x)
return F.mse_loss(y_hat, y)

def test_step(self, batch, batch_idx):
x = self.get_example(batch, "data")
y = self.get_example(batch, "label")
y_hat = self.net(x)
self.compute_stats(y_hat, y)

def compute_stats(self, y_hat, y):
y_hat = torch.flatten(y_hat)
y = torch.flatten(y).to(torch.int)
self.log("accuracy", binary_accuracy(y_hat, y))
self.log("precision", binary_precision(y_hat, y))
self.log("recall", binary_recall(y_hat, y))
self.log("f1", binary_f1_score(y_hat, y))

def get_example(self, batch, key):
return batch[key].view(batch[key].size(0), -1)


def train(model, optimizer, criterion, train_data):
Expand Down Expand Up @@ -48,6 +117,10 @@ def test(model, data):


"""
from torch_geometric.datasets import Planetoid
from torch_geometric.nn import GCNConv
import torch_geometric.transforms as T
if __name__ == "__main__":
if torch.cuda.is_available():
device = torch.device('cuda')
Expand All @@ -62,14 +135,15 @@ def test(model, data):
T.RandomLinkSplit(num_val=0.05, num_test=0.1, is_undirected=True,
add_negative_train_samples=False),
])
path = osp.join(osp.dirname(osp.realpath(__file__)), '..', 'data', 'Planetoid')
path = os.path.join(
os.path.dirname(os.path.realpath(__file__)), '..', 'data', 'Planetoid'
)
dataset = Planetoid(path, name='Cora', transform=transform)
# After applying the `RandomLinkSplit` transform, the data is transformed from
# a data object to a list of tuples (train_data, val_data, test_data), with
# each element representing the corresponding split.
train_data, val_data, test_data = dataset[0]
print(train_data)
model = Net(dataset.num_features, 128, 64).to(device)
Expand Down
1 change: 0 additions & 1 deletion tests/test_single_graph_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"""

import networkx as nx
import torch
import torch_geometric.transforms as T

Expand Down

0 comments on commit 5a8c606

Please sign in to comment.