Skip to content
Snippets Groups Projects
Commit d460e791 authored by Gudmundur's avatar Gudmundur
Browse files

Project update by Peter, minor path changes by Gudmundur

parent 1cecdb36
Branches
No related tags found
No related merge requests found
Showing
with 965 additions and 612 deletions
File added
File added
......@@ -49,6 +49,7 @@ accuracy_methods_difficulties = {
def get_accuracy_methods(args):
if args.EVAL_METRICS.BACKBONE in accuracy_methods_embeddings:
backbone_func = accuracy_methods_embeddings[args.EVAL_METRICS.BACKBONE]
else:
......
%% Cell type:code id: tags:
``` python
import pandas as pd
import numpy as np
import pickle
import os
```
%% Cell type:code id: tags:
``` python
pcl = pickle.load(open(r'C:\Users\ptrkm\data_aisc\difficulties.pkl','rb'))
labels = pd.read_csv(r'C:\Users\ptrkm\data_aisc\labels.csv')
labels
```
%% Output
names labels
0 9a298f46-46d0-4a3c-a9df-ca828ea73d5d.jpg 1
1 9d60b81b-fdc6-492a-a3ef-ecdb99b79cd3.jpg 1
2 e5787ca3-2978-4ef5-8d14-7d2519e6b0f9.jpg 1
3 b6cab130-7489-45a1-a0bf-484afc502c75.jpg 1
4 7e1ff9a0-e2fd-4e03-bce3-beb9dcc9090e.jpg 4
... ... ...
208411 829651a4-43cd-43e1-b741-9885532ff9e8.jpg 0
208412 829651a4-43cd-43e1-b741-9885532ff9e8.jpg 0
208413 829651a4-43cd-43e1-b741-9885532ff9e8.jpg 0
208414 829651a4-43cd-43e1-b741-9885532ff9e8.jpg 0
208415 829651a4-43cd-43e1-b741-9885532ff9e8.jpg 0
[208416 rows x 2 columns]
%% Cell type:code id: tags:
``` python
labels = labels.drop_duplicates(['names'])
print(labels[labels['labels'] == 0])
print(len(labels))
```
%% Output
names labels
17 ce0e901f-6071-40c8-a43e-142b242d05cb.jpg 0
32 48ba2642-31da-495e-81b6-9429e56f983b.jpg 0
54 2b0bf191-fca9-43c6-ab93-a69579d280bd.jpg 0
74 555065cc-43a2-40ef-a624-2b5212476972.jpg 0
75 80776db5-3814-4495-8ed9-e93ec9a98ecd.jpg 0
... ... ...
206834 c9851b01-4518-41de-899b-62d4bf7d1ba6.jpg 0
206952 9e6be42d-f880-48a4-b21f-575b905841cd.jpg 0
207218 be21630a-354a-4769-adbe-0990fb1c5198.jpg 0
207338 32291605-bb1a-463a-9ddb-8c7ba990f124.jpg 0
208303 829651a4-43cd-43e1-b741-9885532ff9e8.jpg 0
[2404 rows x 2 columns]
40635
%% Cell type:code id: tags:
``` python
label_pcl = {name: lab for name, lab in zip(labels['names'], labels['labels'])}
print(len(pcl))
```
%% Output
40967
%% Cell type:code id: tags:
``` python
dist = np.zeros((8, ))
for key, val in pcl.items():
if val != -1:
if key in label_pcl:
dist[label_pcl[key]] += 1
print(dist)
dist = dist/sum(dist)
```
%% Output
[ 334. 1103. 74. 19. 285. 150. 140. 69.]
%% Cell type:code id: tags:
``` python
pcl = {key: val for key, val in pcl.items() if key in label_pcl}
```
%% Cell type:code id: tags:
``` python
lab_and_diff = np.array([[val, label_pcl[key], val != -1, idx] for idx, (key, val) in enumerate(pcl.items())])
names = np.array([[key, val, idx] for idx, (key, val) in enumerate(pcl.items())])
```
%% Cell type:code id: tags:
``` python
```
%% Output
[False False True False False False False False False False]
%% Cell type:code id: tags:
``` python
def split_class(arr, c):
relevant_ones = arr[arr[:, 1] == c]
sample = np.random.permutation(relevant_ones[:, 3].ravel())
return np.array_split(sample.astype(int), 5)
splits = {f'split_{i}': {'train': [], 'val': []} for i in range(5)}
for c in range(8):
splitted_class = split_class(lab_and_diff, c)
for idx in range(len(splitted_class)):
train = []
for i, s in enumerate(splitted_class):
if i != idx:
train += list(s)
val = list(splitted_class[idx])
splits[f'split_{idx}']['train'] += train
splits[f'split_{idx}']['val'] += val
print("Done")
```
%% Output
Done
%% Cell type:code id: tags:
``` python
for key, val in splits.items():
print("len train = ", len(val['train']))
print("len val = ", len(val['val']))
print("len diff = ", len(set('train').intersection(set(val['val']))))
```
%% Output
len train = 32507
len val = 8128
len diff = 0
len train = 32507
len val = 8128
len diff = 0
len train = 32508
len val = 8127
len diff = 0
len train = 32508
len val = 8127
len diff = 0
len train = 32510
len val = 8125
len diff = 0
%% Cell type:code id: tags:
``` python
ac_splits = {f'split_{i}': {'train': [], 'val': []} for i in range(5)}
for key, val in splits.items():
for idx in val['train']:
ac_splits[key]['train'].append(names[idx, 0])
for idx in val['val']:
ac_splits[key]['val'].append(names[idx, 0])
```
%% Cell type:code id: tags:
``` python
ac_splits
with open(r'C:\Users\ptrkm\data_aisc\splits.pkl', 'wb') as handle:
pickle.dump(ac_splits, handle, protocol=pickle.HIGHEST_PROTOCOL)
```
import yaml
from argparse import Namespace
import os
from Embeddings.New_Embeddings.models.DEMD import Demd
from Embeddings.New_Embeddings.dataloaders.AISC import AISC
import savers_and_loaders
from Embeddings.New_Embeddings.optimizers import get_optimizer
from Embeddings.New_Embeddings.losses import losses_head, losses_backbone
from models.DEMD import Demd
from dataloaders.AISC import AISC
from misc import savers_and_loaders
from optimizers import get_optimizer
from losses import losses_head, losses_backbone
from torch.utils.data import DataLoader
def read_yaml(path, return_namespace=False):
"""
......@@ -17,6 +18,11 @@ def read_yaml(path, return_namespace=False):
with open(path, 'r') as f:
file = yaml.safe_load(f)
if return_namespace:
for key, val in file.items():
if type(val) is dict:
file[key] = Namespace(**val)
elif isinstance(val, (tuple, list)):
file[key] = Namespace(*val)
file = Namespace(**file)
return file
......@@ -25,12 +31,16 @@ def get_dataloader_from_args(args, path):
augmentation_args = read_yaml(path)
augmentation_args = {'name': args.AUGMENTATION.NAME, 'vals': augmentation_args}
dataset_params = args.DATA
dataset_params.data_augmentation = Namespace(augmentation_args)
dataset_params.data_augmentation = Namespace(**augmentation_args)
dataloader = AISC(dataset_params)
dataloader = DataLoader(dataloader, batch_size=args.TRAIN.BATCH_SIZE, num_workers=args.DATA_LOADER.NUM_WORKERS,
pin_memory=args.DATA_LOADER.PIN_MEMORY)
return dataloader
def get_model_from_args(args):
args.NETWORK.BACKBONE = Namespace(**args.NETWORK.BACKBONE)
args.NETWORK.HEAD = Namespace(**args.NETWORK.HEAD)
network = Demd(args.NETWORK)
network, score_keeper = savers_and_loaders.find_latest_network(network, args)
......@@ -39,16 +49,15 @@ def get_model_from_args(args):
def get_optimizer_from_args(model, args, path):
optimizer_args = read_yaml(path, return_namespace=True)
optimizer_args = optimizer_args.args.OPTIMIZER
optimizer_args.NAME = args.OPTIMIZER
optimizer_args.NAME = args.SOLVER.OPTIMIZER
return get_optimizer(optimizer_args, model)
def get_losses_from_args(args, paths):
backbone_loss_args = read_yaml(paths[0], return_namespace=False)
header_loss_args = read_yaml(paths[1], return_namespace=False)
backbone_loss_args = read_yaml(paths[0], return_namespace=True)
header_loss_args = read_yaml(paths[1], return_namespace=True)
header_loss = losses_head.get_loss(args.TRAINING.HEAD.LOSS, header_loss_args)
backbone_loss = losses_backbone.get_loss(args.TRAINING.BACKBONE.LOSS, backbone_loss_args)
......@@ -63,10 +72,12 @@ def read_main_config(path):
else:
raise ValueError("The path entered for the general config file is not valid on this device")
config_paths = os.path.join(os.path.dirname(path), 'configs')
config_paths = os.path.dirname(path)
augmentation_arguments_path = os.path.join(config_paths, general_args.AUGMENTATION.CONFIG)
optimizer_arguments_path = os.path.join(os.path.join(config_paths, 'config_optimizers'), 'config_optim.yaml')
dataloader = get_dataloader_from_args(general_args, augmentation_arguments_path)
model, score_keeper = get_model_from_args(general_args)
optimizer = get_optimizer_from_args(model, general_args, optimizer_arguments_path)
loss_argument_paths = [
......
......@@ -2,7 +2,8 @@ import os
import numpy as np
import torch
import pickle
from Embeddings.New_Embeddings.misc import accuracy_calculator
from misc import accuracy_calculator
from argparse import Namespace
def save_trained(network, score_keeper, args):
"""
......@@ -54,12 +55,16 @@ def find_latest_network(network, args):
:param args: The general args in config "General"
:return: (nn.Module, int) (loaded_network, num_epochs_left)
"""
early_stop_patience = (args.NETWORK.BACKONE.EARLY_STOP_PATIENCE,
args.NETWORK.HEAD.EARLY_STOP_PATIENCE,
args.NETWORK.COMBINED.EARLY_STOP_PATIENCE)
if ((file := args.NETWORK.PATH_TO_SAVED is not None) and
(scp := os.path.exists(os.path.join(os.path.dirname(file), 'score_keepers.pkl')))):
for key, val in args.TRAINING.__dict__.items():
args.TRAINING.__dict__[key] = Namespace(**val)
early_stop_patience = (args.TRAINING.BACKBONE.EARLY_STOP_PATIENCE,
args.TRAINING.HEAD.EARLY_STOP_PATIENCE,
args.TRAINING.COMBINED.EARLY_STOP_PATIENCE)
if (((file := args.NETWORK.PATH_TO_SAVED) is not None) and
(os.path.exists(scp := os.path.join(os.path.dirname(file), 'score_keepers.pkl')))):
score_keeper = pickle.load(open(scp, 'rb'))
if args.NETWORK.PATH_TO_SAVED in score_keeper:
score_keeper = score_keeper[args.NETWORK.PATH_TO_SAVED]
......
......@@ -3,13 +3,14 @@ import torch.nn as nn
import numpy as np
import torch
import os
import pretrained_models_getter as pmg
from models import pretrained_models_getter as pmg
activations = {'sigmoid': nn.Sigmoid()}
class Demd(nn.Module):
def __init__(self, args):
super(Demd, self).__init__()
"""
The network subgroup of arguments from config general.yaml
:param args: (args.Namespace)
......@@ -18,7 +19,7 @@ class Demd(nn.Module):
self.embedding_dimension = args.BACKBONE.OUTPUT_DIM
self.head_structure = args.HEAD.STRUCTURE
self.batch_norm_struct = args.HEAD.BATCH_NORM_STRUCTURE
self.freeze_affine_batchnorm = args.BACKBONE.FREEZE_AFFINE_BATCHNORM
# self.freeze_affine_batchnorm = args.BACKBONE.FREEZE_AFFINE_BATCHNORM
self.freeze_full_batchnorm = args.BACKBONE.FREEZE_BATCHNORM
if self.head_structure[0] != self.embedding_dimension:
self.head_structure = [self.embedding_dimension] + self.head_structure
......
File added
File added
......@@ -11,17 +11,17 @@ resnet_models = {'50': models.resnet50,
'152': models.resnet152}
def load_pretrained_model(args):
if args.NETWORK.NAME.split("-")[0] == "efficientnet":
model = EfficientNet.from_pretrained(args.NETWORK.NAME, num_classes=args.NETWORK.BACKBONE_OUTPUT_DIM)
if args.BACKBONE.NAME.split("-")[0] == "efficientnet":
model = EfficientNet.from_pretrained(args.BACKBONE.NAME, num_classes=args.BACKBONE.OUTPUT_DIM)
elif re.search(r"[a-zA-Z]*", args.NETWORK.NAME).group(0) == 'ResNet':
layers = re.search(r"\d+", args.NETWORK.NAME)
elif re.search(r"[a-zA-Z]*", args.BACKBONE.NAME).group(0) == 'ResNet':
layers = re.search(r"\d+", args.BACKBONE.NAME)
if layers is not None:
layers = layers.group(0)
if layers in resnet_models:
model = resnet_models[layers](pretrained = True)
model.fc = nn.Linear(in_features=model.fc.in_features, out_features=args.NETWORK.BACKBONE_OUTPUT_DIM)
model.fc = nn.Linear(in_features=model.fc.in_features, out_features=args.BACKBONE.OUTPUT_DIM)
UserWarning("Loaded network, but last linear layer is untrained")
else:
raise NotImplementedError(
......
......@@ -6,15 +6,16 @@ def stochastic_gradient_descent(model,params):
return optim.SGD(model.parameters(), lr = params.lr, momentum=params.momentum)
def Adam(model, params):
return optim.Adam(
model.parameters(),lr = params.lr, betas = params.betas, eps = params.eps, weight_decay=params.weight_decay
model.parameters(),lr = params.lr, betas = params.betas, eps = float(params.eps), weight_decay=params.weight_decay
)
optimizers = {'adam': Adam,
'sgd': stochastic_gradient_descent}
optimizers = {'ADAM': Adam,
'SGD': stochastic_gradient_descent}
def get_optimizer(args, model):
return optimizers[args.OPTIMIZER.NAME](model, args.OPTIMIZER.PARAMS)
return optimizers[args.NAME](model, args.__dict__[args.NAME])
import os
import argparse
from argparse import Namespace
from Embeddings.New_Embeddings.trainers import main_trainer as mt
from Embeddings.New_Embeddings.misc import read_configs, savers_and_loaders, accuracy_calculator
from Embeddings.New_Embeddings.losses import losses
from trainers import main_trainer as mt
from misc import read_configs, savers_and_loaders, accuracy_calculator
from losses import losses
import sys
def main_runner(args):
......@@ -16,13 +17,16 @@ def main_runner(args):
if args.TEST.ENABLE:
score, embeddings, difficulties, files, labels = mt.run_test_eval(model, dataloader, score_keeper)
savers_and_loaders.save_all_results(score, embeddings, difficulties, files, labels, args)
savers_and_loaders.save_all_results(
score, embeddings, difficulties, files, labels, args
)
return None
if __name__ == "__main__":
parser = argparse.ArgumentParser(allow_abbrev=False)
parser.add_argument("--path_to_config", type=str, default=None)
parser.add_argument("--path_to_config", type=str, default='configs/general.yaml')
args, _ = parser.parse_known_args()
os.chdir('embeddings_and_difficulty')
main_runner(args)
File added
......@@ -3,8 +3,7 @@ import torch
import numpy
import os
from tqdm import tqdm
from Embeddings.New_Embeddings.misc import accuracy_calculator
from Embeddings.New_Embeddings.misc import savers_and_loaders
from misc import accuracy_calculator, savers_and_loaders
def train_model(model, optimizer, dataloader, losses, score_keeper, args):
......@@ -19,7 +18,7 @@ def train_model(model, optimizer, dataloader, losses, score_keeper, args):
:return: A trained model
"""
max_epochs = {'bacbkone': args.TRAINING.BACKBONE.MAX_EPOCH,
max_epochs = {'backbone': args.TRAINING.BACKBONE.MAX_EPOCH,
'head': args.TRAINING.HEAD.MAX_EPOCH,
'combined': args.TRAINING.COMBINED.MAX_EPOCH}
while score_keeper.is_training is not None:
......@@ -29,6 +28,7 @@ def train_model(model, optimizer, dataloader, losses, score_keeper, args):
model.freeze('backbone')
elif score_keeper.is_training == 'mixed':
model.freeze('unfreeze')
epochs = (max_epochs[score_keeper.is_training] -
score_keeper.number_of_epochs_trained[score_keeper.is_training])
......@@ -36,8 +36,10 @@ def train_model(model, optimizer, dataloader, losses, score_keeper, args):
for idx, (image, label, difficulty) in enumerate(dataloader):
optimizer.zero_grad()
embedding, diff = model(image)
loss = losses(embedding, diff, score_keeper)
try:
loss = losses(embedding, diff, label, difficulty, score_keeper)
except:
breakpoint()
loss.backward()
optimizer.step()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment