VGGNet介绍

2023-05-16

VGGNet介绍

1 简要概括

    VGGNet由牛津大学计算机视觉组合和Google DeepMind公司研究员一起研发的深度卷积神经网络。它探索了卷积神经网络的深度和其性能之间的关系,通过反复的堆叠3*3的小型卷积核和2*2的最大池化层,成功的构建了16~19层深的卷积神经网络。VGGNet获得了ILSVRC 2014年比赛的亚军和定位项目的冠军,在top5上的错误率为7.5%。目前为止,VGGNet依然被用来提取图像的特征。

2 创新点

    VGGNet全部使用3*3的卷积核和2*2的池化核,通过不断加深网络结构来提升性能。网络层数的增长并不会带来参数量上的爆炸,因为参数量主要集中在最后三个全连接层中。同时,两个3*3卷积层的串联相当于1个5*5的卷积层,3个3*3的卷积层串联相当于1个7*7的卷积层,即3个3*3卷积层的感受野大小相当于1个7*7的卷积层。但是3个3*3的卷积层参数量只有7*7的一半左右,同时前者可以有3个非线性操作,而后者只有1个非线性操作,这样使得前者对于特征的学习能力更强。


    使用1*1的卷积层来增加线性变换,输出的通道数量上并没有发生改变。这里提一下1*1卷积层的其他用法,1*1的卷积层常被用来提炼特征,即多通道的特征组合在一起,凝练成较大通道或者较小通道的输出,而每张图片的大小不变。有时1*1的卷积神经网络还可以用来替代全连接层。

    其他小技巧。VGGNet在训练的时候先训级别A的简单网络,再复用A网络的权重来初始化后面的几个复杂模型,这样收敛速度更快。VGGNet作者总结出LRN层作用不大,越深的网络效果越好,1*1的卷积也是很有效的,但是没有3*3的卷积效果好,因为3*3的网络可以学习到更大的空间特征。

3 网络结构

    VGGNet的网络结构如下图所示。VGGNet包含很多级别的网络,深度从11层到19层不等,比较常用的是VGGNet-16和VGGNet-19。VGGNet把网络分成了5段,每段都把多个3*3的卷积网络串联在一起,每段卷积后面接一个最大池化层,最后面是3个全连接层和一个softmax层。


4 代码实现

代码实现参考自tensorflow的开源实现

#%%
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
from datetime import datetime
import math
import time
import tensorflow as tf

def conv_op(input_op, name, kh, kw, n_out, dh, dw, p):
    n_in = input_op.get_shape()[-1].value

    with tf.name_scope(name) as scope:
        kernel = tf.get_variable(scope+"w",
                                 shape=[kh, kw, n_in, n_out],
                                 dtype=tf.float32, 
                                 initializer=tf.contrib.layers.xavier_initializer_conv2d())
        conv = tf.nn.conv2d(input_op, kernel, (1, dh, dw, 1), padding='SAME')
        bias_init_val = tf.constant(0.0, shape=[n_out], dtype=tf.float32)
        biases = tf.Variable(bias_init_val, trainable=True, name='b')
        z = tf.nn.bias_add(conv, biases)
        activation = tf.nn.relu(z, name=scope)
        p += [kernel, biases]
        return activation

def fc_op(input_op, name, n_out, p):
    n_in = input_op.get_shape()[-1].value

    with tf.name_scope(name) as scope:
        kernel = tf.get_variable(scope+"w",
                                 shape=[n_in, n_out],
                                 dtype=tf.float32, 
                                 initializer=tf.contrib.layers.xavier_initializer())
        biases = tf.Variable(tf.constant(0.1, shape=[n_out], dtype=tf.float32), name='b')
        activation = tf.nn.relu_layer(input_op, kernel, biases, name=scope)
        p += [kernel, biases]
        return activation

def mpool_op(input_op, name, kh, kw, dh, dw):
    return tf.nn.max_pool(input_op,
                          ksize=[1, kh, kw, 1],
                          strides=[1, dh, dw, 1],
                          padding='SAME',
                          name=name)


