经典卷积神经网络(3)--VGGNet卷积网络模型
相关介绍
VGGNet是牛津大学计算机视觉组(Visual Geometry Group)和Google DeepMind公司的研究员一起研发的的深度卷积神经网络。
他们研究了卷积网络深度在大规模的图像识别环境下对准确性的影响。他们的主要贡献是使用非常小的(3×3)卷积滤波器架构对网络深度的增加进行了全面评估,这表明通过将深度推到16-19加权层可以实现对现有技术配置的显著改进。这些发现是他们的ImageNet Challenge 2014提交的基础,他们的团队在定位和分类过程中分别获得了第一名和第二名。VGG对于其他数据集泛化的很好,在其它数据集上取得了最好的结果。
1.VGGNet 探索的是神经网络的深度(depth)与其性能之间的关系。
VGGNet论文中全部使用了3´3的卷积核和2´2的池化核,通过不断加深网络结构来进行性能对比,最终得出较好的深层网络结构。牛津大学计算机视觉几何组对11-19层的网络都进行了相近的性能测试,根据网络深度的不同以及是否使用LRN,VGGNet可以分为A-E6个级别.各级网络结构如下图所示:
尽管A-E对网络逐步加深了,但是网络的参数量并没有显著增加,因为最后的3个全连层占据了大量的参数。在6个级别的VVGNet中,全连层都是相同的。
卷积层的参数共享和局部连接对降低参数数量做出了巨大贡献,但是由于卷积操作和池化操作的运算过程比较复杂,所以训练中比较耗时的部分是卷积层。
2.VGG结构全部都采用较小的卷积核(3×3,部分1×1)
在VGG出现之前的深度网络,比如ZFNet或Overfeat普遍都采用了7×7和11×11的卷积核。
如何选择卷积核的大小?越大越好还是越小越好?
答案是小而深,单独较小的卷积核也是不好的,只有堆叠很多小的卷积核,模型的性能才会提升。
为什么选择小而深的卷积核(即堆叠使用3×3的卷积核)
VGGNet相比AlexNet的一个改进是采用连续的几个3x3的卷积核代替AlexNet中的较大卷积核(11x11,5x5)。
原因:1.两个3´3的卷积层串联相当于1个5´5的卷积层,即串联后一个像素感受野大小为5´5。而3个3´3的卷积层串联的效果则相当于1个7´7的卷积层。
2.除此之外,2个串联的3´3的卷积层,拥有比1个5´5的卷积层更少的参数量.
3.最重要的是,2个3´3的卷积层拥有比1个5´5的卷积层更多的非线性变换(前者可以使用2次ReLU激活函数,而后者只有1次),使得CNN对特征的学习能力更强。
如下图
3. 在训练与测试时进行数据增强处理(Multi-scale:多尺寸)
Multi-scale方法(多尺寸图片数据)
大致过程:先将原始图片缩放到不同尺寸,然后再将得到的图片进行224* 224的随机裁剪
初始对原始图片进行裁剪时,原始图片的最小边不宜过小,这样的话,裁剪到224x224的时候,就相当于几乎覆盖了整个图片,这样对原始图片进行不同的随机 裁剪得到的图片就基本上没差别,就失去了增加数据集的意义,但同时也不宜过大,这样的话,裁剪到的图片只含有目标的一小部分,也不是很好。 针对上述裁剪的问题,提出的两种解决办法:
(1) 固定最小边的尺寸为256
(2) 最小边随机从[256,512]的确定范围内进行抽样,这样原始图片尺寸不一,有利于训练,这个方法叫做尺度抖动scal jittering,有利于训练集增强。 训练时运用大量的裁剪图片有利于提升识别精确率。
单尺度评估
测试图像大小设置为单一固定的最小边,训练图像使用两种裁剪方式进行对比(是否进行尺寸抖动)
首先,我们注意到,使用局部响应归一化(A-LRN网络)对模型A没有改善。因此,我们在较深的架构(B-E)中不采用归一化。
第二,我们观察到分类误差随着ConvNet深度的增加而减小:从A中的11层到E中的19层。值得注意的是,尽管深度相同,配置C(包含三个1×1卷积层)比在整个网络层中使用3×3卷积的配置D更差。这表明,虽然额外的非线性确实有帮助(C优于B),但也可以通过使用具有非平凡感受野(D比C好)的卷积滤波器来捕获空间上下文。当深度达到19层时,我们架构的错误率饱和,但更深的模型可能有益于较大的数据集。 三,我们还将网络B与具有5×5卷积层的浅层网络进行了比较,浅层网络可以通过用单个5×5卷积层替换B中每对3×3卷积层得到。测量的浅层网络top-1错误率比网络B的top-1错误率高7%,这证实了具有小滤波器的深层网络优于具有较大滤波器的浅层网络。
最后,训练时的尺度抖动得到了与固定最小边的图像训练相比更好的结果,即使在测试时使用单尺度。这证实了通过尺度抖动进行的训练集增强确实有助于捕获多尺度图像统计。
多尺度评估
在单尺度上评估ConvNet模型后,我们现在评估测试时尺度抖动的影响。考虑到训练和测试尺度之间的巨大差异会导致性能下降,用固定S训练的模型在三个测试图像尺度上进行了评估。同时,训练时的尺度抖动允许网络在测试时应用于更广的尺度范围,所以用变量训练的模型在更大的尺寸范围上进行评估。表4中给出的结果表明,测试时的尺度抖动导致了更好的性能
可以看到结果稍好于前者测试图片采用单一尺寸的效果。
最后将多个模型进行合并进一步得到了更好的效果,并在ILSVRC比赛上拿到了第二的成绩。
新技术点:
①LRN层作用不大,还耗时,抛弃。
②网络越深,效果越好。
③卷积核用较小的卷积核,比如3*3。
import tensorflow as tf
from datetime import datetime
import math
import timebatch_size = 12
num_batches = 100# 定义卷积操作
def conv_op(input, name, kernel_h, kernel_w, num_out, step_h, step_w, para):# num_in是输入的深度,这个参数被用来确定过滤器的输入通道数num_in = input.get_shape()[-1].valuewith tf.name_scope(name) as scope:kernel = tf.get_variable(scope + "w", shape=[kernel_h, kernel_w, num_in, num_out],dtype=tf.float32,initializer=tf.contrib.layers.xavier_initializer_conv2d())conv = tf.nn.conv2d(input, kernel, (1, step_h, step_w, 1), padding="SAME")biases = tf.Variable(tf.constant(0.0, shape=[num_out], dtype=tf.float32),trainable=True, name="b")# 计算relu后的激活值activation = tf.nn.relu(tf.nn.bias_add(conv, biases), name=scope)para += [kernel, biases]return activation# 定义全连操作
def fc_op(input, name, num_out, para):# num_in为输入单元的数量num_in = input.get_shape()[-1].valuewith tf.name_scope(name) as scope:weights = tf.get_variable(scope + "w", shape=[num_in, num_out], dtype=tf.float32,initializer=tf.contrib.layers.xavier_initializer())biases = tf.Variable(tf.constant(0.1, shape=[num_out], dtype=tf.float32), name="b")# tf.nn.relu_layer()函数会同时完成矩阵乘法以加和偏置项并计算relu激活值# 这是分步编程的良好替代activation = tf.nn.relu_layer(input, weights, biases)para += [weights, biases]return activation# 定义前向传播的计算过程,input参数的大小为224x224x3,也就是输入的模拟图片数据
def inference_op(input, keep_prob):parameters = []# 第一段卷积,输出大小为112x112x64(省略了第一个batch_size参数)conv1_1 = conv_op(input, name="conv1_1", kernel_h=3, kernel_w=3, num_out=64,step_h=1, step_w=1, para=parameters)conv1_2 = conv_op(conv1_1, name="conv1_2", kernel_h=3, kernel_w=3, num_out=64,step_h=1, step_w=1, para=parameters)pool1 = tf.nn.max_pool(conv1_2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],padding="SAME", name="pool1")print(pool1.op.name, ' ', pool1.get_shape().as_list())# 第二段卷积,输出大小为56x56x128(省略了第一个batch_size参数)conv2_1 = conv_op(pool1, name="conv2_1", kernel_h=3, kernel_w=3, num_out=128,step_h=1, step_w=1, para=parameters)conv2_2 = conv_op(conv2_1, name="conv2_2", kernel_h=3, kernel_w=3, num_out=128,step_h=1, step_w=1, para=parameters)pool2 = tf.nn.max_pool(conv2_2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],padding="SAME", name="pool2")print(pool2.op.name, ' ', pool2.get_shape().as_list())# 第三段卷积,输出大小为28x28x256(省略了第一个batch_size参数)conv3_1 = conv_op(pool2, name="conv3_1", kernel_h=3, kernel_w=3, num_out=256,step_h=1, step_w=1, para=parameters)conv3_2 = conv_op(conv3_1, name="conv3_2", kernel_h=3, kernel_w=3, num_out=256,step_h=1, step_w=1, para=parameters)conv3_3 = conv_op(conv3_2, name="conv3_3", kernel_h=3, kernel_w=3, num_out=256,step_h=1, step_w=1, para=parameters)pool3 = tf.nn.max_pool(conv3_3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],padding="SAME", name="pool3")print(pool2.op.name, ' ', pool2.get_shape().as_list())# 第四段卷积,输出大小为14x14x512(省略了第一个batch_size参数)conv4_1 = conv_op(pool3, name="conv4_1", kernel_h=3, kernel_w=3, num_out=512,step_h=1, step_w=1, para=parameters)conv4_2 = conv_op(conv4_1, name="conv4_2", kernel_h=3, kernel_w=3, num_out=512,step_h=1, step_w=1, para=parameters)conv4_3 = conv_op(conv4_2, name="conv4_3", kernel_h=3, kernel_w=3, num_out=512,step_h=1, step_w=1, para=parameters)pool4 = tf.nn.max_pool(conv4_3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],padding="SAME", name="pool4")print(pool4.op.name, ' ', pool4.get_shape().as_list())# 第五段卷积,输出大小为7x7x512(省略了第一个batch_size参数)conv5_1 = conv_op(pool4, name="conv5_1", kernel_h=3, kernel_w=3, num_out=512,step_h=1, step_w=1, para=parameters)conv5_2 = conv_op(conv5_1, name="conv5_2", kernel_h=3, kernel_w=3, num_out=512,step_h=1, step_w=1, para=parameters)conv5_3 = conv_op(conv5_2, name="conv5_3", kernel_h=3, kernel_w=3, num_out=512,step_h=1, step_w=1, para=parameters)pool5 = tf.nn.max_pool(conv5_3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],padding="SAME", name="pool5")print(pool5.op.name, ' ', pool5.get_shape().as_list())# pool5的结果汇总为一个向量的形式pool_shape = pool5.get_shape().as_list()flattened_shape = pool_shape[1] * pool_shape[2] * pool_shape[3]reshped = tf.reshape(pool5, [-1, flattened_shape], name="reshped")# 第一个全连层fc_6 = fc_op(reshped, name="fc6", num_out=4096, para=parameters)fc_6_drop = tf.nn.dropout(fc_6, keep_prob, name="fc6_drop")# 第二个全连层fc_7 = fc_op(fc_6_drop, name="fc7", num_out=4096, para=parameters)fc_7_drop = tf.nn.dropout(fc_7, keep_prob, name="fc7_drop")# 第三个全连层及softmax层fc_8 = fc_op(fc_7_drop, name="fc8", num_out=1000, para=parameters)softmax = tf.nn.softmax(fc_8)# predictions模拟了通过argmax得到预测结果predictions = tf.argmax(softmax, 1)return predictions, softmax, fc_8, parameterswith tf.Graph().as_default():# 创建模拟的图片数据image_size = 224images = tf.Variable(tf.random_normal([batch_size, image_size, image_size, 3],dtype=tf.float32, stddev=1e-1))# Dropout的keep_prob会根据前向传播或者反向传播而有所不同,在前向传播时,# keep_prob=1.0,在反向传播时keep_prob=0.5keep_prob = tf.placeholder(tf.float32)# 为当前计算图添加前向传播过程predictions, softmax, fc_8, parameters = inference_op(images, keep_prob)init_op = tf.global_variables_initializer()# 使用BFC算法确定GPU内存最佳分配策略config = tf.ConfigProto()config.gpu_options.allocator_type = "BFC"with tf.Session(config=config) as sess:sess.run(init_op)num_steps_burn_in = 10total_dura = 0.0total_dura_squared = 0.0back_total_dura = 0.0back_total_dura_squared = 0.0# 运行前向传播的测试过程for i in range(num_batches + num_steps_burn_in):start_time = time.time()_ = sess.run(predictions, feed_dict={keep_prob: 1.0})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_dura += durationtotal_dura_squared += duration * durationaverage_time = total_dura / num_batches# 打印前向传播的运算时间信息print("%s: Forward across %d steps, %.3f +/- %.3f sec / batch" %(datetime.now(), num_batches, average_time,math.sqrt(total_dura_squared / num_batches - average_time * average_time)))# 定义求解梯度的操作grad = tf.gradients(tf.nn.l2_loss(fc_8), parameters)# 运行反向传播测试过程for i in range(num_batches + num_steps_burn_in):start_time = time.time()_ = sess.run(grad, feed_dict={keep_prob: 0.5})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))back_total_dura += durationback_total_dura_squared += duration * durationback_avg_t = back_total_dura / num_batches# 打印反向传播的运算时间信息print("%s: Forward-backward across %d steps, %.3f +/- %.3f sec / batch" %(datetime.now(), num_batches, back_avg_t,math.sqrt(back_total_dura_squared / num_batches - back_avg_t * back_avg_t)))
经典卷积神经网络(3)--VGGNet卷积网络模型相关推荐
- 深度学习经典卷积神经网络之VGGNet
论文地址:https://arxiv.org/abs/1409.1556 VGGNet是牛津大学计算机视觉组(VisualGeometry Group)和GoogleDeepMind公司的研究员一起研 ...
- 吴恩达.深度学习系列-C4卷积神经网络-W2深度卷积模型案例
吴恩达.深度学习系列-C4卷积神经网络-W2深度卷积模型案例 (本笔记部分内容直接引用redstone的笔记http://redstonewill.com/1240/.原文整理的非常好,引入并添加我自 ...
- 04.卷积神经网络 W2.深度卷积网络:实例探究(作业:Keras教程+ResNets残差网络)
文章目录 作业1:Keras教程 1. 快乐的房子 2. 用Keras建模 3. 用你的图片测试 4. 一些有用的Keras函数 作业2:残差网络 Residual Networks 1. 深层神经网 ...
- 花书+吴恩达深度学习(十)卷积神经网络 CNN 之卷积层
目录 0. 前言 1. 2D 图像卷积 2. 3D 图像卷积 3. 过滤器(核函数) 4. 过滤器应用于边缘检测 5. padding 填充 6. stride 步长 7. 使用卷积的动机 8. 1乘 ...
- 神经网络与卷积神经网络,什么是卷积神经网络
前馈神经网络.BP神经网络.卷积神经网络的区别与联系 一.计算方法不同1.前馈神经网络:一种最简单的神经网络,各神经元分层排列.每个神经元只与前一层的神经元相连.接收前一层的输出,并输出给下一层.各层 ...
- 图卷积神经网络3-空域卷积:GNN/GraphSAGE/PGC的引入和介绍
知乎主页https://www.zhihu.com/people/shuang-shou-cha-dai-53https://www.zhihu.com/people/shuang-shou-cha- ...
- 图卷积神经网络4-空域卷积:空域卷积局限性分析和过平滑解决方案
知乎主页https://www.zhihu.com/people/shuang-shou-cha-dai-53https://www.zhihu.com/people/shuang-shou-cha- ...
- 描述卷积神经网络的结构,卷积神经网络三大特点
什么是卷积神经网络?为什么它们很重要 卷积神经网络(ConvolutionalNeuralNetwork,CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理 ...
- 神经网络与卷积神经网络,深度残差卷积神经网络
深度残差网络是卷积网络的一种吗 谷歌人工智能写作项目:神经网络伪原创 深度残差网络是卷积网络的一种吗 神经网络的历史是什么? 沃伦·麦卡洛克和沃尔特·皮茨(1943)基于数学和一种称为阈值逻辑的算法创 ...
- 卷积神经网络预测彩票,卷积神经网络预测模型
1.卷积神经网络能用于参数预测吗 卷积神经网络有以下几种应用可供研究: 1.基于卷积网络的形状识别 物体的形状是人的视觉系统分析和识别物体的基础,几何形状是物体的本质特征的表现,并具有平移.缩放和旋转 ...
最新文章
- C#程序调用cmd执行命令
- 100+篇技术文章推荐总有一篇你想看的
- 全球及中国软件外包行业“十四五”展望发展建议及创新布局战略报告2021-2027年
- ubuntu右键打开终端(Open Terminal Here)失效
- 缩点(有向图的强连通分量)学习笔记
- c语言给bmp图片加滤镜,关于BMP位图透明通道的详解制作教程, 教你输出透明的BMP位图...
- 亚马逊推荐python_使用python查找amazon类别
- 使用Jedis连接远程服务器的redis
- dbm和mysql使用场景_mysql基本用法总结
- volatile关键字使用总结
- 如何批量Ping 1000个IP地址,一个小技巧节约N小时?
- java mysql 分页_mysql分页查询总结
- 计算机专业软件工程专业学科排名2015,软件工程专业排名
- win10计算机到桌面显示器,win10电脑外接显示器设置
- 自己不优秀,认识谁都没用
- Badboy 安装 使用 常见问题 badboy当前页面脚本发生错误
- VBA宏批量处理多个Word文档
- 酒店市场消费趋势洞察报告
- Python:实现字符串Z 函数或 Z 算法(附完整源码)
- 机器学习 | MATLAB实现MLP多层感知机newff参数设定(下)