TensorFlow学习笔记(一)入门

一、 TensorFlow是什么?

是谷歌开源的机器学习实现框架,本文从Python语言来理解学习Tensorflow以及机器学习的知识。

TensorFlow的API主要分两个层次,核心层和基于核心层的高级API。核心层面向机器学习的研究人员,以及对模型控制精细的相关人员。高级API使用和学习相对容易,简化重复性任务,使不同的用户之间保持一致性。

高级API,如tf.contrib.learn可以帮助管理数据集data set,估计量estimators,训练training,推理inference

注意,一些高级API的方法名中包含contrib,意味着这些API依然处于开发过程中,这些方法在后续的TensorFlow版本中可能改变或者不再使用

这篇教程从核心层开始,后边会提到如何使用tf.contrib.learn实现模型。了解核心层,在使用高级API的时候知道程序是如何工作的。

1. 张量Tensors

数据的核心单元,一个tensor是一个包含任意维度的数组,张量的阶Tensor' rank是数组的维度,如下:

3 # 0阶张量,一个标量scalar with shape[]
[1. ,2., 3.] # 1阶张量; 一个向量vector with shape [3]
[[1., 2., 3.], [4., 5., 6.]] #  2阶 张量; 一个矩阵matrix with shape [2, 3]
[[[1., 2., 3.]], [[7., 8., 9.]]] #  3阶 张量tensor with shape [2, 1, 3]
2 是指[[1., 2., 3.]] 和 [[7., 8., 9.]]

1 是指[[1., 2., 3.]] 中有1个 [1., 2., 3.]

3 是指 [1., 2., 3.]中有3个:1., 2., 3.

二、 核心层TensorFlow Core学习

1. 引入TensorFlow

典型的引入语句:import tensorflow as tf

该语句是tensorflow的所有类,方法,符号的入口

2. 计算图Computational Graph

Tensorflow编程包含两个步骤:

1.构造计算图

2.运行计算图

计算图是什么?计算图是一系列的计算操作抽象为图中的节点。

构造一个简单的计算图:每个节点将0或多个tensor作为输入,输出一个tensor。一种类型的节点是常量节点constant,就如同tensorflow中的常数,它有0个输入,输出一个值。

构建两个浮点型tensor:node1和node2

[python]  view plain  copy
  1. node1 = tf.constant(3.0, tf.float32)  
  2. node2 = tf.constant(4.0# also tf.float32 implicitly  
  3. print(node1, node2)  

输出结果:

[python]  view plain  copy
  1. Tensor("Const:0", shape=(), dtype=float32) Tensor("Const_1:0", shape=(), dtype=float32)  
需要说明,打印结果并不是我们期待的3.0 , 4.0,因为这是打印的节点(属于计算操作),当评估运行之后,才是我们期待的值。

评估一个节点,必须在一个会话Session中运行计算图,会话封装了Tensorflow运行时的状态和控制

接下来创建一个Session会话对象,调用run方法,运行计算图,去评估node1和node2

[python]  view plain  copy
  1. sess=tf.Session()  
  2. print(sess.run([node1,node2]))  
输出结果:

[python]  view plain  copy
  1. [3.04.0]  
可以使用计算操作将多个节点组合,构建更复杂的计算,例如将两个常量节点相加,产生一个新的计算图:

[python]  view plain  copy
  1. node3 = tf.add(node1, node2)  
  2. print("node3: ", node3)  
  3. print("sess.run(node3): ",sess.run(node3))  
输出结果:

[python]  view plain  copy
  1. node3: Tensor("Add:0", shape=(), dtype=float32)  
  2. sess.run(node3): 7.0  
Tensorflow提供了一个名为 TensorBoard 的部分,可以以图片的方式展示计算图。


这个计算图不是特别有趣,因为它产生的是一个常量结果。

计算图可以使用占位符placeholder参数化的从外部输入数据,placeholder的作用是在稍后提供一个值

[python]  view plain  copy
  1. # 构造计算图  
  2. a=tf.placeholder(tf.float32)  
  3. b=tf.placeholder(tf.float32)  
  4. adder_node=a+b  
  5. #运行计算图  
  6. print("adder_node:",adder_node)  
  7. print(sess.run(adder_node,{a:3,b:4.5}))  
  8. print(sess.run(adder_node,{a:[1,3],b:[2,4]}))  

输出结果:

[python]  view plain  copy
  1. adder_node: Tensor("add:0", dtype=float32)  
  2. 7.5  
  3. 3.  7.]  
我们可以添加一个操作,使计算图更加复杂:

