TensorFlow Tutorial-1

1、Why TensorFlow?

网上有关介绍太多了,我就不多说了,这里主要注重使用。

Intro.PNG

github.PNG

2、Programing model

2.1.Big Idea

将数值的计算转化为图(computational graph),任何tensorflow的计算都是基于图的。

2.2 Graph Nodes

图中的结点是有输入和输出的操作(operations),input的数量可以任意,output只有一个。

2.3 Graph Edges

图的边是在结点见浮动的张量(tensors),tensors可以理解为n-维数组。

2.4 Advantages

使用flow graphs作为deep learning framework的优点是可以通过简单少量的operations来构建复杂模型,使梯度的计算容易很多。当你在编写比较大的模型时,自动微分将会帮助到你。

2.5 Another way to think it

每一个operation可以理解为在某一点可以执行的函数。

2. 6 举个详细使用的例子

下面这个图展示了只有一个隐藏层的神经网络在Tensorflow中的计算,我们以Relu作为激活函数。

Nodes.PNG

ReLu Function.PNG

  • W: 待训练的参数
  • X: input
  • b: bias

下面将介绍一下上图中出现的几个结点:

1、Variables:

W 和 b 参数作为TensorFlow中的Variables,在训练的过程中你需要调整这些参数,使得你的loss function最小,这些变量是有状态的结点,在图中多种的计算结点之间保持他们的状态,所谓保持状态就是指它们的值会被存下来,因此想要复原数据很容易,并且可以随时输出他们当前的值(current value),这些变量还有一些其他的features,可以在训练或者训练结束后持久化到disk中,因此可以允许不同的公司不同的组织去使用这些大型模型训练好的参数,并且默认进行梯度更新。

W 和 b这些变量也是operations。

2、Placeholders:

是一些在执行的过程中才会被赋值的结点,如果你网络的input 需要依赖一些其他外界的数据。

比如你不想用真实的值来计算。placeholders是你在训练过程中可以加入数据的地方。对于placeholders,我们不用对其进行任何初始化,我们只定义一个data type,并且赋值一个给定大小的tensor,我们的计算图就可以知道怎么去计算,甚至不用存储任何的数据。

3、Mathematical operations:

用于矩阵的乘法,加法,ReLu函数的计算。

4、废话少说,上代码!!! :

# 导入tensorflow包 import tensorflow as tf # 创建一个有100个值的vector,作为bias, 默认为0 b=tf.Variable(tf.zeros((100,))) # 创建并出示化权重,一个784*100 的矩阵,矩阵的初始值在-1到1之间 W=tf.Variable(tf.random_uniform((784,100),-1,1)) #为输入创建一个placeholder,不需要任何数据,只需要定义数据类型为一个32位浮点数, shape 为100*784 x=tf.placeholder(tf.float32,(100,784)) # tensorflow mathematical operations h=tf.nn.relu(tf.matmul(x,W)+b)

关于h我想说:和numpy中很像,就是调用了tensorflow mathematical operations,我们没有真的乘某个数值,而仅仅在图中创建了一个符号来表示他,所以你不能输出该值,因为x只是一个placeholder,没有任何真值。我们现在只为我们的model创建了一个骨架。

5、说好的图呢 :

看了半天,这不和numpy手撸一样吗,其实作为程序员我们只要心里有着种抽象的概念就好,底层确实是以这种结点来实现的,如果你想看到,可以调用

tf.get_default_graph().get_operations()

你将会看到如下内容:

Absta.PNG

6、怎么跑这个例子呢? :

目前为止,我们已经定义了一个graph,我们需要把这个graph部署到一个session中,一个session可以绑定到一个具体的执行环境中(CPU或者GPU)

接着刚才的代码,我们在后面补充三行:

import numpy as np import tensorflow as tf b=tf.Variable(tf.zeros((100,))) W=tf.Variable(tf.random_uniform((784,100),-1,1)) x=tf.placeholder(tf.float32,(100,784)) h=tf.nn.relu(tf.matmul(x,W)+b) #创建session对象,初始化相关的参数 sess=tf.Session() # initialize b 和 w sess.run(tf.initialize_all_variables()) # 第一个参数是图中结点的输出,第二个参数是给placeholder赋的值,是一个map,定义每个结点的具体值 sess.run(h,{x : np.random.random(100,784)})

更多的关于Session的使用方法:

#自己创建一个session,不使用默认的session,使用完记得关了 sess=tf.Session() sess=tf.run(train_step) sess.close() with tf.Session() as sess: #使用这个创建的session计算结果 sess.run(train_step) #不用close,with体帮我们进行资源的回收 #with体使用默认的 session sess=tf.Session() with sess.as_default(): print(train_step.eval()) #也是使用默认的session sess=tf.Session() print(train_step.eval(session=sess)) #定义一个可交互式的session,自动将会话注册为默认会话 sess=tf.InteractiveSession() train_step.eval() sess.close() #用自己的参数配置session config=tf.ConfigProto(allow_aoft_placement=True, log_device_placement=True) sess1=tf.InteractiveSession(config=config) sess2=tf.Session(config=config)

