您的位置:首页 > 编程语言 > Python开发

tensorflow学习笔记1——入门

2017-12-28 15:01 501 查看

一、 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

node1 = tf.constant(3.0, tf.float32)  
node2 = tf.constant(4.0) # also tf.float32 implicitly  
print(node1, node2)  

输出结果:

[python]
view plain
copy

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

sess=tf.Session()  
print(sess.run([node1,node2]))  

输出结果:

[python]
view plain
copy

[3.0, 4.0]  

可以使用计算操作将多个节点组合,构建更复杂的计算,例如将两个常量节点相加,产生一个新的计算图:

[python]
view plain
copy

node3 = tf.add(node1, node2)  
print("node3: ", node3)  
print("sess.run(node3): ",sess.run(node3))  

输出结果:

[python]
view plain
copy

node3: Tensor("Add:0", shape=(), dtype=float32)  
sess.run(node3): 7.0  

Tensorflow提供了一个名为TensorBoard的部分,可以以图片的方式展示计算图。

Tensorboard

点击打开链接

Tensorboard是tensorflow自带的可视化模块,网上关于它的资源很少,而且基本一上来就是默认你已经有很高的水平的那种,对新手十分不友好,我摸索了好久,才搞懂怎么把官网教程里的那张图显示出来:



python中运行的代码如下:

import tensorflow as tf

node1 = tf.constant(3.0,dtype=tf.float32)
node2 = tf.constant(4.0)
node3 = tf.add(node1, node2)

writer = tf.summary.FileWriter('D:/ten',tf.get_default_graph())
writer.close()
1
2
3
4
5
6
7
8
writer = tf.summary.FileWriter(‘D:/ten’, tf.get_default_graph())这句话生成了当前计算图的日志并保存在D:/ten。

然后命令行输入

C:\WINDOWS\system32>D:
D:\>tensorboard --logdir="ten"
1
2
然后打开浏览器访问http://localhost:6006就可以看到上图界面,推荐使用谷歌浏览器查看。

这里说一下我踩的一个坑,一定要先进D盘在选目录,不能直接

C:\WINDOWS\system32>tensorboard --logdir="D:\ten"
1

不然你看到的画面会是这样:


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

[python]
view plain
copy

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

输出结果:

[python]
view plain
copy

adder_node: Tensor("add:0", dtype=float32)  
7.5  
[ 3.  7.]  

我们可以添加一个操作,使计算图更加复杂:

[python]
view plain
copy

add_and_triple=adder_node * 3  
print("add_and_triple:",add_and_triple)  
print("sess run result:",sess.run(add_and_triple,{a:3,b:4.5}))  

输出结果:

[python]
view plain
copy

add_and_triple: Tensor("mul:0", dtype=float32)  
sess run result: 22.5  

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

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

[python]
view plain
copy

W=tf.Variable([.3],tf.float32)  
b=tf.Variable([-.3],tf.float32)  
x=tf.placeholder(tf.float32)  
linear_model=W*x+b  

常量节点在调用tf.constant时就被初始化,而变量在调用tf.Variable时并不初始化,必须显性的执行如下操作:

[python]
view plain
copy

init = tf.global_variables_initializer()  
sess.run(init)  

意识到init对象是Tensorflow子图初始化所有全局变量的句柄是重要的,在调用sess.run(init)方法之前,所有变量都是未初始化的。
因为x是一个占位符,我们可以指定几个值来评估linear_model模型(训练)

运行计算图:

[python]
view plain
copy

print("linear_model:",linear_model)  
print(sess.run(linear_model,{x:[1,2,3,4]}))  

得到输出:

[python]
view plain
copy

