Paper Information

  • Paper title: PLIP: Language-Image Pre-training for Person Representation Learning
  • Date Published: 15/5/2023
  • Conference: not yet!
  • Link github: https://github.com/Zplusdragon/PLIP
  • Link paper: http://export.arxiv.org/abs/2305.08386
  • Why should read this paper?
    • Create the largest and high quality dataset for pretraining: 4.5M
    • Propose a new strategy to generate caption for dataset based on GPT model
    • Powerful backbone can be adapted to various tasks: PAR, Re-ID, TBPR

Overview/Main contribution

Main contribution

  • Construct a large-scale person dataset named SYNTH-PEDES, which consist 4.5M pairs of (image, text)
  • Create a new backbone PLIP on new dataset for general pretraining
    • PLIP is just a backbone, need a model baseline to used transfered represenation for TBPR finetunning
    • Baselines choosen for finetunning:
      • CMPC/C
      • LGUR
  • Design 3 pretext task for training PLIP:
    • Semantic-fused Image Colorization:
      • Given a textual description and greyscale version of the matched image
      • Try to restore the color information of a grayscale person image
    • Visual-fused Attributes Prediction:
      • Given a masked attributes version of textual description, and it's corresponed colorful image
      • Try to predict the masked attributes phrases in textual descriptions
    • Vision-language Constrastive Learning
  • Backbone is powerful that can be adapted for 3 downstream task:
    • Text-based Person Retrieval
    • Image-based Peron Re-Identification
    • Pedestrian Attribute Recogition

Recall ancestor/baseline papers

CMPC/C

LGUR

SYNTH-PEDES dataset

Overview dataset

  • SYNTH-PEDES is the largest dataset for TBPR:
    • Based on LUPerson-NL and LPW, two large-scale dataset for Image-based Person Re-Identification
      • Create and train a powerful model named SPAC for image captioning on LUPerson-NL
      • Stylish Pedestrian Attributesunion Captioning (SPAC) mainly comprises two modules:
        • Image Encoder: ResNet101-FPN
        • Caption Generator (decoder): GPT2
    • Size:
      • About 4.5M images, 3x the size of MALS (in APTM)
      • 12M text decription
    • Compared to MALS dataset in APTM
      • SYNTH-PEDES is high quality and more realistic than MALS
    • Each image also has the ID of person
    • Camera view is diversity

image.png

Label format

Each image have:

  • ID of person
  • List of attribute keyword
    • Keyword is dynamic (constrast to fixed label of PAR dataset)
    • Length of keywords list: 6
  • Caption text: 1 or 2 captions for each image
  • Attribute prompt caption:
    • Just fill the attribute keywords into blanks of the predefined template
    • --> Each image has 2 or 3 style of captions image.png

Labels from json file

[
    {
        "id": 1,
        "file_path": "Part1/1/0.jpg",
        "attributes": [
            "woman,short hair,black jacket,blue denim jeans,black sneakers,black backpack"
        ],
        "captions": [
            "A woman with black hair and she is wearing a black jacket with blue jeans paired with black shoes."
        ],
        "prompt_caption": [
            "The woman has short hair. She is wearing a black jacket, blue denim jeans and black sneakers. She is carrying a black backpack. "
        ]
    },
    
    {
        "id": 1,
        "file_path": "Part1/1/1.jpg",
        "attributes": [
            "girl,dark hair,black jacket,blue jeans,black shoes,unknown"
        ],
        "captions": [
            "A woman wearing a black jacket over a Gray shirt, a pair of blue jeans and a pair of black shoes."
        ],
        "prompt_caption": [
            "A girl with dark hair wearing a black jacket and blue jeans with black shoes."
        ]
    }, ...]

Construction process

Step 1: Manual labeling

  • Collected person Re-ID datasets LUPerson-NL and LPW
  • Filter the noise from LUPerson-NL, which contain some error and noise
  • Before training SPACE, label for small subset of dataset to make datase

Step 2: Train model SPAC to generate a texual caption and list of 6 attribute keywords for image