def inference_op(input_op, keep_prob):
    p = []
    # assume input_op shape is 224x224x3

    # block 1 -- outputs 112x112x64
    conv1_1 = conv_op(input_op, name="conv1_1", kh=3, kw=3, n_out=64, dh=1, dw=1, p=p)
    conv1_2 = conv_op(conv1_1,  name="conv1_2", kh=3, kw=3, n_out=64, dh=1, dw=1, p=p)
    pool1 = mpool_op(conv1_2,   name="pool1",   kh=2, kw=2, dw=2, dh=2)

    # block 2 -- outputs 56x56x128
    conv2_1 = conv_op(pool1,    name="conv2_1", kh=3, kw=3, n_out=128, dh=1, dw=1, p=p)
    conv2_2 = conv_op(conv2_1,  name="conv2_2", kh=3, kw=3, n_out=128, dh=1, dw=1, p=p)
    pool2 = mpool_op(conv2_2,   name="pool2",   kh=2, kw=2, dh=2, dw=2)

    # # block 3 -- outputs 28x28x256
    conv3_1 = conv_op(pool2,    name="conv3_1", kh=3, kw=3, n_out=256, dh=1, dw=1, p=p)
    conv3_2 = conv_op(conv3_1,  name="conv3_2", kh=3, kw=3, n_out=256, dh=1, dw=1, p=p)
    conv3_3 = conv_op(conv3_2,  name="conv3_3", kh=3, kw=3, n_out=256, dh=1, dw=1, p=p)    
    pool3 = mpool_op(conv3_3,   name="pool3",   kh=2, kw=2, dh=2, dw=2)

    # block 4 -- outputs 14x14x512
    conv4_1 = conv_op(pool3,    name="conv4_1", kh=3, kw=3, n_out=512, dh=1, dw=1, p=p)
    conv4_2 = conv_op(conv4_1,  name="conv4_2", kh=3, kw=3, n_out=512, dh=1, dw=1, p=p)
    conv4_3 = conv_op(conv4_2,  name="conv4_3", kh=3, kw=3, n_out=512, dh=1, dw=1, p=p)
    pool4 = mpool_op(conv4_3,   name="pool4",   kh=2, kw=2, dh=2, dw=2)

    # block 5 -- outputs 7x7x512
    conv5_1 = conv_op(pool4,    name="conv5_1", kh=3, kw=3, n_out=512, dh=1, dw=1, p=p)
    conv5_2 = conv_op(conv5_1,  name="conv5_2", kh=3, kw=3, n_out=512, dh=1, dw=1, p=p)
    conv5_3 = conv_op(conv5_2,  name="conv5_3", kh=3, kw=3, n_out=512, dh=1, dw=1, p=p)
    pool5 = mpool_op(conv5_3,   name="pool5",   kh=2, kw=2, dw=2, dh=2)

    # flatten
    shp = pool5.get_shape()
    flattened_shape = shp[1].value * shp[2].value * shp[3].value
    resh1 = tf.reshape(pool5, [-1, flattened_shape], name="resh1")

    # fully connected
    fc6 = fc_op(resh1, name="fc6", n_out=4096, p=p)
    fc6_drop = tf.nn.dropout(fc6, keep_prob, name="fc6_drop")

    fc7 = fc_op(fc6_drop, name="fc7", n_out=4096, p=p)
    fc7_drop = tf.nn.dropout(fc7, keep_prob, name="fc7_drop")

    fc8 = fc_op(fc7_drop, name="fc8", n_out=1000, p=p)
    softmax = tf.nn.softmax(fc8)
    predictions = tf.argmax(softmax, 1)
    return predictions, softmax, fc8, p
    
    