[python]  view plain  copy
  1. add_and_triple=adder_node * 3  
  2. print("add_and_triple:",add_and_triple)  
  3. print("sess run result:",sess.run(add_and_triple,{a:3,b:4.5}))  
输出结果:

[python]  view plain  copy
  1. add_and_triple: Tensor("mul:0", dtype=float32)  
  2. sess run result: 22.5  

在机器学习中,需要模型可以任意输入,为了模型具有可训练能力,需要修正计算图,使对于同样的输入得到新的输出。变量Variable允许我们为计算图添加训练参数。

构造一个变量,需要提供类型和初始值:

[python]  view plain  copy
  1. W=tf.Variable([.3],tf.float32)  
  2. b=tf.Variable([-.3],tf.float32)  
  3. x=tf.placeholder(tf.float32)  
  4. linear_model=W*x+b  
常量节点在调用tf.constant时就被初始化,而变量在调用tf.Variable时并不初始化,必须显性的执行如下操作:

[python]  view plain  copy
  1. init = tf.global_variables_initializer()  
  2. sess.run(init)  
意识到init对象是Tensorflow子图初始化所有全局变量的句柄是重要的,在调用sess.run(init)方法之前,所有变量都是未初始化的。

因为x是一个占位符,我们可以指定几个值来评估linear_model模型(训练)

运行计算图:

[python]  view plain  copy
  1. print("linear_model:",linear_model)  
  2. print(sess.run(linear_model,{x:[1,2,3,4]}))  
得到输出:

[python]  view plain  copy
  1. linear_model: Tensor("add_1:0", dtype=float32)  
  2. 0.          0.30000001  0.60000002  0.90000004]  

我们创建了一个模型,但是不知道这个模型的效果怎么样,基于训练数据来评估模型,还需要一个placeholder y 来提供期望值,我们需要一个损失函数loss function

损失函数测量当前模型与真实数据之间的差距,对于线性模型,我们使用标准损失函数,求模型预测结果与实际数据之间差值的平方和sum the squares of the deltas

linear_model - y 构造了一个向量,对应每个元素的差值,我们调用 tf.square 求平方,使用 tf.reduce_sum 求和所有的平方差为一个标量scalar

[python]  view plain  copy
  1. y=tf.placeholder(tf.float32)  
  2. squared_deltas=tf.square(linear_model-y)  
  3. loss=tf.reduce_sum(squared_deltas)  
  4. print("loss:",loss)  
  5. print(sess.run(loss,{x:[1,2,3,4],y:[0,-1,-2,-3]}))  
输出结果:

[python]  view plain  copy
  1. loss: Tensor("Sum:0", dtype=float32)  
  2. 23.66  
平方差为23.66

我们可以通过手动的方式将参数W和b置为W=-1,b=1,使模型最优,即损失函数最小。初始化后的变量可以通过tf.assign来更改,tf.assign后需要tf.run生效

[python]  view plain  copy
  1. fixW=tf.assign(W,[-1.])  
  2. fixb=tf.assign(b,[1.])  
  3. sess.run([fixW,fixb])  
  4. print("fix loss:",sess.run(loss,{x:[1,2,3,4],y:[0,-1,-2,-3]}))  
输出结果:

[python]  view plain  copy
  1. fix loss: 0.0  
我们猜想最优的W和b值,但是在机器学习中,就是自动的寻找这些最优的模型参数。下节介绍》》

三、 API  tf. train 

Tensorflow提供了优化器Optimizer慢慢改变每个变量来最小化损失函数。最简单的Optimizer是梯度下降gradient descent,它根据损失函数相对于该变量的导数大小来修改参数值,一般来讲,手动计算导数是乏味且易出错的,Tensorflow可以使用方法tf.gradients自动的为给定模型计算导数。优化器通常做这个工作。

[python]  view plain  copy
  1. optimizer=tf.train.GradientDescentOptimizer(0.01)  
  2. train=optimizer.minimize(loss)  
  3. print("train:\n",trian)  
  4. sess.run(init)#重置变量到初始化值  
  5. for i in range(1000):  
  6.     sess.run(train,{x:[1,2,3,4],y:[0,-1,-2,-3]})  
  7. print(sess.run([W,b]))  
输出结果:

[python]  view plain  copy
  1. train:  
  2.  name: "GradientDescent"  
  3. op: "NoOp"  
  4. [array([-0.9999969], dtype=float32), array([ 0.99999082], dtype=float32)]  
