Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
5bd9eee
Added checking for nan in topo_ae training
Jun 11, 2023
a5e5437
Added spectrogram support
HubertPalo Jun 19, 2023
2af4dfb
Check patience + new hyperparameters for ConvTAE
Jun 26, 2023
2f0e0c2
Test topo_ae
Jul 11, 2023
59a1895
LSTM from Vinicius - 1st version
Aug 3, 2023
cad97b1
LSTM - added patience
Aug 7, 2023
d6c081a
Add loss and acc plots
viniandrs Aug 9, 2023
16db5b6
plot loss fixed
viniandrs Aug 9, 2023
f761d86
Have accuracy plots
viniandrs Aug 10, 2023
1ecbba9
Fix topo_ae + lstm
Aug 14, 2023
f507b61
add lstm
Aug 14, 2023
1f8daba
updated version for topo_ae
HubertPalo Sep 15, 2023
aa1af49
Test
HubertPalo Sep 15, 2023
f2fd2fa
Test
HubertPalo Sep 15, 2023
228e238
Update topo_ae.py
HubertPalo Sep 15, 2023
ae8ff87
Update topo_ae.py
HubertPalo Sep 15, 2023
ec94cf0
removing optimizer features after using
HubertPalo Sep 15, 2023
edee51e
added groups and convtae2d
HubertPalo Sep 19, 2023
6c9b3d5
add pca
HubertPalo Oct 11, 2023
c2acfa7
Merge branch 'master' into autoencoders
HubertPalo Oct 18, 2023
057473b
Delete masked_ae.py
HubertPalo Oct 18, 2023
54a7f3d
Update model_submodules.py
HubertPalo Oct 18, 2023
eb151f2
print model
HubertPalo Oct 18, 2023
3b40eb0
Update model_submodules.py
HubertPalo Oct 18, 2023
9b626bd
Update model_submodules.py
HubertPalo Oct 19, 2023
5a4579f
Update topo_ae.py
HubertPalo Nov 26, 2023
ea73599
Update topo_ae.py
HubertPalo Nov 28, 2023
2506f0a
Update topo_ae.py
HubertPalo Dec 4, 2023
19f73c1
Update topo_ae.py
HubertPalo Dec 4, 2023
0a4f8c7
Update topo_ae.py
HubertPalo Dec 6, 2023
13179df
Update topo_ae.py
HubertPalo Dec 6, 2023
b5df0a6
Update topo_ae.py
HubertPalo Dec 6, 2023
d46f279
Update topo_ae.py
HubertPalo Dec 6, 2023
3f38779
Update topo_ae.py
HubertPalo Dec 6, 2023
eeecbe2
Update topo_ae.py
HubertPalo Dec 17, 2023
3900a6e
Update topo_ae.py
HubertPalo Dec 17, 2023
ff93015
Update dimred_evaluator.py
HubertPalo Feb 17, 2024
c6df58e
Update topo_ae.py
HubertPalo Feb 23, 2024
c28135c
ConvTAE rebuilt
HubertPalo Feb 27, 2024
b963eb1
Update topo_ae_model.py
HubertPalo Feb 28, 2024
e059c7e
Update topo_ae_model.py
HubertPalo Feb 28, 2024
50ee7d7
fix
HubertPalo Feb 28, 2024
eff9d73
Update topo_ae_model.py
HubertPalo Feb 28, 2024
4546979
Update topo_ae_model.py
HubertPalo Feb 28, 2024
0d576e8
Update topo_ae_model.py
HubertPalo Mar 16, 2024
3570ae2
Update topo_ae_model.py
HubertPalo Mar 16, 2024
55adbd2
Update topo_ae_model.py
HubertPalo Mar 16, 2024
b59344a
Update topo_ae_model.py
HubertPalo Mar 16, 2024
4cbf66a
Update topo_ae_model.py
HubertPalo Mar 16, 2024
57f54b9
Update topo_ae_model.py
HubertPalo Mar 16, 2024
e6f803a
Update topo_ae_model.py
HubertPalo Mar 16, 2024
ea4d2d2
Update topo_ae_model.py
HubertPalo Mar 16, 2024
4a8d9c9
Added dropout
HubertPalo Mar 16, 2024
ac96084
Update topo_ae_model.py
HubertPalo Mar 16, 2024
92edd3a
Update topo_ae_model.py
HubertPalo Mar 17, 2024
d85e446
Update topo_ae_remade.py
HubertPalo Mar 17, 2024
c56b7b3
Update topo_ae_model.py
HubertPalo Mar 17, 2024
b4953cc
Update topo_ae_model.py
HubertPalo Mar 17, 2024
76ee47c
Update topo_ae_model.py
HubertPalo Mar 17, 2024
6d03b56
Update topo_ae_model.py
HubertPalo Mar 17, 2024
1f2889f
Update topo_ae_model.py
HubertPalo Mar 18, 2024
94a4298
Update topo_ae_model.py
HubertPalo Mar 18, 2024
8069fb6
Update topo_ae_model.py
HubertPalo Mar 18, 2024
19764c9
Update topo_ae_model.py
HubertPalo Mar 18, 2024
47a79d0
Update topo_ae_model.py
HubertPalo Mar 18, 2024
17c12c5
Update topo_ae_model.py
HubertPalo Mar 18, 2024
6caed0a
Update topo_ae_model.py
HubertPalo Mar 18, 2024
7ed96a1
Update topo_ae_model.py
HubertPalo Mar 18, 2024
ede49f5
Update topo_ae_model.py
HubertPalo Mar 18, 2024
7308b29
Update topo_ae_model.py
HubertPalo Mar 18, 2024
4da249c
Update topo_ae_model.py
HubertPalo Mar 18, 2024
630c90c
Update topo_ae_model.py
HubertPalo Mar 18, 2024
bff9d11
Update topo_ae_remade.py
HubertPalo Mar 19, 2024
772fa11
new version
HubertPalo Mar 21, 2024
a258976
Update topo_ae_model.py
HubertPalo Mar 21, 2024
61d3568
More conv layers
HubertPalo Apr 11, 2024
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
182 changes: 167 additions & 15 deletions src/librep/estimators/ae/torch/models/topological_ae/model_submodules.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,24 +314,176 @@ def forward(self, x):
x_reconst = self.decode(latent)
reconst_error = self.reconst_error(x, x_reconst)
return reconst_error, {'reconstruction_error': reconst_error}


