Files
cvpr_2023/models/base.py
T
2023-05-23 22:57:08 +02:00

98 lines
3.1 KiB
Python

import torch
from torch import nn
from models.convnext_orig import ConvNeXt, CNBlock, CNBlockConfig
from typing import Any, Callable, List, Optional, Sequence
class VariationalEncoder(nn.Module):
def __init__(self, block_setting: List[CNBlockConfig], kernel_size: int = 7, input_features: int = 16, device: str = 'cuda'):
super(VariationalEncoder, self).__init__()
self.encoder = ConvNeXt(block_setting=block_setting, kernel_size=kernel_size, input_features=input_features, device=device)
layers = [CNBlock(block_setting[-1].input_channels, kernel_size=kernel_size) for _ in range(5)]
self.mean_branch = nn.Sequential(*layers).to(device)
layers = [CNBlock(block_setting[-1].input_channels, kernel_size=kernel_size) for _ in range(5)]
self.var_branch = nn.Sequential(*layers).to(device)
self.flatten_mean = nn.Flatten()
self.flatten_var = nn.Flatten()
def forward(self, inputs):
x = inputs
x = self.encoder(x)
mean = self.mean_branch(x)
log_var = self.var_branch(x)
mean = self.flatten_mean(mean)
log_var = self.flatten_var(log_var)
return mean, log_var
class AEEncoder(nn.Module):
def __init__(self, block_setting: CNBlockConfig, kernel_size: int = 7, activation='tanh', is_label=False, nr_of_labels=None, device='cuda', input_features=3):
super(AEEncoder, self).__init__()
self.encoder = ConvNeXt(block_setting=block_setting, kernel_size=kernel_size, is_label=is_label, nr_of_labels=nr_of_labels, device=device, input_features=input_features)
if activation == 'tanh':
self.act = nn.Tanh()
elif activation == 'sigmoid':
self.act = nn.Sigmoid()
else:
raise ValueError('Activation function not supported')
def forward(self, inputs):
if len(inputs) == 2:
x, _ = inputs
else:
x = inputs
x = self.encoder(x)
x = self.act(x)
if len(inputs) == 2:
return x, inputs[1]
else:
return x
class Decoder(nn.Module):
def __init__(self, block_setting: CNBlockConfig, kernel_size=7, is_label=False, nr_of_classes=None, device='cuda'):
super(Decoder, self).__init__()
self.is_label = is_label
self.decoder = ConvNeXt(block_setting=block_setting, kernel_size=kernel_size, is_label=is_label, nr_of_labels=nr_of_classes, device=device, reversed=True)
if self.is_label:
self.softmax = nn.Softmax(dim=1)
def forward(self, inputs):
if len(inputs) == 2:
x, mask = inputs
else:
x = inputs
x = self.decoder(x)
if self.is_label:
x = x * mask[:,None,:,:]
background = torch.ones((mask.shape[0],1,512,256), device=mask.get_device()) * (1 - mask[:,None,:,:])
x = torch.concat((background, x), dim=1)
x = self.softmax(x)
if len(inputs) == 2:
if len(mask.shape) == 2:
x = x * mask[None,None,:,:]
else:
x = x * mask[:,None,:,:]
return x