import torch
import torch.nn as nn
import torch.nn.functional as F
from torchsummary import summary
# 定义 Inception 模块
class InceptionModule(nn.Module):
def __init__(self, in_channels, out_channels):
super(InceptionModule, self).__init__()
# 1x1 卷积
self.branch1x1 = nn.Conv2d(in_channels, out_channels[0], kernel_size=1)
# 1x1 卷积后接 3x3 卷积
self.branch3x3_1 = nn.Conv2d(in_channels, out_channels[1], kernel_size=1)
self.branch3x3_2 = nn.Conv2d(out_channels[1], out_channels[2], kernel_size=3, padding=1)
# 1x1 卷积后接 5x5 卷积
self.branch5x5_1 = nn.Conv2d(in_channels, out_channels[3], kernel_size=1)
self.branch5x5_2 = nn.Conv2d(out_channels[3], out_channels[4], kernel_size=5, padding=2)
# 3x3 最大池化后接 1x1 卷积
self.branch_pool = nn.Conv2d(in_channels, out_channels[5], kernel_size=1)
def forward(self, x):
branch1x1 = F.relu(self.branch1x1(x))
branch3x3 = F.relu(self.branch3x3_2(F.relu(self.branch3x3_1(x))))
branch5x5 = F.relu(self.branch5x5_2(F.relu(self.branch5x5_1(x))))
branch_pool = F.relu(self.branch_pool(F.max_pool2d(x, kernel_size=3, stride=1, padding=1)))
# 拼接多个分支的输出
outputs = [branch1x1, branch3x3, branch5x5, branch_pool]
return torch.cat(outputs, 1)
# 定义 GoogleNet
class GoogleNet(nn.Module):
def __init__(self, num_classes=1000):
super(GoogleNet, self).__init__()
# 初始卷积层
self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3)
self.maxpool1 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
# 第二卷积层
self.conv2 = nn.Conv2d(64, 192, kernel_size=3, padding=1)
self.maxpool2 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
# 第一组 Inception 模块
self.inception3a = InceptionModule(192, [64, 64, 128, 16, 32, 32])
self.inception3b = InceptionModule(256, [128, 128, 192, 32, 96, 64])
self.maxpool3 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
# 第二组 Inception 模块
self.inception4a = InceptionModule(480, [192, 96, 208, 16, 48, 64])
self.inception4b = InceptionModule(512, [160, 112, 224, 24, 64, 64])
self.inception4c = InceptionModule(512, [128, 128, 256, 24, 64, 64])
self.inception4d = InceptionModule(512, [112, 144, 288, 32, 64, 64])
self.inception4e = InceptionModule(528, [256, 160, 320, 32, 128, 128])
self.maxpool4 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
# 第三组 Inception 模块
self.inception5a = InceptionModule(832, [256, 160, 320, 32, 128, 128])
self.inception5b = InceptionModule(832, [384, 192, 384, 48, 128, 128])
# 全局平均池化层
self.avgpool = nn.AdaptiveAvgPool2d(1)
# 全连接层
self.fc = nn.Linear(1024, num_classes)
def forward(self, x):
x = F.relu(self.conv1(x))
x = self.maxpool1(x)
x = F.relu(self.conv2(x))
x = self.maxpool2(x)
x = self.inception3a(x)
x = self.inception3b(x)
x = self.maxpool3(x)
x = self.inception4a(x)
x = self.inception4b(x)
x = self.inception4c(x)
x = self.inception4d(x)
x = self.inception4e(x)
x = self.maxpool4(x)
x = self.inception5a(x)
x = self.inception5b(x)
x = self.avgpool(x)
x = torch.flatten(x, 1)
x = self.fc(x)
return x
"""错误代码,相关报错
RuntimeError: Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same"""
# if __name__ == "__main__":
# # 创建 GoogleNet 模型
# device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# print(torch.cuda.device_count()) # 输出可用 GPU 的数量
# # 输入相关的张量
# x = torch.rand([1, 3, 28, 28])
# model = GoogleNet(num_classes=1000)
# y = model(x).to(device)
# # 打印模型相关的权重
# print(y)
# summary(model,(3, 224, 224))
#
"""已修改正确的代码"""
if __name__ == "__main__":
# 创建 GoogleNet 模型
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(torch.cuda.device_count()) # 输出可用 GPU 的数量
# 输入相关的张量,调整尺寸为 (3, 224, 224)
x = torch.rand([1, 3, 224, 224]).to(device)
model = GoogleNet(num_classes=1000).to(device)
y = model(x)
# 打印模型相关的权重
print(y)
# 方法一
# summary(model, (3, 224, 224), device=device.type)
# 方法二
summary(model, (3, 224, 224))