到此,我们实现了一次真实的机器学习,尽管我们只实现的是简单的线下回归,不需要多少Tensorflow core代码,然而复杂的模型和方法输入数据会需要更多的代码量,因此Tensorflow对于一般的模式、结构和功能提供了高级别的抽象。我们在下一章节学习。

完整的代码:

[python]  view plain  copy
  1. import tensorflow as tf  
  2. # NumPy is often used to load, manipulate and preprocess data.  
  3. import numpy as np  
  4. node1 = tf.constant(3.0,tf.float32)  
  5. node2 = tf.constant(4.0)  
  6. print(node1,node2)  
  7. sess=tf.Session()  
  8. print(sess.run([node1,node2]))  
  9. node3=tf.add(node1,node2)  
  10. print("node3:",node3)  
  11. print("sess.run(node3):",sess.run(node3))  
  12. # 构造计算图  
  13. a=tf.placeholder(tf.float32)  
  14. b=tf.placeholder(tf.float32)  
  15. adder_node=a+b  
  16. #运行计算图  
  17. print("adder_node:",adder_node)  
  18. print(sess.run(adder_node,{a:3,b:4.5}))  
  19. print(sess.run(adder_node,{a:[1,3],b:[2,4]}))  
  20. add_and_triple=adder_node * 3  
  21. print("add_and_triple:",add_and_triple)  
  22. print("sess run result:",sess.run(add_and_triple,{a:3,b:4.5}))  
  23.   
  24. W=tf.Variable([.3],tf.float32)  
  25. b=tf.Variable([-.3],tf.float32)  
  26. x=tf.placeholder(tf.float32)  
  27. linear_model=W*x+b  
  28. init = tf.global_variables_initializer()  
  29. sess.run(init)  
  30. print("linear_model:",linear_model)  
  31. print(sess.run(linear_model,{x:[1,2,3,4]}))  
  32.   
  33. y=tf.placeholder(tf.float32)  
  34. squared_deltas=tf.square(linear_model-y)  
  35. loss=tf.reduce_sum(squared_deltas)  
  36. print("loss:",loss)  
  37. print(sess.run(loss,{x:[1,2,3,4],y:[0,-1,-2,-3]}))  
  38.   
  39. fixW=tf.assign(W,[-1.])  
  40. fixb=tf.assign(b,[1.])  
  41. sess.run([fixW,fixb])  
  42. print("fix loss:",sess.run(loss,{x:[1,2,3,4],y:[0,-1,-2,-3]}))  
  43.   
  44. optimizer=tf.train.GradientDescentOptimizer(0.01)  
  45. train=optimizer.minimize(loss)  
  46. print("train:\n",train)  
  47. sess.run(init)#重置变量到初始化值  
  48. for i in range(1000):  
  49.     sess.run(train,{x:[1,2,3,4],y:[0,-1,-2,-3]})  
  50.   
  51. curr_W, curr_b, curr_loss  = sess.run([W, b, loss],{x:[1,2,3,4],y:[0,-1,-2,-3]})  
  52. print("W: %s b: %s loss: %s"%(curr_W, curr_b, curr_loss))  

四、 API tf. contrib. learn

tf.contrib.learn是Tensorflow高级别的库,简化机器学习:

1.运行训练循环

2.运行评估循环

3.管理数据集

4.管理feeding

tf.contrib.learn定义了许多常见的模型

1.基本使用

使用tf.contrib.learn简化线性回归:

numpy是开源的数值计算扩展,可以用来存储和处理大型矩阵。

声明特征列表list of features:我们在此使用一个real-valued列,另外还有其他复杂有用的列类型

[python]  view plain  copy
  1. import tensorflow as tf  
  2. import numpy as np  
  3.   
  4. features=[tf.contrib.layers.real_valued_column("x",dimension=1)]  
  5. print("features:",features)  
输出:

[python]  view plain  copy
  1. features: [_RealValuedColumn(column_name='x', dimension=1, default_value=None, dtype=tf.float32, normalizer=None)]  
声明 估计器estimator ,estimator负责调用训练和评估。它有很多预先定的类型,如 线性回归linear regression, 逻辑回归logistic regerssion, 线性分类linear classification, 逻辑分类logistic classification, 以及许多神经网络分类器,回归器neural network classifiers and regressors

这里做线性回归,指定特征列表:

[python]  view plain  copy
  1. estimator=tf.contrib.learn.LinearRegressor(feature_columns=features)  
  2. print("estimator:",estimator)  
输出结果:

