主要内容:
1.CNN之VGG-net的测试
2.该实现中的函数总结

平台:
1.windows 10 64位
2.Anaconda3-4.2.0-Windows-x86_64.exe (当时TF还不支持python3.6,又懒得在高版本的anaconda下配置多个Python环境,于是装了一个3-4.2.0(默认装python3.5),建议装anaconda3的最新版本,TF1.2.0版本已经支持python3.6!)
3.TensorFlow1.1.0

牛津大学计算机视觉组(Visual Geometry Group)出产的VGGnet是 ILSVRC 2014年 分类第二名,定位项目第一名,其VGG-16\VGG-19广泛应用于图像领域!
论文《very deep convolutional networks for large-scale image recognition》
特点就是多个小卷积核(3*3)的堆叠来替代大卷积核(5*5,7*7),减少参数的同时增加了特征提取的能力。

来看看论文中给了5个模型的基本情况:

今天就用TF写一个VGG-16 ,上图红框中的那个,由于硬件问题,这里和Alex-net一样,只是做了一个前向和反向的耗时计算。(PS: GTX960m的 GPU(2G显存),没办法实现 batch_size为32,全连接层1为4096,全连接层2为4096个神经元的VGG网络,因此我修改了网络大小, batch_size为16, 全连接层1和2 都改为2048个神经元)

# -*- coding: utf-8 -*-
"""
Created on Mon Jun 12 16:36:43 2017@author: ASUS
"""
from datetime import datetime
import math
import time
import tensorflow as tf# 定义函数对卷积层进行初始化
# input_op : 输入数据
# name : 该卷积层的名字,用tf.name_scope()来命名
# kh,kw : 分别是卷积核的高和宽
# n_out : 输出通道数
# dh,dw : 步长的高和宽
# p : 是参数列表,存储VGG所用到的参数
# 采用xavier方法对卷积核权值进行初始化
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# 定义函数对全连接层进行初始化
# input_op : 输入数据
# name : 该全连接层的名字
# n_out : 输出的通道数
# p : 参数列表
# 初始化方法用 xavier方法
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())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 # 定义函数 创建 maxpool层
# input_op : 输入数据
# name : 该卷积层的名字,用tf.name_scope()来命名
# kh,kw : 分别是卷积核的高和宽
# dh,dw : 步长的高和宽
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)#---------------创建 VGG-16------------------def inference_op(input_op, keep_prob):p = []# 第一块 conv1_1-conv1_2-pool1conv1_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)# 第二块 conv2_1-conv2_2-pool2conv2_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,dw = 2, dh = 2)# 第三块 conv3_1-conv3_2-conv3_3-pool3conv3_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,dw = 2, dh = 2)# 第四块 conv4_1-conv4_2-conv4_3-pool4conv4_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,dw = 2, dh = 2)# 第五块 conv5_1-conv5_2-conv5_3-pool5conv5_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)# 把pool5 ( [7, 7, 512] )  拉成向量shp  = pool5.get_shape()flattened_shape = shp[1].value * shp[2].value * shp[3].valueresh1 = tf.reshape(pool5, [-1, flattened_shape], name = 'resh1')# 全连接层1 添加了 Droput来防止过拟合    fc1 = fc_op(resh1, name = 'fc1', n_out = 2048, p = p)fc1_drop = tf.nn.dropout(fc1, keep_prob, name = 'fc1_drop')# 全连接层2 添加了 Droput来防止过拟合    fc2 = fc_op(fc1_drop, name = 'fc2', n_out = 2048, p = p)fc2_drop = tf.nn.dropout(fc2, keep_prob, name = 'fc2_drop')# 全连接层3 加一个softmax求给类别的概率fc3 = fc_op(fc2_drop, name = 'fc3', n_out = 1000, p = p)softmax = tf.nn.softmax(fc3)predictions = tf.argmax(softmax, 1)return predictions, softmax, fc3, p# 定义评测函数def 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 not i  % 10: print('%s: step %d, duration = %.3f' % (datetime.now(), i-num_steps_burn_in, duration))total_duration += durationtotal_duration_squared += duration * durationmean_dur = total_duration / num_batches var_dur = total_duration_squared / num_batches - mean_dur * mean_durstd_dur = math.sqrt(var_dur)print('%s: %s across %d steps, %.3f +/- %.3f sec / batch' %(datetime.now(), info_string, num_batches, mean_dur, std_dur))# 定义函数 运行网络
def run_benchmark():with 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))keep_prob = tf.placeholder(tf.float32)predictions, softmax, fc3, p = inference_op(images, keep_prob)# 创建session ,初始化参数init = tf.global_variables_initializer()sess = tf.Session()sess.run(init)# 评测  forward的耗时time_tensorflow_run(sess, predictions, {keep_prob: 1.0}, 'Forward')# 评测 forward 和 backward objective = tf.nn.l2_loss(fc3)gard = tf.gradients(objective, p)time_tensorflow_run(sess,gard,predictions, {keep_prob: 0.5}, 'Forward-backward')batch_size = 16
num_batches = 100
run_benchmark() 

