import torch.nn as nn import torch import torch import torch.nn as nn import torch.nn.functional as F class SE_block(nn.Module): def __init__(self, inchannel, ratio = 16):#压缩比默认16 super(SE_block, self).__init__() #全局平均池化 self.gap = nn.AdaptiveAvgPool2d((1,1)) #两个全连接层 self.fc = nn.Sequential( nn.Linear(inchannel, inchannel // ratio, bias = False), nn.ReLU(), nn.Linear(inchannel // ratio, inchannel, bias=False), nn.Sigmoid() ) def forward(self, x): b ,c ,h ,w =x.size()#读取数据图片数量和通道数 #print(b, c, h, w) (32, 128, 27, 27) y = self.gap(x).view(b ,c)#经过池化后输出b*c的矩阵 y =self.fc(y).view(b ,c, 1, 1)#经过全连接层输出(b,c,1,1)矩阵 return x * y.expand_as(x)#将得到的权重*原来的特征图x class ImprovedAlexNet(nn.Module): def __init__(self, num_classes=1000): super(ImprovedAlexNet, self).__init__() self.features = nn.Sequential( # 卷积层提取图像特征 nn.Conv2d(3, 48, kernel_size=11, stride=4, padding=2), # input[3, 224, 224] output[48, 55, 55] nn.ReLU(inplace=True), # 直接修改覆盖原值,节省运算内存 nn.MaxPool2d(kernel_size=3, stride=2), # output[48, 27, 27] SE_block(48), nn.Conv2d(48, 128, kernel_size=5, padding=2), # output[128, 27, 27] nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=3, stride=2), # output[128, 13, 13] nn.Conv2d(128, 192, kernel_size=3, padding=1), # output[192, 13, 13] nn.ReLU(inplace=True), nn.Conv2d(192, 192, kernel_size=3, padding=1), # output[192, 13, 13] nn.ReLU(inplace=True), nn.Conv2d(192, 128, kernel_size=3, padding=1), # output[128, 13, 13] nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=3, stride=2), # output[128, 6, 6] ) self.classifier = nn.Sequential( # 全连接层对图像分类 nn.Dropout(p=0.5), # Dropout 随机失活神经元,默认比例为0.5 nn.Linear(128 * 6 * 6, 2048), nn.ReLU(inplace=True), nn.Dropout(p=0.5), nn.Linear(2048, 2048), nn.ReLU(inplace=True), nn.Linear(2048, num_classes), ) def forward(self, x): x = self.features(x)#进行卷积操作 x = torch.flatten(x, start_dim=1)#展平 x = self.classifier(x)#输出 return x