inception块 import torch import torch.nn as nn class InceptionBlock(nn.Module): #__init__ 方法用于初始化模型的各个子模块 def __init__ (self,in_channels,out_channels1,out_channels2,out_channels3,out_channels4): super(InceptionBlock,self).__init__() #在 InceptionBlock 类中调用其父类的构造函数用于初始化父类的属性和方法。 #通路1(由一个 1x1 卷积层 和一个 ReLU 激活函数 的组合构成) self.branch1 nn.Sequential( nn.Conv2d(in_channels,out_channels1,kernel_size 1), nn.ReLU() ) #通路2(由 两个卷积层 和 两个 ReLU 激活函数 按顺序组成) self.branch2 nn.Sequential( nn.Conv2d(in_channels,out_channels2,kernel_size 1), nn.ReLU(), nn.Conv2d(out_channels1,out_channels2,kernel_size 3,padding 1), nn.ReLU() ) #通路3由 两个卷积层 和 两个 ReLU 激活函数 按顺序组成 self.branch3 nn.Sequential( nn.Conv2d(in_channels,out_channels3,kernel_size 1), nn.ReLU(), nn.Conv2d(out_channels1,out_channels2,kernel_size 5,padding 2), nn.ReLU(), ) #通路4(由 最大池化层、1x1 卷积层 和 ReLU 激活函数 依次组) self.branch4 nn.Sequential( nn.MaxPool2d(3, 1, 1), # 3x3 MaxPool, stride1, padding1 nn.Conv2d(in_channels, out_channels4, kernel_size1), nn.ReLU() ) #forward 方法定义模型前向计算过程,并将它们在通道维度上拼接 def forward(self, x): b1 self.branch1(x) b2 self.branch2(x) b3 self.branch3(x) b4 self.branch4(x) #沿着输入张量的第 1 个维度即通道维度进行拼接,4D张量为[batch_size, channels, height, width] #这里dim1表示在channels维度上进行拼接其他维度保持一致 return torch.cat([b1,b2,b3,b4],dim1) 测试代码输出结果torch.Size([1, 64, 28, 28])inc InceptionBlock( in_channels64, out_channels116, # branch1 输出 16 个通道 out_channels216, # branch2 输出 16 个通道 out_channels316, # branch3 输出 16 个通道 out_channels416 # branch4 输出 16 个通道 ) x torch.randn(1, 64, 28, 28) # batch size1, in_channels64, 输入大小 28×28 output inc(x) print(output.shape)
GoogleNet网络结构(代码)
inception块 import torch import torch.nn as nn class InceptionBlock(nn.Module): #__init__ 方法用于初始化模型的各个子模块 def __init__ (self,in_channels,out_channels1,out_channels2,out_channels3,out_channels4): super(InceptionBlock,self).__init__() #在 InceptionBlock 类中调用其父类的构造函数用于初始化父类的属性和方法。 #通路1(由一个 1x1 卷积层 和一个 ReLU 激活函数 的组合构成) self.branch1 nn.Sequential( nn.Conv2d(in_channels,out_channels1,kernel_size 1), nn.ReLU() ) #通路2(由 两个卷积层 和 两个 ReLU 激活函数 按顺序组成) self.branch2 nn.Sequential( nn.Conv2d(in_channels,out_channels2,kernel_size 1), nn.ReLU(), nn.Conv2d(out_channels1,out_channels2,kernel_size 3,padding 1), nn.ReLU() ) #通路3由 两个卷积层 和 两个 ReLU 激活函数 按顺序组成 self.branch3 nn.Sequential( nn.Conv2d(in_channels,out_channels3,kernel_size 1), nn.ReLU(), nn.Conv2d(out_channels1,out_channels2,kernel_size 5,padding 2), nn.ReLU(), ) #通路4(由 最大池化层、1x1 卷积层 和 ReLU 激活函数 依次组) self.branch4 nn.Sequential( nn.MaxPool2d(3, 1, 1), # 3x3 MaxPool, stride1, padding1 nn.Conv2d(in_channels, out_channels4, kernel_size1), nn.ReLU() ) #forward 方法定义模型前向计算过程,并将它们在通道维度上拼接 def forward(self, x): b1 self.branch1(x) b2 self.branch2(x) b3 self.branch3(x) b4 self.branch4(x) #沿着输入张量的第 1 个维度即通道维度进行拼接,4D张量为[batch_size, channels, height, width] #这里dim1表示在channels维度上进行拼接其他维度保持一致 return torch.cat([b1,b2,b3,b4],dim1) 测试代码输出结果torch.Size([1, 64, 28, 28])inc InceptionBlock( in_channels64, out_channels116, # branch1 输出 16 个通道 out_channels216, # branch2 输出 16 个通道 out_channels316, # branch3 输出 16 个通道 out_channels416 # branch4 输出 16 个通道 ) x torch.randn(1, 64, 28, 28) # batch size1, in_channels64, 输入大小 28×28 output inc(x) print(output.shape)