目录
为什么是tensorflow:
现在玩机器学习的人大概没有不知道tensorflow大名的吧,但是与caffe,keras相比,这位“仁兄”确实不怎么友好。即是这样,在众多开源的深度学习框架当中,tensorflow也是一枝独秀。Google的大名和号召力当然是其中一方面原因,但是,tensorflow也具有众多的优点。比如,网络结构代码十分简洁,分布式深度学习算法的执行效率等等。作为一个“菜鸡”来看,最吸引我的地方就是tensorflow对于python接口的支持十分良好。毕竟没有一个数据挖掘工作是单单定义网络就可以完成的。Python所拥有的Numpy, Scipy, Pandas等组建能大大提升工作的效率。
出来以上的优点以外,tensorflow对于网络结构的可视化和训练过程的可视化也有非常优秀的地方,下面是两个例子,第一个是tensorflow的tensorboard工具,第二个是tensorflow的playground。
关于tensorflowplayground可以参考网页:http://playground.tensorflow.org/
说说目的:
写这一系列博文的目的当然不是为了将深度学习,毕竟这是一个太宽泛,我的知识水平难以完全驾驭的领域。我只是提供一个途径,一种入门的方式。在最初接触一个领域的知识的时候如果单纯看论文会非常枯燥,而且顾前不顾后,狗熊掰棒子。但是如果能从一开始就动手操作,再看论文,做理论推导,整个过程会像揭秘一样有趣。我的目的就是把学习tensorflow这个“迷”给大家呈现出来。怎么去理解,分析,就看个人的功夫了。
这一系列的文章会以一种:代码段->代码解释->运行结果->调试心得的形式展现我一个月以来的学习成果。也算是一种笔记。但是,鲜有涉及原理的部分。或者以后的文章会讲到原理。但是作为一篇技术入门文章,我力图使文章尽量简洁,操作性强,而不是全面。
其中的代码大部分都是我从《Tensorflow实战Google深度学习框架》,《Tensorflow实战》还有Tensorflow的自带例子里面修改过来的。每一段都在自己的计算机上(ubuntu14.04+tensorflow 0.8.0)上实验过。如果复制代码而不能运行多半是版本的问题,或者是有些路径的问题。希望大家多加谅解。
文章结构
文章将会涉及以下内容:
- mnist手写数字识别
- 从mnist例子看tensorflow基础知识
- 来写个Lenet5
- 经典卷积神经网络之AlexNet
- 经典卷积神经网络之VGG
- 吓死人的Inception Net以及迁移学习
- Resnet和没学会的tf.contrib.slim模块
- Word2Vec探秘
- 循环神经网络到底是什么?
- 深度强化学习初探
mnist手写数字识别
为了让第一篇文章不要这么水过去,就在这一篇文章当中介绍这个系列的第一个内容,mnist手写数字识别。这几乎是每一个学习神经网络的人遇到的第一个例子了。我不想介绍原理,直接从输入输出和网络结果来介绍吧:
- 输入:
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
这两行代码是利用tensorflow里面的python代码自动下载mnist数据集。其中,one_hot = True 是将图片的标签,也就是0-9这九个数字向量化,比如:4 就变成:
[0,0,0,0,1,0,0,0,0,0]。这样才能可网络的输出,也就是一个长度为10的向量匹配。
现在我们观察一下数据集:
代码中主要用到的是mnist.train, mnist.validation, mnist.test部分,分别用于训练,训练时验证和最后检验模型。mnist.train又分为images和labels部分(其他当然也一样)。图片部分是将一幅 28×28 的图片拉伸成784长,labels部分就是向量化的标签。
展示一张图片:
import numpy as np
import matplotlib.pyplot as plt
image = np.reshape(mnist.train.images[1],[28,28])
plt.imshow(image)
plt.show()
- 定义网络结构:
import tensorflow as tf
#定义输入输出节点
INPUT_NODE = 784
OUTPUT_NODE = 10
#中间层节点
LAYER1_NODE = 500
#定义变量生成函数
def get_weight_variable(shape,regularizer):
#tf.get_variable生成tf变量
weights = tf.get_variable("weights",shape,
initializer=tf.truncated_normal_initializer(stddev=0.1))
#如果正则化,将正则化因子加入损失函数
if regularizer !=None:
tf.add_to_collection("losses",regularizer(weights))
return weights
#定义网络结构
def inference(input_tensor,regularizer):
#定义变量作用域
with tf.variable_scope("layer1"):
#定义网络权重
weights = get_weight_variable([INPUT_NODE,LAYER1_NODE],regularizer)
#定义偏置值
biases = tf.get_variable("biases",[LAYER1_NODE],initializer=tf.constant_initializer(0.0))
#第一层输出
layer1 = tf.nn.relu(tf.matmul(input_tensor,weights)+biases)
#第二层类似
with tf.variable_scope("layer2"):
weights = get_weight_variable([LAYER1_NODE,OUTPUT_NODE],regularizer)
biases = tf.get_variable("biases",[OUTPUT_NODE],initializer=tf.constant_initializer(0.0))
layer2 = tf.matmul(layer1,weights)+biases
return layer2
- 训练网络mnist_train.py
import tensorflow as tf
import mnist_inference
from tensorflow.examples.tutorials.mnist import input_data
#set network parameters
BATCH_SIZE = 100
LEARNING_RATE_BASE = 0.8
LEARNING_RATE_DECAY = 0.99
REGULATION_RATE = 0.0001
TRAINING_STEPS = 30000
MOVING_AVERAGE_DECAY = 0.99
def train(mnist):
#定义输入输出的容器
x = tf.placeholder(tf.float32,[None,mnist_inference.INPUT_NODE],name='x-input')
y_ = tf.placeholder(tf.float32,[None,mnist_inference.OUTPUT_NODE],name='y-input')
#定义正则化方法
regularizer = tf.contrib.layers.l2_regularizer(REGULATION_RATE)
#定义输出的运算
y = mnist_inference.inference(x,regularizer)
#定义滑动平均模型
global_step = tf.Variable(0.0,trainable=False)
#训练轮数不可训练
variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step)
#滑动平均
variable_averages_op = variable_averages.apply( tf.trainable_variables())#滑动平均运算operator
#定义交叉熵
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(y,tf.argmax(y_,1))
cross_entropy_mean = tf.reduce_mean(cross_entropy)
loss = tf.add_n(tf.get_collection('losses')) + cross_entropy_mean #损失函数是交叉熵和正则化之和
#定义学习率和训练(梯度下降法)
learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE,global_step, mnist.train.num_examples / BATCH_SIZE, LEARNING_RATE_DECAY)
train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step = global_step)
#定义训练operator,同步梯度下降和滑动平均
with tf.control_dependencies([train_step,variable_averages_op]):
train_op = tf.no_op(name='train')
#定义存储函数
saver = tf.train.Saver()
#开始一个会话
with tf.Session() as sess:
#初始化所有变量
tf.initialize_all_variables().run()
for i in range(TRAINING_STEPS):
#获取每一个batch的数据
xs, ys = mnist.train.next_batch(BATCH_SIZE)
#训练,得到损失和步骤,输入为xs, ys
_,loss_value,step = sess.run([train_op,loss,global_step],feed_dict={x:xs,y_:ys})
if i % 1000 ==0:
print("After %d training step(s), loss on training batch is %g" % (step,loss_value))
#存储
saver.save(sess,"model/model_mnist.ckpt",global_step)
def main(argv=None):
#read data set
mnist = input_data.read_data_sets("tmp/data",one_hot=True)
train(mnist)
if __name__ == '__main__':
tf.app.run()
训练结果:
-验证:
import time
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import mnist_inference
import mnist_train
#每10秒验证一次
EVAL_INTERVAL_SECS = 10
def evalute(mnist):
with tf.Graph().as_default() as g:
#同样的输入输出
x = tf.placeholder(tf.float32,[None,mnist_inference.INPUT_NODE],name='x-input')
y_ = tf.placeholder(tf.float32,[None,mnist_inference.OUTPUT_NODE],name='y-input')
#验证集
validate_feed = {x:mnist.validation.images,y_:mnist.validation.labels}
y = mnist_inference.inference(x,None)
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
#通过重命名的方式加载模型,这样就可以加载mnist_inferece.py中的向前传播模型
variable_averages = tf.train.ExponentialMovingAverage(mnist_train.MOVING_AVERAGE_DECAY)
variable_to_restore = variable_averages.variables_to_restore()
saver = tf.train.Saver(variable_to_restore)
with tf.Session() as sess:
#读取模型,计算存储了几个模型
ckpt = tf.train.get_checkpoint_state(
"model/")
length = len(ckpt.all_model_checkpoint_paths)
for i in range(length):
#读取模型
saver.restore(sess,ckpt.all_model_checkpoint_paths[i])
#读取时哪一个步骤的
global_step = ckpt.all_model_checkpoint_paths[i].split('/')[-1].split('/')[-1]
accuracy_score = sess.run(accuracy,feed_dict=validate_feed)
print ("After %s training step(s),validation accuracy=%g" % (global_step,accuracy_score))
time.sleep(EVAL_INTERVAL_SECS)
def main(argv=None):
mnist = input_data.readd sets("tmp/data",one_hot=True)
evalute(mnist)
if __name__ == '__main__':
tf.app.run()
结果: