Commit 4641d928 authored by Lukas Wolf's avatar Lukas Wolf
Browse files

load data batch wise into gpu mem

parent 6298acfe
......@@ -40,8 +40,8 @@ config['root_dir'] = '.'
# Choose task and dataset
##################################################################
#config['task'] = 'prosaccade-clf'
config['task'] = 'gaze-reg'
config['task'] = 'prosaccade-clf'
#config['task'] = 'gaze-reg'
#config['task'] = 'angle-reg'
if config['task'] != 'prosaccade-clf':
......
from numpy.core.numeric import cross
from config import config
import logging
import torch
import torch.nn as nn
import os
import numpy as np
from sklearn.model_selection import train_test_split
from torch_models.torch_utils.custom_losses import angle_loss
from torch_models.torch_utils.utils import compute_loss, compute_accuracy
from sklearn.model_selection import train_test_split
from torch_models.torch_utils.plot import plot_array
from torch_models.torch_utils.dataloader import create_dataloader
from torch_models.CNN.CNN import CNN
......@@ -41,15 +38,15 @@ class Ensemble_torch:
elif config['task'] == 'angle-reg':
self.loss_fn = angle_loss
elif config['task'] == 'gaze-reg':
self.loss_fn = nn.MSELoss
self.loss_fn = nn.MSELoss()
def run(self, x, y):
"""
Fit all the models in the ensemble and save them to the run directory
Inputs:
x: dataset as np.array
y: labels as np.array
"""
# Metrics to save across the ensemble
loss=[]
accuracy=[]
# Create a split
x = np.transpose(x, (0, 2, 1)) # (batch_size, samples, channels) to (bs, ch, samples) as torch conv layers want it
X_train, X_val, y_train, y_val = train_test_split(x, y, test_size=0.2, random_state=42)
......@@ -57,6 +54,9 @@ class Ensemble_torch:
train_dataloader = create_dataloader(X_train, y_train, batch_size=config['batch_size'])
test_dataloader = create_dataloader(X_val, y_val, batch_size=config['batch_size'])
# Metrics to save across the ensemble
loss=[]
accuracy=[]
# Fit the models
for i in range(len(self.models)):
logging.info("------------------------------------------------------------------------------------")
......@@ -73,32 +73,27 @@ class Ensemble_torch:
#pred[j] = pred[j] + pred_epoch
logging.info('Finished training model number {}/{} ...'.format(i+1, self.nb_models))
# Create the ensemble metrics
for j, pred_epoch in enumerate(pred):
print(f"compute loss epoch number {j}")
#pred_epoch = (pred_epoch/config['ensemble']).tolist() this is now done in compute_loss with the tensor
loss.append(compute_loss(loss_fn=self.loss_fn, dataloader=test_dataloader, pred_list=pred_epoch, nb_models=config['ensemble']))
#pred_epoch = np.round(pred_epoch,0) this is now done in compute_accuracy with the tensor
if config['task'] == 'prosaccade-clf':
#accuracy.append(np.mean((np.array(pred_epoch).reshape(-1)+np.array(pred_ensemble.targets).reshape(-1)-1)**2))
accuracy.append(compute_accuracy(dataloader=test_dataloader, pred_list=pred_epoch, nb_models=config['ensemble']))
# Adapt model name if necessary
if config['ensemble']>1:
config['model']+='_ensemble'
if config['split']:
config['model'] = config['model'] + '_cluster'
#TODO: create plots for torch models
#hist.history['val_loss'] = loss
np.savetxt(X=loss, fname=config['model_dir']+'/'+'ensemble_loss.csv', delimiter=',')
#plot_loss(hist, config['model_dir'], config['model'], val = True)
#if config['task'] == 'prosaccade-clf':
## plot_acc(hist, config['model_dir'], config['model'], val = True)
# Save metrics and plot them
np.savetxt(X=loss, fname=config['model_dir']+'/'+'ensemble_loss_val.csv', delimiter=',')
plot_array(loss, config['model_dir'], 'loss')
if config['task'] == 'prosaccade-clf':
np.savetxt(X=accuracy, fname=config['model_dir']+'/'+'ensemble_acc_val.csv', delimiter=',')
plot_array(accuracy, config['model_dir'], 'accuracy')
# Save logs
#save_logs(hist, config['model_dir'], config['model'], pytorch = False)
def predict(self, X):
#TODO: implement for torch dataloader
pass
def _build_ensemble_model(self):
"""
Create a list of compiled models
......@@ -116,16 +111,8 @@ class Ensemble_torch:
def predict(self, X):
"""
Predict with all models on the dataset X
Return the average prediction of all models in self.models
"""
for i in range(len(self.models)):
if i == 0:
pred = self.models[i].model.predict(X)
else:
pred += self.models[i].model.predict(X)
return pred / len(self.models)
#TODO: implement for torch dataloader
pass
# optional
def load_models(self, path_to_models):
......
"""
Definition of custum loss functions that can be used in our models
"""
import torch
import numpy as np
def angle_loss(a, b):
"""
......@@ -12,18 +10,4 @@ def angle_loss(a, b):
Angles pi/2 and -pi/2 should lead to a large loss, since this is a difference by pi on the unit circle
Therefore we compute the absolute error of the "shorter" direction on the unit circle
"""
return torch.mean(torch.abs(torch.atan2(torch.sin(a - b), torch.cos(a - b))))
def cross_entropy(predictions, targets):
"""
Cross-entropy loss
"""
N = predictions.shape[0]
ce = -np.sum(targets * np.log(predictions)) / N
return ce
def mse(A, B):
"""
Mean squared error loss
"""
return ((A - B)**2).mean(axis=0)
\ No newline at end of file
return torch.mean(torch.abs(torch.atan2(torch.sin(a - b), torch.cos(a - b))))
\ No newline at end of file
......@@ -12,9 +12,6 @@ def create_dataloader(X, y, batch_size):
tensor_y = torch.tensor(y)
# Set device
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# Move tensors to gpu if possible
tensor_x.cuda()
tensor_y.cuda()
# Create dataset and dataloader
dataset = TensorDataset(tensor_x, tensor_y)
return DataLoader(dataset, batch_size=batch_size, drop_last=True)
\ No newline at end of file
import numpy as np
import matplotlib.pyplot as plt
from config import config
import logging
def plot_from_csv(file_path, output_dir, metric, savefig=True):
"""
Plot the metric saved in the file_path file
"""
logging.info("Plotting metrics...")
x = np.loadtxt(file_path, delimiter=',')
epochs = np.arange(len(x))
plt.figure()
if config['pretrained']:
plt.title("Pretrained " + config['model'] + ' loss')
else:
plt.title(config['model'] + ' loss')
plt.plot(epochs, x, 'b-', label='validation')
plt.legend()
plt.xlabel('epochs')
if config['task'] == 'gaze-reg':
plt.ylabel("MSE")
elif config['task'] == 'angle-reg':
plt.ylabel("Mean Absolute Angle Error")
else:
plt.ylabel('Binary Cross Entropy Loss')
if savefig:
plt.savefig(output_dir + '/' + config['model'] + '_val_' + metric + '.png')
def plot_array(x, output_dir, metric, savefig=True):
"""
Plot the metric saved in the file_path file
"""
logging.info("Plotting metrics...")
epochs = np.arange(len(x))
plt.figure()
if config['pretrained']:
plt.title("Pretrained " + config['model'] + ' loss')
else:
plt.title(config['model'] + ' loss')
plt.plot(epochs, np.array(x), 'b-', label='validation')
plt.legend()
plt.xlabel('epochs')
if config['task'] == 'gaze-reg':
plt.ylabel("MSE")
elif config['task'] == 'angle-reg':
plt.ylabel("Mean Absolute Angle Error")
else:
plt.ylabel('Binary Cross Entropy Loss')
if savefig:
plt.savefig(output_dir + '/' + config['model'] + '_val_' + metric + '.png')
\ No newline at end of file
......@@ -9,8 +9,9 @@ def train_loop(dataloader, model, loss_fn, optimizer):
"""
size = len(dataloader.dataset)
for batch, (X, y) in enumerate(dataloader):
#print(f"batchsize X {X.size()}")
#print(f"batchsize y {y.size()}")
if torch.cuda.is_available():
X.cuda()
y.cuda()
# Compute prediction and loss
pred = model(X.float())
loss = loss_fn(pred.float(), y.float())
......@@ -32,6 +33,9 @@ def test_loop(dataloader, model, loss_fn):
with torch.no_grad():
for X, y in dataloader:
if torch.cuda.is_available():
X.cuda()
y.cuda()
pred = model(X.float())
test_loss += loss_fn(pred.float(), y.float()).item()
if config['task'] == 'prosaccade_clf':
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment