網(wǎng)站后端怎么做河北網(wǎng)站建設(shè)公司排名
1.1 在哪里縫
測試文件?(×)
訓(xùn)練文件?(×)
模型文件?(√)
1.2 骨干網(wǎng)絡(luò)與模塊縫合
以Vision Transformer為例,模型文件里有很多類,我們只在最后集大成的那個(gè)類里添加模塊。
之后后,我們準(zhǔn)備好我們要縫合的模塊,比如SE Net模塊,我們先建立一個(gè)測試文件測試能否跑通
import numpy as np
import torch
from torch import nn
from torch.nn import initclass SEAttention(nn.Module):# 初始化SE模塊,channel為通道數(shù),reduction為降維比率def __init__(self, channel=512, reduction=16):super().__init__()self.avg_pool = nn.AdaptiveAvgPool2d(1) # 自適應(yīng)平均池化層,將特征圖的空間維度壓縮為1x1self.fc = nn.Sequential( # 定義兩個(gè)全連接層作為激勵(lì)操作,通過降維和升維調(diào)整通道重要性nn.Linear(channel, channel // reduction, bias=False), # 降維,減少參數(shù)數(shù)量和計(jì)算量nn.ReLU(inplace=True), # ReLU激活函數(shù),引入非線性nn.Linear(channel // reduction, channel, bias=False), # 升維,恢復(fù)到原始通道數(shù)nn.Sigmoid() # Sigmoid激活函數(shù),輸出每個(gè)通道的重要性系數(shù))# 權(quán)重初始化方法def init_weights(self):for m in self.modules(): # 遍歷模塊中的所有子模塊if isinstance(m, nn.Conv2d): # 對于卷積層init.kaiming_normal_(m.weight, mode='fan_out') # 使用Kaiming初始化方法初始化權(quán)重if m.bias is not None:init.constant_(m.bias, 0) # 如果有偏置項(xiàng),則初始化為0elif isinstance(m, nn.BatchNorm2d): # 對于批歸一化層init.constant_(m.weight, 1) # 權(quán)重初始化為1init.constant_(m.bias, 0) # 偏置初始化為0elif isinstance(m, nn.Linear): # 對于全連接層init.normal_(m.weight, std=0.001) # 權(quán)重使用正態(tài)分布初始化if m.bias is not None:init.constant_(m.bias, 0) # 偏置初始化為0# 前向傳播方法def forward(self, x):b, c, _, _ = x.size() # 獲取輸入x的批量大小b和通道數(shù)cy = self.avg_pool(x).view(b, c) # 通過自適應(yīng)平均池化層后,調(diào)整形狀以匹配全連接層的輸入y = self.fc(y).view(b, c, 1, 1) # 通過全連接層計(jì)算通道重要性,調(diào)整形狀以匹配原始特征圖的形狀return x * y.expand_as(x) # 將通道重要性系數(shù)應(yīng)用到原始特征圖上,進(jìn)行特征重新校準(zhǔn)# 示例使用
if __name__ == '__main__':input = torch.randn(50, 512, 7, 7) # 隨機(jī)生成一個(gè)輸入特征圖se = SEAttention(channel=512, reduction=8) # 實(shí)例化SE模塊,設(shè)置降維比率為8output = se(input) # 將輸入特征圖通過SE模塊進(jìn)行處理print(output.shape) # 打印處理后的特征圖形狀,驗(yàn)證SE模塊的作用
打印處理后的形狀,我們這里要注意,縫合模塊時(shí)只需要注意第一維,也就是這個(gè)channel,要和骨干網(wǎng)絡(luò)保持一致,只要你把輸入輸出的通道數(shù)對齊,那么這個(gè)通道數(shù)就可以縫合成功。
把模塊復(fù)制進(jìn)骨干網(wǎng)絡(luò)中:
然后進(jìn)行縫合,在縫合之前要先測試通道是否匹配,不然肯定報(bào)錯(cuò)。
如何驗(yàn)證通道數(shù)
我們找到骨干網(wǎng)絡(luò)前向傳播的部分,在你想加入這個(gè)模塊地方print(x.shape)即可。運(yùn)行訓(xùn)練文件:
放在最前面:
通道數(shù)為3(8為batch size)。
將模塊添加進(jìn)骨干網(wǎng)絡(luò)
在骨干網(wǎng)絡(luò)的init函數(shù)下添加:(ctrl+p可查看參數(shù))通道數(shù)與之前查的對齊。
在前向傳播中添加:
看看是否正常運(yùn)行:
正常運(yùn)行,說明模塊縫合成功!
打印縫合后的模型結(jié)構(gòu)
該操作在模型文件中進(jìn)行。
VisionTransformer(
? (patch_embed): PatchEmbed(
? ? (proj): Conv2d(3, 768, kernel_size=(16, 16), stride=(16, 16))
? ? (norm): Identity()
? )
? (pos_drop): Dropout(p=0.0, inplace=False)
? (blocks): Sequential(
? ? (0): Block(
? ? ? (norm1): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (attn): Attention(
? ? ? ? (qkv): Linear(in_features=768, out_features=2304, bias=True)
? ? ? ? (attn_drop): Dropout(p=0.0, inplace=False)
? ? ? ? (proj): Linear(in_features=768, out_features=768, bias=True)
? ? ? ? (proj_drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? ? (drop_path): Identity()
? ? ? (norm2): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (mlp): Mlp(
? ? ? ? (fc1): Linear(in_features=768, out_features=3072, bias=True)
? ? ? ? (act): GELU()
? ? ? ? (fc2): Linear(in_features=3072, out_features=768, bias=True)
? ? ? ? (drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? )
? ? (1): Block(
? ? ? (norm1): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (attn): Attention(
? ? ? ? (qkv): Linear(in_features=768, out_features=2304, bias=True)
? ? ? ? (attn_drop): Dropout(p=0.0, inplace=False)
? ? ? ? (proj): Linear(in_features=768, out_features=768, bias=True)
? ? ? ? (proj_drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? ? (drop_path): Identity()
? ? ? (norm2): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (mlp): Mlp(
? ? ? ? (fc1): Linear(in_features=768, out_features=3072, bias=True)
? ? ? ? (act): GELU()
? ? ? ? (fc2): Linear(in_features=3072, out_features=768, bias=True)
? ? ? ? (drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? )
? ? (2): Block(
? ? ? (norm1): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (attn): Attention(
? ? ? ? (qkv): Linear(in_features=768, out_features=2304, bias=True)
? ? ? ? (attn_drop): Dropout(p=0.0, inplace=False)
? ? ? ? (proj): Linear(in_features=768, out_features=768, bias=True)
? ? ? ? (proj_drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? ? (drop_path): Identity()
? ? ? (norm2): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (mlp): Mlp(
? ? ? ? (fc1): Linear(in_features=768, out_features=3072, bias=True)
? ? ? ? (act): GELU()
? ? ? ? (fc2): Linear(in_features=3072, out_features=768, bias=True)
? ? ? ? (drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? )
? ? (3): Block(
? ? ? (norm1): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (attn): Attention(
? ? ? ? (qkv): Linear(in_features=768, out_features=2304, bias=True)
? ? ? ? (attn_drop): Dropout(p=0.0, inplace=False)
? ? ? ? (proj): Linear(in_features=768, out_features=768, bias=True)
? ? ? ? (proj_drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? ? (drop_path): Identity()
? ? ? (norm2): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (mlp): Mlp(
? ? ? ? (fc1): Linear(in_features=768, out_features=3072, bias=True)
? ? ? ? (act): GELU()
? ? ? ? (fc2): Linear(in_features=3072, out_features=768, bias=True)
? ? ? ? (drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? )
? ? (4): Block(
? ? ? (norm1): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (attn): Attention(
? ? ? ? (qkv): Linear(in_features=768, out_features=2304, bias=True)
? ? ? ? (attn_drop): Dropout(p=0.0, inplace=False)
? ? ? ? (proj): Linear(in_features=768, out_features=768, bias=True)
? ? ? ? (proj_drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? ? (drop_path): Identity()
? ? ? (norm2): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (mlp): Mlp(
? ? ? ? (fc1): Linear(in_features=768, out_features=3072, bias=True)
? ? ? ? (act): GELU()
? ? ? ? (fc2): Linear(in_features=3072, out_features=768, bias=True)
? ? ? ? (drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? )
? ? (5): Block(
? ? ? (norm1): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (attn): Attention(
? ? ? ? (qkv): Linear(in_features=768, out_features=2304, bias=True)
? ? ? ? (attn_drop): Dropout(p=0.0, inplace=False)
? ? ? ? (proj): Linear(in_features=768, out_features=768, bias=True)
? ? ? ? (proj_drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? ? (drop_path): Identity()
? ? ? (norm2): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (mlp): Mlp(
? ? ? ? (fc1): Linear(in_features=768, out_features=3072, bias=True)
? ? ? ? (act): GELU()
? ? ? ? (fc2): Linear(in_features=3072, out_features=768, bias=True)
? ? ? ? (drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? )
? ? (6): Block(
? ? ? (norm1): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (attn): Attention(
? ? ? ? (qkv): Linear(in_features=768, out_features=2304, bias=True)
? ? ? ? (attn_drop): Dropout(p=0.0, inplace=False)
? ? ? ? (proj): Linear(in_features=768, out_features=768, bias=True)
? ? ? ? (proj_drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? ? (drop_path): Identity()
? ? ? (norm2): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (mlp): Mlp(
? ? ? ? (fc1): Linear(in_features=768, out_features=3072, bias=True)
? ? ? ? (act): GELU()
? ? ? ? (fc2): Linear(in_features=3072, out_features=768, bias=True)
? ? ? ? (drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? )
? ? (7): Block(
? ? ? (norm1): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (attn): Attention(
? ? ? ? (qkv): Linear(in_features=768, out_features=2304, bias=True)
? ? ? ? (attn_drop): Dropout(p=0.0, inplace=False)
? ? ? ? (proj): Linear(in_features=768, out_features=768, bias=True)
? ? ? ? (proj_drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? ? (drop_path): Identity()
? ? ? (norm2): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (mlp): Mlp(
? ? ? ? (fc1): Linear(in_features=768, out_features=3072, bias=True)
? ? ? ? (act): GELU()
? ? ? ? (fc2): Linear(in_features=3072, out_features=768, bias=True)
? ? ? ? (drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? )
? ? (8): Block(
? ? ? (norm1): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (attn): Attention(
? ? ? ? (qkv): Linear(in_features=768, out_features=2304, bias=True)
? ? ? ? (attn_drop): Dropout(p=0.0, inplace=False)
? ? ? ? (proj): Linear(in_features=768, out_features=768, bias=True)
? ? ? ? (proj_drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? ? (drop_path): Identity()
? ? ? (norm2): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (mlp): Mlp(
? ? ? ? (fc1): Linear(in_features=768, out_features=3072, bias=True)
? ? ? ? (act): GELU()
? ? ? ? (fc2): Linear(in_features=3072, out_features=768, bias=True)
? ? ? ? (drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? )
? ? (9): Block(
? ? ? (norm1): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (attn): Attention(
? ? ? ? (qkv): Linear(in_features=768, out_features=2304, bias=True)
? ? ? ? (attn_drop): Dropout(p=0.0, inplace=False)
? ? ? ? (proj): Linear(in_features=768, out_features=768, bias=True)
? ? ? ? (proj_drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? ? (drop_path): Identity()
? ? ? (norm2): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (mlp): Mlp(
? ? ? ? (fc1): Linear(in_features=768, out_features=3072, bias=True)
? ? ? ? (act): GELU()
? ? ? ? (fc2): Linear(in_features=3072, out_features=768, bias=True)
? ? ? ? (drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? )
? ? (10): Block(
? ? ? (norm1): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (attn): Attention(
? ? ? ? (qkv): Linear(in_features=768, out_features=2304, bias=True)
? ? ? ? (attn_drop): Dropout(p=0.0, inplace=False)
? ? ? ? (proj): Linear(in_features=768, out_features=768, bias=True)
? ? ? ? (proj_drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? ? (drop_path): Identity()
? ? ? (norm2): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (mlp): Mlp(
? ? ? ? (fc1): Linear(in_features=768, out_features=3072, bias=True)
? ? ? ? (act): GELU()
? ? ? ? (fc2): Linear(in_features=3072, out_features=768, bias=True)
? ? ? ? (drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? )
? ? (11): Block(
? ? ? (norm1): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (attn): Attention(
? ? ? ? (qkv): Linear(in_features=768, out_features=2304, bias=True)
? ? ? ? (attn_drop): Dropout(p=0.0, inplace=False)
? ? ? ? (proj): Linear(in_features=768, out_features=768, bias=True)
? ? ? ? (proj_drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? ? (drop_path): Identity()
? ? ? (norm2): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? ? ? (mlp): Mlp(
? ? ? ? (fc1): Linear(in_features=768, out_features=3072, bias=True)
? ? ? ? (act): GELU()
? ? ? ? (fc2): Linear(in_features=3072, out_features=768, bias=True)
? ? ? ? (drop): Dropout(p=0.0, inplace=False)
? ? ? )
? ? )
? )
? (norm): LayerNorm((768,), eps=1e-06, elementwise_affine=True)
? (pre_logits): Sequential(
? ? (fc): Linear(in_features=768, out_features=768, bias=True)
? ? (act): Tanh()
? )
? (head): Linear(in_features=768, out_features=21843, bias=True)
? (se): SEAttention(
? ? (avg_pool): AdaptiveAvgPool2d(output_size=1)
? ? (fc): Sequential(
? ? ? (0): Linear(in_features=3, out_features=0, bias=False)
? ? ? (1): ReLU(inplace=True)
? ? ? (2): Linear(in_features=0, out_features=3, bias=False)
? ? ? (3): Sigmoid()
? ? )
? )
)
我們可以看到多了一個(gè)SEAttention,說明模塊縫合進(jìn)去了!
1.3 模塊之間縫合
以SENet和ECA模塊為例。
串聯(lián)模塊
方式1
同1.2。照貓畫虎。(注意通道數(shù)保持一致)
打印模型結(jié)構(gòu):
ECAAttention(
? (gap): AdaptiveAvgPool2d(output_size=1)
? (conv): Conv1d(1, 1, kernel_size=(3,), stride=(1,), padding=(1,))
? (sigmoid): Sigmoid()
? (se): SEAttention(
? ? (avg_pool): AdaptiveAvgPool2d(output_size=1)
? ? (fc): Sequential(
? ? ? (0): Linear(in_features=64, out_features=4, bias=False)
? ? ? (1): ReLU(inplace=True)
? ? ? (2): Linear(in_features=4, out_features=64, bias=False)
? ? ? (3): Sigmoid()
? ?)))
?方式2
我們定義一個(gè)串聯(lián)函數(shù),將模塊之間串聯(lián)起來:
實(shí)例化查看一下模型結(jié)構(gòu)
輸出結(jié)果:
torch.Size([1, 63, 64, 64]) torch.Size([1, 63, 64, 64])
Cascade(
? (se): SEAttention(
? ? (avg_pool): AdaptiveAvgPool2d(output_size=1)
? ? (fc): Sequential(
? ? ? (0): Linear(in_features=63, out_features=3, bias=False)
? ? ? (1): ReLU(inplace=True)
? ? ? (2): Linear(in_features=3, out_features=63, bias=False)
? ? ? (3): Sigmoid()
? ? )
? )
? (eca): ECAAttention(
? ? (gap): AdaptiveAvgPool2d(output_size=1)
? ? (conv): Conv1d(1, 1, kernel_size=(63,), stride=(1,), padding=(31,))
? ? (sigmoid): Sigmoid()
? )
)
并聯(lián)模塊
對于并聯(lián)模塊,方法有很多種,兩個(gè)兩個(gè)模塊輸出的張量可以:
(1)逐元素相加(2)逐元素相乘(3)concat拼接(4)等等
輸出結(jié)果:
torch.Size([1, 63, 64, 64]) torch.Size([1, 126, 64, 64])
Cascade(
? (se): SEAttention(
? ? (avg_pool): AdaptiveAvgPool2d(output_size=1)
? ? (fc): Sequential(
? ? ? (0): Linear(in_features=63, out_features=3, bias=False)
? ? ? (1): ReLU(inplace=True)
? ? ? (2): Linear(in_features=3, out_features=63, bias=False)
? ? ? (3): Sigmoid()
? ? )
? )
? (eca): ECAAttention(
? ? (gap): AdaptiveAvgPool2d(output_size=1)
? ? (conv): Conv1d(1, 1, kernel_size=(63,), stride=(1,), padding=(31,))
? ? (sigmoid): Sigmoid()
? )
)
1.4 思考?
我們不要拘泥于只串聯(lián)獲并聯(lián),可以將二者結(jié)合,多個(gè)模塊中,部分模塊并聯(lián)后又與其他模塊串聯(lián),等等。。這種排列組合之后,總會(huì)有一個(gè)你想要的模型!!!