VGG16经典神经网络总结

2014_VGG16_牛津**

图:

img

网络描述:

VGG16总共有16层,13个卷积层和3个全连接层,第一次经过64个卷积核的两次卷积后,采用一次pooling,第二次经过两次128个卷积核卷积后,再采用pooling,再重复两次三个512个卷积核卷积后,再pooling,最后经过三次全连接。 输入图像尺寸224×224×3,进行第一个卷积之后得到224×224×64的特征图,接着还有一层224×224×64,得到这样2个厚度为64的卷积层,意味着我们用64个过滤器进行了两次卷积。这里采用的都是大小为3×3,步幅为1的过滤器,并且都是采用same卷积。接下来创建一个池化层,池化层将输入图像进行压缩,从224×224×64缩小到112×112×64。然后又是若干个卷积层,使用129个过滤器,以及一些same卷积,112×112×128然后进行池化,可以推导出池化后的结果是这样(56×56×128)。接着再用256个相同的过滤器进行三次卷积操作,然后再池化,然后再卷积三次,再池化。如此进行几轮操作后,将最后得到的7×7×512的特征图进行全连接操作,得到4096个单元,然后进行softmax激活,输出从1000个对象中识别的结果。

特点,优点:

(1)VGGNet探索了卷积神经网络的深度与其性能之间的关系,通过反复堆叠3×3的小型卷积核和2×2的最大池化层,VGGNet成功地构筑了16-19层深的卷积神经网络

(2) VGGNet结构简洁,整个网络都使用了同样大小的卷积核尺寸(3×3)和最大池化尺寸(2×2)

(3) 拥有5段卷积,每段内有2-3个卷积层,每段段尾连接一个最大池化层,用来缩小图片

(4) 使用非常多的3*3卷积串联 ,卷积串联比单独使用一个较大的卷积核,拥有更少的参数量,同时会比单独一个卷积层拥有更多的非线性变换

缺点:

(1)由于用了较多的全连接层(3个),参数量很大。

(2)因为很多的卷积层执行了通道数翻倍,主要缺点是需要训练的特征数量非常巨大。

代码:
keras实现:
class vgg16():
    def __init__(self):
        self.model = Sequential()
        self.mean = [103.93, 116.79, 123.68]

    def load_img(self, imgurl):
        self.img = cv2.imread(imgurl)
        im = cv2.resize(self.img,(224, 224)).astype(np.float32)
        im[:,:,0] -= self.mean[0]		#RGB三通道图像,对每一个通道减去这个通道的均值,目的是加快网络收敛。
        im[:, :, 1] -= self.mean[1]
        im[:, :, 2] -= self.mean[2]
        im = np.expand_dims(im, axis= 0)		#增加batch这一列,[batch, img_height, img_weight, channel]
        return im

    def model_add(self, filter = None, isConv = False, isMax = False, input_shape = None):
        if isConv:
            if input_shape:
                self.model.add(Convolution2D(filters=filter, kernel_size=(3,3),strides=(1,1)
                                             ,padding="same", activation = "relu", input_shape = input_shape))
            else:
                self.model.add(Convolution2D(filters= filter, kernel_size=(3,3), strides=(1,1)
                                             , padding="same", activation = "relu"))
                                             #这里注意kernel_size = (3,3)
                                             #不同于tf.nn.conv2(kernel_size = [1,3,3,1])
                                             #我的理解是keras是tf的高级融合api,一切都按着简单来考虑

        if isMax:
            self.model.add(MaxPooling2D(pool_size= (2,2), strides=(2,2), padding="valid"))

    def nn(self):
        self.model_add(filter=64, isConv= True, input_shape=(224,224,3))
        self.model_add(filter=64, isConv= True)
        self.model_add(isMax= True)
        self.model_add(filter=128, isConv=True)
        self.model_add(filter=128, isConv=True)
        self.model_add(isMax=True)
        self.model_add(filter=256, isConv=True)
        self.model_add(filter=256, isConv=True)
        self.model_add(filter=256, isConv=True)
        self.model_add(isMax=True)
        self.model_add(filter=512, isConv=True)
        self.model_add(filter=512, isConv=True)
        self.model_add(filter=512, isConv=True)
        self.model_add(isMax=True)
        self.model_add(filter=512, isConv= True)
        self.model_add(filter=512, isConv= True)
        self.model_add(filter=512, isConv= True)
        self.model_add(isMax=True)
        self.model.add(Flatten())
        self.model.add(Dense(4096, activation= "relu"))
        self.model.add(Dense(4096,activation="relu"))
        self.model.add(Dense(1000, activation="softmax"))
        self.model.load_weights("model/vgg/vgg16_weights_tf_dim_ordering_tf_kernels.h5")	
						        #这里是参数文件的具体位置,我所有工程文件与测试图片“timg.jpg”都在model这个文件夹内。

    def pred(self, imgurl):
        self.nn()
        cls = open("model/vgg/classes.txt")	#标签文件
        lines = cls.readlines()
        cls.close()
        img = self.load_img(imgurl= imgurl)
        pre = np.argmax(self.model.predict(img))
        self.show_img(lines[pre].split(' ', 1)[1])

    def show_img(self, text):
        cv2.putText(self.img, text, (25,25), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0,0,255), 1)
        cv2.imshow("img", self.img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
pytorch实现:
class VGG16(nn.Module):
    def __init__(self):
        super(VGG16, self).__init__()
        self.maxpool1 = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=3,stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, kernel_size=3,stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2)
            )
        
        self.maxpool2 = nn.Sequential(
            nn.Conv2d(64, 128, kernel_size=3,stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(128, 128, kernel_size=3,stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2)
            )
        
        self.maxpool3 = nn.Sequential(
            nn.Conv2d(128, 256, kernel_size=3,stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3,stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3,stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2)
            )
        
        self.maxpool4 = nn.Sequential(
            nn.Conv2d(256, 512, kernel_size=3,stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3,stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3,stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2)
            )
        
        self.maxpool5= nn.Sequential(
            nn.Conv2d(512, 512, kernel_size=3,stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3,stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3,stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2)
            )
        
        self.dense = nn.Sequential(
            nn.Linear(512 * 5 * 5, 4096),
            nn.ReLU(),
            nn.Linear(4096, 4096),
            nn.ReLU(),
            nn.Linear(4096, 1000)
        )
 
    def forward(self, x):
        pool1=self.maxpool1(x)
        pool2=self.maxpool2(pool1)
        pool3=self.maxpool3(pool2)
        pool4=self.maxpool4(pool3)
        pool5=self.maxpool5(pool4)
        
        flat = pool5.view(pool5.size(0), -1)
        class_ = self.dense(flat)
        return class_

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值