6、损失函数的创建 :

通过prediction 和 labels 创建loss node

# neural network的最后一步,用softmax做一个逻辑回归 prediction=tf.nn.softmax(...) label=tf.placeholder(tf.float32,[100,10]) # 损失函数,用label乘上logP在列上的值 cross_entropy=-tf.reduce_sum(label* tf.log(prediction),axis=1)

7、如何计算梯度?:

tf.train.GradientDescentOptimizer创建了一个Optimizer是TensorFlow中定义的一个抽象类,它的每个子类,可以作为一个特定的学习算法,默认是梯度下降。在我们的图上面加了一个optimization operation,当我们执行这个train_step方法时(sess.run(train_step,feed_dict={x: batch_x, label: batch_label})),将会应用所有的梯度到模型中的变量中。这是因为minimize函数做了两件事情,首先是计算cross_entropy的梯度,然后进行梯度更新。

# 梯度下降,learning rate 为0.5,minimize方法的参数是一个需要被梯度下降的结点。 train_step= tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

7、训练模型?:

sess=tf.Session() sess.run(tf.initialize_all_variables()) # 创建一个learning schedule, iterate 1000 次 for i in range(1000): batch_x, batch_label = data.next_batch() sess.run(train_step,feed_dict={x: batch_x, label: batch_label})

3、变量共享

当你在使用Tensorflow时,你想在一个地方初始化所有的变量,比如我想多次实例化我的graph或者我想在GPU集群上训练,我们需要共享变量。有以下两个解决方案:

其中一个方法是创建一个map,在需要使用的地方调用key获得value。但缺点是它大破了封装的思想。

TensorFlow的variable scope解决了这个问题,它为我们提供了一个提供了一个命名空间,避免了冲突。

with tf.variable_scope("hello world"): v=tf.get_variable("v",shape=[1]) # v.name== " hello world/v:0" with tf.variable_scope("hello world" reuse=True): v=tf.get_variable("v",shape=[1]) # 可以找到共享的变量v with tf.variable_scope("hello world" reuse=False): v=tf.get_variable("v",shape=[1]) # CRASH hello world/v:0 已经存在了

4、官方demo (Official Demo)

MNIST手写体识别

4、1 基于softmax逻辑回归

利用softmax regression,训练一个手写体分类:

from __future__ import absolute_import from __future__ import division from __future__ import print_function import gzip import os import tempfile import numpy from six.moves import urllib from six.moves import xrange # pylint: disable=redefined-builtin import tensorflow as tf from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) # 定义一个placeholder, x = tf.placeholder(tf.float32, [None, 784]) W = tf.Variable(tf.zeros([784, 10])) b = tf.Variable(tf.zeros([10])) y = tf.nn.softmax(tf.matmul(x, W) + b) #定义一个用于存储正确标示的占位符 y_=tf.placeholder("float",[None,10]) #交叉熵损失函数 cross_entropy=-tf.reduce_sum(y_*tf.log(y)) #梯度下降进行训练 train_step=tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy) init=tf.initialize_all_variables() sess=tf.Session()

sess.run(init) #随机梯度下降 for i in range(1000): batch_xs, batch_ys=mnist.train.next_batch(100) print(sess.run(train_step,feed_dict={x:batch_xs,y_:batch_ys})) correct_prediction=tf.equal(tf.argmax(y,1),tf.argmax(y_,1)) accuracy=tf.reduce_mean(tf.cast(correct_prediction,"float")) print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

4、2 基于CNN神经网络

# 利用CNN,训练一个手写体分类 """Functions for downloading and reading MNIST data.""" from __future__ import absolute_import from __future__ import division from __future__ import print_function import gzip import os import tempfile import numpy from six.moves import urllib from six.moves import xrange # pylint: disable=redefined-builtin import tensorflow as tf from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets from tensorflow.examples.tutorials.mnist import input_data # 将系统默认的session作ion sess = tf.InteractiveSession() mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) # 正确答案