函数总结(续上篇)

sess = tf.InteractiveSession() 将sess注册为默认的session
tf.placeholder() , Placeholder是输入数据的地方,也称为占位符,通俗的理解就是给输入数据(此例中的图片x)和真实标签(y_)提供一个入口,或者是存放地。(个人理解,可能不太正确,后期对TF有深入认识的话再回来改~~)
tf.Variable() Variable是用来存储模型参数,与存储数据的tensor不同,tensor一旦使用掉就消失
tf.matmul() 矩阵相乘函数
tf.reduce_mean 和tf.reduce_sum 是缩减维度的计算均值,以及缩减维度的求和
tf.argmax() 是寻找tensor中值最大的元素的序号 ,此例中用来判断类别
tf.cast() 用于数据类型转换
————————————–我是分割线(一)———————————–
tf.random_uniform 生成均匀分布的随机数
tf.train.AdamOptimizer() 创建优化器,优化方法为Adam(adaptive moment estimation,Adam优化方法根据损失函数对每个参数的梯度的一阶矩估计和二阶矩估计动态调整针对于每个参数的学习速率)
tf.placeholder “占位符”,只要是对网络的输入,都需要用这个函数这个进行“初始化”
tf.random_normal 生成正态分布
tf.add 和 tf.matmul 数据的相加 、相乘
tf.reduce_sum 缩减维度的求和
tf.pow 求幂函数
tf.subtract 数据的相减
tf.global_variables_initializer 定义全局参数初始化
tf.Session 创建会话.
tf.Variable 创建变量,是用来存储模型参数的变量。是有别于模型的输入数据的
tf.train.AdamOptimizer (learning_rate = 0.001) 采用Adam进行优化,学习率为 0.001
————————————–我是分割线(二)———————————–
1. hidden1_drop = tf.nn.dropout(hidden1, keep_prob) 给 hindden1层增加Droput,返回新的层hidden1_drop,keep_prob是 Droput的比例
2. mnist.train.next_batch() 来详细讲讲 这个函数。一句话概括就是,打乱样本顺序,然后按顺序读取batch_size 个样本 进行返回。
具体看代码及其注释,首先要找到函数定义,在tensorflow\contrib\learn\python\learn\datasets 下的mnist.py
————————————–我是分割线(三)———————————–
1. tf.nn.conv2d(x, W, strides = [1, 1, 1, 1], padding =’SAME’)对于这个函数主要理解 strides和padding,首先明确,x是输入,W是卷积核,并且它们的维数都是4(发现strides里有4个元素没,没错!就是一一对应的)
先说一下卷积核W也是一个四维张量,各维度表示的信息是:[filter_height, filter_width, in_channels, out_channels]

输入x,x是一个四维张量 ,各维度表示的信息是:[batch, in_height, in_width, in_channels]

strides里的每个元素就是对应输入x的四个维度的步长,因为第2,3维是图像的长和宽,所以平时用的strides就在这里设置,而第1,4维一般不用到,所以是1

