1 效果展示
2 Tensorflow基本概念
3 神经网络搭建
4 在Tensorflow中搭建神经网络步骤总结
1 效果展示
由上图,模拟一段类似的TensorFlow生成神经网络的代码
# coding:utf-8
# 0导入模块,生成模拟数据集。
import tensorflow as tf
import numpy as np
BATCH_SIZE = 8
SEED = 23455
# 基于seed产生随机数
rdm = np.random.RandomState(SEED)
# 随机数返回32行2列的矩阵 作为输入数据集
X = rdm.rand(32, 2)
# 作为输入数据集的标签(正确答案)
Y_ = [[int(x0 + x1 < 1)] for (x0, x1) in X]
print
"X:\n", X
print
"Y_:\n", Y_
# 1定义神经网络的输入、参数和输出,定义前向传播过程。
x = tf.placeholder(tf.float32, shape=(None, 2))
y_ = tf.placeholder(tf.float32, shape=(None, 1))
w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
# 2定义损失函数及反向传播方法。
loss_mse = tf.reduce_mean(tf.square(y - y_))
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss_mse)
# train_step = tf.train.MomentumOptimizer(0.001,0.9).minimize(loss_mse)
# train_step = tf.train.AdamOptimizer(0.001).minimize(loss_mse)
# 3生成会话,训练STEPS轮
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
# 输出目前(未经训练)的参数取值。
print("w1:\n", sess.run(w1))
print("w2:\n", sess.run(w2))
print("\n")
# 训练模型。
STEPS = 3000
for i in range(STEPS):
start = (i * BATCH_SIZE) % 32
end = start + BATCH_SIZE
sess.run(train_step, feed_dict={x: X[start:end], y_: Y_[start:end]})
if i % 500 == 0:
total_loss = sess.run(loss_mse, feed_dict={x: X, y_: Y_})
print("After %d training step(s), loss_mse on all data is %g" % (i, total_loss))
# 输出训练后的参数取值。
print("\n")
print("w1:\n", sess.run(w1))
print("w2:\n", sess.run(w2))
代码运行结果
2 Tensorflow的基本概念
2.1 Tensorflow
TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,其命名来源于本身的运行原理。Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算,TensorFlow为张量从流图的一端流动到另一端计算过程。TensorFlow是将复杂的数据结构传输至人工智能神经网中进行分析和处理过程的系统。
TensorFlow可被用于语音识别或图像识别等多项机器学习和深度学习领域,对2011年开发的深度学习基础架构DistBelief进行了各方面的改进,它可在小到一部智能手机、大到数千台数据中心服务器的各种设备上运行。TensorFlow将完全开源,任何人都可以用。
2.2 基于Tensorflow的神经网络(Neural Networks,NN)
基于Tensorflow的神经网络:用张量表示数据,用计算图搭建神经网络,用会话执行计算图,优化线上的权重(参数),得到模型。
2.3 张量
张量:张量就是多维数组(列表),用“阶”表示张量的维度。
0阶张量称作标量,表示一个单独的数 ;
举例 S=123
1阶张量称作向量,表示一个维数组 ;
举例 V=[1,2,3]
2阶张量称作矩阵,表示一个二维数组它可以有i行j列个元素,每个元素可以用行号和列共同索引到 ;
举例 m=[[1, 2, 3], [4, 5, 6], 7, 8, 9]]
判断张量是几阶的 , 就通过张量右边的方括号数,0个是0阶, n个是 n阶, 张量可以表示0阶到n阶数组(列表)
举例 t=[ [ [ … ] ] ]为 3阶
2.4 数据类型
数据类型:Tensorflow的数据类型有tf.float32 、tf.int32等。
举例我们实现Tensorflow的加法
import tensorflow as tf
a = tf.constant([[1.0, 2.0]])
b = tf.constant([[3.0], [4.0]])
result = a+b
print(result)
2.5 计算图(Graph)
计算图(Graph): 搭建神经网络的计算过程,是承载一个或多个计算节点的一张图,只搭建网络,不运算。
举例
神经网络的基本模型是神经元,神经元的基本性质其实就是数学中的乘、加运算。例如搭建如下的计算图:
x1、x2表示输入,w1、w2分别是x1到y和x2到y的权重,y=x1w1+x2w2。
我们实现上述计算图:
#引入模块
import tensorflow as tf
#定义一个 2 阶张量等于[[1.0,2.0]]
x = tf.constant([[1.0, 2.0]])
#定义一个 2 阶张量等于[[3.0],[4.0]]
w = tf.constant([[3.0], [4.0]])
#实现 xw 矩阵乘法
y = tf.matmul(x, w)
#打印出结果
print(y)
结果
从这里我们可以看出,print 的结果显示 y 是一个张量,只搭建承载计算过程的计算图,并没有运算,如果我们想得到运算结果就要用到“会话 Session()”了。
2.6 会话(Session)
会话(Session):执行计算图中的节点运算。
我们用with结构实现,语法如下:
import tensorflow as tf
x = tf.constant([[1.0, 2.0]])
w = tf.constant([[3.0], [4.0]])
y = tf.matmul(x, w)
print(y)
with tf.Session() as sess:
print(sess.run(y))
结果
2.7 神经网络的参数
神经网络的参数:是指神经元线上的权重w,用变量表示,一般会先随机生成这些参数。生成参数的方法是让w等于tf.Variable,把生成的方式写在括号里
import tensorflow as tf
# 定义输入和参数
x = tf.constant([[0.7, 0.5]])
w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1)) # 2*3的矩阵
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1)) # 3*1的矩阵
# 定义前向传播过程
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
# 用会话计算结果
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
print("y in tf3_3.py is:\n", sess.run(y))
结果
3 神经网络搭建
介绍过张量、计算图、会话和参数后,我们可以讨论神经网络的实现过程了。
3.1 神经网络的实现过程:
- 准备数据集,提取特征,作为输入给神经元网络(NN);
- 搭建NN结构,从输入到输出(先搭建计算图,在用会话执行);
(NN前向传播算法 ————> 计算输出) - 大量特征数据输入给NN,迭代优化NN参数;
(NN反向传播算法 ————> 优化参数训练模型) - 使用训练好的模型预测和分类;
由此可见,基于神经网络的机器学习主要分为两个过程,即训练过程和使用。训练过程是第一步前向传播、第二步反向传播 、第三步是循环迭代 ,使用过程是第四步,一旦参数优化完成就可以固定这些参数,实现特定应用了 。
很多实际应用中 ,我们会先使用现有的成熟网络结构,传入新的数据,训练相应模型,判断是否能对传入的从未见过新数据作出正确响应,再适当更改网络结构,反复迭代,让机器自动训练参数找出最优结构和,以固定专用模型 。
3.2 前向传播
前向传播就是搭建模型的计算过程,让模型具有推理能力,可以针对一组输入给出相应的输出。
举例
假如生产一批零件,体积为x1 ,重量为x2 ,体积和重量就是我们选择的特征,把它们传入神经网络,当体积和重量这组数据走过神经网络后会得到一个输出。
由搭建的神经网络可得, 隐藏层节点 a11 =x1 * w11 +x2 *w21 =0.14+0.15 =0.29 ,同理算得节点 a12=0.32 ,a13 =0.38 ,最终计算得到输出层 Y=-0.015 ,这便实现了前向传播过程 。
import tensorflow as tf
# 定义输入和参数
x = tf.constant([[0.7, 0.5]])
w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1)) # 2*3的矩阵
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1)) # 3*1的矩阵
# 定义前向传播过程
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
# 用会话计算结果
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
print("y in tf3_3.py is:\n", sess.run(y))
3.3 反向传播
反向传播 :训练模型参数,在所有参数上用梯度下降,使 NN 模型在训练数据上的损失函数最小。
- 损失函数(loss):计算得到的预测值y与已知答案y_ 的差距。
- 均方误差(MSE):求前向传播计算结果与已知答案之差的平方再求平均。
用 tensorflow 函数表示为:
loss_mse = tf.reduce_mean(tf.square(y_ - y))
反向传播训练方法:以减小loss值为优化目标,有梯度下降、momentum优化器、adamadam优化器等方法。
# 使用随机梯度下降算法,使参数沿着梯度的反方向,即总损失减小的方向移动,实现更新参数。
train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
# 在更新参数时,利用了超参数
train_step=tf.train.MomentumOptimizer(learning_rate, momentum).minimize(loss)
# 是利用自适应学习率的优化算法,Adam 算法和随机梯度下降算法不同。
train_step=tf.train.AdamOptimizer(learning_rate).minimize(loss)
学习率:决定每次参数更新的幅度。
优化器中都需要一个叫做学习率的参数,使用时,如果学习率选择过大会出现震荡不收敛的情况,如果学习率选择过小,会出现收敛速度慢的情况。我们可以选个比较小的值填入,比如 0.01、0.001。
# coding:utf-8
# 0导入模块,生成模拟数据集。
import tensorflow as tf
import numpy as np
BATCH_SIZE = 8
SEED = 23455
# 基于seed产生随机数
rdm = np.random.RandomState(SEED)
# 随机数返回32行2列的矩阵 表示32组 体积和重量 作为输入数据集
X = rdm.rand(32, 2)
# 从X这个32行2列的矩阵中 取出一行 判断如果和小于1 给Y赋值1 如果和不小于1 给Y赋值0
# 作为输入数据集的标签(正确答案)
Y_ = [[int(x0 + x1 < 1)] for (x0, x1) in X]
print
"X:\n", X
print
"Y_:\n", Y_
# 1定义神经网络的输入、参数和输出,定义前向传播过程。
x = tf.placeholder(tf.float32, shape=(None, 2))
y_ = tf.placeholder(tf.float32, shape=(None, 1))
w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
# 2定义损失函数及反向传播方法。
loss_mse = tf.reduce_mean(tf.square(y - y_))
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss_mse)
# train_step = tf.train.MomentumOptimizer(0.001,0.9).minimize(loss_mse)
# train_step = tf.train.AdamOptimizer(0.001).minimize(loss_mse)
# 3生成会话,训练STEPS轮
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
# 训练模型。
STEPS = 3000
for i in range(STEPS):
start = (i * BATCH_SIZE) % 32
end = start + BATCH_SIZE
sess.run(train_step, feed_dict={x: X[start:end], y_: Y_[start:end]})
代码运行结果
4 在Tensorflow中搭建神经网络一般步骤
准备工作、前向传播、后向传播、循环迭代。
4.1 准备工作
import、常量定义、生成数据集
# coding:utf-8
# 0导入模块,生成模拟数据集。
import tensorflow as tf
import numpy as np
BATCH_SIZE = 8
SEED = 23455
4.2 前向传播,生成函数集
定义输入、参数和输出
x=
y_=
w1=
w2=
x = tf.placeholder(tf.float32, shape=(None, 2))
y_ = tf.placeholder(tf.float32, shape=(None, 1))
w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
4.3 反向传播,减小loss值至最小
定义损失函数,反向传播方法
loss=
train_step=
loss_mse = tf.reduce_mean(tf.square(y - y_))
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss_mse)
# train_step = tf.train.MomentumOptimizer(0.001,0.9).minimize(loss_mse)
# train_step = tf.train.AdamOptimizer(0.001).minimize(loss_mse)
4.4 迭代,生成会话,训练step轮
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
# 训练模型。
STEPS = 3000
for i in range(STEPS):
start =
end =
sess.run(train_step, feed_dict={x: X[start:end], y_: Y_[start:end]})
4.5 在Tensorflow中搭建一个神经网络的完整代码
举例
随机产生 32 组生产出的零件的体积和重量,训练 3000 轮,每 500 轮输出一次损
失函数。下面我们通过源代码进一步理解神经网络的实现过程:
# coding:utf-8
# 0导入模块,生成模拟数据集。
import tensorflow as tf
import numpy as np
BATCH_SIZE = 8
SEED = 23455
# 基于seed产生随机数
rdm = np.random.RandomState(SEED)
# 随机数返回32行2列的矩阵 表示32组 体积和重量 作为输入数据集
X = rdm.rand(32, 2)
# 从X这个32行2列的矩阵中 取出一行 判断如果和小于1 给Y赋值1 如果和不小于1 给Y赋值0
# 作为输入数据集的标签(正确答案)
Y_ = [[int(x0 + x1 < 1)] for (x0, x1) in X]
print
"X:\n", X
print
"Y_:\n", Y_
# 1 定义神经网络的输入、参数和输出,定义前向传播过程。
x = tf.placeholder(tf.float32, shape=(None, 2))
y_ = tf.placeholder(tf.float32, shape=(None, 1))
w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
# 2 定义损失函数及反向传播方法。
loss_mse = tf.reduce_mean(tf.square(y - y_))
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss_mse)
# train_step = tf.train.MomentumOptimizer(0.001,0.9).minimize(loss_mse)
# train_step = tf.train.AdamOptimizer(0.001).minimize(loss_mse)
# 3生成会话,训练STEPS轮
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
# 输出目前(未经训练)的参数取值。
print("w1:\n", sess.run(w1))
print("w2:\n", sess.run(w2))
print("\n")
# 训练模型。
STEPS = 3000
for i in range(STEPS):
start = (i * BATCH_SIZE) % 32
end = start + BATCH_SIZE
sess.run(train_step, feed_dict={x: X[start:end], y_: Y_[start:end]})
if i % 500 == 0:
total_loss = sess.run(loss_mse, feed_dict={x: X, y_: Y_})
print("After %d training step(s), loss_mse on all data is %g" % (i, total_loss))
# 输出训练后的参数取值。
print("\n")
print("w1:\n", sess.run(w1))
print("w2:\n", sess.run(w2))
代码运行结果
由神经网络的实现结果,我们可以看出,总共训练 3000 轮,每轮从 X 的数据集和 Y 的标签中抽取相对应的从 start 开始到 end 结束个特征值和标签,传入神经网络,用 sess.run 求出 loss,每 500 轮打印一次 loss 值。经过 3000 轮后,我们打印出最终训练好的参数 w1、w2。