y_ = tf.placeholder('float', [None, 10]) # 定义函数用于初始化权值,和bias def weight_initialize(shape): # 标准差为一,初始化权值 initial = tf.truncated_normal(shape, stddev=0.1) return tf.Variable(initial) def bias_variable(shape): initail = tf.constant(0.1, shape=shape) return tf.Variable(initail) x = tf.placeholder('float', [None, 784]) # 卷积 def conv2d(x, W): #tf.nn.conv2d提供了一个非常方便的函数来实现卷积层向前传播的算法,这个函数的第一个输入为 #当前层节点矩阵,这个矩阵是一个四维矩阵,后面的三个维度对应一个节点矩阵,第一个维度对应一个 #输入batch.比如在输入层,input[0,:,:,:]表示第一张图片,input[1,:,:,:]表示第张图片二,tf.nn.conv2d #第二个参数提供了卷积层的权重,第三个参数为步长,步长第一维,和最后一维固定是1,最后一个参数是填充方法 #SAME表示全0填充,VALID表示不添加 return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME') # 池化 def max_pool_2x2(x): #ksize提供了过滤器的大小为2*2 return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') # 卷积层第一层 W_conv1 = weight_initialize([5, 5, 1, 32]) b_conv1 = bias_variable([32]) x_image = tf.reshape(x, [-1, 28, 28, 1]) # 卷积层第一层的relu和池化 h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) h_pool1 = max_pool_2x2(h_conv1) # 5*5*32 # 卷积层第二层 W_conv2 = weight_initialize([5, 5, 32, 64]) b_conv2 = bias_variable([64]) # 卷积层第二层的relu和池化 h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) h_pool2 = max_pool_2x2(h_conv2) # 全连接层的weight和bias W_fc1 = weight_initialize([7 * 7 * 64, 1024]) b_fc1 = bias_variable([1024]) # output层 h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64]) h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1) # 使用dropout防止过拟合 # 过拟合概率 keep_prob = tf.placeholder("float") h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) # 1024个神经元*10个输出 W_fc2 = weight_initialize([1024, 10]) b_fc2 = bias_variable([10]) y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2)) # 定义一个损失函数 cross_entropy = -tf.reduce_sum(y_ * tf.log(y_conv)) train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy) correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction,"float")) # 初始化所有变量 sess.run(tf.initialize_all_variables()) for i in range(2000): batch = mnist.train.next_batch(50) if i % 100 == 0: train_accuracy = accuracy.eval(feed_dict={ x: batch[0], y_: batch[1], keep_prob: 1.0 }) print("step %d, train accuracy %g" % (i, train_accuracy)) train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: [0.5]}) print("test accuracy %g" % accuracy.eval(feed_dict={ x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))

训练结果如下:

result.png

5、 总结

  • TensorFlow 每个结点都对应着梯度操作
  • Computational graphy 很容易backwards每一个结点。
  • 这些都是自动完成的。
  • TensorFlow也把复杂的计算放在python之外完成,但是为了避免前面说的那些开销,它做了进一步完善。Tensorflow不单独地运行单一的复杂计算,而是让我们可以先用图描述一系列可交互的计算操作,然后全部一起在Python之外运行。

原文发布于微信公众号 - 人工智能LeadAI(atleadai)

原文发表时间:2017-10-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏决胜机器学习

机器学习(十八) ——SVM实战

机器学习(十八)——SVM实战 (原创内容,转载请注明来源,谢谢) 一、概述 本篇主要用python来实现SVM算法,并用SVM算法进行预测分类结果。对于SM...

3575
来自专栏码云1024

编程英语之KNN算法

1114
来自专栏Petrichor的专栏

tensorflow: 损失函数(Losses Functions) 探究

易得 l2_loss( t, name=None ) 等同于 output = sum(t ** 2) / 2

1551
来自专栏闪电gogogo的专栏

tensorflow

2911
来自专栏Python专栏

Python | 21行轻松搞定拼写检查器

链接:http://blog.csdn.net/Pwiling/article/details/50573650

1453
来自专栏程序生活

Leetcode-Easy 887. Projection Area of 3D Shapes

当时自己没有想到好办法,就是按部就班的分别求三个面的面积,注意求xy的面积的时候需要考虑grid[i][j]值是否为0

862
来自专栏每日一篇技术文章

OpenGL ES _ 着色器_纹理图像

玩过游戏的同学们,都知道在游戏人物身上穿的那个叫皮肤,专业点将那个就叫做纹理图像。GLSL 支持在顶点和片段着色器使用纹理图像。

1703
来自专栏利炳根的专栏

学习笔记CB013: TensorFlow、TensorBoard、seq2seq

tensorflow基于图结构深度学习框架,内部通过session实现图和计算内核交互。

4237
来自专栏量化投资与机器学习

【致敬周杰伦】基于TensorFlow让机器生成周董的歌词(附源码)

? 周杰伦 深深地 影响了我们 一代人 这句话 不足为过 前言 今日推文将介绍如何使用TensorFlow一步步来搭建一个序列建模的应用——机器创作歌词,训练...

1.3K5
来自专栏CDA数据分析师

教你一招 | Python实现无向图最短路径

一心想学习算法,很少去真正静下心来去研究,前几天趁着周末去了解了最短路径的资料,用python写了一个最短路径算法。算法是基于带权无向图去寻找两个点之间的最短路...

5145

扫码关注云+社区