padding只有两种取值方式,一个是 padding=[‘VALID’] 一个是padding=[‘SAME’]
valid:采用丢弃的方式,只要移动一步时,最右边有超出,则这一步不移动,并且剩余的进行丢弃。如下图,图片长13,卷积核长6,步长是5,当移动一步之后,已经卷积核6-11,再移动一步,已经没有足够的像素点了,所以就不能移动,因此 12,13被丢弃。
same:顾名思义,就是保持输入的大小不变,方法是在图像边缘处填充全0的像素
————————————–我是分割线(四)———————————–
1.tf.nn.l2_loss()是对一个Tensor对象求L2 norm,这里用来求权值的L2范数
2.tf.add_to_collection(‘losses’, weight_loss), 把weight_loss 加到名为losses的loss中去
3.tf.nn.lrn,做局部相应归一化,来看看函数的定义

lrn(input, depth_radius=None, bias=None, alpha=None, beta=None,name=None)

函数有6个输入,第一个自然是输入啦,2-5是LRN用到的参数,第一个是depth半径,bias alpha beta是相应的参数,来看看伪代码就清楚了

sqr_sum[a, b, c, d] = sum(input[a, b, c, d - depth_radius : d + depth_radius + 1] ** 2)
output = input / (bias + alpha * sqr_sum) ** beta
2-5的参数是有默认值的,分别是5,1,1,0.5

3.tf.nn.sparse_softmax_cross_entropy_with_logits()就是计算交叉熵的,但是如果是一个batch的,得出的是一个向量,还需要配合tf.reduce_mean()才能计算得出最终的loss(标量)

4.tf.get_collection(‘losses’), 从一个集合中取出全部变量,返回的是一个列表,这里是把losses的都取出来,在上面把 weight_loss和输出层的loss都加到losses中了,这个函数就是把losses中的loss取出来

5.tf.add_n:把一个列表的东西都依次加起来 (Adds all input tensors element-wise.) 输入是一个list (inputs: A list of Tensor objects, each with same shape and type.)
————————————–我是分割线(五)———————————–

1.t.get_shape().as_list() ,t是一个tensor,函数以list的形式返回 tensor的shape
2.tf.name_scope(‘conv1’) as scope ,tf.name_scope是用来命名Variable的,print(parameters)可以看到命名
3. tf.Graph().as_default()能够在这个上下文里面覆盖默认的图,测试了一下 不用这个也可以,但是用上好点,可能是避免冲突吧~
————————————–我是分割线(六)———————————–
1. tensor.get_shape()[-1].value 获得 倒数第一个维度上的维数
2. tf.get_variable(scope+’w’,
shape = [kh, kw, n_in, n_out], dtype = tf.float32,
initializer = tf.contrib.layers.xavier_initializer_conv2d())
来看看函数定义:

def get_variable(name,shape=None,dtype=None,initializer=None,regularizer=None,trainable=True,collections=None,caching_device=None,partitioner=None,validate_shape=True,use_resource=None,custom_getter=None):

这下就清楚多了,除了第一个形参,其余都是带默认值的关键字参数,这样不根据参形参的顺序对参数赋值啦

3.tf.nn.relu_layer(input_op, kernel, biases, name = scope)
这个函数把 卷积操作,加偏置操作,relu操作 集成在一块儿了,不过这个仅限于全连接层这种一维的层,因为输入必须是2D的,具体如下:

def relu_layer(x, weights, biases, name=None):
Args:
x: a 2D tensor. Dimensions typically: batch, in_units
weights: a 2D tensor. Dimensions typically: in_units, out_units
biases: a 1D tensor. Dimensions: out_units
name: A name for the operation (optional). If not specified
“nn_relu_layer” is used.
Returns:
A 2-D Tensor computing relu(matmul(x, weights) + biases).
Dimensions typically: batch, out_units.