def time_tensorflow_run(session, target, feed, info_string):
    num_steps_burn_in = 10
    total_duration = 0.0
    total_duration_squared = 0.0
    for i in range(num_batches + num_steps_burn_in):
        start_time = time.time()
        _ = session.run(target, feed_dict=feed)
        duration = time.time() - start_time
        if i >= num_steps_burn_in:
            if not i % 10:
                print ('%s: step %d, duration = %.3f' %
                       (datetime.now(), i - num_steps_burn_in, duration))
            total_duration += duration
            total_duration_squared += duration * duration
    mn = total_duration / num_batches
    vr = total_duration_squared / num_batches - mn * mn
    sd = math.sqrt(vr)
    print ('%s: %s across %d steps, %.3f +/- %.3f sec / batch' %
           (datetime.now(), info_string, num_batches, mn, sd))



def run_benchmark():
    with tf.Graph().as_default():
        image_size = 224
        images = tf.Variable(tf.random_normal([batch_size,
                                               image_size,
                                               image_size, 3],
                                               dtype=tf.float32,
                                               stddev=1e-1))

        keep_prob = tf.placeholder(tf.float32)
        predictions, softmax, fc8, p = inference_op(images, keep_prob)

        init = tf.global_variables_initializer()

        config = tf.ConfigProto()
        config.gpu_options.allocator_type = 'BFC'
        sess = tf.Session(config=config)
        sess.run(init)

        time_tensorflow_run(sess, predictions, {keep_prob:1.0}, "Forward")

        objective = tf.nn.l2_loss(fc8)
        grad = tf.gradients(objective, p)
        time_tensorflow_run(sess, grad, {keep_prob:0.5}, "Forward-backward")

batch_size=32
num_batches=100
run_benchmark()

      

5 参考文献

[1]黄文坚,唐源.TensorFlow实战[M].北京:电子工业出版社,2017.

[2] https://arxiv.org/abs/1409.1556v6

[3]https://github.com/machrisaa/tensorflow-vgg


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VGGNet介绍 的相关文章

  • 第三十二篇:Windbg中USB2.0调试环境的搭建

    2011年的时候 xff0c 为了开发USB Mass storage UASP USB attached SCSI Protocol 的设备驱动程序 xff0c 从米国买了两个USB2 0的调试小设备 xff08 如下图 xff0c 每个
  • 理解SerDes 之一

    理解SerDes FPGA发展到今天 xff0c SerDes Serializer Deserializer 基本上是标配了 从PCI到PCI Express 从ATA到SATA xff0c 从并行ADC接口到JESD204 从RIO到S
  • 理解SerDes 之二

    理解SerDes 之二 2012 11 11 21 17 12 转载 标签 xff1a dfe serdes it 2 3 接收端均衡器 Rx Equalizer 2 3 1 线形均衡器 Linear Equalizer 接收端均衡器的目标
  • USB3.0的物理层测试探讨

    USB简介 USB Universal Serial Bus 即通用串行总线 xff0c 用于把键盘 鼠标 打印机 扫描仪 数码相机 MP3 U盘等外围设备连接到计算机 xff0c 它使计算机与周边设备的接口标准化 在USB1 1版本中支持
  • ARM SoC漫谈

    作者 xff1a 重走此间路 链接 xff1a https zhuanlan zhihu com p 24878742 来源 xff1a 知乎 著作权归作者所有 商业转载请联系作者获得授权 xff0c 非商业转载请注明出处 芯片厂商向客户介
  • μC/OS III - 任务调度 Ⅰ:调度过程和调度点

    这是 C OS III任务调度的第一篇文章 xff1a 调度过程和调度点 基于Cortex M系列的处理器 xff0c 从最简单的创建任务开始 xff0c 分析 C OS III的任务调度过程 包括上下文切换的详细过程 任务的栈分配详情 引
  • 使用CANAPE脚本script周期性发送报文

    1 新建一个drive 选择devices选项卡中的device configuration 选择device菜单 xff0c new一个新驱动CAN 名称可自定义 Next 配置通道 xff0c 导入DBC Next 选择CANAPE对应
  • 【图像处理】MATLAB:基本原理

    前言 兜兜转转 xff0c 越发意识到夯实基础的重要性 不积跬步无以至千里 xff0c 想要深入学习图像处理 xff0c 就得安下心来踏实学习 xff0c 掌握基本理论知识 xff0c 切不可再得过且过 吊儿郎当 谨记两个词 刻苦 创新 x
  • 【Kalman】卡尔曼滤波Matlab简单实现

    本节卡尔曼滤波Matlab实现是针对线性系统估计的 xff0c 仅为简单仿真 1 离散时间线性动态系统的状态方程 线性系统采用状态方程 观测方程及其初始条件来描述 线性离散时间系统的一般状态方程可描述为 其中 xff0c X k 是 k 时
  • 安装Airsim并在Airsim仿真环境下进行DDPG DQN强化学习算法无人机训练

    微软开源了基于虚幻4引擎的一款用于模拟无人机飞行的工具AirSim 用户可以用在虚幻引擎下模拟无人机的飞行并进行数据采集 非常适合做视觉算法的测试以及仿真环境的训练等等 xff0c 下面介绍如何快速使用次仿真环境完成project的运行和使
  • Android面试专题 (十一):显式Intent & 隐式Intent

    面试官 xff1a 来 xff0c 说一下Android中的显式Intent 和 隐式Intent吧 xff01 嗯 xff0c 乍一听觉得这么简单你让我说什么呢 xff1f 但是 xff0c 没办法 xff0c 面试往往面的就是基础不是嘛
  • Java设计模式 | 观察者模式解析与实战

    概述 观察者模式是一个使用率非常高的模式 xff0c 它最常用的地方是 GUI 系统 订阅 发布系统 这个模式的一个重要作用就是解耦 xff0c 将被观察者和观察者解耦 xff0c 使得它们之间的依赖性更小 xff0c 甚至做到毫无依赖 以