class ConvTAE_def(AutoencoderModel):
"""Convolutional Topological Autoencoder - definitive version"""
def __init__(
self,
input_dims=(1, 180),
input_dims=(1, 180), # (6, 30) tambien funciona con input_dims[0]
latent_dim=10,
num_CL=3, # 2 a 5
size_CL=12, # 4 a 24
num_HL=3, # 2 a 5
size_HL=50,
down_HL=0,
kernel_size=5,
groups=1
):
"""Convolutional Autoencoder."""
# print('ConvTAE, Input:', input_dims,'Latent dim:', latent_dim, 'CL,HL', num_CL, size_CL, num_HL, size_HL)
super().__init__()
# Size of the connection between conv-hidden / hidden-conv
connection_size = size_CL*(input_dims[1]-num_CL*(kernel_size-1))
if num_CL == 0:
connection_size = input_dims[1]
# Defining the list of layers to use
encoder_list_layers = []
decoder_list_layers = []
# --------------------------------------------------------------
# -------------------- BUILDING THE ENCODER --------------------
# --------------------------------------------------------------
# CONVOLUTIONAL LAYERS -----------------------------------------
# --------------------------------------------------------------
# Check if num_CL == 0
if num_CL != 0:
# All convolutional layers (only sizes)
conv_layers = [(size_CL, size_CL) for i in range(num_CL)]
# Editing first convolutional layer
conv_layers[0] = (input_dims[0], size_CL)
# Updating encoder layers
for pair in conv_layers:
layer = nn.Conv1d(
in_channels=pair[0],
out_channels=pair[1],
kernel_size=kernel_size,
stride=1,
padding=0,
groups=groups
)
encoder_list_layers.append(layer)
encoder_list_layers.append(nn.ReLU())
# Add the "View" view
encoder_list_layers.append(View((-1, connection_size)))
# --------------------------------------------------------------
# HIDDEN LAYERS ------------------------------------------------
# --------------------------------------------------------------
# Create dimensions with the sizes of the layers as intermediate valus between connection and latent
dimensions = np.linspace(connection_size, latent_dim, num_HL+1).round().astype(int)
for index, dim in enumerate(dimensions[:-1]):
layer = nn.Linear(dim, dimensions[index+1])
encoder_list_layers.append(layer)
encoder_list_layers.append(nn.ReLU())
# All hidden layers (only sizes)
# hidden_layers = [(size_HL-(i-1)*down_HL, size_HL-i*down_HL) for i in range(num_HL)]
# First layer (last of convolutional layers)
# hidden_layers[0] = (connection_size, size_HL)
# Last layer (low dimensionality)
# hidden_layers[-1] = (size_HL-(num_HL-2)*down_HL, latent_dim)
# Updating encoder layers
# for pair in hidden_layers:
# layer = nn.Linear(pair[0], pair[1])
# encoder_list_layers.append(layer)
# encoder_list_layers.append(nn.ReLU())
# Delete the last ReLU()
encoder_list_layers.pop()
# Build the encoder
self.encoder = nn.Sequential(*encoder_list_layers)
# --------------------------------------------------------------
# -------------------- BUILDING THE DECODER --------------------
# --------------------------------------------------------------
# HIDDEN LAYERS ------------------------------------------------
# --------------------------------------------------------------
# All hidden layers (only sizes)
# hidden_layers = [(size_HL-(num_HL-i)*down_HL, size_HL-(num_HL-i+1)*down_HL) for i in range(num_HL)]
# First layer (low dimensionality)
# hidden_layers[0] = (latent_dim, size_HL-(num_HL-2)*down_HL)
# Last layer (first of convolutional layers)
# hidden_layers[-1] = (size_HL, connection_size)
# Updating decoder layers
# for pair in hidden_layers:
# layer = nn.Linear(pair[0], pair[1])
# decoder_list_layers.append(layer)
# decoder_list_layers.append(nn.ReLU())
# Reversing dimensions
dimensions = dimensions[::-1]
for index, dim in enumerate(dimensions[:-1]):
layer = nn.Linear(dim, dimensions[index+1])
decoder_list_layers.append(layer)
decoder_list_layers.append(nn.ReLU())
# Adding the "View" view before the last ReLU()
if num_CL != 0:
last_relu = decoder_list_layers.pop()
decoder_list_layers.append(View((-1, size_CL, input_dims[1]-num_CL*(kernel_size-1))))
decoder_list_layers.append(last_relu)
# --------------------------------------------------------------
# CONVOLUTIONAL LAYERS -----------------------------------------
# --------------------------------------------------------------
# All convolutional layers (only sizes)
# Check if num_CL == 0
if num_CL != 0:
conv_layers = [(size_CL, size_CL) for i in range(num_CL)]
# Editing last convolutional layer
conv_layers[-1] = (size_CL, input_dims[0])
# Updating decoder layers
for pair in conv_layers:
layer = nn.ConvTranspose1d(
in_channels=pair[0],
out_channels=pair[1],
kernel_size=kernel_size,
stride=1,
padding=0
)
decoder_list_layers.append(layer)
decoder_list_layers.append(nn.ReLU())
# Build the decoder
self.decoder = nn.Sequential(*decoder_list_layers)
# print(self.encoder, '\n')
# print(self.decoder)
self.reconst_error = nn.MSELoss()

