- 安装tensorflow
大家都知道tensorflow是google开发的一款开源的深度学习编程框架,是当今最流行的深度学习开发框架,因此对有志于深度学习研究的小伙伴来说,tensorflow是当仁不让的第一选择。
首先看看tensorflow的安装,其实非常简单,在python环境安装好的前提下,直接运行:
pip install tensorflow就可以了。
笔者用的是python3.5环境,tensorflow是1.4版本。
【问题1】如何加快pip安装速率
在默认pip安装的时候,国内的网络下经常会报超时,这时有个很好的解决办法就是将pip的目标库改到国内的网址,怎么改呢?只要设置pip.ini文件就可以了,笔者的pip.ini文件内容是这样的:
[global]
timeout = 60000
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
[install]
use-mirrors = true
mirrors = https://pypi.tuna.tsinghua.edu.cn
这是连到清华的网站上了,然后将pip.ini放到C:\用户\当前账号\pip\目录下就可以了。下面用pip install tensorflow,速度飞快啊!
- 基本使用
1、使用图(graphs)来表示计算任务,用于搭建神经网络的计算过程,但其只搭建网络,不计算
2、在被称之为会话(Session)的上下文(context)中执行图
3、使用张量(tensor)表示数据,用“阶”表示张量的维度。关于这一点需要展开一下
0阶张量称为标量,表示单独的一个数
1阶张量称为向量, 表示一个一维数组
2阶张量称为矩阵,表示一个二维数组
……
张量是几阶的可以通过张量右边的方括号数来判断。例如 t = [ [ [ ] ] ],显然这个为3阶。
4、通过变量(Variable)维护状态
5、使用feed和fetch可以为任意的操作赋值或者从其中获取数据
tensorflow是一个编程系统,使用图(graphs)来表示计算任务,图(graphs)中的节点称之为op(operation),一个op获得0个或者多个tensor,执行计算,产生0个或多个tensor,tensor看作是一个n维的数组或列表。图必须在会话(session)里被启动。
最简单的例子:
import tensorflow as tf # 简写方便一点
# 创建两个常量(constant)
m1=tf.constant([[3,3]]) #一行两列的矩阵,这里是矩阵乘法,所以是二维数组,注意书写格式以及矩阵乘法规则
m2=tf.constant([[2],[3]]) #两行一列的矩阵
# 创建一个矩阵乘法(matmul)的op
product=tf.matmul(m1,m2)
print(product)
tf.constant定义一个常量
tf.matmul是乘法运算,也可以写成a * b。tensorflow对乘法等基础运算都默认内嵌了对应的反向求导函数。
变量是用tf.Variable()表示。打印变量不能直接用print方法,要用:print(sess.run(variable1))来打印。
import tensorflow as tf
x=tf.Variable([1,2]) # 定义一个变量,这里是张量的加减法,所以一维数组即可
a=tf.constant([3,3]) # 定义一个常量
sub=tf.subtract(x,a) # 增加一个减法op
add=tf.add(x,sub) # 增加一个加法op
init=tf.global_variables_initializer() # 在tensorflow中使用变量要初始化,此条语句也可以初始化多个变量
with tf.Session() as sess:
sess.run(init) # 变量初始化,也要放在会话中,才能执行
print(sess.run(sub))
print(sess.run(add))
运行将得到结果
[-2 -1]
[-1 1]
值得一提的是,在打印常量和变量时,不能像python中的直接print(a),而是需要放在sess.run()中。
定义变量时可先不输入具体数值,先占位,在会话中调用op时,再输入具体值,这就是placeholder占位符的含义了。
import tensorflow as tf
input1 = tf.placeholder(tf.float32) # 使用placeholder()占位,需要提供类型
input2 = tf.placeholder(tf.float32)
output = tf.multiply(input1,input2)
with tf.Session() as sess:
print(sess.run(output,feed_dict={input1:8.0,input2:2.0})) # 以字典形式输入feed_dict
运行结果为:16.0
总结:常量、变量、占位符都必须在sess.run中运行。
- 求导gradients
tf.gradients()
在tensorflow中,tf.gradients()的参数如下:
tf.gradients(ys, xs,
grad_ys=None,
name='gradients',
colocate_gradients_with_ops=False,
gate_gradients=False,
aggregation_method=None,
stop_gradients=None)
先不给出参数的意义。对求导函数而言,其主要功能即求导公式:∂ys/∂xs。在tensorflow中,ys和xs都是tensor。
更进一步,tf.gradients()接受求导值ys和xs不仅可以是tensor,还可以是list,形如[tensor1, tensor2, …, tensorn]。当ys和xs都是list时,它们的求导关系返回值是一个list,list的长度等于len(xs)。
假设返回值是[grad1, grad2, grad3],ys=[y1, y2],xs=[x1, x2, x3]。则,真实的计算过程为:
grad1=y1/x1+y2/x1
grad2=y1/x2+y2/x2
grad3=y1/x3+y2/x3
grad_ys也是一个list,其长度等于len(ys)。这个参数的意义在于对xs中的每个元素的求导加权种。
假设grad_ys=[grad_ys1, grad_ys2, grad_ys3],xs=[x1, x2, x3],则list中每个元素,如grad_ys1的shape与xs的shape相同。
例如:
z1 = 3 * w1 + 2 * w2+ w3
z2 = -1 * w3 + w4
grads = tf.gradients([z1, z2], [w1, w2, w3, w4], grad_ys=[[-2.0, -3.0, -5.0], [-2.0, -3.0, 4.0]])
xs=[w1,w2,w3,w4],所以会返回4个元素。
第1个元素对w1求导,计算过程:[z1]中的3*w1扩展成3*[-2.0,-3.0,-5.0];[z2]没有对w1的导数,因此返回[-6,-9,-15]。
第2个元素对w2求导,计算过程:[z1]中的2*w2扩展成2*[-2.0,-3.0,-5.0];[z2]没有对w2的导数,因此返回[-4,-6,-10]。
第3个元素对w3求导,计算过程:[z1]中的w3扩展成1*[-2.0,-3.0,-5.0];[z2]中的w3扩展成-1*[-2.0,-3.0,4.0],因此最后的结果是[1*-2+(-1*-2) , 1*-3+-1*-3 , 1*-5+-1*4]=[0,0,-9];
第4个元素对w4求导,计算过程:[z1]中的w4没有,所以没梯度;[z2]中的w4扩展成1*[-2.0,-3.0,4.0],因此最后的结果是[-2.0,-3.0,4.0];
因此最终的打印结果是:
[array([ -6., -9., -15.], dtype=float32),
array([-4., -6., -10.], dtype=float32),
array([ 0., 0., -9.], dtype=float32),
array([-2., -3., 4.], dtype=float32)]
- stop_gradients
stop_gradients也是一个list,list中的元素是tensorflow graph中的op,一旦进入这个list,将不会被计算梯度,更重要的是,在该op之后的BP计算都不会运行。
例如:
a = tf.constant(0.)
b = 2 * a
c = a + b
g = tf.gradients(c, [a, b])
计算得g = [3.0, 1.0]。
但如果冻结operator a和b的梯度计算:
a = tf.constant(0.)
b = 2 * a
g = tf.gradients(a + b, [a, b], stop_gradients=[a, b])
计算得g=[1.0, 1.0]。
上面的代码也等效于:
a = tf.stop_gradient(tf.constant(0.))
b = tf.stop_gradient(2 * a)
g = tf.gradients(a + b, [a, b])
- 线性模型
真正的机器学习过程中,我们当然是不知道变量的,我们真正的目的就是去习得这些变量,以达到模型能够尽可能准确预测样本的期望,也就是所谓的损失(loss)最小化。
机器学习的4部曲:
(1)定义输入变量和输出变量
(2)定义神经网络的结构
(3)定义损失函数和优化函数
(4)将输入输出数据代入到神经网络进行训练,生成神经网络的权重参数。
Tensorflow提供了优化器(optimizers)来做这个工作。最简单的优化器算法叫梯度下降,这是在线性模型中最常用的一种优化算法。优化器底层会调用Tensorflow Core中的tf.gradients方法来实现梯度下降。
线性模型是机器学习中最简单的模型,通俗的说就是用线性方程去拟合一些数据,这个方程要满足的条件就是这些数据到这个方程的距离要最小。
在上面的坐标图上,分布着一些点,怎么才能找出一条线(这条线可以是直线,也可是曲线)使这些点到这条线的距离的和最短,这就是线性模型学习的过程。本文主要是讲述怎么用tensorflow去实现线性模型,因此,更多线性模型的知识留给读者去了解。
优化器的作用是不断迭代模型直到模型的损失函数达到最小。有好几种优化器,比如Adam、GradientDescent等。各种优化器的不同点主要在于步长选择的方式不一样,有固定步长,有随着迭代次数增加步长逐渐减少。
线性模型主要是推导公式Y =w*X+b中的权重参数w和偏置参数b。输入已知的X和Y,定义好损失函数loss,通过优化器的训练之后得出w和b
import tensorflow as tf
# y = Wx + b, 初始化的时候随便定义一个初始值
#(1)定义输入输出变量
W = tf.Variable([.3], dtype=tf.float32)
b = tf.Variable([-.3], dtype=tf.float32)
x = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)
# (2)定义神经网络模型
linear_model = W*x + b
# 损失loss函数,线性模型中以欧式距离来衡量损失值
loss = tf.reduce_sum(tf.square(linear_model - y))
# 定义优化器optimizer
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)
# 训练数据
x_train = [1.01, 1.99, 3.02, 4.01]
y_train = [0, -1.05, -2.03, -3.04]
# 初始化Session
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
# 循环1000次,训练模型
for i in range(1000):
sess.run(train, {x: x_train, y: y_train})
# 评估准确率
curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x: x_train, y: y_train})
print("W: %s b: %s loss: %s"%(curr_W, curr_b, curr_loss))
输出结果:
W: [-1.0067805] b: [0.99450076] loss: 0.0024434922
这就是Tensorflow中线性模型的训练方式,线性模型是tensorflow的入门砖,怎么样,是不是看起来很简单。