经典网络实现:
LeNet:
class Reshpe(nn.Module):
def __init__(self):
super(Reshpe, self).__init__()
def forward(self, x):
return x.reshape(-1, 1, 28, 28)
class lenet(nn.Module):
def __init__(self):
super(lenet, self).__init__()
self.reshape = Reshpe()
self.net = nn.Sequential(
self.reshape, nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Sigmoid(), nn.AvgPool2d(2, 2),
nn.Conv2d(6, 16, kernel_size=5), nn.Sigmoid(), nn.AvgPool2d(2, 2),
nn.Flatten(), nn.Linear(400, 120), nn.Sigmoid(),
nn.Linear(120, 84), nn.Sigmoid(),
nn.Linear(84, 10)
)
self.init_weight()
def forward(self, x):
return self.net(x)
def init_weight(self):
for m in self.net:
if type(m) == nn.Linear or type(m) == nn.Conv2d:
nn.init.xavier_normal_(m.weight)
AlexNet:
更大更深的Lenet,使用relu,dropout,最大池化。
但不规则。
class AlexNet(nn.Module):
def __init__(self):
super(AlexNet, self).__init__()
self.net = nn.Sequential(
nn.Conv2d(1, 96, kernel_size=11, stride=4), nn.ReLU(), nn.MaxPool2d(3, 2),
nn.Conv2d(96, 256, kernel_size=5, padding=2), nn.ReLU(), nn.MaxPool2d(3, 2),
nn.Conv2d(256, 384, kernel_size=3, padding=1), nn.ReLU(),
nn.Conv2d(384, 384, kernel_size=3, padding=1), nn.ReLU(),
nn.Conv2d(384, 384, kernel_size=3, padding=1), nn.ReLU(),
nn.MaxPool2d(3, 2), nn.Flatten(),
nn.Linear(9600, 4096), nn.ReLU(), nn.Dropout(0.5),
nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout(0.5),
nn.Linear(4096, 10)
)
self.init_weight()
def forward(self, x):
return self.net(x)
def init_weight(self):
for m in self.net:
if type(m) == nn.Linear or type(m) == nn.Conv2d:
nn.init.xavier_normal_(m.weight)
VGG:
规则化,模块化。
def vgg_bolck(input_channel, output_channel, num_conv):
layer = []
for _ in range(num_conv):
layer.append(nn.Conv2d(input_channel, output_channel, kernel_size=3, padding=1))
layer.append(nn.ReLU())
input_channel = output_channel
layer.append(nn.MaxPool2d(kernel_size=2, stride=2))
return nn.Sequential(*layer)
class VGG(nn.Module):
def __init__(self, conv_arch):
super(VGG, self).__init__()
self.input_channel = 1
self.conv_blks = []
self.vgg_net = nn.Sequential()
for (num_conv, output_channel) in conv_arch:
self.conv_blks.append(
vgg_bolck(self.input_channel, output_channel, num_conv)
)
self.input_channel = output_channel
self.vgg_net = nn.Sequential(
*self.conv_blks, nn.Flatten(),
nn.Linear(self.input_channel*7*7, 4096), nn.ReLU(),
nn.Dropout(0.5), nn.Linear(4096, 4096), nn.ReLU(),
nn.Dropout(0.5), nn.Linear(4096, 10)
)
def forward(self, x):
return self.vgg_net(x)
NiN net:
把VGG的模块修改为卷积+2层1x1卷积的形式。
不使用全连接层,采用全局平均池化作为最后的预测输出。
def nin_block(input_channels, output_channels, kernel_size, stride, padding):
return nn.Sequential(
nn.Conv2d(input_channels, output_channels, kernel_size, stride=stride, padding=padding),
nn.ReLU(),
nn.Conv2d(output_channels, output_channels, kernel_size=1), nn.ReLU(),
nn.Conv2d(output_channels, output_channels, kernel_size=1), nn.ReLU(),
)
class NinNet(nn.Module):
def __init__(self):
super(NinNet, self).__init__()
self.net = nn.Sequential(
nin_block(1, 96, kernel_size=11, stride=4, padding=0),
nn.MaxPool2d(3, 2),
nin_block(96, 256, kernel_size=5, stride=1, padding=2),
nn.MaxPool2d(3, 2),
nin_block(256, 384, kernel_size=3, stride=1, padding=1),
nn.MaxPool2d(3, 2),
nin_block(384, 10, kernel_size=3, stride=1, padding=1),
nn.AdaptiveAvgPool2d((1, 1)),
nn.Flatten()
)
def forward(self, x):
return self.net(x)
def init_weight(self):
for m in self.net:
if type(m) == nn.Conv2d:
nn.init.xavier_normal_(m.parameters())