特征图输出类型 Tensor或Tuple

前言

最近在修改网络模型时,发现有些特征图输出的类型是Tensor,有的特征图输出的类型却是Tuple,一开始不知到为什么是这样的,苦恼了半天,后来上网查询后发现了基本的规律,本文分享一下。

一、为什么特征图输出类型是Tensor或Tuple

在深度学习模型中,有些层或模块输出的特征图是一个张量(Tensor),而有些输出的是一个元组(Tuple)。这通常是由于模型的设计不同导致的。

模型输出的特征图可能是由多个Tensor组成的Tuple,也可能只是一个单独的Tensor。这取决于模型的设计和输出。

一些模型在输出时可能需要返回多个特征图,这些特征图会被打包成一个Tuple返回。

  • 对于输出为元组的模块,则通常表示模块的输出不止一个。这种情况下,通常需要使用元组的方式来保存不同的特征图。例如,在目标检测任务中,YOLOv3模型的输出是一个元组,其中包含3个张量,分别对应不同尺度下的检测结果。
  • 在物体检测模型中,模型可以输出包括目标类别、位置、置信度等信息的张量Tensor,以及一些中间特征图的张量Tensor,如特征金字塔。这两个Tensor张量通常被组合成一个元组返回,以便更容易地处理和分析输出。
  • 在图像分割任务中,模型可能需要同时预测目标掩模像素分类,因此输出将是一个Tuple,其中包含两个Tensor,分别表示掩模和分类结果。

二、特征图输出类型Tensor

这里写一个简单的示例程序,模型最终输出特征图类型是Tensor;

import torch
import torch.nn as nn

class SimpleModelTuple(nn.Module):
    def __init__(self):
        super(SimpleModelTuple, self).__init__()
        self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)
        self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
        self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)

    def forward(self, x):
        x = self.conv1(x)
        x = nn.functional.relu(x)
        x = self.pool1(x)
        x = self.conv2(x)
        x = nn.functional.relu(x)
        x = self.pool2(x)
        return (x) # 返回一个tensor

# 测试输出
model = SimpleModelTuple()
x = torch.randn(1, 3, 32, 32)
output = model(x)
print(type(output)) # 输出的类型是tensor
print(output)

这个程序中模型只有一个输出,通过常见的卷积层、池化层等,其输出是一个张量。

三、特征图输出类型Tuple

这里写一个简单的示例程序,模型最终输出特征图类型是Tuple,它由两个一样的Tensor组成;

import torch
import torch.nn as nn

class SimpleModelTuple(nn.Module):
    def __init__(self):
        super(SimpleModelTuple, self).__init__()
        self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)
        self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
        self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)

    def forward(self, x):
        x = self.conv1(x)
        x = nn.functional.relu(x)
        x = self.pool1(x)
        x = self.conv2(x)
        x = nn.functional.relu(x)
        x = self.pool2(x)
        return (x,x) # 返回两个一样的tensor结果

# 测试输出
model = SimpleModelTuple()
x = torch.randn(1, 3, 32, 32)
output = model(x)
print(type(output)) # 输出的类型是tuple
print(output)

这里再写一个简单的示例程序,模型最终输出特征图类型是Tuple,它由两Tensor组成;

  • 一个Tensor是只进行了一次卷积、激活、池化操作,对应特征图x1;
  • 另一个Tensor是只进行了两次卷积、激活、池化操作,对应特征图x2;
import torch
import torch.nn as nn

class SimpleModelTuple(nn.Module):
    def __init__(self):
        super(SimpleModelTuple, self).__init__()
        self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)
        self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
        self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)

    def forward(self, x):
        x1 = self.conv1(x)
        x1 = nn.functional.relu(x1)
        x1 = self.pool1(x)

        x2 = self.conv2(x1)
        x2 = nn.functional.relu(x2)
        x2 = self.pool2(x2)
        return (x1,x2) # 返回两个不同的tensor结果

# 测试输出
model = SimpleModelTuple()
x = torch.randn(1, 3, 32, 32)
output = model(x)
print(type(output)) # 输出的类型是tuple
print(output)

小结一下:

在深度学习模型中,有些层或模块输出的特征图是一个张量(Tensor),而有些输出的是一个元组(Tuple)。这通常是由于模型的设计不同导致的。

模型输出的特征图可能是由多个Tensor组成的Tuple,也可能只是一个单独的Tensor。这取决于模型的设计和输出。

一些模型在输出时可能需要返回多个特征图,这些特征图会被打包成一个Tuple返回。

  • 对于输出为元组的模块,则通常表示模块的输出不止一个。这种情况下,通常需要使用元组的方式来保存不同的特征图。例如,在目标检测任务中,YOLOv3模型的输出是一个元组,其中包含3个张量,分别对应不同尺度下的检测结果。
  • 在物体检测模型中,模型可以输出包括目标类别、位置、置信度等信息的张量Tensor,以及一些中间特征图的张量Tensor,如特征金字塔。这两个Tensor张量通常被组合成一个元组返回,以便更容易地处理和分析输出。
  • 在图像分割任务中,模型可能需要同时预测目标掩模像素分类,因此输出将是一个Tuple,其中包含两个Tensor,分别表示掩模和分类结果。

分享完成,继续改网络结构啦~

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一颗小树x

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值