def encode(self, x):
"""Compute latent representation using convolutional autoencoder."""
return self.encoder(x)

def decode(self, z):
"""Compute reconstruction using convolutional autoencoder."""
return self.decoder(z)

def forward(self, x):
"""Apply autoencoder to batch of input images.
Args:
x: Batch of images with shape [bs x channels x n_row x n_col]
Returns:
tuple(reconstruction_error, dict(other errors))
"""
latent = self.encode(x)
x_reconst = self.decode(latent)
# print('LATENT', latent.shape, 'XRECONST', x_reconst.shape)
reconst_error = self.reconst_error(x, x_reconst)
return reconst_error, {'reconstruction_error': reconst_error}


class ConvTAE_def_2d(AutoencoderModel):
"""Convolutional Topological Autoencoder - definitive version"""
def __init__(
self,
input_dims=(1, 6, 60), # (6, 30) tambien funciona con input_dims[0]
latent_dim=10,
num_CL=3, # 2 a 5
size_CL=12, # 4 a 24
num_HL=3, # 2 a 5
size_HL=50
size_HL=50,
down_HL=0,
kernel_size=(6,2), # (6,n) (3,n) con stride 3
stride=1,
padding=0
):
"""Convolutional Autoencoder."""
print('ConvTAE, Input:', input_dims,'Latent dim:', latent_dim)
# print('ConvTAE, Input:', input_dims,'Latent dim:', latent_dim, 'CL,HL', num_CL, size_CL, num_HL, size_HL)
super().__init__()
# Size of the connection between conv-hidden / hidden-conv
connection_size = size_CL*(input_dims[1]-num_CL*4)
connection_size = size_CL*(input_dims[1]*input_dims[2]-num_CL*(kernel_size-1))
if num_CL == 0:
connection_size = input_dims[1]
# Defining the list of layers to use
Expand All @@ -347,13 +499,13 @@ def __init__(
# All convolutional layers (only sizes)
conv_layers = [(size_CL, size_CL) for i in range(num_CL)]
# Editing first convolutional layer
conv_layers[0] = (1, size_CL)
conv_layers[0] = (input_dims[0], size_CL)
# Updating encoder layers
for pair in conv_layers:
layer = nn.Conv1d(
in_channels=pair[0],
out_channels=pair[1],
kernel_size=5,
kernel_size=kernel_size,
stride=1,
padding=0
)
Expand All @@ -365,11 +517,11 @@ def __init__(
# HIDDEN LAYERS ------------------------------------------------
# --------------------------------------------------------------
# All hidden layers (only sizes)
hidden_layers = [(size_HL, size_HL) for i in range(num_HL)]
hidden_layers = [(size_HL-(i-1)*down_HL, size_HL-i*down_HL) for i in range(num_HL)]
# First layer (last of convolutional layers)
hidden_layers[0] = (connection_size, size_HL)
# Last layer (low dimensionality)
hidden_layers[-1] = (size_HL, latent_dim)
hidden_layers[-1] = (size_HL-(num_HL-2)*down_HL, latent_dim)
# Updating encoder layers
for pair in hidden_layers:
layer = nn.Linear(pair[0], pair[1])
Expand All @@ -385,9 +537,9 @@ def __init__(
# HIDDEN LAYERS ------------------------------------------------
# --------------------------------------------------------------
# All hidden layers (only sizes)
hidden_layers = [(size_HL, size_HL) for i in range(num_HL)]
hidden_layers = [(size_HL-(num_HL-i)*down_HL, size_HL-(num_HL-i+1)*down_HL) for i in range(num_HL)]
# First layer (low dimensionality)
hidden_layers[0] = (latent_dim, size_HL)
hidden_layers[0] = (latent_dim, size_HL-(num_HL-2)*down_HL)
# Last layer (first of convolutional layers)
hidden_layers[-1] = (size_HL, connection_size)
# Updating decoder layers
Expand All @@ -398,7 +550,7 @@ def __init__(
# Adding the "View" view before the last ReLU()
if num_CL != 0:
last_relu = decoder_list_layers.pop()
decoder_list_layers.append(View((-1, size_CL, input_dims[1]-num_CL*4)))
decoder_list_layers.append(View((-1, size_CL, input_dims[1]-num_CL*(kernel_size-1))))
decoder_list_layers.append(last_relu)
# --------------------------------------------------------------
# CONVOLUTIONAL LAYERS -----------------------------------------
Expand All @@ -408,21 +560,21 @@ def __init__(
if num_CL != 0:
conv_layers = [(size_CL, size_CL) for i in range(num_CL)]
# Editing last convolutional layer
conv_layers[-1] = (size_CL, 1)
conv_layers[-1] = (size_CL, input_dims[0])
# Updating decoder layers
for pair in conv_layers:
layer = nn.ConvTranspose1d(
in_channels=pair[0],
out_channels=pair[1],
kernel_size=5,
kernel_size=kernel_size,
stride=1,
padding=0
)
decoder_list_layers.append(layer)
decoder_list_layers.append(nn.ReLU())
# Build the decoder
self.decoder = nn.Sequential(*decoder_list_layers)
# print(self.encoder)
# print(self.encoder, '\n')
# print(self.decoder)
self.reconst_error = nn.MSELoss()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ def __init__(self, lam=1., autoencoder_model='ConvolutionalAutoencoder',
ae_kwargs: Kewords to pass to `ConvolutionalAutoencoder` class
toposig_kwargs: Keywords to pass to `TopologicalSignature` class
"""
print('Topologically Regularized', autoencoder_model)
super().__init__()
self.lam = lam
ae_kwargs = ae_kwargs if ae_kwargs else {}
Expand Down Expand Up @@ -59,8 +58,6 @@ def forward(self, x):

# Use reconstruction loss of autoencoder
ae_loss, ae_loss_comp = self.autoencoder(x)
# print('TEST'*20)
# print(self.topo_sig(x_distances, latent_distances))
topo_error, topo_error_components = self.topo_sig(
x_distances, latent_distances)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ def __init__(self, sort_selected=False, use_cycles=False,
##self.signature_calculator = AlephPersistenHomologyCalculation(
## compute_cycles=use_cycles, sort_selected=sort_selected)
# else:
print('Using python to compute signatures')
self.signature_calculator = PersistentHomologyCalculation()

def _get_pairings(self, distances):
Expand Down
82 changes: 82 additions & 0 deletions src/librep/estimators/convaelstm/convaelstm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import torch
import torch.nn as nn
import torch.nn.functional as F


class ConvAELSTM_part_ConvAE(nn.Module):
def __init__(self, start_dim, n_channels, kernel_size=3, stride=2, padding=0, filter_size=64):
super().__init__()
self.start_dim = start_dim
self.model = nn.Sequential(
nn.Conv1d(in_channels=n_channels,out_channels=filter_size,kernel_size=kernel_size,stride=stride,padding=padding),
nn.MaxPool1d(kernel_size=kernel_size, stride=stride, padding=padding),
nn.ConvTranspose1d(in_channels=filter_size,out_channels=n_channels,kernel_size=kernel_size,stride=stride,padding=padding),
nn.ReLU())
print('MODEL', self.model)

def forward(self, x):
return self.model(x)


class ConvAELSTM_part_LSTM(nn.Module):
def __init__(self, latent_dim, device, n_layers, input_size):
super(ConvAELSTM_part_LSTM, self).__init__()
self.device = device
self.n_layers = n_layers
self.lstm = nn.LSTM(
hidden_size = latent_dim,
input_size=input_size,
num_layers=n_layers,
batch_first=True
)
self.latent_dim=latent_dim

def forward(self, x):
# h_0 = torch.zeros(self.n_layers, x.shape[0], self.latent_dim).float().to(self.device)
# c_0 = torch.zeros(self.n_layers, x.shape[0], self.latent_dim).float().to(self.device)
h_n, _ = self.lstm(x)
return h_n[:,-1] # returning the last hidden state


class ConvAELSTM_part_Softmax(nn.Module):
def __init__(self, latent_dim, n_classes):
super().__init__()
self.fully_connected = nn.Linear(latent_dim, n_classes)

def forward(self, x):
x = self.fully_connected(x)
x = F.log_softmax(x, dim=1)
return x


class ConvAELSTM_full(nn.Module):
def __init__(self, latent_dim, device, n_layers, input_size, n_classes, sequence_length=60):
super().__init__()
self.sequence_length = sequence_length
self.input_size = input_size
self.conv = ConvAELSTM_part_ConvAE(start_dim=60, n_channels=input_size)
self.lstm = ConvAELSTM_part_LSTM(latent_dim=latent_dim, device=device, n_layers=n_layers, input_size=input_size)
self.softmax = ConvAELSTM_part_Softmax(latent_dim=latent_dim, n_classes=n_classes)

# Reshape the dataset into LSTM input
def _reshapeToLSTM(self, tensor):
# tensor = torch.reshape(tensor, (tensor.shape[0], self.input_size, self.sequence_length)) # (n_samples, 6, 60)
return torch.permute(tensor, (0, 2, 1)) # (n_samples, seq_length, H_in)


def forward(self, x):
# print('x before conv', x.shape)
x = self.conv(x)
# print('x after conv', x.shape)
x = self.lstm(self._reshapeToLSTM(x))
x = self.softmax(x)
return x

def reduce_dim(self, x):
self.conv.eval()
self.lstm.eval()
print('x before conv', x.shape)
x = self.conv(x)
print('x after conv', x.shape)
x = self.lstm(self._reshapeToLSTM(x))
return x
4 changes: 2 additions & 2 deletions src/librep/metrics/dimred_evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,12 @@ def evaluate(
if self.use_local_property:
# res = np.mean([drm.Qlocal for drm in drms])
res = drm.Qlocal
result["local property"] = res
result["local property"] = float(res)

if self.use_global_property:
# res = np.mean([drm.Qglobal for drm in drms])
res = drm.Qglobal
result["global property"] = res
result["global property"] = float(res)

return result

Expand Down
1 change: 1 addition & 0 deletions src/librep/transforms/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .fft import *
from .lstm import *
from .resampler import *
from .umap import *
from .tsne import *
Expand Down
Loading