1.模型为resnet152, 默认输出图片大小是224*224*3
2.获取除去全连接层的模型
import torch
import torch.nn as nn
import torchvision.models as models
from torch.autograd import Variable
resnet152 = models.resnet152(pretrained=True)
modules=list(resnet152.children())[:-1]
resnet152=nn.Sequential(*modules)
for p in resnet152.parameters():
p.requires_grad = False
2.使用新模型处理图片
import cv2
import torch
import torch.nn as nn
import torchvision.models as models
from torch.autograd import Variable
from PIL import Image
import torchvision.transforms as transforms
class ResNet152Bottom(nn.Module):
def __init__(self, original_model):
super(ResNet152Bottom, self).__init__()
self.features = nn.Sequential(*list(original_model.children())[:-1])
def forward(self, x):
x = self.features(x)
return x
def image_for_pytorch(img_file):
Data = Image.open(img_file).convert('RGB')
transform = transforms.Compose([
transforms.Resize(224),transforms.ToTensor(), # range [0, 255] -> [0.0,1.0]
transforms.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225))
]
)
imData = transform(Data)
imData = Variable(torch.unsqueeze(imData, dim=0), requires_grad=True)
return imData
res152_model = models.resnet152(pretrained=True)
res152_conv2 = ResNet152Bottom(res152_model)
img_file = "test.jpg"
# inputs = cv2.imread("8.jpg")
inputs = image_for_pytorch(img_file)
outputs = res152_conv2(inputs)
print(outputs.data.shape)
torch.Size([1, 2048, 2, 6])
产生这种情况的原因是图片比例不是1:1,resize的时候自然变不成224*224,
解决方法:
1.从输入考虑:
使用transforms.
CenterCrop(224),把图片从中间裁剪为224*224的输入图片,满足要求
2.从输出考虑,最后一层的AvgPool2d输出为(1, 2048, 2, 6) ,替换为平均层,resnet152_conv2.avgpool = nn.AdaptiveAvgPool2d((1, 1)),把结果变成(1, 2048, 1, 1)
参考:https://discuss.pytorch.org/t/how-can-l-use-the-pre-trained-resnet-to-extract-feautres-from-my-own-dataset/9008
https://blog.csdn.net/jiangpeng59/article/details/79609392
python2.7 执行 resnet152_model = models.resnet152(pretrained=True)
print(resnet152_model)
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)
(maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
(layer1): Sequential(
(0): Bottleneck()
(1): Bottleneck()
(2): Bottleneck()
)
(layer2): Sequential(
(0): Bottleneck()
(1): Bottleneck()
(2): Bottleneck()
(3): Bottleneck()
(4): Bottleneck()
(5): Bottleneck()
(6): Bottleneck()
(7): Bottleneck()
)
(layer3): Sequential(
(0): Bottleneck()
(35): Bottleneck()
)
(layer4): Sequential(
(0): Bottleneck()
(1): Bottleneck()
(2): Bottleneck()
)
(avgpool): AvgPool2d(kernel_size=7, stride=1, padding=0)
(fc): Linear(in_features=2048, out_features=1000, bias=True)
)
python3.6执行 resnet152_model = models.resnet152(pretrained=True)
print(resnet152_model)
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)
(maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
(layer1): Sequential(
(0): Bottleneck()
(1): Bottleneck()
(2): Bottleneck()
)
(layer2): Sequential(
(0): Bottleneck()
(1): Bottleneck()
(2): Bottleneck()
(3): Bottleneck()
(4): Bottleneck()
(5): Bottleneck()
(6): Bottleneck()
(7): Bottleneck()
)
(layer3): Sequential(
(0): Bottleneck()
(35): Bottleneck()
)
(layer4): Sequential(
(0): Bottleneck()
(1): Bottleneck()
(2): Bottleneck()
)
(avgpool): AdaptiveAvgPool2d(output_size=(1, 1))
(fc): Linear(in_features=2048, out_features=1000, bias=True)
)
发现:resnet152在python2.7和python3.6下倒数第二层avgpool不一样,所以pyhont3.6下输出的结果[1,2048,1,1]