datnguyentien204's picture
Upload 337 files
ce91ea1 verified
import torchvision
import torch.nn as nn
import pretrainedmodels
import torch.nn.functional as F
import torch
from constant import SCALE_FACTOR
import math
import pdb
class DenseNet(nn.Module):
def __init__(self, variant):
super(DenseNet, self).__init__()
assert variant in ['densenet121', 'densenet161', 'densenet201']
# load retrain model
model = pretrainedmodels.__dict__[variant](num_classes=1000, pretrained='imagenet')
self.features = model.features
num_ftrs = model.last_linear.in_features
self.classifier = nn.Sequential(
nn.Linear(num_ftrs, 14),
nn.Sigmoid()
)
# TODO: BCELoss with logit for numeric stable
# self.classifier = nn.Linear(num_ftrs, 14)
# load other info
self.mean = model.mean
self.std = model.std
self.input_size = model.input_size[1] # assume every input is a square image
self.input_range = model.input_range
self.input_space = model.input_space
self.resize_size = int(math.floor(self.input_size / SCALE_FACTOR))
def forward(self, x, **kwargs):
x = self.features(x) # 1x1024x7x7
s = x.size()[3] # 7 if input image is 224x224, 16 if input image is 512x512
x = F.relu(x, inplace=True) # 1x1024x7x7
pooling = kwargs['pooling']
if pooling == 'MAX':
x = F.max_pool2d(x, kernel_size=s, stride=1)
x = x.view(x.size(0), -1) # 1x1024
elif pooling == 'AVG':
x = F.avg_pool2d(x, kernel_size=s, stride=1) # 1x1024x1x1
x = x.view(x.size(0), -1) # 1x1024
elif pooling == 'LSE':
r = kwargs.lse_r
x_max = F.max_pool2d(x, kernel_size=s, stride=1)
p = ((1/r) * torch.log((1 / (s*s)) * torch.exp(r*(x - x_max)).sum(3).sum(2)))
x_max = x_max.view(x.size(0), -1)
x = x_max + p
else:
raise ValueError('Invalid pooling')
x = self.classifier(x) # 1x1000
return x
def extract(self, x):
return self.features(x)
# def count_params(self):
# return sum(p.numel() for p in self.parameters() if p.requires_grad)
def build(variant):
net = DenseNet(variant).cuda()
return net
architect='densenet'