【fishing-pan:https://blog.csdn.net/u013921430转载请注明出处】

前言

现在已经到了Tensorflow实现卷积神经网络的第四讲了,既然是学习、实践,我一直坚持每一次试验都需要有新的知识点,每一次都要有新的收获才行,所以今天实现的VGGNet主要讲他的思想和创新。VGGNet探索了卷积网络的深度与其性能之间的关系,通过反复堆叠3x3的卷积核与2x2的最大池化层,VGGNet构建了16-19层深的网络。具体细节在下面讲述;

VGGNet

VGGNet中全部使用3x3的卷积核与2x2的最大池化层,并且整个网络都未使用LRN层。与之前的AlexNet不同的是,VGGNet没有像AlexNet那样一个卷积对应一个池化。而是将连续两到三个卷积层连接成为一个卷积段,在卷积段后面添加最大值池化。具体不同级别的网络结构图如下所示;

图1  VGGNet各级别网络结构图(图片来自网络)

分析&讨论

1x1卷积核

其中C比B多了几个1x1的卷积层。这是很有意思的,因为很少有人会用1x1的卷积核。但是当添加了1x1的卷积核后,相当于给前面的计算结果乘上一个系数,虽然卷积是线性变换,但是激活函数是非线性的运算,这个1x1的卷积核其实是增加了激活函数的结果的非线性效果。

上面六种网络结构的参数量很相近,原因在之前的博文中有提到过,在卷积神经网络中,计算量主要来自卷积层的卷积运算,但是参数量主要取决于全连接层。

图2  VGGNet各级别网络的参数量(单位为百万)(图片来自网络)

多个卷积层堆叠的意义

上面的网络结构经常出现多个完全一样的3x3的卷积核堆叠的情况,这样设计大致有两个目的,其一是这样做可以减少参数量,两个3x3的卷积核串联起来的效果相当于一个5x5的卷积核,而三个3x3的卷积核串联起来与一个7x7的卷积核的效果相当。在效果相近的情况下,前者只有3x3x3=27个参数,而后者参数多达49个,减少了将近一半的参数,同时运算量也减少了。其二是为了验证网络深度与性能之间的关系,因为卷积核的大小也是影响网络性能的一个因素,所以都是用一样大小的卷积核,保证不同网络结构中变量只有网络的深度。而且每个卷积层都有一个ReLU函数,多个激活函数可以增加网络中非线性的部分,使网络更具判别性。

图 3 两个串联的3x3的卷积核的效用类似于一个5x5的卷积核

VGGNet在训练时有一个小技巧就是先训练级别A的网络,然后将A网络的权重用于初始化后面几个复杂的模型,这样收敛更快。其实这一步在图像处理中经常用到,特别是在处理图像尺度比较大、图像复杂的情况。这种情况下往往首先对图像进行降采样等处理,然后对降采样的结果进行计算,然后用这些计算结果用作原始分辨图像的初始计算,这样可以大大节省迭代次数和计算时间。

此外,VGGNet还将图像缩放到不同的尺度然后随机剪切图像,从而实现数据增广,增加数据量,还可以防止模型过拟合。

代码

由于训练一个VGGNet需要非常多的时间,我这里不会用ImageNet的数据去训练它,与上一篇博文中的AlexNet一样,这里只构造网络,并且测试前馈计算(forward)和反馈计算(backward)的速度。

因为代码中没有太多要讲的,所以我就不逐行讲解了,只在代码中进行简单的标注。下面提供所有代码,需要说明一下,代码与书中的代码有细微的不同,但是功能是一样的。

# -*- coding: utf-8 -*-
"""
Created on Thu May 10 14:49:48 2018@author: most_pan
"""from datetime import datetime
import math
import time
import tensorflow as tf#定义卷积层,输入参数依次为输入图像,这一层的名字,卷积核的高kh,卷积层的宽kw,卷积核输出通道数,卷积核步长dh、dk,以及参数列表p;
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())bias_init_val=tf.constant(0.0,shape=[n_out],dtype=tf.float32)biases=tf.Variable(bias_init_val,trainable=True,name='b')activation=tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(input_op,kernel,(1,dh,dw,1),padding='SAME'),biases),name=scope)p+=[kernel,biases]return activation#定义全连接层,输入参数依次为输入图像,这一层的名字,输出通道数,以及参数列表p;
def fc_op(input_op,name,n_out,p):n_in=input_op.get_shape()[-1].valuewith 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_conv2d())biases=tf.Variable(tf.constant(0.1,shape=[n_out],dtype=tf.float32),trainable=True,name='b')activation=tf.nn.relu_layer(input_op,kernel,biases,name=scope)p+=[kernel,biases]return activation#定义最大值池化,输入参数依次为输入图像,这一层的名字,卷积核的高kh,卷积层的宽kw,卷积核步长dh、dk;
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=[]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,dh=2,dw=2)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)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)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)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,dh=2,dw=2)shp=pool5.get_shape() #shp[0]是batch_sizeflattened_shape=shp[1].value*shp[2].value*shp[3].valueresh1=tf.reshape(pool5,shape=[-1,flattened_shape],name="resh1")fc6=fc_op(resh1,"fc6",4096,p=p)fc6_drop=tf.nn.dropout(fc6,keep_prob,name="fc6_drop")fc7=fc_op(fc6_drop,"fc7",4096,p=p)fc7_drop=tf.nn.dropout(fc7,keep_prob,name="fc7_drop")fc8=fc_op(fc7_drop,"fc7",1000,p=p)softmax=tf.nn.softmax(fc8)  predictions=tf.argmax(softmax,1)#返回是概率最大的分类    return predictions,softmax,fc8,pdef time_tensorflow_run(session,target,feed,info_string):num_steps_burn_in=10total_duration=0.0total_duration_squared=0.0for i in range(num_batches+num_steps_burn_in):start_time=time.time()_=session.run(target,feed_dict=feed)duration=time.time()-start_timeif i>=num_steps_burn_in:if i%10==0:print('%s: step %d,duration= %.3f' % (datetime.now(),i-num_steps_burn_in,duration))total_duration+=durationtotal_duration_squared+=duration*durationmn=total_duration/num_batchesvr=total_duration_squared/num_batches-mn*mnsd=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()  sess = tf.Session()  sess.run(init)  #调用time_tensorflow_run函数,前向计算时候,dropout为1time_tensorflow_run(sess, predictions,{keep_prob:1.0}, "Forward")  #获得backward计算时间 ,反向计算(训练网络时),dropout为0.5; 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()

