pytorch打印model的层级结构以及模型更改

本文介绍了如何基于预训练的TF-EfficientNet-B0_ns模型,调整输出层以实现1维输出,并详细展示了模型的层级结构变化。通过`model.children()`、`model._modules.items()`、`model.named_modules()`和`model.modules()`,一步步揭示了模型内部结构。
摘要由CSDN通过智能技术生成

pip install python-box timm pytorch-lightning==1.4.0 grad-cam ttach

import os
import warnings
from pprint import pprint
from glob import glob
from tqdm import tqdm

import torch
import torch.optim as optim
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import torchvision.transforms as T
from box import Box
from timm import create_model
from sklearn.model_selection import StratifiedKFold
from torchvision.io import read_image
from torch.utils.data import DataLoader, Dataset
from pytorch_grad_cam import GradCAMPlusPlus
from pytorch_grad_cam.utils.image import show_cam_on_image


import pytorch_lightning as pl
from pytorch_lightning.utilities.seed import seed_everything
from pytorch_lightning import callbacks
from pytorch_lightning.callbacks.progress import ProgressBarBase
from pytorch_lightning.callbacks.early_stopping import EarlyStopping
from pytorch_lightning.loggers import TensorBoardLogger
from pytorch_lightning import LightningDataModule, LightningModule


warnings.filterwarnings("ignore")

#tf_efficientnet_b0_ns


config = {'seed': 202126,
          'root': '/kaggle/input/petfinder-pawpularity-score/', 
          'n_splits': 1,
          'epoch': 1,
          'trainer': {
              'gpus': 1,
              'accumulate_grad_batches': 1,
              'progress_bar_refresh_rate': 1,
              'fast_dev_run': False,
              'num_sanity_val_steps': 0,
              'resume_from_checkpoint': None,
          },
          'transform':{
              'name': 'get_default_transforms',
              'image_size': 224
          },
          'train_loader':{
              'batch_size': 64,
              'shuffle': True,
              'num_workers': 4,
              'pin_memory': False,
              'drop_last': True,
          },
          'val_loader': {
              'batch_size': 64,
              'shuffle': False,
              'num_workers': 4,
              'pin_memory': False,
              'drop_last': False
         },
          'model':{
              'name': 'tf_efficientnet_b0_ns',
              'output_dim': 1
          },
          'optimizer':{
              'name': 'optim.AdamW',
              'params':{
                  'lr': 1e-5
              },
          },
          'scheduler':{
              'name': 'optim.lr_scheduler.CosineAnnealingWarmRestarts',
              'params':{
                  'T_0': 20,
                  'eta_min': 1e-4,
              }
          },
          'loss': 'nn.BCEWithLogitsLoss',
}

config = Box(config)#配置参数并进行实例化

def mixup(x: torch.Tensor, y: torch.Tensor, alpha: float = 1.0):
    assert alpha > 0, "alpha should be larger than 0"
    assert x.size(0) > 1, "Mixup cannot be applied to a single instance."

    lam = np.random.beta(alpha, alpha)
    rand_index = torch.randperm(x.size()[0])
    mixed_x = lam * x + (1 - lam) * x[rand_index, :]
    target_a, target_b = y, y[rand_index]
    return mixed_x, target_a, target_b, lam

class Model(pl.LightningModule):
    def __init__(self, cfg):
        super().__init__()
        self.cfg = cfg
        self.__build_model()
        self._criterion = eval(self.cfg.loss)()
        self.transform = get_default_transforms()
        self.save_hyperparameters(cfg)

    def __build_model(self):
        self.backbone = create_model(
            self.cfg.model.name, pretrained=True, num_classes=0, in_chans=3
        )
        num_features = self.backbone.num_features
        self.fc = nn.Sequential(
            nn.Dropout(0.5), nn.Linear(num_features, self.cfg.model.output_dim)
        )

    def forward(self, x):
        f = self.backbone(x)
        out = self.fc(f)
        return out

    def training_step(self, batch, batch_idx):
        loss, pred, labels = self.__share_step(batch, 'train')
        return {'loss': loss, 'pred': pred, 'labels': labels}
        
    def validation_step(self, batch, batch_idx):
        loss, pred, labels = self.__share_step(batch, 'val')
        return {'pred': pred, 'labels': labels}
    
    def __share_step(self, batch, mode):
        images, labels = batch
        labels = labels.float() / 100.0
        images = self.transform[mode](images)
        
        if torch.rand(1)[0] < 0.5 and mode == 'train':
            mix_images, target_a, target_b, lam = mixup(images, labels, alpha=0.5)
            logits = self.forward(mix_images).squeeze(1)
            loss = self._criterion(logits, target_a) * lam + \
                (1 - lam) * self._criterion(logits, target_b)
        else:
            logits = self.forward(images).squeeze(1)
            loss = self._criterion(logits, labels)
        
        pred = logits.sigmoid().detach().cpu() * 100.
        labels = labels.detach().cpu() * 100.
        return loss, pred, labels
        
    def training_epoch_end(self, outputs):
        self.__share_epoch_end(outputs, 'train')

    def validation_epoch_end(self, outputs):
        self.__share_epoch_end(outputs, 'val')    
        
    def __share_epoch_end(self, outputs, mode):
        preds = []
        labels = []
        for out in outputs:
            pred, label = out['pred'], out['labels']
            preds.append(pred)
            labels.append(label)
        preds = torch.cat(preds)
        labels = torch.cat(labels)
        metrics = torch.sqrt(((labels - preds) ** 2).mean())
        self.log(f'{mode}_loss', metrics)
    
    def check_gradcam(self, dataloader, target_layer, target_category, reshape_transform=None):
        cam = GradCAMPlusPlus(
            model=self,
            target_layers = [target_layer],
            use_cuda=self.cfg.trainer.gpus, 
            reshape_transform=reshape_transform)
        
        org_images, labels = iter(dataloader).next()
        cam.batch_size = len(org_images)
        images = self.transform['val'](org_images)
        images = images.to(self.device)
        logits = self.forward(images).squeeze(1)
        pred = logits.sigmoid().detach().cpu().numpy() * 100
        labels = labels.cpu().numpy()
        
        grayscale_cam = cam(input_tensor=images, target_category=target_category, eigen_smooth=True)
        org_images = org_images.detach().cpu().numpy().transpose(0, 2, 3, 1) / 255.
        return org_images, grayscale_cam, pred, labels

    def configure_optimizers(self):
        optimizer = eval(self.cfg.optimizer.name)(
            self.parameters(), **self.cfg.optimizer.params
        )
        scheduler = eval(self.cfg.scheduler.name)(
            optimizer,
            **self.cfg.scheduler.params
        )
        return [optimizer], [scheduler]
 
