3-10 TensorFlow
常用的深度学习框架
选用的参考依据:
- 便于编程
- 运行速度
- 是否真的开放
TensorFlow
使用Tensorflow求使损失函数$Jw = {w^2} - 10w + 25$最小的参数:
#导入所需要的库
import numpy as np
import tensorflow as tf
#使用tf.Variable定义参数w
w = tf.Variable(0,dtype=tf.float32)
#定义损失函数
cost = tf.add(tf.add(w**2,tf.multiply(-10.,w)),25);
#定义优化方法为梯度下降,使用的学习率为0.01,目标是最小化损失
train = tf.train.GradientDescentOptimizer(0.01).minimize(const)
init = tf.global_variables_initializer()
#开启一个 TensorFlow session
session = tf.Session()
#初始化全局变量
session.run(init)
#session.run(w)评估了 w,现在为0
print(session.run(w))
#运行一步梯度下降法
session.run(train)
print(session.run(w))
#运行梯度下降 1000 次迭代
for i in range(1000):
session.run(train)
print(session.run(w))
输出:
如果觉得上面计算的形式表示复杂,可以将上面表达式的书写形式修改为:
#cost = tf.add(tf.add(w**2,tf.multiply(-10.,w)),25);
cost = w**2-10*w+25
如果你想要最小化的函数是训练集函数,当你训练神经网络时,训练数据x会改变。在这个例子中可以把x定义为:
x = tf.placeholder(tf.float32,[3,1])
cost替换成:
cost = x[0][0]*w**2+x[1][0]*w+x[2][0]
定义一个数组,用于给x赋值:
coefficients = np.array([[1.],[-10.],[25.]])
训练步骤中给x提供值的方法:
feed_dict={x:coefficients}
完整的代码:
#导入所需要的库
import numpy as np
import tensorflow as tf
#定义一个数组,即x的初始化数据
coefficients = np.array([[1.],[-10.],[25.]])
#使用tf.Variable定义参数w
w = tf.Variable(0,dtype=tf.float32)
#定义训练集数据x,使之成为[3,1]数组,placeholder函数告诉tensorflow稍后会给x赋值
x = tf.placeholder(tf.float32,[3,1])
#定义损失函数
#cost = tf.add(tf.add(w**2,tf.multiply(-10.,w)),25);
cost = x[0][0]*w**2+x[1][0]*w+x[2][0]
#定义优化方法为梯度下降,使用的学习率为0.01,目标是最小化损失
train = tf.train.GradientDescentOptimizer(0.01).minimize(cost)
init = tf.global_variables_initializer()
#开启一个 TensorFlow session
session = tf.Session()
#初始化全局变量
session.run(init)
#session.run(w)评估了 w,现在为0
print(session.run(w))
#运行一步梯度下降法
session.run(train,feed_dict={x:coefficients})
print(session.run(w))
#运行梯度下降 1000 次迭代
for i in range(1000):
session.run(train, feed_dict={x: coefficients})
print(session.run(w))
输出结果;
现在如果你想改变这个二次函数的系数,假设你把:
coefficient = np.array([[1.],[-10.],[25.]])
改为:
coefficient = np.array([[1.],[-20.],[100.]])
此时输出:
TensorFlow 中的 placeholder 是一个你之后会赋值的变量,这种方式便于把训练数据加入损失方程,把数据加入损失方程用的是这个句法,当你运行训练迭代,用 feed_dict 来让 x=coefficients。如果你在做 mini-batch 梯度下降,在每次迭代时,你需要插入不同的 mini-batch,那么每次迭代,你就用 feed_dict 来喂入训练集的不同子集,把不同的 mini-batch 喂入损失函数需要数据的地方。
上面的代码中有三行是固定的格式:
session = tf.Session()
session.run(init)
print(session.run(w))
也可以写成:
with tf.session() as session:
session.run(init)
print(session.run(w))
上面两种写法是等价的,根据自己的习惯进行选用。但是 Python 中的 with 命令更方便清理,以防在执行这个内循环时出现错误或例外。
式子:
cost = x[0][0]*w**2 +x[1][0]*w + x[2][0]#(w-5)**2
实际上是建立计算图,计算图所做的就是取 x[0][0],取 w,然后将它平方,然后将 x[0][0]乘以w的平方,你就得到了 $x\left[ 0 \right]\left[ 0 \right]{\rm{*}}{{\rm{w}}^2}$,以此类推 。。。
最终整个建立起来计算 :
cost = x[0][0]*w**2 +x[1][0]*w + x[2][0]#(w-5)**2
最后你得到了损失函数。
TensorFlow 的优点在于,通过用这个计算损失,计算图基本实现前向传播, TensorFlow已经内置了所有必要的反向函数。这就是为什么你不需要明确实现反向传播,这是编程框架能帮你变得高效的原因之一。