nn.Linear和nn.Conv2d_1x1等效验证

现在视觉transformer中,有些会把单个像素点视为一个token,在这样的粒度下进行transformer block的计算,其中一个比较重要的操作是nn.Linear,其和nn.Conv2d_1x1是等价的。验证代码如下:

import torch
import torch.nn as nn

b,c,h,w = 1,3,10,10
in_ch,out_ch = c,5


a = torch.randn(b,c,h,w)           # input:[b,c,h,w]

params = torch.randn(out_ch,in_ch) #预设的参数,输出为out_ch,输入为in_ch
bias = torch.randn(out_ch)         #bias

#线性层,将预设参数代入
linear = nn.Linear(in_ch,out_ch)
linear.weight.data = params.data
linear.bias.data = bias.data   
#1*1卷积层,将预设参数代入
conv = nn.Conv2d(in_ch,out_ch,1)
conv.weight.data = params.data.unsqueeze(-1).unsqueeze(-1) 
conv.bias.data = bias.data

#两个模块对a处理
a_l = linear(a.flatten(2).permute(0,2,1)).permute(0,2,1).view(b,out_ch,h,w) 
a_c = conv(a)

print(torch.allclose(a_l,a_c, atol=1e-10))
#输出为: True

图像的卷积本质上也是矩阵相乘,验证结果是符合预期的。
私以为现有的某些vision transformer可以不用写的太华丽,可以在原空间使用卷积实现self-attention和mlp,此外对layernorm进行修改,这样的话,写出来的transformer block中,self-attention=non-local,mlp=conv_1x1 Group。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
你可以使用以下代码来打印网络结构层级和输出尺寸等信息: ```python import torch import torch.nn as nn class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(3, 128, kernel_size=1, stride=1) self.conv2 = nn.Conv2d(128, 256, kernel_size=3, stride=2, padding=1, groups=128) self.conv3 = nn.Conv2d(256, 128, kernel_size=1, stride=1) self.conv4 = nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1, groups=256) self.conv5 = nn.Conv2d(256, 256, kernel_size=1, stride=1) self.conv6 = nn.Conv2d(256, 512, kernel_size=1, stride=1) self.avgpool = nn.AvgPool2d(kernel_size=1) self.linear = nn.Linear(512, 10) self.softmax = nn.Softmax(dim=1) def forward(self, x): x = self.conv1(x) print("Conv1*1,s=1:", x.size()) x = self.conv2(x) print("conv3*3,s=2, p=1,g=128:", x.size()) x = self.conv3(x) print("80*80*128:", x.size()) x = self.conv4(x) print("Conv1*1,s=1:", x.size()) x = self.conv5(x) print("80*80*256:", x.size()) x = self.conv6(x) print("Conv1*1,s=1:", x.size()) x = self.conv6(x) print("80*80*512:", x.size()) x = self.avgpool(x) print("Avgpool1*1*512:", x.size()) x = x.view(x.size(0), -1) x = self.linear(x) print("Linear1*10:", x.size()) x = self.softmax(x) print("Softmax:", x.size()) return x # Create an instance of the network net = Net() # Create a random input tensor with shape (batch_size, channels, height, width) input_tensor = torch.randn(1, 3, 160, 160) # Pass the input tensor through the network output_tensor = net(input_tensor) ``` 这段代码定义了一个名为`Net`的类,该类继承自`nn.Module`。在构造函数`__init__`中,我们定义了网络的各个层级,包括卷积层、池化层和全连接层。在前向传播函数`forward`中,我们打印了每个层级的输出尺寸。 你可以根据需要修改网络结构和输入张量的形状来适应你的具体情况。运行代码后,你将会看到每个层级的输出尺寸打印出来。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值