model = Model(config) 
model.load_state_dict(torch.load(f'{config.model.name}/default/version_0/checkpoints/best_loss.ckpt')['state_dict'])
model = model.cuda().eval()
config.val_loader.batch_size = 64
datamodule = PetfinderDataModule(train_df, val_df, config)

print(model.backbone)

1. 查看层级结构方式

基于tf_efficientnet_b7_ns模型

class ETSSModel(nn.Module):
    def __init__(self, model_name=CFG.model_name, out_dim=1):
        super().__init__()
        self.model = timm.create_model(model_name, pretrained=True, in_chans=1)
        for n in (self.model.children()):print(n)
        print("*1model.children()"*20)
        for name, module in self.model._modules.items():print(name," : ",module)
        print("*2model._modules.items()"*20)
        for n in self.model.named_modules():print(n)
        print("*3model.named_modules()"*20)
        for n in (self.model.modules()):print(n)
        print("*4model.modules()"*20)
        self.n_features = self.model.classifier.in_features
        self.model.classifier = nn.Linear(self.n_features, out_dim)

    def forward(self, x):
        output = self.model(x)
        return output

输出

  • model.children()
Conv2d(640, 2560, kernel_size=(1, 1), stride=(1, 1), bias=False)
BatchNorm2d(2560, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
SiLU(inplace=True)
SelectAdaptivePool2d (pool_type=avg, flatten=True)
Linear(in_features=2560, out_features=1000, bias=True)
  • model._modules.items()
  
conv_head  :  Conv2d(640, 2560, kernel_size=(1, 1), stride=(1, 1), bias=False)
bn2  :  BatchNorm2d(2560, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
act2  :  SiLU(inplace=True)
global_pool  :  SelectAdaptivePool2d (pool_type=avg, flatten=True)
classifier  :  Linear(in_features=2560, out_features=1000, bias=True)

  • model.named_modules()

BatchNorm2d(2560, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
SiLU(inplace=True)
SelectAdaptivePool2d (pool_type=avg, flatten=True)
AdaptiveAvgPool2d(output_size=1)
Linear(in_features=2560, out_features=1000, bias=True)

基于上述的模型对模型的输出维度进行更改
对于

class ETSSModel(nn.Module):
    def __init__(self, model_name=CFG.model_name, out_dim=1):
        super().__init__()
        self.model = timm.create_model(model_name, pretrained=True, in_chans=1)
        self.n_features = self.model.classifier.in_features
        self.model.classifier = nn.Linear(self.n_features, out_dim)#由1000维改成1维

    def forward(self, x):
        output = self.model(x)
        return output

对于

  • model._modules.items()
    在这里插入图片描述
      (1): SwinTransformerBlock(
        
norm  :  LayerNorm((1536,), eps=1e-05, elementwise_affine=True)
avgpool  :  AdaptiveAvgPool1d(output_size=1)
head  :  Linear(in_features=1536, out_features=1000, bias=True)

改为

class ETSSModel(nn.Module):
    def __init__(self, model_name=CFG.model_name, out_dim=1):
        super().__init__()
        self.model = timm.create_model(model_name, pretrained=True, in_chans=1)
        self.n_features = self.model.head.in_features
        self.model.head = nn.Linear(self.n_features, out_dim)#由1000维改成1维

    def forward(self, x):
        output = self.model(x)
        return output

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值