Step 3: Attributes Prompt Engineering

  • After step 2, each image has a caption, and a list of generated attribute keywords
  • Adding a new style of caption for each image, based on the attribute keywords that was generated by SPAC
    • Just by fill-in-blank method image.png

Stylish Pedestrian Attributes union Captioning (SPAC)

  • Stylish Pedestrian Attributesunion Captioning (SPAC) mainly comprises two modules: a prefix encoder and a shared generator.
    • Specifically, use ResNet101-FPN as the encoder and GPT2 as the generator
  • What is prefix encoder?
    • Use output of embedding vectors of an encoder to use as prefix queries
    • Input of the decoder is the prefix queries + learnable input queries of decoder
      • Bi-directional attention is applied for prefix queries
        • Behave as cross-attention between encoder decoder
      • Left-to-right/Casual attention is applied for the remain input queries of decoder

image.png

Architecture of SPAC

  • Prefix image encoder $PE$: ResNet101-FPN
  • $m$ styled encoder $SE$: each encoder encode the image to different styled embedding, will be fed into a shared decoder to generated m different styled of text caption
  • A shared decoder $G$ for different styled of text caption and 6 type of attribute phrases

Training SPAC

  • Ground-true data: triplet of (image, list of attribute keywords, caption $\{x^i, A^i, y^i\}_{i=1}^{N}$
    • $A^i$ is list of 6 attribute keywords,
      • e.g. {man, black hair, white shirt, yellow trousers, brown shoes}
  • Consider 6 attribute phares and 1 texual caption ---> as 7 sequence (by adding some padding token)
    • Ground-true label for each image $x_i$ is the list of 7 sequence $\{s_1, s_2, \dotsc, s_7\}$

Data flow for generating different captions for each image

  • Feed image $x$ into prefix encoder and n different branches:
    • $7$ branches:
      • 6 for 6 attribute phrases
      • $1$ for text caption
    • How branches are implemented?
      • Not shown in paper and source code!
      • Perhap a MLP!
      • $e_k$ is the ouput embedding vector of branch $k$, correspond to attribute phrase $k$
      • $n=7$ $$ \{e_1, e_2, \dotsc, e_7\} = \{ BR_{k}(PE(x)) \}_{k=1}^7$$
    • Consider $e_{concat}$ as concat vector of 7 vectors
  • Feed concat vector into $m$ styled encoders:
    • $c_k$ is the ouput embedding vector of styled encoder $k$
    • How styled encoder is implemented ?
      • Each styled encoder receive only an concat input vector
      • Perhap MLP!
    • In paper $m$ = 2 --> generate two styled of text caption for each image $$\mathbf{C}=\{c_1, c_2, \dotsc, c_m\} = \{SE(e_{concat}) \}_{i=1}^m$$

image.png

  • Let $Q_{style}= \{ q_1, q_2, \dotsc, q_{l_{max}} \}$ the casual input queries of decoder $G$:
    • For each style:
      • $c_{style}$: prefix query
      • $Q$: casual query (length = $l_{max}$) $$Y = sequence \{ y_1, y_2, \dotsc, y_{l_{max}} \} = G(concat([c_{style}, Q_{style}]))$$ $$\mathcal{L}_{style}=\sum_{j=1}^{\ell_{max}}- \log G\left(y_j \mid c_{style}, y_1, \ldots, y_{j-1}\right)$$
  • Final loss for generate diffentes style of captions $$\mathcal{L}_{caption} = \sum\mathcal{L}_{style}$$

Flow for generating attributes phrases (keywords)

image.png

  • Let $Q_{att}= \{ q_1, q_2, \dotsc, q_{l_{max}} \}$ the casual input queries of decoder $G$:
    • For attribute phrase $k$
      • $e_{k}$: attribute embedding from branch $k$
      • $Q$: casual query (length = $l_{max}$) $$Y = sequence \{ y_1, y_2, \dotsc, y_{l_{max}} \} = G(concat([e_{k}, Q]))$$ $$\mathcal{L}_{attr-k}=\sum_{j=1}^{\ell_{max}}- \log G\left(y_j \mid c_{style}, y_1, \ldots, y_{j-1}\right)$$
  • Final loss for generate diffentes style of captions $$\mathcal{L}_{attribute} = \sum\mathcal{L}_{attr-k}$$

Final loss for SPAC $$\mathcal{L_{generate}} = \lambda \mathcal{L}_{attribute} + \mathcal{L}_{caption} $$

image.png

PLIP Architecture

Architecture

image.png

Vision Encoder

  • Vision Encoder: ResNet Feature Pyramid Network
    • Output of encoder is 4 3-d tensor of feature maps that come from 4 different blocks in ResNet image.png

Text Encoder

  • Text Encoder: BERT base

Additional module for learning pretext task:

  • Vision-Matching Matching (VLM): just a Constrastive Learning module

  • Visual-fused Attributes Prediction (VAP): module learn masked text prediction from image clues

  • Semantic-fused Image Colorization (SIC): module learn image colorization from text clues

Objective Functions

Vision-Language Matching (VLM)

Just other name of vision-language constrastive learning

Global visual feature vector

  • The feature maps with smalles resolution that comes out the last block of ResNet: $F_{last}$: CxHxW
  • $F_{last}$:
    • --> tokenization --> (HW)xC
    • -->add global pooling feature --> (HW+1)xC
    • --> multi-head self-attention --> $v_{g}$: 1xC

Global text feature vector

  • Just CLS 's output embedding from BERT -->global text feature vector $t_{g}$

Recall the CMPM loss

  • A comon loss used for constrastive learning
  • From paper "Deep Cross-Modal Projection Learning for Image-Text Matching", ECCV 2018

  • Given a mini-batch with $n$ image and text samples, for each image $\boldsymbol{x}_i$ the image-text pairs are constructed as $\left\{\left(\boldsymbol{x}_i, \boldsymbol{z}_j\right), y_{i, j}\right\}_{j=1}^n$, where $y_{i, j}=1$ means that $\left(\boldsymbol{x}_i, \boldsymbol{z}_j\right)$ is a matched pair, while $y_{i, j}=0$ indicates the unmatched ones. The probability of matching $\boldsymbol{x}_i$ to $\boldsymbol{z}_j$ is defined as: $$ p_{i, j}=\frac{\exp \left(\boldsymbol{x}_i^{\top} \overline{\boldsymbol{z}}_j\right)}{\sum_{k=1}^n \exp \left(\boldsymbol{x}_i^{\top} \overline{\boldsymbol{z}}_k\right)} \quad \text { s.t. } \overline{\boldsymbol{z}}_j=\frac{\boldsymbol{z}_j}{\left\|\boldsymbol{z}_j\right\|} $$

  • Normalized Ground-true vector: $$q_{i, j}=\frac{y_{i, j}}{\sum_{k=1}^n y_{i, k}}$$

  • The matching loss of associating $\boldsymbol{x}_i$ with correctly matched text samples is defined as $$ \mathcal{L}_i= KL(\mathbf{p_i}|| \mathbf{q_i})= \sum_{j=1}^n p_{i, j} \log \frac{p_{i, j}}{q_{i, j}+\epsilon} $$ where $\epsilon$ is a small number to avoid numerical problems, and the matching loss from image to text in a mini-batch is computed by $$ \mathcal{L}_{i 2 t}=\frac{1}{n} \sum_{i=1}^n \mathcal{L}_i $$

$$\mathcal{L}_{CMPM} = \mathcal{L}_{i2t} + \mathcal{L}_{t2i}$$

  • What is different about CMPM vs SDM in IRRA?
    • CMPM similarity function:
      • $sim(v_1, v_2) = \text{length projected vector of } v_1 \text{ on } v_2$
    • IRRA similarity function:
      • $sim(v_1, v_2) = cosine(v_1, v_2)$
    • IRRA paper show that SDM is better than CMPM

PLIP apply CMPM loss for VLM

  • Loss is calculated for a matrix of N image-text pairs in minibatch

$$\mathcal{L}_{VLM} = \mathbb{E}_{\sim minibatch}[\mathcal{L}_{CMPM}(v_{g}, t_{g})]$$

Visual-fused Attributes Prediction:

  • Just Masked Language Modeling but only masked the attribute keywords
  • Don't need to use cross encoder like APTM, IRRA:
    • Just concatenate the global visual feature vector and text feature vector at masked position -> cross-modal representation vector for each masked position
    • Use a shared MLP to predict what the origin word at masked position

image.png

Semantic-fused Image Colorization (SIC)

  • 4 tensor output of vision encoder is concatenated together to use as input for Semantic-fused Image Colorization

image.png

image.png

  • What in MSE (multimodal Sequeeze-Exciter) block?
    • What is channel-wise attention?
      • Given a feature map $F$ with resolutioin C x H x W (C channel)
      • Try to generate a vector $s$ of size C that contains attention weight for each channel
    • For MSE block:
      • $F$: C1 x H x W --> Max Pooling --> vector $f$: size C1 --> concat with CLS text feature vector + Fully-connected layer --> a vector score $s$ with size C1
      • $s$ --> broadcast --> $S$: C1 x H x W
      • Element-wise product $F$ and $S$ --> new output feature maps $Z$
  • What is Deconv?
    • Just a module use several transpose convolution layers to decode the feature maps $F$ into image $I_{restore}$
  • Loss for SIC:
    • $\mathcal{D}$: L2 distance $$\mathcal{L}_{\text {sic }}=\sum^N \mathcal{D}(I_{\text {origin }}, I_{\text {restore }} ) $$

Training phase

Dataset & Data Augmentation

Implemention detail

  • Train the model with 4 Geforce RTX 3090 GPUs for 70 epochs with batch size 512

Evaluation result

Inference phase

Conclusion

New points in this paper

Pro

Cons

How to improve?

Demo in notebook

Loss for pretraining is not shown in source code! Just vision encoder and text encoder are shown

Set up

Define path

In [2]:
import os, sys
print(os.getcwd())
from pathlib import Path
ROOT_PATH = Path('../paper_clones/PLIP').resolve(); sys.path.append(str(ROOT_PATH))
FINETUNE_PATH = ROOT_PATH/'Downstreams/CMPM-C'; sys.path.append(str(FINETUNE_PATH))
IMAGE_PATH = Path('../DATASET').resolve(); sys.path.append(str(IMAGE_PATH))
/home/jovyan/workspace/BA-PRE_THESIS/REPORT

Import libries / local modules

In [85]:
import torchvision.transforms as transforms
from torchinfo import summary
import torch
import yaml
from utils import *
import time
import os
import shutil
import torch.backends.cudnn as cudnn
from test_dataloader import get_loader_test
import pickle
import argparse
from PLIPmodel import Create_PLIP_Model

Load config

In [74]:
class MyArgumentParser:
    def __init__(self):
        self.args = {}
        
    def __str__(self):
        return str(self.args)
    
    def add_argument(self, str_arg, type, default, help=None):
        self.args[str_arg[2:]] = type(default)
        setattr(self, str_arg[2:], type(default))
        
    def parse_args(self):
        return self
In [75]:
def test_parse_args(parser):
    parser.add_argument('--model_path', type=str, default='checkpoints/PLIP_MRN50.pth.tar')
    parser.add_argument('--image_path', type=str, default='data/CUHK-PEDES/imgs')
    parser.add_argument('--test_path', type=str,
                        default='data/CUHK-PEDES/CUHK-PEDES-test.json',
                        help='path for test annotation json file')
# ***********************************************************************************************************************
# 设置模型backbone的类型和参数
    parser.add_argument('--plip_model', type=str, default='MResNet_BERT')
    parser.add_argument('--img_backbone', type=str, default='ModifiedResNet',
                        help="ResNet:xxx, ModifiedResNet, ViT:xxx")
    parser.add_argument('--txt_backbone', type=str, default="bert-base-uncased")
    parser.add_argument('--img_dim', type=int, default=768, help='dimension of image embedding vectors')
    parser.add_argument('--text_dim', type=int, default=768, help='dimension of text embedding vectors')
    parser.add_argument('--layers', type=list, default=[3, 4, 6, 3], help='Just for ModifiedResNet model')
    parser.add_argument('--heads', type=int, default=8, help='Just for ModifiedResNet model')
    parser.add_argument('--height', type=int, default=256)
    parser.add_argument('--width', type=int, default=128)
    # 设置超参数
    parser.add_argument('--batch_size', type=int, default=128)
    parser.add_argument('--num_workers', type=int, default=4)
    parser.add_argument('--device',type=str,default="cuda:0")
    parser.add_argument('--feature_size', type=int, default=768)
    args = parser.parse_args()
    return args
In [76]:
args = test_parse_args(MyArgumentParser())

Load model checkpoint

In [ ]:
model = Create_PLIP_Model(args).to('cpu')
model_file = args.model_path

Get and summary model

In [92]:
modules = [x for x in dict(model.named_modules()).keys() if '.' not in x and len(x) > 0]
modules
Out[92]:
['image_encoder', 'text_encoder']

Text encoder

In [86]:
summary(model.text_encoder)
Out[86]:
================================================================================
Layer (type:depth-idx)                                  Param #
================================================================================
Textual_encoder                                         --
├─BertModel: 1-1                                        --
│    └─BertEmbeddings: 2-1                              --
│    │    └─Embedding: 3-1                              (23,440,896)
│    │    └─Embedding: 3-2                              (393,216)
│    │    └─Embedding: 3-3                              (1,536)
│    │    └─LayerNorm: 3-4                              (1,536)
│    │    └─Dropout: 3-5                                --
│    └─BertEncoder: 2-2                                 --
│    │    └─ModuleList: 3-6                             85,054,464
│    └─BertPooler: 2-3                                  --
│    │    └─Linear: 3-7                                 590,592
│    │    └─Tanh: 3-8                                   --
================================================================================
Total params: 109,482,240
Trainable params: 28,942,080
Non-trainable params: 80,540,160
================================================================================
In [87]:
modules = [x for x in dict(model.text_encoder.encoder.named_modules()).keys() if '.' not in x and len(x) > 0]
modules
Out[87]:
['embeddings', 'encoder', 'pooler']
In [89]:
model.text_encoder.encoder.embeddings
Out[89]:
BertEmbeddings(
  (word_embeddings): Embedding(30522, 768, padding_idx=0)
  (position_embeddings): Embedding(512, 768)
  (token_type_embeddings): Embedding(2, 768)
  (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
  (dropout): Dropout(p=0.1, inplace=False)
)
In [91]:
summary(model.text_encoder.encoder.encoder)
Out[91]:
======================================================================
Layer (type:depth-idx)                        Param #
======================================================================
BertEncoder                                   --
├─ModuleList: 1-1                             --
│    └─BertLayer: 2-1                         --
│    │    └─BertAttention: 3-1                (2,363,904)
│    │    └─BertIntermediate: 3-2             (2,362,368)
│    │    └─BertOutput: 3-3                   (2,361,600)
│    └─BertLayer: 2-2                         --
│    │    └─BertAttention: 3-4                (2,363,904)
│    │    └─BertIntermediate: 3-5             (2,362,368)
│    │    └─BertOutput: 3-6                   (2,361,600)
│    └─BertLayer: 2-3                         --
│    │    └─BertAttention: 3-7                (2,363,904)
│    │    └─BertIntermediate: 3-8             (2,362,368)
│    │    └─BertOutput: 3-9                   (2,361,600)
│    └─BertLayer: 2-4                         --
│    │    └─BertAttention: 3-10               (2,363,904)
│    │    └─BertIntermediate: 3-11            (2,362,368)
│    │    └─BertOutput: 3-12                  (2,361,600)
│    └─BertLayer: 2-5                         --
│    │    └─BertAttention: 3-13               (2,363,904)
│    │    └─BertIntermediate: 3-14            (2,362,368)
│    │    └─BertOutput: 3-15                  (2,361,600)
│    └─BertLayer: 2-6                         --
│    │    └─BertAttention: 3-16               (2,363,904)
│    │    └─BertIntermediate: 3-17            (2,362,368)
│    │    └─BertOutput: 3-18                  (2,361,600)
│    └─BertLayer: 2-7                         --
│    │    └─BertAttention: 3-19               (2,363,904)
│    │    └─BertIntermediate: 3-20            (2,362,368)
│    │    └─BertOutput: 3-21                  (2,361,600)
│    └─BertLayer: 2-8                         --
│    │    └─BertAttention: 3-22               (2,363,904)
│    │    └─BertIntermediate: 3-23            (2,362,368)
│    │    └─BertOutput: 3-24                  (2,361,600)
│    └─BertLayer: 2-9                         --
│    │    └─BertAttention: 3-25               2,363,904
│    │    └─BertIntermediate: 3-26            2,362,368
│    │    └─BertOutput: 3-27                  2,361,600
│    └─BertLayer: 2-10                        --
│    │    └─BertAttention: 3-28               2,363,904
│    │    └─BertIntermediate: 3-29            2,362,368
│    │    └─BertOutput: 3-30                  2,361,600
│    └─BertLayer: 2-11                        --
│    │    └─BertAttention: 3-31               2,363,904
│    │    └─BertIntermediate: 3-32            2,362,368
│    │    └─BertOutput: 3-33                  2,361,600
│    └─BertLayer: 2-12                        --
│    │    └─BertAttention: 3-34               2,363,904
│    │    └─BertIntermediate: 3-35            2,362,368
│    │    └─BertOutput: 3-36                  2,361,600
======================================================================
Total params: 85,054,464
Trainable params: 28,351,488
Non-trainable params: 56,702,976
======================================================================
In [88]:
model.text_encoder.encoder.pooler
Out[88]:
BertPooler(
  (dense): Linear(in_features=768, out_features=768, bias=True)
  (activation): Tanh()
)

Image Encoder

In [95]:
summary(model.image_encoder)
Out[95]:
=================================================================
Layer (type:depth-idx)                   Param #
=================================================================
Image_encoder_ModifiedResNet             --
├─Conv2d: 1-1                            864
├─BatchNorm2d: 1-2                       64
├─ReLU: 1-3                              --
├─Conv2d: 1-4                            9,216
├─BatchNorm2d: 1-5                       64
├─ReLU: 1-6                              --
├─Conv2d: 1-7                            18,432
├─BatchNorm2d: 1-8                       128
├─ReLU: 1-9                              --
├─AvgPool2d: 1-10                        --
├─Sequential: 1-11                       --
│    └─Bottleneck: 2-1                   --
│    │    └─Conv2d: 3-1                  4,096
│    │    └─BatchNorm2d: 3-2             128
│    │    └─ReLU: 3-3                    --
│    │    └─Conv2d: 3-4                  36,864
│    │    └─BatchNorm2d: 3-5             128
│    │    └─ReLU: 3-6                    --
│    │    └─Identity: 3-7                --
│    │    └─Conv2d: 3-8                  16,384
│    │    └─BatchNorm2d: 3-9             512
│    │    └─ReLU: 3-10                   --
│    │    └─Sequential: 3-11             16,896
│    └─Bottleneck: 2-2                   --
│    │    └─Conv2d: 3-12                 16,384
│    │    └─BatchNorm2d: 3-13            128
│    │    └─ReLU: 3-14                   --
│    │    └─Conv2d: 3-15                 36,864
│    │    └─BatchNorm2d: 3-16            128
│    │    └─ReLU: 3-17                   --
│    │    └─Identity: 3-18               --
│    │    └─Conv2d: 3-19                 16,384
│    │    └─BatchNorm2d: 3-20            512
│    │    └─ReLU: 3-21                   --
│    └─Bottleneck: 2-3                   --
│    │    └─Conv2d: 3-22                 16,384
│    │    └─BatchNorm2d: 3-23            128
│    │    └─ReLU: 3-24                   --
│    │    └─Conv2d: 3-25                 36,864
│    │    └─BatchNorm2d: 3-26            128
│    │    └─ReLU: 3-27                   --
│    │    └─Identity: 3-28               --
│    │    └─Conv2d: 3-29                 16,384
│    │    └─BatchNorm2d: 3-30            512
│    │    └─ReLU: 3-31                   --
├─Sequential: 1-12                       --
│    └─Bottleneck: 2-4                   --
│    │    └─Conv2d: 3-32                 32,768
│    │    └─BatchNorm2d: 3-33            256
│    │    └─ReLU: 3-34                   --
│    │    └─Conv2d: 3-35                 147,456
│    │    └─BatchNorm2d: 3-36            256
│    │    └─ReLU: 3-37                   --
│    │    └─AvgPool2d: 3-38              --
│    │    └─Conv2d: 3-39                 65,536
│    │    └─BatchNorm2d: 3-40            1,024
│    │    └─ReLU: 3-41                   --
│    │    └─Sequential: 3-42             132,096
│    └─Bottleneck: 2-5                   --
│    │    └─Conv2d: 3-43                 65,536
│    │    └─BatchNorm2d: 3-44            256
│    │    └─ReLU: 3-45                   --
│    │    └─Conv2d: 3-46                 147,456
│    │    └─BatchNorm2d: 3-47            256
│    │    └─ReLU: 3-48                   --
│    │    └─Identity: 3-49               --
│    │    └─Conv2d: 3-50                 65,536
│    │    └─BatchNorm2d: 3-51            1,024
│    │    └─ReLU: 3-52                   --
│    └─Bottleneck: 2-6                   --
│    │    └─Conv2d: 3-53                 65,536
│    │    └─BatchNorm2d: 3-54            256
│    │    └─ReLU: 3-55                   --
│    │    └─Conv2d: 3-56                 147,456
│    │    └─BatchNorm2d: 3-57            256
│    │    └─ReLU: 3-58                   --
│    │    └─Identity: 3-59               --
│    │    └─Conv2d: 3-60                 65,536
│    │    └─BatchNorm2d: 3-61            1,024
│    │    └─ReLU: 3-62                   --
│    └─Bottleneck: 2-7                   --
│    │    └─Conv2d: 3-63                 65,536
│    │    └─BatchNorm2d: 3-64            256
│    │    └─ReLU: 3-65                   --
│    │    └─Conv2d: 3-66                 147,456
│    │    └─BatchNorm2d: 3-67            256
│    │    └─ReLU: 3-68                   --
│    │    └─Identity: 3-69               --
│    │    └─Conv2d: 3-70                 65,536
│    │    └─BatchNorm2d: 3-71            1,024
│    │    └─ReLU: 3-72                   --
├─Sequential: 1-13                       --
│    └─Bottleneck: 2-8                   --
│    │    └─Conv2d: 3-73                 131,072
│    │    └─BatchNorm2d: 3-74            512
│    │    └─ReLU: 3-75                   --
│    │    └─Conv2d: 3-76                 589,824
│    │    └─BatchNorm2d: 3-77            512
│    │    └─ReLU: 3-78                   --
│    │    └─AvgPool2d: 3-79              --
│    │    └─Conv2d: 3-80                 262,144
│    │    └─BatchNorm2d: 3-81            2,048
│    │    └─ReLU: 3-82                   --
│    │    └─Sequential: 3-83             526,336
│    └─Bottleneck: 2-9                   --
│    │    └─Conv2d: 3-84                 262,144
│    │    └─BatchNorm2d: 3-85            512
│    │    └─ReLU: 3-86                   --
│    │    └─Conv2d: 3-87                 589,824
│    │    └─BatchNorm2d: 3-88            512
│    │    └─ReLU: 3-89                   --
│    │    └─Identity: 3-90               --
│    │    └─Conv2d: 3-91                 262,144
│    │    └─BatchNorm2d: 3-92            2,048
│    │    └─ReLU: 3-93                   --
│    └─Bottleneck: 2-10                  --
│    │    └─Conv2d: 3-94                 262,144
│    │    └─BatchNorm2d: 3-95            512
│    │    └─ReLU: 3-96                   --
│    │    └─Conv2d: 3-97                 589,824
│    │    └─BatchNorm2d: 3-98            512
│    │    └─ReLU: 3-99                   --
│    │    └─Identity: 3-100              --
│    │    └─Conv2d: 3-101                262,144
│    │    └─BatchNorm2d: 3-102           2,048
│    │    └─ReLU: 3-103                  --
│    └─Bottleneck: 2-11                  --
│    │    └─Conv2d: 3-104                262,144
│    │    └─BatchNorm2d: 3-105           512
│    │    └─ReLU: 3-106                  --
│    │    └─Conv2d: 3-107                589,824
│    │    └─BatchNorm2d: 3-108           512
│    │    └─ReLU: 3-109                  --
│    │    └─Identity: 3-110              --
│    │    └─Conv2d: 3-111                262,144
│    │    └─BatchNorm2d: 3-112           2,048
│    │    └─ReLU: 3-113                  --
│    └─Bottleneck: 2-12                  --
│    │    └─Conv2d: 3-114                262,144
│    │    └─BatchNorm2d: 3-115           512
│    │    └─ReLU: 3-116                  --
│    │    └─Conv2d: 3-117                589,824
│    │    └─BatchNorm2d: 3-118           512
│    │    └─ReLU: 3-119                  --
│    │    └─Identity: 3-120              --
│    │    └─Conv2d: 3-121                262,144
│    │    └─BatchNorm2d: 3-122           2,048
│    │    └─ReLU: 3-123                  --
│    └─Bottleneck: 2-13                  --
│    │    └─Conv2d: 3-124                262,144
│    │    └─BatchNorm2d: 3-125           512
│    │    └─ReLU: 3-126                  --
│    │    └─Conv2d: 3-127                589,824
│    │    └─BatchNorm2d: 3-128           512
│    │    └─ReLU: 3-129                  --
│    │    └─Identity: 3-130              --
│    │    └─Conv2d: 3-131                262,144
│    │    └─BatchNorm2d: 3-132           2,048
│    │    └─ReLU: 3-133                  --
├─Sequential: 1-14                       --
│    └─Bottleneck: 2-14                  --
│    │    └─Conv2d: 3-134                524,288
│    │    └─BatchNorm2d: 3-135           1,024
│    │    └─ReLU: 3-136                  --
│    │    └─Conv2d: 3-137                2,359,296
│    │    └─BatchNorm2d: 3-138           1,024
│    │    └─ReLU: 3-139                  --
│    │    └─AvgPool2d: 3-140             --
│    │    └─Conv2d: 3-141                1,048,576
│    │    └─BatchNorm2d: 3-142           4,096
│    │    └─ReLU: 3-143                  --
│    │    └─Sequential: 3-144            2,101,248
│    └─Bottleneck: 2-15                  --
│    │    └─Conv2d: 3-145                1,048,576
│    │    └─BatchNorm2d: 3-146           1,024
│    │    └─ReLU: 3-147                  --
│    │    └─Conv2d: 3-148                2,359,296
│    │    └─BatchNorm2d: 3-149           1,024
│    │    └─ReLU: 3-150                  --
│    │    └─Identity: 3-151              --
│    │    └─Conv2d: 3-152                1,048,576
│    │    └─BatchNorm2d: 3-153           4,096
│    │    └─ReLU: 3-154                  --
│    └─Bottleneck: 2-16                  --
│    │    └─Conv2d: 3-155                1,048,576
│    │    └─BatchNorm2d: 3-156           1,024
│    │    └─ReLU: 3-157                  --
│    │    └─Conv2d: 3-158                2,359,296
│    │    └─BatchNorm2d: 3-159           1,024
│    │    └─ReLU: 3-160                  --
│    │    └─Identity: 3-161              --
│    │    └─Conv2d: 3-162                1,048,576
│    │    └─BatchNorm2d: 3-163           4,096
│    │    └─ReLU: 3-164                  --
├─AttentionPool2d: 1-15                  67,584
│    └─Linear: 2-17                      4,196,352
│    └─Linear: 2-18                      4,196,352
│    └─Linear: 2-19                      4,196,352
│    └─Linear: 2-20                      1,573,632
=================================================================
Total params: 37,757,536
Trainable params: 37,757,536
Non-trainable params: 0
=================================================================
In [ ]: