本文主要讲解TensorFlow是什么,如何理解TensorFlow的开发模式。其他TensorFlow学习内容请参考TensorFlow学习目录。
目录
一、深度学习的四个步骤
二、TensorFlow搭建的模型分成三个主要部分
三、TensorFlow的基本构成
四、流向问题
五、TensorFlow开发的基本步骤
六、完整的一段TensorFlow线性回归的代码,整个构建的过程,无论是复杂还是简单,其基本模式,都是如下代码所包含(除了保存加载模型-之后会介绍)
TensorFlow是一种深度学习的开发环境,用于解决上述深度学习中的后三步内容。
理解:现在想象有一段下水管道,有一个起点(也就是输入),有一个终点(也就是输出),中间有着复杂的管道网络结构(也就是中间节点,管道与管道间的连接处)。这里可以想象先已经构建好了管道,然后再往里面去注水,而不是加一节管道就往这节管道里面注入水。比如说只用numpy实现了多层感知器的BP的过程,每定义一个变量就相当于加入了一节带水的管道,而TensorFlow构建的深度神经网络就是将所有的空管道,按照“图纸”将其拼接起来,然后将数据(水)从输入口注入,之后可以从输出口得到结果,之后比较输出与理想输出之间的“差”(与损失函数有关),然后通过BP算法反向更新深度神经网络的参数。
<1>通过占位符定义(一般使用这种方式)
tf.placeholder(dtype, shape=None, name=None)
# 定义一个int类型
tf.placeholder(tf.int32)
# 定义一个张量
tf.placeholder(tf.float32, shape=(10, 10))
tf.placeholder(tf.float32, [10, 10])
<2>通过字典类型定义(一般用于输入比较多的情况)
inputdict = {
'a': tf.placeholder(tf.int32),
'b': tf.placeholder(tf.int32),
'X': tf.placeholder(tf.int32, [10, 10])
}
# 提取
inputdict['a']
inputdict['b']
inputdict['X']
<3>直接定义(一般很少使用)
a = 10
b = tf.placeholder(tf.int32)
add = tf.add(a, b)
# 直接定义a,然后将其与b运算,之后只需要给b喂值即可
<1>直接定义
#tf.Variable中的参数很多,还有是否需要训练之类的
W = tf.Variable(tf.random_normal([10, 10], mean=0, stddev=1.0, dtype=tf.float32))
# 在sess中需要加入
sess.run(tf.global_variables_initializer())
<2>字典定义
inputdict = {
'W': tf.Variable(tf.random_normal([10, 10], mean=0, stddev=1.0, dtype=tf.float32))
}
# 使用时候
inputdict['W']
简单的就是加减乘除的运算,这里不是直接使用“+-*/”,而是使用TensorFlow定义的符号,之后会接触,卷积运算,池化迅运算之类的。之后需要定义损失函数(用于计算“输出值”与“期望输出值”之间的误差,用于反向传播算法)。
定义了正向的结构以及损失函数之后,反向传播的过程就是沿着正向传播的结构向相反反向将误差传递过去。这里涉及到的技术就有很多,L1、L2正则化、冲量调节、学习率自适应、adm随机梯度下降算法等等,针对不同问题,使用不同的技巧搭配,以此达到更好的训练效果。
在定义完所有的变量之后,需要初始化所有变量。通过如下代码
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
一般采用minibatch概念进行迭代训练。
通过将新的数据喂入神经网络,得到输出的过程。
一般会将模型训练好的参数保存起来,当使用的时候,将参数进行加载,之后进行预测即可。
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
# 生成模拟数据
train_X = np.linspace(-1, 1, 100)
train_Y = 2 * train_X + np.random.randn(*train_X.shape) * 0.3 # y=2x,但是加入了噪声
# 创建模型
# 占位符----入口
X = tf.placeholder("float")
Y = tf.placeholder("float")
# 模型参数----管道
W = tf.Variable(tf.random_normal([1]), name="weight")
b = tf.Variable(tf.zeros([1]), name="bias")
# 前向结构----管道连接处
z = tf.multiply(X, W) + b
# 反向优化
cost = tf.reduce_mean(tf.square(Y - z)) # 定义损失函数
learning_rate = 0.01
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost) # Gradient descent
# 初始化变量
init = tf.global_variables_initializer()
# 训练参数
training_epochs = 20
display_step = 2
# 启动session
with tf.Session() as sess:
sess.run(init)
# Fit all training data
for epoch in range(training_epochs):
for (x, y) in zip(train_X, train_Y):
sess.run(optimizer, feed_dict={X: x, Y: y})
# 显示训练中的详细信息
if epoch % display_step == 0:
loss = sess.run(cost, feed_dict={X: train_X, Y: train_Y})
print("Epoch:", epoch + 1, "cost=", loss, "W=", sess.run(W), "b=", sess.run(b))
print("Finished!")
print("cost=", sess.run(cost, feed_dict={X: train_X, Y: train_Y}), "W=", sess.run(W), "b=", sess.run(b))
# 图形显示
plt.plot(train_X, train_Y, 'ro', label='Original data')
plt.plot(train_X, sess.run(W) * train_X + sess.run(b), label='Fitted line')
plt.legend()
plt.show()
输出结果:
Epoch: 1 cost= 0.6766722 W= [0.9135755] b= [0.35516635]
Epoch: 3 cost= 0.14571519 W= [1.762745] b= [0.12959701]
Epoch: 5 cost= 0.1017361 W= [1.9932247] b= [0.04283942]
Epoch: 7 cost= 0.09868479 W= [2.0530028] b= [0.01992826]
Epoch: 9 cost= 0.09846208 W= [2.0684636] b= [0.01399574]
Epoch: 11 cost= 0.09844241 W= [2.0724616] b= [0.0124615]
Epoch: 13 cost= 0.09843986 W= [2.0734932] b= [0.01206568]
Epoch: 15 cost= 0.098439366 W= [2.0737617] b= [0.01196259]
Epoch: 17 cost= 0.09843925 W= [2.0738313] b= [0.01193587]
Epoch: 19 cost= 0.09843922 W= [2.0738487] b= [0.01192924]
Finished!
cost= 0.09843922 W= [2.073851] b= [0.0119283]