File size: 4,435 Bytes
caa56d6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
'''
# author: Zhiyuan Yan
# email: [email protected]
# date: 2023-0706
The code is for EfficientNetB4 backbone.
'''
import torch
import torch.nn as nn
import torch.nn.functional as F
from typing import Union
from efficientnet_pytorch import EfficientNet
from metrics.registry import BACKBONE
import os
@BACKBONE.register_module(module_name="efficientnetb4")
class EfficientNetB4(nn.Module):
def __init__(self, efficientnetb4_config):
super(EfficientNetB4, self).__init__()
""" Constructor
Args:
efficientnetb4_config: configuration file with the dict format
"""
self.num_classes = efficientnetb4_config["num_classes"]
inc = efficientnetb4_config["inc"]
self.dropout = efficientnetb4_config["dropout"]
self.mode = efficientnetb4_config["mode"]
# Load the EfficientNet-B4 model without pre-trained weights
if efficientnetb4_config['pretrained']:
self.efficientnet = EfficientNet.from_pretrained('efficientnet-b4',weights_path=efficientnetb4_config['pretrained']) # FIXME: load the pretrained weights from online
# self.efficientnet = EfficientNet.from_name('efficientnet-b4')
else:
self.efficientnet = EfficientNet.from_name('efficientnet-b4')
# Modify the first convolutional layer to accept input tensors with 'inc' channels
self.efficientnet._conv_stem = nn.Conv2d(inc, 48, kernel_size=3, stride=2, bias=False)
# Remove the last layer (the classifier) from the EfficientNet-B4 model
self.efficientnet._fc = nn.Identity()
if self.dropout:
# Add dropout layer if specified
self.dropout_layer = nn.Dropout(p=self.dropout)
# Initialize the last_layer layer
self.last_layer = nn.Linear(1792, self.num_classes)
if self.mode == 'adjust_channel':
self.adjust_channel = nn.Sequential(
nn.Conv2d(1792, 512, 1, 1),
nn.BatchNorm2d(512),
nn.ReLU(inplace=True),
)
def block_part1(self,x):
x = self.efficientnet._swish(self.efficientnet._bn0(self.efficientnet._conv_stem(x)))
# x = self.efficientnet._blocks[0:10](x)
for idx, block in enumerate(self.efficientnet._blocks[:10]):
drop_connect_rate = self.efficientnet._global_params.drop_connect_rate
if drop_connect_rate:
drop_connect_rate *= float(idx+0) / len(self.efficientnet._blocks) # scale drop connect_rate
x = block(x, drop_connect_rate=drop_connect_rate)
return x
def block_part2(self,x):
for idx, block in enumerate(self.efficientnet._blocks[10:22]):
drop_connect_rate = self.efficientnet._global_params.drop_connect_rate
if drop_connect_rate:
drop_connect_rate *= float(idx+10) / len(self.efficientnet._blocks) # scale drop connect_rate
x = block(x, drop_connect_rate=drop_connect_rate)
return x
def block_part3(self,x):
for idx, block in enumerate(self.efficientnet._blocks[22:]):
drop_connect_rate = self.efficientnet._global_params.drop_connect_rate
if drop_connect_rate:
drop_connect_rate *= float(idx+22) / len(self.efficientnet._blocks) # scale drop connect_rate
x = block(x, drop_connect_rate=drop_connect_rate)
x = self.efficientnet._swish(self.efficientnet._bn1(self.efficientnet._conv_head(x)))
return x
def features(self, x):
# Extract features from the EfficientNet-B4 model
x = self.efficientnet.extract_features(x)
if self.mode == 'adjust_channel':
x = self.adjust_channel(x)
return x
def end_points(self,x):
return self.efficientnet.extract_endpoints(x)
def classifier(self, x):
x = F.adaptive_avg_pool2d(x, (1, 1))
x = x.view(x.size(0), -1)
# Apply dropout if specified
if self.dropout:
x = self.dropout_layer(x)
# Apply last_layer layer
self.last_emb = x
y = self.last_layer(x)
return y
def forward(self, x):
# Extract features and apply classifier layer
x = self.features(x)
# if False:
# x = F.adaptive_avg_pool2d(x, (1, 1))
# x = x.view(x.size(0), -1)
x = self.classifier(x)
return x
|