在构建好数据集以后就可以动手搭卷积神经网络了。这里我还是使用Pytorch来实现几个常用的卷积神经网络结构,由于计算资源有限,有些网络参数已经被我简化了,完整的网络结构可以查看原文献。
本文将简要的介绍如何使用pytorch实现几个经典的卷积神经网络。
1.Lenet
class LeNet_simple(nn.Module):
def __init__(self):
super(LeNet_simple,self).__init__()
#input data shape(N=64,C=1,H=28,W=28)
self.layer1 = nn.Sequential(
nn.Conv2d(in_channels = 1, out_channels = 6, kernel_size = 3, padding = 1),
#(N=64,C=6,H=28,W=28)
nn.MaxPool2d(2,2)
)
#(N=64,C=6,H=14,W=14)
self.layer2 = nn.Sequential(
nn.Conv2d(in_channels = 6, out_channels = 16, kernel_size = 5, padding = 0),
#(N=64,C=16,H=10,W=10)
nn.MaxPool2d(2,2)
)
#(N=64,C=16,H=5,W=5)
self.layer3 = nn.Sequential(
nn.Linear(400,120),
nn.Linear(120,84),
nn.Linear(84,10)
)
def forward(self, x):
x = self.layer1(x)
x = self.layer2(x)
x = x.view(x.size(0), -1)
x = self.layer3(x)
return x
运行结果:
epoch: 10, Train Loss: 0.036077, Train Acc: 0.988065
epoch: 10, Eval Loss: 0.067934, Eval Acc: 0.980350
Time: 134.69537901878357
2. AlexNet
由于·AlexNet原本使用的数据集图片的大小是224*224,在下的电脑实在是跑不动,所以还是用CIFAR-10来跑,其中的一些池化层已经被我删掉了。
class AlexNet_simple(nn.Module):
def __init__(self):
super(AlexNet_simple,self).__init__()
self.features = nn.Sequential(
#input data shape(N=64,C=1,H=28,W=28)
nn.Conv2d(in_channels = 1, out_channels = 64, kernel_size = 8, stride = 2, padding = 1),
#(N=64,C=64,H=12,W=12)
nn.ReLU(inplace=True),
#nn.MaxPool2d(kernel_size = 2, stride =1),
#(N=64,C=64,H=12,W=12)
nn.Conv2d(in_channels = 64, out_channels = 192, kernel_size = 3, stride = 1, padding = 1),
#(N=64,C=192,H=12,W=12)
nn.ReLU(inplace=True),
#nn.MaxPool2d(kernel_size = 2, stride =1),
#(N=64,C=192,H=12,W=12)
nn.Conv2d(in_channels = 192, out_channels = 384, kernel_size = 3, stride = 1, padding = 1),
#(N=64,C=384,H=12,W=12)
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size = 2, stride =2),
#((N=64,C=384,H=6,W=6)
nn.Conv2d(in_channels = 384, out_channels = 256, kernel_size = 3, stride = 1, padding = 1),
#(N=64,C=256,H=6,W=6)
nn.ReLU(inplace=True),
#nn.MaxPool2d(kernel_size = 2, stride =1),
#(N=64,C=256,H=6,W=6)
nn.Conv2d(in_channels = 256, out_channels = 256, kernel_size = 3, stride = 1, padding = 1),
#(N=64,C=256,H=3,W=3)
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size = 2, stride = 2),
#(N=64,C=256,H=3,W=3)
)
self.classifier = nn.Sequential(
nn.Dropout(),
nn.Linear(256*3*3,1024),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(1024,64),
nn.ReLU(inplace = True),
nn.Linear(64,10),
)
def forward(self, x):
x = self.features(x)
x = x.view(x.size(0), 256*3*3)
x = self.classifier(x)
return x
运行10个Epoch以后的结果如下:
epoch: 10, Train Loss: 0.030733, Train Acc: 0.991696
epoch: 10, Eval Loss: 0.042204, Eval Acc: 0.989702
Time: 10565.903186559677
3. "VGGNet"
按照VGG的思想,跑了一个五层的卷积神经网络,效果还挺好。
#input data shape(N=64,C=1,H=28,W=28)
class VGG_simple(nn.Module):
def __init__(self):
super(VGG_simple,self).__init__()
self.layer1 = nn.Sequential(
nn.Conv2d(1, 32, kernel_size = 3, stride=1, padding=1),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.Dropout2d(p=0.5),
nn.Conv2d(32, 64, kernel_size = 3, stride=1, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.Dropout2d(p=0.5),
nn.Conv2d(64, 64, kernel_size = 3, stride=1, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.Dropout2d(p=0.5),
nn.MaxPool2d((2,2)),
nn.Conv2d(64, 128, kernel_size = 3, stride=1, padding=1),
nn.BatchNorm2d(128),
nn.ReLU(),
nn.Dropout2d(p=0.5),
nn.Conv2d(128, 128, kernel_size = 3, stride=1, padding=1),
nn.BatchNorm2d(128),
nn.ReLU(),
nn.Dropout2d(p=0.5),
nn.MaxPool2d((2,2)),
#Flatten(),
)
self.layer2 = nn.Sequential(
nn.Linear(128*7*7, 400),
nn.BatchNorm1d(400),
nn.ReLU(),
nn.Dropout(p=0.5),
nn.Linear(400, 10)
)
def forward(self, x):
x = self.layer1(x)
x = x.view(x.size(0), -1)
x = self.layer2(x)
return x
epoch: 10, Train Loss: 0.049828, Train Acc: 0.983988
epoch: 10, Eval Loss: 0.025206, Eval Acc: 0.991951
Time: 6769.592412233353
4.
5.