Tensorflow实现VGGNet
来源:互联网 发布:金属脚镣淘宝 编辑:程序博客网 时间:2024/06/05 02:18
Tensorflow实现VGGNet
VGGNet 在2014年获得了imageNet的亚军,其探索了卷积神经网络的深度和性能之间的关系,通过反复堆叠3x3的卷积神经网络和2x2的池化层,成功构建了16-19层深的卷积神经网络。VGGNet结构很简洁,拓展性很强,很容易迁移到其他图像数据上。
VGGNet中全部是用“小型”卷积核,通过不断加深网络深度来提升性能。上图为VGGNet的结构。
虽然从A 到E么以及网络逐渐加深,但是网络的参数数量增加的不多,因为该网络的主要参数实在后面的三个全链接层中。其中D和E就是常说的VGGNet-16和VGGNet-19。
C中相比B,多了1x1的卷积层,该层主要意义是为了“线性变换”,而输入的通道数和输出通道数不变,没有发生降维。
VGGNet拥有5段卷积,每一段中拥有2-3个卷积层,同时每一段卷积层后面有一个最大池化层。每一段内的卷积核个数相同,越靠后的卷积段,卷积核个数越多。
TRICKs:
经常出现多个完全一样的3x3卷积层串联在一起的情况。
两个3x3的卷积层串联在一起,相当于一个5x5的卷积层,[3个3x3的卷积层,相当于一个 7x7的卷积层]但是参数数量变得更少了,而且还具有更多的非线性变换(每一层后面都会有一个Relu激活函数)
作者在论文中总结了几个观点:
(1)LRN作用不大
(2)越深的网络效果越好
(3)1x1的卷积也是很有效的,但是没有3x3的有效,大一些的卷积核可以学到打大的特征空间。
# 导入库import tensorflow as tf # 1.3import mathimport timefrom datetime import datetime
VGGNet中具有很多层,可以降每一个卷积层(参数初始化、卷积、relu)放在一个函数中,方便后面编写网络。
def conv_op(input_op, name, kh, kw, n_out, dh, dw, p): """ input_op: 输入的tensor name: 用于name_scope中,该层的名称 kh kw 卷积核的参数 n_out 卷积核数量 (输出通道数) dh dw strides的参数 p 输出的参数列表,(可有可无) """ n_in = input_op.get_shape()[-1].value # 首先获取输入通道数。比如224×224×3 得到3 # 卷积核[kh, kw, n_in, n_out] with tf.name_scope(name) as scope: kernel = tf.get_variable(name=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") biases = tf.Variable(tf.constant(0.0, shape=[n_out], dtype=tf.float32), trainable=True, name='b') bias = tf.nn.bias_add(conv, biases) activation = tf.nn.relu(bias, 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(name=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') a = tf.matmul(input_op, kernel)+biases activation = tf.nn.relu(a, name=scope) # 上面两句还可以合成一句 # tf.nn.relu_layer(input_op, kernel, biases, name='scope') p += [kernel, biases] return activation
# 定义池化层函数def max_pool_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 print_activation(t): print(t.op.name, ": ", t.get_shape().as_list())
# 开始创建VGGNet-16def inference(input_op, keep_prob): p = [] # 初始化p # 第一段有两个卷积 64 64 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 = max_pool_op(conv1_2, name='pool1', kh=2, kw=2, dh=2, dw=2) print_activation( pool1) # 第二段有两个个卷积 128 128 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 = max_pool_op(conv2_2, name='pool2', kh=2, kw=2,dh=2, dw=2) print_activation(pool2) # 第三段有三个卷积 256 256 256 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 = max_pool_op(conv3_3, name='pool3', kh=2,kw=2,dh=2,dw=2) # 第四段有三个卷积 512 512 512 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 = max_pool_op(conv4_3, name='pool4', kh=2, kw=2, dh=2, dw=2) # 第五段有三个卷积 512 512 512 conv5_1 = conv_op(pool4, name='con5_1', kh=3,kw=3, n_out=512, dh=1, dw=1, p=p) conv5_2 = conv_op(conv5_1, name='con5_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 = max_pool_op(conv5_3, name='pool5', kh=2,kw=2, dh=2,dw=2) print_activation(pool5) # 在全连接层之前,需要降pool5进行扁平化 shp = pool5.get_shape().as_list() flattened_shape = shp[1] * shp[2] * shp[3] resh1 = tf.reshape(pool5, [-1, flattened_shape], name='resh1') # FC1 4096 fc6 = fc_op(resh1, name='fc6', n_out=4096, p=p) # 全连接层加上dropout fc6_drop = tf.nn.dropout(fc6, keep_prob, name='fc6_drop') # fc2 4096 fc7 = fc_op(fc6_drop, name='fc7', n_out=4096, p=p) fc7_drop = tf.nn.dropout(fc7, keep_prob, name='fc7_drop') # fc3 1000 fc8 = fc_op(fc7_drop, name='fc8', n_out=1000, p=p) # softmax softmax = tf.nn.softmax(fc8) prediction = tf.argmax(softmax, 1) # 概率最大的类别 return prediction, softmax, fc8, p
搭建完网络就可以搭建计算loss的过程,还有优化、训练等过程。然后创建session。开始训练
init = tf.global_variables_initializer()with tf.Session() as sess: sess.run(init) image_size = 224 image = tf.Variable(tf.random_normal([32, image_size, image_size, 3], dtype=tf.float32, stddev=0.1)) keep_prob = tf.placeholder(tf.float32) # 一个数的占位符 a, b, c, d = inference(image, keep_prob) print(sess.run(a, feed_dict={keep_prob:0.5}))
- Tensorflow实现VGGNet
- Tensorflow实现VGGNet
- VGGNet原理及Tensorflow实现
- 【深度学习】VGGNet的tensorflow实现code
- Tensorflow实战学习(三十一)【实现VGGNet】
- tensorflow34《TensorFlow实战》笔记-06-02 TensorFlow实现VGGNet code
- TensorFlow实现VGGNet-16(forward和backward耗时计算)
- Tensorflow实战8:VGGNet实现及时间测评
- 神经网络之VGGNet模型的实现(Python+TensorFlow)
- TensorFlow学习--VGGNet实现&图像识别
- TensorFlow实现经典深度学习网络(2):TensorFlow实现VGGNet
- VGGNet
- VGGNet
- 学习笔记TF031:实现VGGNet
- Deep Learning-TensorFlow (11) CNN卷积神经网络_解读 VGGNet
- TensorFlow实战:Chapter-4(CNN-2-经典卷积神经网络(AlexNet、VGGNet))
- VGGNet笔记
- VGGNet笔记
- 导航栏按钮返回
- 多线程同步锁是谁
- JavaWeb--初学者的一点认识和想法(1)
- 设计模式之一:单例模式
- 羊毛党大揭秘:一亿手机黑卡在手 半年撸垮上市公司
- Tensorflow实现VGGNet
- Android:自动点击屏幕
- Android 最简单实现广告轮播效果ConvenientBanner
- 目前流行的开源监控框架有哪些
- centos 7 linux系统安装 mysql5.7.17(glibc版)
- 问题解决:gradle project sync failed. basic functionality (e.g.editing, debugging )will not work properly
- java实现文件的压缩解决服务器(亲测windows server 2008)中文乱码
- DrawerLayout侧栏 加ViewPager +子布局横栏+XlistView
- LDAP 域操作