【TensorFlow-windows】(六) CNN之Alex-net的测试
主要内容:
1.CNN之Alex-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
2012年以Alex-net为代表的深度学习在imagenet上大放异彩,之后深度学习席卷大江南北,往后的Imagenet的冠军无不采用深度学习……(吹不下去了),Alex-net就是近期(神经网络生命期来看)神经网络重回众人视线的开端。
Alex-net的成功得益于其采用了多个Trick,并且这些trick早就被学者提出,只不过Alex等人将其整合,发挥得当。其中包括抗梯度消失以及提供稀疏性的激活函数Relu;类似bagging的作用的Dropout来解决过拟合问题;模仿生物神经元的侧抑制的LRN( Local Response Normalization);数据增强(data augmentation)来获得更多数据,从而防止过拟合;采用双GPU加速训练等等;
来看看Alex-net的结构:
具体是: conv1–LRN1–pool1—-conv2–LRN2–pool2–conv3–conv4–conv5–pool3–fc1–fc2–fc3(输出层)
由于硬件限制,只是做了一个前向和反向的耗时计算,配置好的同学可以稍作修改即可训练。
代码:
# -*- 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
batch_size = 32
num_batches = 100
# 定义一个显示函数,来观察每一层输出的尺寸和名称
def print_activations(t):
print(t.op.name, ' ', t.get_shape().as_list()) # 以list的形式返回tensor的shape
# 输入为一个batch的图片,输出为Alex-net全连接层3的输出(未经sotfmax)
def inference(images):
parameters = []
# conv1
# tf.name_scope是用来命名Variable的,print(parameters)可以看到命名
with tf.name_scope('conv1') as scope:
kernel = tf.Variable(tf.truncated_normal([11, 11, 3, 64],
dtype = tf.float32, stddev = 1e-1), name = 'weights')
conv = tf.nn.conv2d(images, kernel, [1,4,4,1], padding = 'SAME')
biases = tf.Variable(tf.constant(0.0,shape = [64], dtype = tf.float32),
trainable = True, name = 'biases') # trainable ???
bias = tf.nn.bias_add(conv, biases)
conv1 = tf.nn.relu(bias, name = scope)
parameters += [kernel, biases]
print_activations(conv1)
lrn1 = tf.nn.lrn(conv1, 4, bias =1.0, alpha=0.001/9,
beta = 0.75, name = 'lrn1')
pool1 = tf.nn.max_pool(lrn1, ksize = [1,3,3,1],strides = [1,2,2,1],
padding = 'VALID', name = 'pool1')
print_activations(pool1)
# conv2
# tf.name_scope是用来命名Variable的,print(parameters)可以看到命名
with tf.name_scope('conv2') as scope:
kernel = tf.Variable(tf.truncated_normal([5, 5, 64, 192],
dtype = tf.float32, stddev = 1e-1), name = 'weights')
conv = tf.nn.conv2d(pool1, kernel, [1,1,1,1], padding = 'SAME')
biases = tf.Variable(tf.constant(0.0,shape = [192], dtype = tf.float32),
trainable = True, name = 'biases') # trainable ???
bias = tf.nn.bias_add(conv, biases)
conv2 = tf.nn.relu(bias, name = scope)
parameters += [kernel, biases]
print_activations(conv2)
lrn2 = tf.nn.lrn(conv2, 4, bias =1.0, alpha=0.001/9,
beta = 0.75, name = 'lrn2')
pool2 = tf.nn.max_pool(lrn2, ksize = [1,3,3,1],strides = [1,2,2,1],
padding = 'VALID', name = 'pool2')
print_activations(pool2)
# conv3
# tf.name_scope是用来命名Variable的,print(parameters)可以看到命名
with tf.name_scope('conv3') as scope:
kernel = tf.Variable(tf.truncated_normal([3, 3, 192, 384],
dtype = tf.float32, stddev = 1e-1), name = 'weights')
conv = tf.nn.conv2d(pool2, kernel, [1,1,1,1], padding = 'SAME')
biases = tf.Variable(tf.constant(0.0,shape = [384], dtype = tf.float32),
trainable = True, name = 'biases') # trainable ???
bias = tf.nn.bias_add(conv, biases)
conv3 = tf.nn.relu(bias, name = scope)
parameters += [kernel, biases]
print_activations(conv3) # 无pool层
# conv4
# tf.name_scope是用来命名Variable的,print(parameters)可以看到命名
with tf.name_scope('conv4') as scope:
kernel = tf.Variable(tf.truncated_normal([3, 3, 384, 256],
dtype = tf.float32, stddev = 1e-1), name = 'weights')
conv = tf.nn.conv2d(conv3, kernel, [1,1,1,1], padding = 'SAME')
biases = tf.Variable(tf.constant(0.0,shape = [256], dtype = tf.float32),
trainable = True, name = 'biases') # trainable ???
bias = tf.nn.bias_add(conv, biases)
conv4 = tf.nn.relu(bias, name = scope)
parameters += [kernel, biases]
print_activations(conv4)
# conv5
# tf.name_scope是用来命名Variable的,print(parameters)可以看到命名
with tf.name_scope('conv5') as scope:
kernel = tf.Variable(tf.truncated_normal([3, 3, 256, 256],
dtype = tf.float32, stddev = 1e-1), name = 'weights')
conv = tf.nn.conv2d(conv4, kernel, [1,1,1,1], padding = 'SAME')
biases = tf.Variable(tf.constant(0.0,shape = [256], dtype = tf.float32),
trainable = True, name = 'biases') # trainable ???
bias = tf.nn.bias_add(conv, biases)
conv5 = tf.nn.relu(bias, name = scope)
parameters += [kernel, biases]
print_activations(conv5)
pool5 = tf.nn.max_pool(conv5, ksize = [1,3,3,1], strides=[1,2,2,1],
padding = 'VALID', name = 'pool5')
print_activations(pool5)
# fcn1
# tf.name_scope是用来命名Variable的,print(parameters)可以看到命名
with tf.name_scope('fcn1') as scope:
reshape = tf.reshape(pool5, [batch_size, -1])
dim = reshape.get_shape()[1].value # 获取数据长度
weight1 = tf.Variable(tf.truncated_normal([dim, 4096], stddev = 1e-1))
bias1 = tf.Variable(tf.constant(0.0, shape = [4096]))
local1 = tf.nn.relu(tf.matmul(reshape, weight1) + bias1, name = scope)
parameters += [weight1, bias1]
# fcn2
# tf.name_scope是用来命名Variable的,print(parameters)可以看到命名
with tf.name_scope('fcn2') as scope:
weight2 = tf.Variable(tf.truncated_normal([4096, 4096], stddev = 1e-1))
bias2 = tf.Variable(tf.constant(0.0, shape = [4096]))
local2 = tf.nn.relu(tf.matmul(local1, weight2) + bias2, name = scope)
parameters += [weight2, bias2]
# fcn3
# tf.name_scope是用来命名Variable的,print(parameters)可以看到命名
with tf.name_scope('fcn3') as scope:
weight3 = tf.Variable(tf.truncated_normal([4096, 1000], stddev = 1e-1))
bias3 = tf.Variable(tf.constant(0.0, shape = [1000]))
local3 = tf.matmul(local2, weight3) + bias3 # 最后一层,不需要进行relu
parameters += [weight2, bias2]
# print('看看local3: ',local3,'看看pool5: ',pool5)
# print('看parameters: ', parameters)
return local3, parameters
# 定义函数来计算每个batch经过Alex-nex的时间
def time_tensorflow_run(session, target, info_string):
num_steps_burn_in = 10 # 预热轮数,头几次会涉及显存加载、cache命中等问题,所以可以跳过
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)
duration = time.time() - start_time
# 超过预热轮数,才开始记录耗时
if i >= num_steps_burn_in:
# 10个 batch才打印一次,
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
#
mean_dur = total_duration / num_batches
var_dur = total_duration_squared / num_batches - mean_dur * mean_dur
std_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():
# tf.Graph.as_default() 的上下文管理器( context manager),它能够在这个上下文里面覆盖默认的图
# with tf.Graph().as_default():
# 生成一个batch的图片 [32,224,224,3]
image_size = 224
images = tf.Variable(tf.random_normal(
[batch_size, image_size,image_size,3],
dtype = tf.float32, stddev = 1e-1))
local3, parameters = inference(images)
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
time_tensorflow_run(sess, local3, "Forward")
objective = tf.nn.l2_loss(local3)
grad = tf.gradients(objective, parameters)
time_tensorflow_run(sess, grad, "Forward-backward")
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()能够在这个上下文里面覆盖默认的图,测试了一下 不用这个也可以,但是用上好点,可能是避免冲突吧~
【TensorFlow-windows】(六) CNN之Alex-net的测试的更多相关文章
- 基于Tensorflow + Opencv 实现CNN自定义图像分类
摘要:本篇文章主要通过Tensorflow+Opencv实现CNN自定义图像分类案例,它能解决我们现实论文或实践中的图像分类问题,并与机器学习的图像分类算法进行对比实验. 本文分享自华为云社区< ...
- tensorflow windows
conda create -n py35 python=3.5 activate py35 pip install --ignore-installed --upgrade https://stora ...
- CNN tensorflow text classification CNN文本分类的例子
from:http://deeplearning.lipingyang.org/tensorflow-examples-text/ TensorFlow examples (text-based) T ...
- Tensorflow object detection API(1)---环境搭建与测试
参考: https://blog.csdn.net/dy_guox/article/details/79081499 https://blog.csdn.net/u010103202/article/ ...
- tensorFlow(六)应用-基于CNN破解验证码
TensorFlow基础见前博客 简介 传统的验证码识别算法一般需要把验证码分割为单个字符,然后逐个识别.本教程将验证码识别问题转化为分类的问题,实现对验证码进行整体识别. 步骤简介 本教程一共分为四 ...
- 【深度学习系列】用PaddlePaddle和Tensorflow实现经典CNN网络AlexNet
上周我们用PaddlePaddle和Tensorflow实现了图像分类,分别用自己手写的一个简单的CNN网络simple_cnn和LeNet-5的CNN网络识别cifar-10数据集.在上周的实验表现 ...
- TensorFlow Windows 安装
欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 本系列教程将手把手带您从零开始学习Tensorflow,并最终通过 ...
- 写个神经网络,让她认得我`(๑•ᴗ•๑)(Tensorflow,opencv,dlib,cnn,人脸识别)
训练一个神经网络 能让她认得我 阅读原文 这段时间正在学习tensorflow的卷积神经网络部分,为了对卷积神经网络能够有一个更深的了解,自己动手实现一个例程是比较好的方式,所以就选了一个这样比较有点 ...
- Tensorflow实践:CNN实现MNIST手写识别模型
前言 本文假设大家对CNN.softmax原理已经比较熟悉,着重点在于使用Tensorflow对CNN的简单实践上.所以不会对算法进行详细介绍,主要针对代码中所使用的一些函数定义与用法进行解释,并给出 ...
随机推荐
- 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---52
以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:
- sublime text3中成功使用bootstrap3
在视图这里卡了挺久的,一直是自己在研究.其实自己有一个坏毛病,遇到问题,在网上搜集下找不到便寻求帮助(大多数是求助无效果,因为自己也没搞懂), 这时候自己就会懈怠一会,然后隔一两天心血起伏后便又继续干 ...
- hdu 1573(中国剩余定理)
X问题 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- Dialog和软键盘在屏幕上的并存问题:
最近做添加门店,门店昵称自动根据文字变化去搜索后台数据,但是一搜索软键盘就关闭了,感觉用户体验不太好.一开始根本不知道啥问题,找了半天才发现是网络请求dialog加载导致软件盘隐藏的,后面直接把dia ...
- Cryptography I 学习笔记 --- 认证加密
1. 认证加密,Alice与Bob共享一个密钥k,Alice可以发送密文E给Bob,Bob可以确定接收到的E一定是拥有密钥k的Alice产生的.而不是攻击者随便产生的. 2. 认证加密必须能抵挡住选择 ...
- 安全性测试入门 (四):Session Hijacking 用户会话劫持的攻击和防御
本篇继续对于安全性测试话题,结合DVWA进行研习. Session Hijacking用户会话劫持 1. Session和Cookies 这篇严格来说是用户会话劫持诸多情况中的一种,通过会话标识规则来 ...
- 洛谷——P1713 麦当劳叔叔的难题
P1713 麦当劳叔叔的难题 题目描述 话说我们铭铭小朋友成功的回答了爸爸的问题,自然少不了要去索要些奖励,抠门的爸爸一看报纸,嘿,门口的麦当劳在搞活动,还有免费午餐哦,不过前提条件:得正确回答麦当劳 ...
- SQLite中使用全文搜索FTS
SQLite中使用全文搜索FTS SQLite支持全文搜索.通过全文搜索功能,可以方便用户快速进行查找.在iOS中,GRDB.FMDB等SQLite框架均支持FTS技术,如FTS3.FTS4等.各 ...
- ios iPhone 如何将应用程序名称本地化
iPhone的应用程序名称也可以本地化,可以按照以下步骤来实施: 1. 修改项目目录下的’ -info.plist’文件名 将’ -info.plist’ 修改为 Info.plist 2. 将Inf ...
- SuperIndicator 一个专用打造轮播的类库
Github地址:https://github.com/hejunlin2013/SuperIndicator,欢迎fork,star.著名Android-Universal-Image-Loader ...