[python]  view plain  copy
  1. estimator: LinearRegressor(params={'head': <tensorflow.contrib.learn.python.learn.estimators.head._RegressionHead object at 0x7f6c88bcb208>, 'feature_columns': [_RealValuedColumn(column_name='x', dimension=1, default_value=None, dtype=tf.float32, normalizer=None)], 'optimizer'None'gradient_clip_norm'None'joint_weights'False})  
Tensorflow提供了很多方法读取和设置数据集,在这里我们使用 numpy_input_fn ,为该方法指定数据的 批次数目num_epochs (how many batches of data ),以及每批次的大小 batch_size

[python]  view plain  copy
  1. x=np.array([1.,2.,3.,4.])  
  2. y=np.array([0.,-1.,-2.,-3.])  
  3. input_fn=tf.contrib.learn.io.numpy_input_fn({"x":x},y,batch_size=4,num_epochs=1000)  
  4. print("input_fn:",input_fn)  
输出结果:

[python]  view plain  copy
  1. input_fn: <function numpy_input_fn.<locals>.input_fn at 0x7fb572e21e18>  
我们可以调用 fit 方法进行1000次训练步骤,并且传递训练数据集:

[python]  view plain  copy
  1. estimator.fit(input_fn=input_fn,steps=1000)  
评价模型,在真实例子中,我们会将验证和测试数据分离,以免 过度拟合overftting
[python]  view plain  copy
  1. print(estimator.evaluate(input_fn=input_fn))  
输出结果:

[python]  view plain  copy
  1. {'loss'1.8005665e-07'global_step'1000}  
完整代码:

[python]  view plain  copy
  1. import tensorflow as tf  
  2. import numpy as np  
  3.   
  4. features=[tf.contrib.layers.real_valued_column("x",dimension=1)]  
  5. print("features:",features)  
  6. estimator=tf.contrib.learn.LinearRegressor(feature_columns=features)  
  7. print("estimator:",estimator)  
  8. x=np.array([1.,2.,3.,4.])  
  9. y=np.array([0.,-1.,-2.,-3.])  
  10. input_fn=tf.contrib.learn.io.numpy_input_fn({"x":x},y,batch_size=4,num_epochs=1000)  
  11. print("input_fn:",input_fn)  
  12. estimator.fit(input_fn=input_fn,steps=1000)  
  13. print(">>>>>>>>>>")  
  14. res=estimator.evaluate(input_fn=input_fn)  
  15. print(res)  

2. 定制化模型

tf.contrib.learn不限定用户使用预先定义的模型,假设我们创建一个Tensorflow中不存在的新模型,我们仍然可以保留tf.contrib.learn中的数据集、feeding、训练等

接下来,我们将实现类比于线性回归器LinearRegressor的自定义的线性回归模型。

使用tf.contrib.learn定制化模型,需要使用到类tf.contrib.learn.Estimator, 线性回归器tf.contrib.learn.LinearRegerssor就是tf.contrib.learn.Estimator的子类

通过为Estimator指定model_fn方法,控制模型如何评估,训练,损失等

[python]  view plain  copy
  1. import tensorflow as tf  
  2. import numpy as np  
  3. def model(features, labels, mode):  
  4.     # 构建线程模型以及预测值  
  5.     W=tf.get_variable("W",[1],dtype=tf.float64)  
  6.     b=tf.get_variable("b",[1],dtype=tf.float64)  
  7.     y=W*features['x']+b  
  8.     # 损失函数  
  9.     loss=tf.reduce_sum(tf.square(y - labels))  
  10.     # 训练子图  
  11.     global_step=tf.train.get_global_step()  
  12.     optimizer=tf.train.GradientDescentOptimizer(0.01)  
  13.     train=tf.group(optimizer.minimize(loss),tf.assign_add(global_step,1))  
  14.     # ModelFnOps方法将我们构造的子图连接到相应的功能  
  15.     return tf.contrib.learn.ModelFnOps(  
  16.         mode=mode,predictions=y,loss=loss,train_op=train)  
  17.   
  18. estimator=tf.contrib.learn.Estimator(model_fn=model)  
  19. # 构建数据集  
  20. x=np.array([1.,2.,3.,4.])  
  21. y=np.array([0.,-1.,-2.,-3.])  
  22. input_fn=tf.contrib.learn.io.numpy_input_fn({"x":x},y,4,num_epochs=1000)  
  23. # 训练  
  24. estimator.fit(input_fn=input_fn,steps=1000)  
  25. # 评价模型  
  26. print(estimator.evaluate(input_fn=input_fn,steps=10))  
说明,model方法中的内容与前边使用底层api的收到模型很相似。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值