linear_model: Tensor("add_1:0", dtype=float32)  
[ 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

y=tf.placeholder(tf.float32)  
squared_deltas=tf.square(linear_model-y)  
loss=tf.reduce_sum(squared_deltas)  
print("loss:",loss)  
print(sess.run(loss,{x:[1,2,3,4],y:[0,-1,-2,-3]}))  

输出结果:

[python]
view plain
copy

loss: Tensor("Sum:0", dtype=float32)  
23.66  

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

[python]
view plain
copy

fixW=tf.assign(W,[-1.])  
fixb=tf.assign(b,[1.])  
sess.run([fixW,fixb])  
print("fix loss:",sess.run(loss,{x:[1,2,3,4],y:[0,-1,-2,-3]}))  

输出结果:

[python]
view plain
copy

fix loss: 0.0  

我们猜想最优的W和b值,但是在机器学习中,就是自动的寻找这些最优的模型参数。下节介绍》》

三、 API  tf. train 

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

[python]
view plain
copy

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

输出结果:

[python]
view plain
copy

train:  
 name: "GradientDescent"  
op: "NoOp"  
[array([-0.9999969], dtype=float32), array([ 0.99999082], dtype=float32)]  

到此,我们实现了一次真实的机器学习,尽管我们只实现的是简单的线下回归,不需要多少Tensorflow core代码,然而复杂的模型和方法输入数据会需要更多的代码量,因此Tensorflow对于一般的模式、结构和功能提供了高级别的抽象。我们在下一章节学习。
完整的代码:

[python]
view plain
copy

import tensorflow as tf  
# NumPy is often used to load, manipulate and preprocess data.  
import numpy as np  
node1 = tf.constant(3.0,tf.float32)  
node2 = tf.constant(4.0)  
print(node1,node2)  
sess=tf.Session()  
print(sess.run([node1,node2]))  
node3=tf.add(node1,node2)  
print("node3:",node3)  
print("sess.run(node3):",sess.run(node3))  
# 构造计算图  
a=tf.placeholder(tf.float32)  
b=tf.placeholder(tf.float32)  
adder_node=a+b  
#运行计算图  
print("adder_node:",adder_node)  
print(sess.run(adder_node,{a:3,b:4.5}))  
print(sess.run(adder_node,{a:[1,3],b:[2,4]}))  
add_and_triple=adder_node * 3  
print("add_and_triple:",add_and_triple)  
print("sess run result:",sess.run(add_and_triple,{a:3,b:4.5}))  
  
W=tf.Variable([.3],tf.float32)  
b=tf.Variable([-.3],tf.float32)  
x=tf.placeholder(tf.float32)  
linear_model=W*x+b  
init = tf.global_variables_initializer()  
sess.run(init)  
print("linear_model:",linear_model)  
print(sess.run(linear_model,{x:[1,2,3,4]}))  
  
y=tf.placeholder(tf.float32)  
squared_deltas=tf.square(linear_model-y)  
loss=tf.reduce_sum(squared_deltas)  
print("loss:",loss)  
print(sess.run(loss,{x:[1,2,3,4],y:[0,-1,-2,-3]}))  
  
fixW=tf.assign(W,[-1.])  
fixb=tf.assign(b,[1.])  
sess.run([fixW,fixb])  
print("fix loss:",sess.run(loss,{x:[1,2,3,4],y:[0,-1,-2,-3]}))  
  
optimizer=tf.train.GradientDescentOptimizer(0.01)  
train=optimizer.minimize(loss)  
print("train:\n",train)  
sess.run(init)#重置变量到初始化值  
for i in range(1000):  
    sess.run(train,{x:[1,2,3,4],y:[0,-1,-2,-3]})  
  
curr_W, curr_b, curr_loss  = sess.run([W, b, loss],{x:[1,2,3,4],y:[0,-1,-2,-3]})  
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

import tensorflow as tf  
import numpy as np  
  
features=[tf.contrib.layers.real_valued_column("x",dimension=1)]  
print("features:",features)  

输出:

[python]
view plain
copy

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

estimator=tf.contrib.learn.LinearRegressor(feature_columns=features)  
print("estimator:",estimator)  

输出结果:

[python]
view plain
copy

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

x=np.array([1.,2.,3.,4.])  
y=np.array([0.,-1.,-2.,-3.])  
input_fn=tf.contrib.learn.io.numpy_input_fn({"x":x},y,batch_size=4,num_epochs=1000)  
print("input_fn:",input_fn)  

输出结果:

[python]
view plain
copy

input_fn: <function numpy_input_fn.<locals>.input_fn at 0x7fb572e21e18>  

我们可以调用fit方法进行1000次训练步骤,并且传递训练数据集:

[python]
view plain
copy

estimator.fit(input_fn=input_fn,steps=1000)  

评价模型,在真实例子中,我们会将验证和测试数据分离,以免过度拟合overftting

[python]
view plain
copy

print(estimator.evaluate(input_fn=input_fn))  

输出结果:

[python]
view plain
copy

{'loss': 1.8005665e-07, 'global_step': 1000}  

完整代码:

[python]
view plain
copy

import tensorflow as tf  
import numpy as np  
  
features=[tf.contrib.layers.real_valued_column("x",dimension=1)]  
print("features:",features)  
estimator=tf.contrib.learn.LinearRegressor(feature_columns=features)  
print("estimator:",estimator)  
x=np.array([1.,2.,3.,4.])  
y=np.array([0.,-1.,-2.,-3.])  
input_fn=tf.contrib.learn.io.numpy_input_fn({"x":x},y,batch_size=4,num_epochs=1000)  
print("input_fn:",input_fn)  
estimator.fit(input_fn=input_fn,steps=1000)  
print(">>>>>>>>>>")  
res=estimator.evaluate(input_fn=input_fn)  
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

import tensorflow as tf  
import numpy as np  
def model(features, labels, mode):  
    # 构建线程模型以及预测值  
    W=tf.get_variable("W",[1],dtype=tf.float64)  
    b=tf.get_variable("b",[1],dtype=tf.float64)  
    y=W*features['x']+b  
    # 损失函数  
    loss=tf.reduce_sum(tf.square(y - labels))  
    # 训练子图  
    global_step=tf.train.get_global_step()  
    optimizer=tf.train.GradientDescentOptimizer(0.01)  
    train=tf.group(optimizer.minimize(loss),tf.assign_add(global_step,1))  
    # ModelFnOps方法将我们构造的子图连接到相应的功能  
    return tf.contrib.learn.ModelFnOps(  
        mode=mode,predictions=y,loss=loss,train_op=train)  
  
estimator=tf.contrib.learn.Estimator(model_fn=model)  
# 构建数据集  
x=np.array([1.,2.,3.,4.])  
y=np.array([0.,-1.,-2.,-3.])  
input_fn=tf.contrib.learn.io.numpy_input_fn({"x":x},y,4,num_epochs=1000)  
# 训练  
estimator.fit(input_fn=input_fn,steps=1000)  
# 评价模型  
print(estimator.evaluate(input_fn=input_fn,steps=10))  

说明,model方法中的内容与前边使用底层api的收到模型很相似。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息