运行结果

从结果中也可以看出但是很明显前馈计算要比反馈计算快上近7倍。所以,在训练网络时,大量时间是花费在了反馈计算中,因为这些计算涉及了大量的求导和除法。

已完。。

参考书籍

《Tensorflow 实战》黄文坚等著;

【Tensorflow】深度学习实战04——Tensorflow实现VGGNet相关推荐

  1. 深度学习实战—基于TensorFlow 2.0的人工智能开发应用

    作者:辛大奇 著 出版社:中国水利水电出版社 品牌:智博尚书 出版时间:2020-10-01 深度学习实战-基于TensorFlow 2.0的人工智能开发应用

  2. 跨年之际,中文版畅销书《TensorFlow深度学习实战大全》分享,直接送!

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 跨年之际,给大家一份福利,赠书抽奖,一共4本!感兴趣的同学可以参与一下,奖品是新书&l ...

  3. TensorFlow 深度学习实战指南中文版

    TensorFlow 深度学习实战指南中文版 第 1 章入门 安装 TensorFlow 简单的计算 逻辑回归模型构建 逻辑回归训练 第 2 章深度神经网络 基本神经网络 单隐藏层模型 单隐藏层的说明 ...

  4. Tensorflow深度学习实战之(七)--MP神经元与BP神经网络模型

    本文是在GPU版本的Tensorflow = 2.6.2 , 英伟达显卡驱动CUDA版本 =11.6,Python版本 = 3.6, 显卡为3060的环境下进行验证实验的!!! 文章目录 一.M-P神 ...

  5. 转:tensorflow深度学习实战笔记(二):把训练好的模型进行固化

    原文地址:https://blog.csdn.net/chenyuping333/article/details/82106863 目录 一.导出前向传播图 二.对模型进行固化 三.pb文件转tfli ...

  6. 【Tensorflow】深度学习实战06——Tensorflow实现ResNet

    前言   ResNet(Residual Neural Network)由前微软研究院的 Kaiming He 等4名华人提出(有兴趣的可以点击这里,查看论文原文),通过使用 Residual Blo ...

  7. 【Tensorflow】深度学习实战01——Tensorflow实现简单的卷积网络(MNIST)

    [fishing-pan:https://blog.csdn.net/u013921430转载请注明出处] 前言 现在深度学习可以说很是热门,自己也非常感兴趣,之前有看过吴恩达老师的课程,也看过一些书 ...

  8. 【Tensorflow】深度学习实战03——Tensorflow实现AlexNet

    [fishing-pan:https://blog.csdn.net/u013921430转载请注明出处] 前言 前两篇博文中分别利用卷积神经网络识别手写数字和对CIFAR-10数据集分类,在这两次的 ...

  9. 【深度学习实战04】——SSD tensorflow图像和视频的目标检测

    关于SSD的源代码详细讲解,请参考文章:https://blog.csdn.net/c20081052/article/details/80391627  代码详解 本文是实战系列的第四篇,逼自己抽空 ...

最新文章

  1. 如何选择容器注册表?这里给出九个选项
  2. codevs 1958 刺激
  3. 【云炬大学生创业基础笔记】第1章第3节 什么是创业的讨论
  4. [2dPIC调试笔记]初始化变量1014(2)
  5. (转)CentOS分区操作详解
  6. 射灯安装方法图解_江苏天筑不锈钢雕塑厂家格栅射灯安装方法,格栅射灯安装注意事项...
  7. leetcode 88
  8. 数据分析融入至BI工具的新思路
  9. 在10分钟内完成微信小程序开发
  10. 香港金像奖40年发展史:香港电影最后的倔强
  11. 6-1 Iterative Mergesort (25分)
  12. 微信搜索引擎中索引的分布式演进
  13. flutter 实现put请求
  14. 螺旋矩阵java_Java实现螺旋矩阵
  15. 基于决策树的电网负荷预测
  16. ycsb mysql_使用 YCSB 测试 MySQL on TerarkDB
  17. 物以致用,人以致爱,以人为本,方得始终。
  18. UE4学习笔记 物体跟着spline移动
  19. 计算机任务管理器介面如何调整,设置win10任务管理器显示性能小窗口的方法
  20. 物联网网关的定义、主要功能、如何工作及应用介绍

热门文章

  1. Robotium 数据驱动测试框架
  2. 给 npm script 传递参数和添加注释
  3. Java中的记录器 - Java日志示例
  4. 计算机编程嘉兴,嘉兴自学电脑编程一对一
  5. Dockerfile 文件结构、docker镜像构建过程详细介绍
  6. Jmeter插件-dubbo
  7. javaweb解决编码问题_学习编码? 首先,学会解决问题。
  8. web开发 学习_是否想学习Web开发但不知道从哪里开始?
  9. hacktoberfest_我刚刚得到了免费的Hacktoberfest衬衫。 这是获取您的商品的快速方法。
  10. 设置api密钥_我应该将我的API密钥设置多长时间?