随机推荐

  • ISO 26262中的ASIL等级确定与分解

    ISO 26262中的ASIL等级确定与分解 1 引言 汽车上电子 电气系统 xff08 E E xff09 数量不断的增加 xff0c 一些高端豪华轿车上有多达70多个ECU xff08 Electronic Control Unit电子
  • 数字电路符号整理

    0 常见的数字电路符号 1 D触发器 这个就是D触发器的示意图 其中 xff0c clk为时钟 xff0c rst n为复位 xff0c d为输入 xff0c q为输出 这个功能非常简单 xff0c 复位有效的时候 xff0c 这个q的值你
  • 进程优先级详解(prio、static_prio、normal_prio、rt_priority)

    Linux 中采用了两种不同的优先级范围 xff0c 一种是 nice 值 xff0c 一种是实时优先级 在上一篇粗略的说了一下 nice 值和实时优先级 xff0c 仍有不少疑问 xff0c 本文来详细说明一下进程优先级 linux 内核
  • C++中struct和class

    在C 43 43 中我们可以看到struct和class的区别并不是很大 xff0c 两者之间有很大的相似性 那么为什么还要保留struct 这是因为C 43 43 是向下兼容的 xff0c 因此C 43 43 中保留了很多C的东西 一 首
  • Linux中的进程栈和线程栈

    转载自 xff1a Linux中的进程栈和线程栈 知乎 1 进程栈 进程栈是属于用户态栈 xff0c 和进程虚拟地址空间 Virtual Address Space 密切相关 那我们先了解下什么是虚拟地址空间 xff1a 在 32 位机器下
  • Linux内存管理(二):PTMalloc

    1 ptmalloc简介 2 内存管理数据结构 3 内存分配 4 内存回收 5 配置选项 6 注意事项 1 ptmalloc简介 Linux 中 malloc 的早期版本是由 Doug Lea 实现的 xff0c 它有一个重要问题就是在并行
  • P问题、NP问题、NP完全问题和NP难问题

    在讲P类问题之前先介绍两个个概念 xff1a 多项式 xff0c 时间复杂度 知道这两概念的可以自动跳过这部分 1 多项式 xff1a axn bxn 1 43 c 恩 就是长这个样子的 xff0c 叫x最高次为n的多项式 咳咳 xff0c
  • 电容基本知识

    旁路电容 xff0c 耦合电容 xff0c 电容不同类型的使用范围 在模拟和数字PCB设计中 xff0c 旁路或去耦电容 0 1uF 应尽量靠近器件 放置 供电电源去耦电容 10uF 应放置在电路板的电源线入口处 所有情 况下 xff0c
  • 最长递增子序列的三种算法

    转载自 xff1a http qiemengdao iteye com blog 1660229 最长递增子序列 问题 给定一个长度为N的数组 xff0c 找出一个最长的单调自增子序列 xff08 不一定连续 xff0c 但是顺序不能乱 x
  • 树莓派手动指定静态IP和DNS 终极解决大法

    在把玩树莓派的过程中 xff0c 往往需要手动给它设定一个静态的IP地址 xff0c 一来可以防范DHCP自动分配的IP来回变动 xff0c 导致远程SSH时常无法连接 xff1b 二来还可以提高树莓派的网络连接速度 对此菲菲君在网上查了很
  • Anroid面试专题(十二):图片大小的优化 及 三级缓存

    面试官 xff1a 你在项目中处理过图片吗 xff0c 说一下你是如何对它做优化的 xff0c 及三级缓存是什么 xff1f 我们可以这样一步一步来回答 xff1a 1 一张图的大小是怎么计算的 要回答这个问题 xff0c 我们要先从图片说
  • UART和RS232/RS485的关系是什么?

    串口通讯是电子工程师和嵌入式开发工程师面对的最基本问题 xff0c RS232则是其中最简单最常用的通讯方式 但是初学者往往搞不清有关的名词如UART和RS232或RS485之间是什么关系 xff0c 因为它们经常被放到语句中同等的位置使用
  • TensorBoard的使用

    介绍 使用 Tensorboard 是TF 的可视化工具 xff0c 它通过对Tensoflow程序运行过程中输出的日志文件进行可视化Tensorflow程序的运行状态 xff0c 如下所示 SCALARS 对标量数据进行汇总和记录 使用方
  • Tensorflow 多 GPU 训练

    介绍 TensorFlow中的并行主要分为模型并行和数据并行 模型并行需要根据不同模型设计不同的并行方式 xff0c 其主要原理是将模型中不同计算节点放在不同硬件资源上运算 比较通用的且能简便地实现大规模并行的方式是数据并行 xff0c 其
  • Hadoop 各组件介绍

    转自 https www cnblogs com klb561 p 9085615 html Hadoop是一个由Apache基金会所开发的分布式系统基础架构 用户可以在不了解分布式底层细节的情况下 xff0c 开发分布式程序 充分利用集群
  • 8、解决Linux无法上网的各种问题

    最近发现Linux重新开机后无法上网 xff0c 不仅不能ping通windows主机也不能上外网 ifconfig后eth0也没有分配IP地址 xff0c 总之各种问题都被我碰到了 现在来一一解决 xff01 1 没有分配到IP地址 开机
  • 解决开发板ping不通主机和虚拟机的问题

    使用TFTP和NFS从虚拟机下载文件或者制作根文件系统的前提是开发板能够ping同虚拟机 xff01 相信很多人都像我一样有过ping不通的经历 xff0c 经过2 3天的研究和实验后终于把问题解决了 xff0c 而且屡试不爽 最后得出结论
  • USB摄像头驱动配置及V4L2编程

    1 摄像头驱动开发 1 1 摄像头软件系统架构 摄像头系统架构分为四层 xff1a 摄像头 支持V4L2的摄像头驱动 V4L2核心 应用程序 V4L2核心是Linux系统自带的组件 xff0c 它可以屏蔽摄像头驱动层的差异 xff0c 不管
  • 机器学习中的五种回归模型及其优缺点

    转自https blog csdn net Katherine hsr article details 79942260 好像有部分公式不能显示 xff0c 请查看原博客 本文将会介绍五种常见的回归模型的概念及其优缺点 xff0c 包括线性
  • VGGNet介绍

    VGGNet介绍 1 简要概括 VGGNet由牛津大学计算机视觉组合和Google DeepMind公司研究员一起研发的深度卷积神经网络 它探索了卷积神经网络的深度和其性能之间的关系 xff0c 通过反复的堆叠3 3的小型卷积核和2 2的最