【TensorFlow-windows】(七) CNN之VGG-net的测试相关推荐

  1. CV之CNN:基于tensorflow框架采用CNN(改进的AlexNet,训练/评估/推理)卷积神经网络算法实现猫狗图像分类识别

    CV之CNN:基于tensorflow框架采用CNN(改进的AlexNet,训练/评估/推理)卷积神经网络算法实现猫狗图像分类识别 目录 基于tensorflow框架采用CNN(改进的AlexNet, ...

  2. [Python人工智能] 十.Tensorflow+Opencv实现CNN自定义图像分类案例及与机器学习KNN图像分类算法对比

    从本专栏开始,作者正式开始研究Python深度学习.神经网络及人工智能相关知识.前一篇详细讲解了gensim词向量Word2Vec安装.基础用法,并实现<庆余年>中文短文本相似度计算及多个 ...

  3. TensorFlow 2.0 - CNN / 预训练 / RNN

    文章目录 1. CNN 卷积神经网络 2. 预训练模型 3. RNN 循环神经网络 学习于:简单粗暴 TensorFlow 2 1. CNN 卷积神经网络 卷积神经网络,卷积后尺寸计算 tf.kera ...

  4. tensorflow windows

    conda create -n py35 python=3.5 activate py35 pip install --ignore-installed --upgrade https://stora ...

  5. 基于Tensorflow + Opencv 实现CNN自定义图像分类

    摘要:本篇文章主要通过Tensorflow+Opencv实现CNN自定义图像分类案例,它能解决我们现实论文或实践中的图像分类问题,并与机器学习的图像分类算法进行对比实验. 本文分享自华为云社区< ...

  6. TensorFlow windows之Tensorboard使用

    TensorBoard是什么 TensorBoard:Tensorflow自带的可视化工具,TensorBoard 来展现 TensorFlow 图像,绘制图像生成的定量指标图以及附加数据 关于如何在 ...

  7. 基于神经网络的人脸识别(Tensorflow,opencv,dlib,cnn,)

    写个神经网络(Tensorflow,opencv,dlib,cnn,人脸识别) lvying 20180427 基于TensorFlow训练的人脸识别神经网络 训练一个神经网络 这段时间正在学习ten ...

  8. 基于TensorFlow实现的CNN神经网络 花卉识别系统Demo

    基于TensorFlow实现的CNN神经网络 花卉识别系统Demo Demo展示 登录与注册 主页面 模型训练 识别 神经网络 训练 Demo下载 Demo展示 登录与注册 主页面 模型训练 识别 神 ...

  9. CV之IC之AlexNet:基于tensorflow框架采用CNN卷积神经网络算法(改进的AlexNet,训练/评估/推理)实现猫狗分类识别案例应用

    CV之IC之AlexNet:基于tensorflow框架采用CNN卷积神经网络算法(改进的AlexNet,训练/评估/推理)实现猫狗分类识别案例应用 目录 基于tensorflow框架采用CNN(改进 ...

  10. 基于Tensorflow卷积神经网络(CNN)的人脸年龄和性别检测系统

    文件大小:150M 开发环境:Python3.7.OpenCV4.0.1.24.Tensorflow1.13.1.PyCharm2020 点击下载:点击下载 简要概述:基于Tensorflow卷积神经 ...

最新文章

  1. testNG的DataProvider返回IteratorObject[]的妙用
  2. oracle+数据到+mysql数据库乱码问题_Linux系统Oracle数据库乱码问题的解决方法
  3. CSDN-markdown编辑器使用指南
  4. 【知识图谱】知识抽取与挖掘(Ⅱ)
  5. c# Invoke和BeginInvoke 区别
  6. JavaWeb之tomcat安装、配置与使用(一)
  7. 如何在Android中设置铃声+震动
  8. 【VTK】VTK 之一 环境准备
  9. html加载富文本_富文本图片懒加载解决方案
  10. http协议报文格式原理图
  11. 2017-7-8 OpenStack手工+oz自动制作CentOS 7.3镜像
  12. java基础练习实例_java基础练习题百度云.doc
  13. 使用ssh连接虚拟机保姆级教程
  14. 图片的格式怎么改?教你快速转格式的方法?
  15. 实现 Excel 多列数据组合
  16. 如何恢复Windows自动更新?
  17. QDateTime 和tm 的时间显示
  18. 各类游戏对应的服务端架构
  19. Unity AzureKinect Ar贴纸
  20. matlab 旋转曲面,在matlab中实现旋转曲面的动画设计

热门文章

  1. 痛苦的vsftpd配置
  2. 【计算机基础】 经常使用的排序算法的时间复杂度和空间复杂度
  3. 如何理解c和c ++的复杂类型声明
  4. python--关于if __name__==__main__的解释
  5. Android 软键盘弹出,界面整体上移的问题
  6. archlinux安装个简单桌面icewm
  7. mysql的with rollup
  8. 第三章 进程管理笔记
  9. 漫谈Google的Native Client(NaCl)技术(二)–技术篇(兼谈LLVM)
  10. 国外资源下载速度太慢怎么办