pytorch实现:Resnet模型识别花朵数据集
一、pytorch实现:Resnet模型识别花朵数据集
1.1 训练模型
import torch, torchvision
from torchvision import datasets, transforms, models
import os
import matplotlib. pyplot as plt
import numpy as np
from torch import nn
from torch import optim
import imageio
import time
import warnings
warnings. filterwarnings( 'ignore' )
import random
import sys
import copy
import json
from PIL import Image
data_dir = r'./flower_data/'
train_dir = data_dir + 'train'
test_dir = data_dir + 'valid'
data_transforms = {
'train' : transforms. Compose( [
transforms. RandomRotation( 45 ) ,
transforms. CenterCrop( 224 ) ,
transforms. RandomHorizontalFlip( p= 0.5 ) ,
transforms. RandomVerticalFlip( p= 0.5 ) ,
transforms. ColorJitter( brightness= 0.2 , contrast= 0.1 , saturation= 0.1 , hue= 0.1 ) ,
transforms. RandomGrayscale( p= 0.025 ) ,
transforms. ToTensor( ) ,
transforms. Normalize( [ 0.485 , 0.456 , 0.406 ] , [ 0.229 , 0.224 , 0.225 ] )
]
) ,
'valid' : transforms. Compose( [
transforms. Resize( 256 ) ,
transforms. CenterCrop( 224 ) ,
transforms. ToTensor( ) ,
transforms. Normalize( [ 0.485 , 0.456 , 0.406 ] , [ 0.229 , 0.224 , 0.225 ] )
] )
}
batch_size = 8
image_datasets = { x: datasets. ImageFolder( root= os. path. join( data_dir, x) , transform= data_transforms[ x] ) for x in
[ 'train' , 'valid' ] }
dataloaders = { x: torch. utils. data. DataLoader( image_datasets[ x] , batch_size= batch_size, shuffle= True ) for x in
[ 'train' , 'valid' ] }
dataset_size = { x: len ( image_datasets[ x] ) for x in [ 'train' , 'valid' ] }
class_names = image_datasets[ 'train' ] . classes
print ( image_datasets)
print ( dataloaders)
print ( dataset_size)
print ( class_names)
with open ( './cat_to_name.json' , 'r' ) as f:
cat_to_name = json. load( f)
print ( cat_to_name)
"""
{'train': Dataset ImageFolder
Number of datapoints: 6552
Root location: ./flower_data/train
StandardTransform
Transform: Compose(
RandomRotation(degrees=[-45.0, 45.0], interpolation=nearest, expand=False, fill=0)
CenterCrop(size=(224, 224))
RandomHorizontalFlip(p=0.5)
RandomVerticalFlip(p=0.5)
ColorJitter(brightness=[0.8, 1.2], contrast=[0.9, 1.1], saturation=[0.9, 1.1], hue=[-0.1, 0.1])
RandomGrayscale(p=0.025)
ToTensor()
Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
),
'valid': Dataset ImageFolder
Number of datapoints: 818
Root location: ./flower_data/valid
StandardTransform
Transform: Compose(
Resize(size=256, interpolation=bilinear, max_size=None, antialias=None)
CenterCrop(size=(224, 224))
ToTensor()
Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
)}
{'train': <torch.utils.data.dataloader.DataLoader object at 0x000001BB8E0CD850>,
'valid': <torch.utils.data.dataloader.DataLoader object at 0x000001BB8E0CD820>}
{'train': 6552, 'valid': 818}
['1', '10', '100', '101', '102', '11', '12', '13', '14', '15', '16', '17', '18', '19', '2', '20', '21', '22',
'23', '24', '25', '26', '27', '28', '29', '3', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39',
'4', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '5', '50', '51', '52', '53', '54', '55',
'56', '57', '58', '59', '6', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '7', '70', '71',
'72', '73', '74', '75', '76', '77', '78', '79', '8', '80', '81', '82', '83', '84', '85', '86', '87', '88',
'89', '9', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99']
{'21': 'fire lily', '3': 'canterbury bells', '45': 'bolero deep blue', '1': 'pink primrose', '34': 'mexican aster',
'27': 'prince of wales feathers', '7': 'moon orchid', '16': 'globe-flower', '25': 'grape hyacinth',
'26': 'corn poppy', '79': 'toad lily', '39': 'siam tulip', '24': 'red ginger', '67': 'spring crocus',
'35': 'alpine sea holly', '32': 'garden phlox', '10': 'globe thistle', '6': 'tiger lily', '93': 'ball moss',
'33': 'love in the mist', '9': 'monkshood', '102': 'blackberry lily', '14': 'spear thistle', '19': 'balloon flower',
'100': 'blanket flower', '13': 'king protea', '49': 'oxeye daisy', '15': 'yellow iris', '61': 'cautleya spicata',
'31': 'carnation', '64': 'silverbush', '68': 'bearded iris', '63': 'black-eyed susan', '69': 'windflower',
'62': 'japanese anemone', '20': 'giant white arum lily', '38': 'great masterwort', '4': 'sweet pea',
'86': 'tree mallow', '101': 'trumpet creeper', '42': 'daffodil', '22': 'pincushion flower',
'2': 'hard-leaved pocket orchid', '54': 'sunflower', '66': 'osteospermum', '70': 'tree poppy',
'85': 'desert-rose', '99': 'bromelia', '87': 'magnolia', '5': 'english marigold', '92': 'bee balm',
'28': 'stemless gentian', '97': 'mallow', '57': 'gaura', '40': 'lenten rose', '47': 'marigold',
'59': 'orange dahlia', '48': 'buttercup', '55': 'pelargonium', '36': 'ruby-lipped cattleya',
'91': 'hippeastrum', '29': 'artichoke', '71': 'gazania', '90': 'canna lily', '18': 'peruvian lily',
'98': 'mexican petunia', '8': 'bird of paradise', '30': 'sweet william', '17': 'purple coneflower',
'52': 'wild pansy', '84': 'columbine', '12': "colt's foot", '11': 'snapdragon', '96': 'camellia',
'23': 'fritillary', '50': 'common dandelion', '44': 'poinsettia', '53': 'primula', '72': 'azalea',
'65': 'californian poppy', '80': 'anthurium', '76': 'morning glory', '37': 'cape flower',
'56': 'bishop of llandaff', '60': 'pink-yellow dahlia', '82': 'clematis', '58': 'geranium',
'75': 'thorn apple', '41': 'barbeton daisy', '95': 'bougainvillea', '43': 'sword lily',
'83': 'hibiscus', '78': 'lotus lotus', '88': 'cyclamen', '94': 'foxglove', '81': 'frangipani',
'74': 'rose', '89': 'watercress', '73': 'water lily', '46': 'wallflower', '77': 'passion flower',
'51': 'petunia'}
"""
def im_convert ( tensor) :
image = tensor. to( 'cpu' ) . clone( ) . detach( )
"""
tensor.clone():返回tensor的拷贝,返回的新tensor和原来的tensor具有同样的大小和数据类型
原tensor的requires_grad=True,clone()返回的tensor是中间节点,梯度会流向原tensor,即返回的tensor的梯度会叠加在原tensor上
tensor.detach():从计算图中脱离出来,返回一个新的tensor,新的tensor和原来的tensor共享数据内存,但不涉及梯度计算
"""
image = image. numpy( )
image = image. transpose( 1 , 2 , 0 )
image = image * np. array( ( 0.485 , 0.456 , 0.406 ) ) + np. array( ( 0.229 , 0.224 , 0.225 ) )
image = image. clip( 0 , 1 )
return image
fig = plt. figure( figsize= ( 20 , 12 ) )
cols = 4
rows = 2
dataiter = iter ( dataloaders[ 'valid' ] )
inputs, classes = dataiter. next ( )
for idx in range ( cols * rows) :
ax = fig. add_subplot( rows, cols, idx + 1 , xticks= [ ] , yticks= [ ] )
ax. set_title( cat_to_name[ str ( int ( class_names[ idx] ) ) ] )
plt. imshow( im_convert( inputs[ idx] ) )
plt. show( )
model_name = 'resnet'
feature_extracting = True
train_on_gpu = torch. cuda. is_available( )
if not train_on_gpu:
print ( 'CUDA is not available, Training on CPU!' )
else :
print ( 'CUDA is available, Training on GPU!' )
device = torch. device( 'cuda:0' if torch. cuda. is_available( ) else "cpu" )
"""
CUDA is not available, Training on CPU!
"""
def set_parameter_require_grad ( model, feature_extract) :
if feature_extract:
for param in model. parameters( ) :
param. requires_grad = False
model_ft = models. resnet152( )
def initialize_model ( model_name, num_classes, feature_extract, use_pretrained= True ) :
if model_name == 'resnet' :
model_ft = models. resnet152( pretrained= use_pretrained)
set_parameter_require_grad( model_ft, feature_extract)
num_feature_in = model_ft. fc. in_features
model_ft. fc = nn. Sequential( nn. Linear( num_feature_in, num_classes) ,
nn. LogSoftmax( dim= 1 ) )
input_size = 224
elif model_name == 'alexnet' :
model_ft = models. alexnet( pretrained= use_pretrained)
set_parameter_require_grad( model_ft, feature_extract)
num_feature_in = model_ft. classifier[ 6 ] . in_features
model_ft. classifier[ 6 ] = nn. Linear( num_feature_in, num_classes)
input_size = 224
elif model_name == 'vgg' :
model_ft = models. vgg16( pretrained= use_pretrained)
set_parameter_require_grad( model_ft, feature_extract)
num_feature_in = model_ft. classifier[ 6 ] . in_features
model_ft. classifier[ 6 ] = nn. Linear( num_feature_in, num_classes)
input_size = 224
elif model_name == 'squeezenet' :
model_ft = models. squeezenet1_0( pretrained= use_pretrained)
set_parameter_require_grad( model_ft, feature_extract)
model_ft. classifier[ 1 ] = nn. Conv2d( 512 , num_classes, kernel_size= ( 1 , 1 ) , stride= ( 1 , 1 ) )
input_size = 224
elif model_name == 'densenet' :
model_ft = models. densenet121( pretrained= use_pretrained)
set_parameter_require_grad( model_ft, feature_extract)
num_feature_in = model_ft. classifier. in_features
model_ft. classifier = nn. Linear( num_feature_in, num_classes)
input_size = 224
elif model_name == 'inception' :
model_ft = models. inception_v3( pretrained= use_pretrained)
set_parameter_require_grad( model_ft, feature_extract)
num_feature_in = model_ft. AuxLogits. fc. in_features
model_ft. AuxLogits. fc = nn. Linear( num_feature_in, num_classes)
input_size = 229
else :
print ( 'Invalid model name, exiting...' )
return model_ft, input_size
model_ft, input_size = initialize_model( model_name, 102 , feature_extracting,
use_pretrained= True )
model_ft = model_ft. to( device)
file_path = './checkpoint.pth'
params_to_update = model_ft. parameters( )
print ( 'Params to learn' )
if feature_extracting:
params_to_update = [ ]
for name, param in model_ft. named_parameters( ) :
if param. requires_grad == True :
params_to_update. append( param)
print ( '\t' , name)
else :
for name, param in model_ft. named_parameters( ) :
if param. requires_grad == True :
print ( '\t' , name)
print ( model_ft)
"""
ResNet(
(conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
(layer1): Sequential(
(0): Bottleneck(
(conv1): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(downsample): Sequential(
(0): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(1): Bottleneck(
(conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(2): Bottleneck(
(conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
)
(layer2): Sequential(
(0): Bottleneck(
(conv1): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(downsample): Sequential(
(0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(1): Bottleneck(
(conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(2): Bottleneck(
(conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(3): Bottleneck(
(conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(4): Bottleneck(
(conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(5): Bottleneck(
(conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(6): Bottleneck(
(conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(7): Bottleneck(
(conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
)
(layer3): Sequential(
(0): Bottleneck(
(conv1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(downsample): Sequential(
(0): Conv2d(512, 1024, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(1): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(2): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(3): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(4): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(5): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(6): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(7): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(8): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(9): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(10): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(11): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(12): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(13): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(14): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(15): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(16): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(17): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(18): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(19): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(20): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(21): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(22): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(23): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(24): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(25): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(26): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(27): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(28): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(29): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(30): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(31): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(32): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(33): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(34): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(35): Bottleneck(
(conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
)
(layer4): Sequential(
(0): Bottleneck(
(conv1): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(downsample): Sequential(
(0): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(1): Bottleneck(
(conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
(2): Bottleneck(
(conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
)
)
(avgpool): AdaptiveAvgPool2d(output_size=(1, 1))
(fc): Linear(in_features=2048, out_features=1000, bias=True)
)
-----------------------------------------------------------------------------------
Params to learn
fc.0.weight
fc.0.bias
"""
optimizer_ft = optim. Adam( params_to_update, lr= 1e-2 )
scheduler = optim. lr_scheduler. StepLR( optimizer_ft, step_size= 7 , gamma= 0.1 )
criterion = nn. NLLLoss( )
def train ( model, dataloader, criterion, optimizer, num_epoch= 5 , filename= file_path) :
start = time. time( )
best_acc = 0
model. to( device)
val_acc = [ ]
val_loss = [ ]
train_acc = [ ]
train_loss = [ ]
LRs = [ optimizer. param_groups[ 0 ] [ 'lr' ] ]
best_model_weights = copy. deepcopy( model. state_dict( ) )
for epoch in range ( num_epoch) :
print ( 'Epoch {}/{}' . format ( epoch, num_epoch - 1 ) )
print ( '-' * 10 )
for phase in [ 'train' , 'valid' ] :
if phase == 'train' :
model. train( )
else :
model. eval ( )
running_loss = 0.0
running_corrects = 0.0
for inputs, labels in dataloader[ phase] :
inputs = inputs. to( device)
labels = labels. to( device)
optimizer. zero_grad( )
with torch. set_grad_enabled( phase == 'train' ) :
outputs = model( inputs)
loss = criterion( outputs, labels)
preds = torch. argmax( outputs, 1 )
if phase == 'train' :
loss. backward( )
optimizer. step( )
running_loss += loss. item( ) * inputs. size( 0 )
running_corrects += torch. sum ( preds == labels. data)
epoch_loss = running_loss / len ( dataloader[ phase] . dataset)
epoch_acc = running_corrects / len ( dataloader[ phase] . dataset)
time_elapsed = time. time( ) - start
print ( 'Time elapsed {:.0f}m {:.0f}s' . format ( time_elapsed // 60 , time_elapsed % 60 ) )
print ( '{} Loss: {:.4f} Acc: {:.4f}' . format ( phase, epoch_loss, epoch_acc) )
if phase == 'valid' and epoch_acc > best_acc:
best_acc = epoch_acc
best_model_weights = copy. deepcopy( model. state_dict( ) )
state = { 'state_dict' : model. state_dict( ) ,
'best_acc' : best_acc,
'optimizer' : optimizer. state_dict( ) }
torch. save( state, filename)
if phase == 'valid' :
val_acc. append( epoch_acc)
val_loss. append( epoch_loss)
scheduler. step( epoch_loss)
if phase == 'train' :
train_acc. append( epoch_acc)
train_loss. append( epoch_loss)
print ( 'Optimizer learning rate: {:.7f}' . format ( optimizer. param_groups[ 0 ] [ 'lr' ] ) )
LRs. append( optimizer. param_groups[ 0 ] [ 'lr' ] )
time_elapsed = time. time( ) - start
print ( 'Training complete in {:.0f}m {:.0f}s' . format ( time_elapsed // 60 , time_elapsed % 60 ) )
print ( 'Best val Acc: {:4f}' . format ( best_acc) )
model. load_state_dict( best_model_weights)
return model, val_acc, train_acc, val_loss, train_loss, LRs
model_ft, val_acc, train_acc, valid_loss, train_loss, LRs = train( model_ft,
dataloaders,
criterion,
optimizer_ft,
num_epoch= 5 )
"""
Epoch 0/4
----------
Time elapsed 20m 16s
train Loss: 10.0411 Acc: 0.3132
Time elapsed 22m 34s
valid Loss: 12.0470 Acc: 0.3765
Optimizer learning rate: 0.0010000
Epoch 1/4
----------
Time elapsed 42m 49s
train Loss: 2.3768 Acc: 0.6980
Time elapsed 45m 6s
valid Loss: 3.3266 Acc: 0.6357
Optimizer learning rate: 0.0100000
Epoch 2/4
----------
Time elapsed 66m 21s
train Loss: 9.7728 Acc: 0.4770
Time elapsed 68m 46s
valid Loss: 15.3826 Acc: 0.4389
Optimizer learning rate: 0.0001000
Epoch 3/4
----------
Time elapsed 90m 8s
train Loss: 4.7683 Acc: 0.6784
Time elapsed 92m 27s
valid Loss: 6.8775 Acc: 0.6088
Optimizer learning rate: 0.0100000
Epoch 4/4
----------
Time elapsed 110m 31s
train Loss: 9.1733 Acc: 0.5499
Time elapsed 112m 31s
valid Loss: 14.6585 Acc: 0.4707
Optimizer learning rate: 0.0001000
Training complete in 112m 31s
Best val Acc: 0.635697
"""
1.2 图像预测和可视化
import torch, torchvision
from torchvision import datasets, transforms, models
import os
import matplotlib. pyplot as plt
import numpy as np
from torch import nn
from torch import optim
import imageio
import time
import warnings
warnings. filterwarnings( 'ignore' )
import random
import sys
import copy
import json
from PIL import Image
data_dir = r'./flower_data/'
train_dir = data_dir + 'train'
test_dir = data_dir + 'valid'
data_transforms = {
'train' : transforms. Compose( [
transforms. RandomRotation( 45 ) ,
transforms. CenterCrop( 224 ) ,
transforms. RandomHorizontalFlip( p= 0.5 ) ,
transforms. RandomVerticalFlip( p= 0.5 ) ,
transforms. ColorJitter( brightness= 0.2 , contrast= 0.1 , saturation= 0.1 , hue= 0.1 ) ,
transforms. RandomGrayscale( p= 0.025 ) ,
transforms. ToTensor( ) ,
transforms. Normalize( [ 0.485 , 0.456 , 0.406 ] , [ 0.229 , 0.224 , 0.225 ] )
]
) ,
'valid' : transforms. Compose( [
transforms. Resize( 256 ) ,
transforms. CenterCrop( 224 ) ,
transforms. ToTensor( ) ,
transforms. Normalize( [ 0.485 , 0.456 , 0.406 ] , [ 0.229 , 0.224 , 0.225 ] )
] )
}
with open ( './cat_to_name.json' , 'r' ) as f:
cat_to_name = json. load( f)
def im_convert ( tensor) :
image = tensor. to( 'cpu' ) . clone( ) . detach( )
"""
tensor.clone():返回tensor的拷贝,返回的新tensor和原来的tensor具有同样的大小和数据类型
原tensor的requires_grad=True,clone()返回的tensor是中间节点,梯度会流向原tensor,即返回的tensor的梯度会叠加在原tensor上
tensor.detach():从计算图中脱离出来,返回一个新的tensor,新的tensor和原来的tensor共享数据内存,但不涉及梯度计算
"""
image = image. numpy( )
image = image. transpose( 1 , 2 , 0 )
image = image * np. array( ( 0.485 , 0.456 , 0.406 ) ) + np. array( ( 0.229 , 0.224 , 0.225 ) )
image = image. clip( 0 , 1 )
return image
batch_size = 8
image_datasets = { x: datasets. ImageFolder( root= os. path. join( data_dir, x) , transform= data_transforms[ x] ) for x in
[ 'train' , 'valid' ] }
dataloaders = { x: torch. utils. data. DataLoader( image_datasets[ x] , batch_size= batch_size, shuffle= True ) for x in
[ 'train' , 'valid' ] }
dataset_size = { x: len ( image_datasets[ x] ) for x in [ 'train' , 'valid' ] }
class_names = image_datasets[ 'train' ] . classes
def set_parameter_require_grad ( model, feature_extract) :
if feature_extract:
for param in model. parameters( ) :
param. requires_grad = False
def initialize_model ( model_name, num_classes, feature_extract, use_pretrained= True ) :
if model_name == 'resnet' :
model_ft = models. resnet152( pretrained= use_pretrained)
set_parameter_require_grad( model_ft, feature_extract)
num_feature_in = model_ft. fc. in_features
model_ft. fc = nn. Sequential( nn. Linear( num_feature_in, num_classes) ,
nn. LogSoftmax( dim= 1 ) )
input_size = 224
elif model_name == 'alexnet' :
model_ft = models. alexnet( pretrained= use_pretrained)
set_parameter_require_grad( model_ft, feature_extract)
num_feature_in = model_ft. classifier[ 6 ] . in_features
model_ft. classifier[ 6 ] = nn. Linear( num_feature_in, num_classes)
input_size = 224
elif model_name == 'vgg' :
model_ft = models. vgg16( pretrained= use_pretrained)
set_parameter_require_grad( model_ft, feature_extract)
num_feature_in = model_ft. classifier[ 6 ] . in_features
model_ft. classifier[ 6 ] = nn. Linear( num_feature_in, num_classes)
input_size = 224
elif model_name == 'squeezenet' :
model_ft = models. squeezenet1_0( pretrained= use_pretrained)
set_parameter_require_grad( model_ft, feature_extract)
model_ft. classifier[ 1 ] = nn. Conv2d( 512 , num_classes, kernel_size= ( 1 , 1 ) , stride= ( 1 , 1 ) )
input_size = 224
elif model_name == 'densenet' :
model_ft = models. densenet121( pretrained= use_pretrained)
set_parameter_require_grad( model_ft, feature_extract)
num_feature_in = model_ft. classifier. in_features
model_ft. classifier = nn. Linear( num_feature_in, num_classes)
input_size = 224
elif model_name == 'inception' :
model_ft = models. inception_v3( pretrained= use_pretrained)
set_parameter_require_grad( model_ft, feature_extract)
num_feature_in = model_ft. AuxLogits. fc. in_features
model_ft. AuxLogits. fc = nn. Linear( num_feature_in, num_classes)
input_size = 229
else :
print ( 'Invalid model name, exiting...' )
return model_ft, input_size
device = torch. device( 'cuda:0' if torch. cuda. is_available( ) else "cpu" )
model_name = 'resnet'
feature_extracting = True
model_ft, input_size = initialize_model( model_name, 102 , feature_extracting, use_pretrained= True )
model_ft = model_ft. to( device)
filename = './checkpoint.pth'
checkpoint = torch. load( filename)
best_acc = checkpoint[ 'best_acc' ]
model_ft. load_state_dict( checkpoint[ 'state_dict' ] )
dataiter = iter ( dataloaders[ 'valid' ] )
images, labels = dataiter. next ( )
model_ft. eval ( )
train_on_gpu = torch. cuda. is_available( )
if train_on_gpu:
output = model_ft( images. cuda( ) )
else :
output = model_ft( images)
print ( output. shape)
preds_tensor = torch. argmax( output, 1 )
print ( preds_tensor)
preds = np. squeeze( preds_tensor. numpy( ) ) if train_on_gpu else np. squeeze( preds_tensor. cpu( ) . numpy( ) )
print ( preds)
fig = plt. figure( figsize= ( 20 , 20 ) )
columns = 4
rows = 2
for idx in range ( columns * rows) :
ax = fig. add_subplot( rows, columns, idx + 1 , xticks= [ ] , yticks= [ ] )
plt. imshow( im_convert( images[ idx] ) )
ax. set_title( "{} ({})" . format ( cat_to_name[ str ( preds[ idx] ) ] , cat_to_name[ str ( labels[ idx] . item( ) ) ] ) ,
color= ( "green" if cat_to_name[ str ( preds[ idx] ) ] == cat_to_name[ str ( labels[ idx] . item( ) ) ] else "red" ) )
plt. show( )
"""
output.shape:torch.Size([8, 102])
preds_tensor:tensor([43, 24, 64, 49, 64, 34, 18, 89])
preds:[43 24 64 49 64 34 18 89]
"""
1.3 对新来的数据进行处理和展示
def process_image ( image_path) :
img = Image. open ( image_path)
if img. size[ 0 ] > img. size[ 1 ] :
img. thumbnail( ( 10000 , 256 ) )
else :
img. thumbnail( ( 256 , 10000 ) )
left_margin = ( img. width - 224 ) / 2
bottom_margin = ( img. height - 224 ) / 2
right_margin = left_margin + 224
top_margin = bottom_margin + 224
img = img. crop( ( left_margin, bottom_margin, right_margin,
top_margin) )
img = np. array( img) / 255
mean = np. array( [ 0.485 , 0.456 , 0.406 ] )
std = np. array( [ 0.229 , 0.224 , 0.225 ] )
img = ( img - mean) / std
img = img. transpose( ( 2 , 0 , 1 ) )
return img
def imshow ( image, ax= None , title= None ) :
"""展示数据"""
if ax is None :
fig, ax = plt. subplots( )
image = np. array( image) . transpose( ( 1 , 2 , 0 ) )
mean = np. array( [ 0.485 , 0.456 , 0.406 ] )
std = np. array( [ 0.229 , 0.224 , 0.225 ] )
image = std * image + mean
image = np. clip( image, 0 , 1 )
ax. imshow( image)
ax. set_title( title)
return ax
image_path = 'image_04248.jpg'
img = process_image( image_path)
imshow( img)
print ( img. shape)