【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的简单实践上.所以不会对算法进行详细介绍,主要针对代码中所使用的一些函数定义与用法进行解释,并给出 ...
随机推荐
- [LeetCode] Minimum Depth of Binary Tree 二叉树最小深度
Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shor ...
- AtCoder Regular Contest 090 F - Number of Digits
题目链接 Description For a positive integer \(n\), let us define \(f(n)\) as the number of digits in bas ...
- [Json] 1 - 数据格式(转)
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.JSON采用完全独立于语言的文本格式,这些特性使JSON成为理想的数据交换语言.易于人阅读和编写,同时也易 ...
- CSU 1777: 大还是小?【模拟/后导0】
293419 roniking 1777 Accepted 2032 0 C++ 2000 2018-04-03 19:21:25 Description 输入两个实数,判断第一个数大,第二个数大还是 ...
- Topcoder SRM 144 DIV 1
BinaryCode 模拟 题意是:定义串P,Q,其中Q[i]=P[i-1]+P[i]+P[i+1],边界取0,并且P必须是01串.现在给你Q,让你求出P. 做法是:枚举第一位是1还是0,然后就可以推 ...
- TCO 2015 Round 2A DIV1
ModModMod 傻逼数论 题意: 这是一道卖萌的题..给你一个取模序列$m$,令$f(x)=(\cdots (x\ mod\ m[0])\ mod m[1])\mod m[2]\cdots $,问 ...
- 屏蔽国内广告的hosts
源码:https://github.com/easonjim/blackhosts bug提交:https://github.com/easonjim/blackhosts/issues
- delphi中如何将string类型的字符串数据转化成byte[]字节数组类型的数据
var S:String; P:PChar; B:array of Byte;begin S:='Hello'; SetLength(B,Length(S)+1); P:=PChar(S) ...
- C# 计算一串字符串算法
工作中遇到一个小问题,就是要做一个类似excel那种的公式的东西,就是A0+A1*B0那样的公式,然后得出结果. 首先,分析. 这不是计算器,计算器要比这个简易,计算器是所按即所得,即你点击+-之类的 ...
- quick-cocos2d 设置横屏
quick cocos2d新建项目,在xcode中 起模拟器,默认的是竖屏,我想做一个横屏的游戏,前面已经说了 选中你的项目,在General这个标签内,Deoployment info的这个分组,有 ...