TensorFlow
TensorFlow是Google基于DistBelief进行研发的第二代人工智能学习系统,其命名来源于本身的运行原理。Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算,TensorFlow为张量从流图的一端流动到另一端计算过程。TensorFlow是将复杂的数据结构传输至人工智能神经网中进行分析和处理过程的系统。TensorFlow 中包含了一款强大的线性代数编译器XLA,这可以帮助TensorFlow代码在嵌入式处理器、CPU(Central Processing Unit)、GPU(Graphics Processing Unit)、TPU(Tensor Processing Unit)和其他硬件平台上尽可能快速地运行。
为什么用TensorFlow
作为学习神经网络的一个python外部库,TensorFlow提供了一个快速入门、方便使用的神经网络框架。TensorFlow被认定为神经网络中最好用的库之一,它擅长的任务就是训练深度神经网络。通过使用TensorFlow,我们就可以快速的入门神经网络,大大降低了深度学习的开发成本和开发难度。使用TensorFlow可以简化backward propagation这一过程中复杂的数学推导,TensorFlow根据你确定的前向传播、成本计算的方式,完成后向传播的过程。
使用TensorFlow
- 将计算流程表示成图;
- 通过Sessions来执行图计算;
- 将数据表示为tensors;
- 使用Variables来保持状态信息;
- 分别使用feeds和fetches来填充数据和抓取任意的操作结果
1.一个简单的例子
import numpy as np
import tensorflow as tf #引入tensorflow
#构造一个size=100的训练集
X = np.random.rand(100).astype(np.float32)
Y = X*3+0.5 #Y定义为X的线性函数,系数为3,0.5
#定义tensorflow的变量,所有待优化的参数须定义为tf变量
W = tf.Variable(tf.random_uniform([1])) #随机均匀分布生成W
b = tf.Variable(tf.zeros([1])) #bias初始化为0
Yhat = W*X+b #用Yhat拟合Y,训练目标是用W,b来逼近Y的系数
loss = tf.reduce_mean((Y-Yhat)**2) #损失函数,差值的平方求均值
#定义优化方式,梯度下降,学习率0.05
optimizer = tf.train.GradientDescentOptimizer(0.05)
#定义训练器,训练目标是使loss减小
train = optimizer.minimize(loss)
#变量初始化,开启session
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
#训练开始
for step in range(1001): #1001次迭代
if step % 100 == 0: #每100次输出W,b
print(step,sess.run(W),sess.run(b))
sess.run(train) #训练
结果如下:
2.Session的使用
Session(会话)持有并管理tensorflow程序运行时的所有资源。
调用Session的两种方式
方式一:明确的调用会话的生成函数和关闭会话函数
import tensorflow as tf
#定义两个矩阵,tf.constant表示tf常量
matrix1 = tf.constant([[3,3]])
matrix2 = tf.constant([[2],[2]])
product = tf.matmul(matrix2,matrix1) #矩阵乘法,类似np.dot
#method 1
sess = tf.Session() #启动session
result = sess.run(product)
print(result)
sess.close() #关闭session
方式二:上下文管理机制自动释放所有资源
import tensorflow as tf
matrix1 = tf.constant([[3,3]])
matrix2 = tf.constant([[2],[2]])
product = tf.matmul(matrix2,matrix1)
#method 2
#可以省去关闭session这一步骤,with结束后会自动关闭session
with tf.Session() as sess:
print(sess.run(product))
两种方式结果相同
Session.run()是一个很重要的操作,执行一次run就是跑一次数据、运算规则。
3.变量的更新
import tensorflow as tf
x = tf.Variable(0) #x是一个tf变量,初始值=0
new_x = x+1 #new_x也是变量,随着x变化而变化
update = tf.assign(x,new_x) #定义一个update规则,用new_x更新x
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init) #初始化变量
for i in range(5):
sess.run(update) #执行更新操作
print("第",i+1,"次更新后的x:",sess.run(x)) #读取更新后的x
print("第",i+1,"次更新后的new_x:",sess.run(new_x)) #读取更新后的new_x
结果:
可以看到new_x的值随x的值变化而变化。还可以把new_x看做一个规则,tf.assign(x,new_x)就表示用new_x这条规则更新x。
4.传入值
构建神经网络时,通常不考虑具体的输入数据是多少,所以定义计算规则时用tf.palceholder(顾名思义:位置占有者)来表示这些输入,到run的时候使用feed_dict来”喂数据”。这有点像函数的参数,定义函数时用形参代表实参。
import tensorflow as tf
import numpy as np
inputs = np.array([[2],[3]]) #传入的值
h = tf.placeholder(tf.float32,[2,1]) #h是一个dtype为float32,shape为[2,1]的placeholder
output = h[1][0]/h[0][0] #h先占好位置,等待传值
with tf.Session() as sess:
print(sess.run(output,feed_dict={h:inputs})) #使用feed_dict传值
palceholder可以定义为[1,None]的形式,这表示允许喂入的数据shape为(1,n),n表示任意大小。这在神经网络训练中很实用,因为我们一般可以确定输入层的结构,不知道输入的样本数,就可以使用这样的placeholder。具体见下面的例子。
5.一个双层神经网络的例子
import tensorflow as tf
import numpy as np
#定义函数,添加一层网络
def add_layer(A_prev,n_prev,n,activation_function = None):
#initialize parameters
W = tf.Variable(tf.random_normal([n,n_prev]))
b = tf.Variable(tf.zeros([n,1])+0.1)
#forward propagation
Z = tf.matmul(W,A_prev) + b
if activation_function == None:
A = Z
else:
A = activation_function(Z)
return A
#create data
#X.shape=Y.shape=Noise.shape=(1,300)
X = np.linspace(-1,1,300)[np.newaxis,:]
Noise = np.random.normal(0,0.05,X.shape) #添加噪声,使数据更加贴近实际
Y = X**2-0.5+Noise
#placeholder
Xs = tf.placeholder(tf.float32,[1,None]) #输入的特征维度为1,不限制样本个数
Ys = tf.placeholder(tf.float32,[1,None]) #输出同上
#propagation
layer1_out = add_layer(Xs,1,10,tf.nn.relu)
prediction = add_layer(layer1_out,10,1)
#define loss function
loss = tf.reduce_mean((Ys-prediction)**2)
#define train step
train = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
#start optimize
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
#1000次训练
for i in range(1000):
sess.run(train,feed_dict={Xs:X,Ys:Y})
#每50次输出loss
if i % 50 == 0:
print(sess.run(loss,feed_dict={Xs:X,Ys:Y}))
可以看到,loss在不断降低,表明训练后的神经网络在不断优化以贴近训练数据。不同于一般的神经网络训练过程,使用TensorFlow后,看不到backward propagation的过程,这个过程都包含在一两行简短的调用中了。只要定义网络结构(层数、参数结构),初始化参数,前向传播,定义cost function,设定优化方式,最后运行训练步骤就行了,实际上由TensorFlow完成了backward propagation的计算过程。