CNN模型分析 | 3 ZFNet

ZFNet网络

ZFNet,Matthew D Zeiler在2013年发表卷积网络模型

AlexNet网络的设计思想

主要设计贡献

  • 可以理解为只是对AlexNet网络进行了微调
  • 使用新颖的可视化技术来一窥中间特征层的功能,以及分类的操作
  • 利用反卷积和反池化技术实现可视化
  • 根据可视化的结果,进一步调整网络结构

ZFNet对AlexNet网络进行的调整

  • 通过可视化发现AlexNet第一层中有大量的高频(图像边缘,图像内物体分界线,图像细节和噪音等)和低频(非边缘部分、图像轮廓)信息的混合,却几乎没有覆盖到中间的频率信息;
    • 解决:将AlexNet的第一层滤波器的大小由11x11变成7x7,使得卷积可以进一步提取中间频率的特征
  • 由于第一层卷积用的步长为4,太大,导致了有非常多的混叠情况,学到的特征不是特别好看,不像是后面的特征能看到一些纹理、颜色等;
    • 解决:将卷积核移动的步长4变成了2

ZFNet网络的核心架构

Z F N e t = ( conv + r e l u + maxpooling ) × 2 + ( conv + r e l u ) × 3 + f c × 2 + Z FNet=(\operatorname{conv}+r e l u+\text {maxpooling}) \times 2+(\operatorname{conv}+r e l u) \times 3+f c \times 2+ softmax
在这里插入图片描述

反卷积和反池化

可以查看我的博客解读进行理解反卷积和反池化:
图像处理中的卷积、池化、反卷积和反池化的理解与思考

keras实现ZFNet

#coding=utf-8
from keras.models import Sequential
from keras.layers import Dense,Flatten,Dropout
from keras.layers.convolutional import Conv2D,MaxPooling2D
from keras.utils.np_utils import to_categorical
import numpy as np
seed = 7
np.random.seed(seed)
 
model = Sequential()
model.add(Conv2D(96,(7,7),strides=(2,2),input_shape=(224,224,3),padding='valid',activation='relu',kernel_initializer='uniform'))
model.add(MaxPooling2D(pool_size=(3,3),strides=(2,2)))
model.add(Conv2D(256,(5,5),strides=(2,2),padding='same',activation='relu',kernel_initializer='uniform'))
model.add(MaxPooling2D(pool_size=(3,3),strides=(2,2)))
model.add(Conv2D(384,(3,3),strides=(1,1),padding='same',activation='relu',kernel_initializer='uniform'))
model.add(Conv2D(384,(3,3),strides=(1,1),padding='same',activation='relu',kernel_initializer='uniform'))
model.add(Conv2D(256,(3,3),strides=(1,1),padding='same',activation='relu',kernel_initializer='uniform'))
model.add(MaxPooling2D(pool_size=(3,3),strides=(2,2)))
model.add(Flatten())
model.add(Dense(4096,activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(4096,activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1000,activation='softmax'))
model.compile(loss='categorical_crossentropy',optimizer='sgd',metrics=['accuracy'])
model.summary()

PyTorch实现ZFNet

class AlexNet(nn.Module):
    def __init__(self,num_classes):
        super(AlexNet, self).__init__()
        self.conv1 = nn.Conv2d(in_channels = 3, out_channels = 96, kernel_size = 7, stride=2, padding=0)
        self.pool1 = nn.MaxPool2d(kernel_size=3, stride=2, padding=0)
        self.conv2 = nn.Conv2d(in_channels = 96, out_channels = 256 , kernel_size = 5, stride = 1, padding = 2)
        self.pool2 = nn.MaxPool2d(kernel_size= 3,stride=2,padding=0)
        self.conv3 = nn.Conv2d(in_channels= 256, out_channels= 384,kernel_size= 3,stride=1,padding=1)
        self.conv4 = nn.Conv2d(in_channels=384,out_channels= 384,kernel_size=3,stride=1,padding=1)
        self.conv5 = nn.Conv2d(in_channels=384,out_channels= 256,kernel_size=3,stride=1,padding=1)
        self.pool3 = nn.MaxPool2d(kernel_size=3,stride=2,padding=0)
        self.fc1   = nn.Linear(6*6*256,4096)
        self.fc2   = nn.Linear(4096,4096)
        self.fc3   = nn.Linear(4096,num_classes)
    
    def forward(self,x):
        x = self.pool1(F.relu(self.conv1(x)))
        x = self.pool2(F.relu(self.conv2(x)))
        x = F.relu(self.conv3(x))
        x = F.relu(self.conv4(x))
        x = self.pool3(F.relu(self.conv5(x)))
        x = x.view(-1, 256 * 6 * 6)
        x = F.dropout(x)
        x = F.relu(self.fc1(x))
        x = F.dropout(x)
        x = F.relu(self.fc2(x))
        x = F.softmax(self.fc3(x))
        return x
发布了123 篇原创文章 · 获赞 54 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_41940950/article/details/103327380