Python 如何从Pytorch中的单个图像中提取特征向量?
我正试图了解更多关于计算机视觉模型的知识,并试图探索它们是如何工作的。为了更好地理解如何解释特征向量,我尝试使用Pytorch来提取特征向量。下面是我从不同地方拼凑的代码Python 如何从Pytorch中的单个图像中提取特征向量?,python,computer-vision,pytorch,feature-extraction,Python,Computer Vision,Pytorch,Feature Extraction,我正试图了解更多关于计算机视觉模型的知识,并试图探索它们是如何工作的。为了更好地理解如何解释特征向量,我尝试使用Pytorch来提取特征向量。下面是我从不同地方拼凑的代码 import torch import torch.nn as nn import torchvision.models as models import torchvision.transforms as transforms from torch.autograd import Variable from PIL impo
import torch
import torch.nn as nn
import torchvision.models as models
import torchvision.transforms as transforms
from torch.autograd import Variable
from PIL import Image
img=Image.open("Documents/01235.png")
# Load the pretrained model
model = models.resnet18(pretrained=True)
# Use the model object to select the desired layer
layer = model._modules.get('avgpool')
# Set model to evaluation mode
model.eval()
transforms = torchvision.transforms.Compose([
torchvision.transforms.Resize(256),
torchvision.transforms.CenterCrop(224),
torchvision.transforms.ToTensor(),
torchvision.transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
def get_vector(image_name):
# Load the image with Pillow library
img = Image.open("Documents/Documents/Driven Data Competitions/Hateful Memes Identification/data/01235.png")
# Create a PyTorch Variable with the transformed image
t_img = transforms(img)
# Create a vector of zeros that will hold our feature vector
# The 'avgpool' layer has an output size of 512
my_embedding = torch.zeros(512)
# Define a function that will copy the output of a layer
def copy_data(m, i, o):
my_embedding.copy_(o.data)
# Attach that function to our selected layer
h = layer.register_forward_hook(copy_data)
# Run the model on our transformed image
model(t_img)
# Detach our copy function from the layer
h.remove()
# Return the feature vector
return my_embedding
pic_vector = get_vector(img)
当我执行此操作时,会出现以下错误:
RuntimeError: Expected 4-dimensional input for 4-dimensional weight [64, 3, 7, 7], but got 3-dimensional input of size [3, 224, 224] instead
我确信这是一个基本的错误,但我似乎不知道如何解决这个问题。我的印象是,totensor转换将使我的数据变成4-d,但它似乎要么工作不正常,要么我误解了它。感谢任何帮助或资源,我可以用来了解更多关于这一点 pytorch中的所有默认nn.模块都需要一个额外的批处理维度。如果模块的输入是形状B。。。然后输出为B。。。尽管后面的尺寸可能会根据图层的不同而变化。此行为允许同时对B批输入进行有效推断。为了使你的代码一致,你可以在t_img张量的前面加上一个幺正维,然后将它发送到你的模型中,使它成为1。。。张量。如果您想将层的输出复制到一维my_嵌入张量中,您还需要在存储它之前对其进行修改
还有几件事:
您应该在torch.no_grad上下文中进行推断,以避免计算渐变,因为您不需要它们注意model.eval只是更改某些层的行为,如退出和批处理规范化,它不会禁用计算图的构造,但torch.no_grad会禁用
我假设这只是一个复制粘贴问题,但transforms是导入模块的名称以及全局变量
o、 数据只是返回o的一个副本。在PyTorch 0.3.1和更早版本的旧变量接口中,这曾经是必要的,但变量接口早在PyTorch中就已经存在,不再做任何有用的事情;现在它的使用只会造成混乱。不幸的是,许多教程仍在使用这个旧的和不必要的界面编写
更新后的代码如下所示:
进口火炬
进口火炬视觉
将torchvision.models导入为模型
从PIL导入图像
img=Image.openDocuments/01235.png
加载预训练模型
model=models.resnet18pretrained=True
使用模型对象选择所需图层
层=模型。\u模块。获取“avgpool”
将模型设置为评估模式
模型评估
transforms=torchvision.transforms.Compose[
torchvision.transforms.Resize256,
torchvision.transforms.CenterCrop224,
torchvision.transforms.ToTensor,
torchvision.transforms.Normalizemean=[0.485,0.456,0.406],标准=[0.229,0.224,0.225],
]
def get_矢量图像:
用变换后的图像创建PyTorch张量
t_img=转换图像
创建一个包含零的向量,它将保存我们的特征向量
“avgpool”层的输出大小为512
my_嵌入=torch.zeros512
定义一个复制图层输出的函数
def复制_数据M、i、o:
非常感谢您的精彩解释。作为后续,我想知道如何最好地解释特征向量。我认为,向量中的每一个值都代表了关于图片的某些信息。有没有办法从resnet的文档中大致了解512个值中的每一个都在描述什么?我好像什么也找不到。作为推论,如果我在两个不同的图像上运行相同的过程,每个结果picu向量中的第一个值是否对应于相同的特征?如果这对于后续工作来说太多了,我理解,谢谢。这有点抽象,但简短的回答是否定的。该功能是输入图像在512维空间中的抽象表示。要素空间的主要特征是,如果比较来自相同类型对象的图像的要素,它们应该彼此靠近,而不同类型的对象将彼此远离。这一特点是网络培训目标的结果。此外,我们通常指的是余弦相似性接近1,到目前为止,我们指的是余弦相似性不接近1。特征中的单个值通常意义不大。例如,可以对特征空间应用任何刚性变换而不进行平移,并且特征之间仍然具有完全相同的余弦相似性,尽管这将完全更改特征向量的各个值。也就是说,有一些方法可以学习从特征向量中提取特定信息,但这通常需要学习与不同属性相关的特征的变换,这需要额外的训练。另一种看待它的方式是抽象层次。对于靠近输入的层,可能表示较低的l
水平概念,如线和边,向上移动一层或两层,也许它代表了一些东西,如角,再往前走一点,你会得到一些特征,这些特征代表了构建块,如轮子和砖块等等。最后,当您到达终点时,特征代表最终目标,在这种情况下,对象类,例如汽车、猫、人等……这更多的是一种解释,而不是一条硬性规则。目标函数中没有明确要求学习这种表示法的东西,但研究和实验表明,这是对正在发生的事情的合理解释。