pytorch获得图片特征

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]

你可能感兴趣的:(数据挖掘)