搭建神经网络
一、基本概念
1.1 基于Tensorflow的Neural Network
用张量(tensor)表示数据,用计算图搭建神经网络,用会话执行计算图,优化权重参数,得到模型。
1.2 数据类型
常用的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 #实现张量a与b的加法
print result #输出结果
输出为:
Tensor("add:0", shape=(2,), dtype=float32)
表示输出是一个名为add:0、大小为2的一维张量,数据类型为float32。print张量并不会计算该张量
1.3 计算图
搭建神经网路的计算过程,不运行计算。
y
=
w
1
×
x
1
+
w
2
×
x
2
y=w_1 \times x_1+w_{2} \times x_{2}
y=w1×x1+w2×x2
利用tensorflow实现上述计算图
import tensorflow as tf #引入模块
x = tf.constant([[1.0, 2.0]]) #定义一个 2 阶张量等于[[1.0,2.0]]
w = tf.constant([[3.0], [4.0]]) #定义一个 2 阶张量等于[[3.0],[4.0]]
y = tf.matmul(x, w) #实现 xw 矩阵乘法
print y #打印出结果
输出是:
Tensor("matmul:0", shape(1,1), dtype=float32)
可以看出,Y是一个名为"matmul:0",shape为1*1的二阶张量(也可以称为矩阵),数据类型是float32。同样,只搭建网络,保存计算过程;不执行计算。
1.4 会话
执行计算图的计算过程。
with tf.Session() as sess:
print sess.run(y)
对于刚刚的计算图,完整计算代码如下。
import tensorflow as tf #引入模块
x = tf.constant([[1.0, 2.0]]) #定义一个 2 阶张量等于[[1.0,2.0]]
w = tf.constant([[3.0], [4.0]]) #定义一个 2 阶张量等于[[3.0],[4.0]]
y = tf.matmul(x, w) #实现 xw 矩阵乘法
print y #打印出结果
with tf.Session() as sess:
print sess.run(y) #执行会话并打印出执行后的结果
输出是
Tensor("matmul:0", shape(1,1), dtype=float32)
[[11,]]
运行Session前打印y只是一个张量,运行后打印sess.run(y)是实际的计算结果了。
二、神经网络的搭建
2.1 神经网络参数
神经网络的参数指神经元线上的权重W,用变量表示。训练模型实际就是优化神经网络参数。一般这些参数在优化前随机生成,生成的方法是tf.Variable。
作用 | 函数 |
---|---|
生成正太分布随机数 | tf.random_normal() |
生成去掉过大偏激点的正太分布随机数 | tf.truncated_normal() |
生成均匀分布随机数 | tf.random_uniform() |
生成全0数组 | tf.zeros |
生成全1数组 | tf.ones |
生成直接给定数组 | tf.constant |
- w=tf.Variable(tf.random_normal([2,3],stddev=2,mean=0,seed=1)),表示生成正太分布随机数,两行三列,标准差是2,平均值是0,随机种子是1,随机种子的目的是保证每次生成的随机数一致。
- w=tf.Variable(tf.Trunctated_normal([2,3],stddev=2,mean=0,seed=1)),表示去掉偏离过大的正太分布,也就是如果随机出来的数据超过两个标准差的话,这个数据将会被重新生成。
- w=tf.zeros([3,2],int32),表示生成[[0,0],[0,0],[0,0]]的常量张量。
2.2 神经网络的搭建
1. 准备数据集
2. 搭建NN结构,从输入到输出
3. 大量数据特征喂给NN,迭代优化NN模型参数
4. 使用训练好的模型预测和分类
2.3 前向传播
定义:搭建模型的计算过程,让模型具有推理能力,能够针对一组输入给出相应的输出。
例如生产一批零件,体积x1和重量x2就是两个特征。假设体积0.7,重量0.5。
由搭建的神经网络可知,隐藏层节点a11=x1×w11+x2×w21=0.29;同理a12=0.32,a13=0.38,最终输出层y=-0.015,这便实现了神经网络的钱箱传播过程。
下面代码是喂入一组数据的前向传播计算
#coding:utf-8
import tensorflow as tf
x=tf.placeholder(tf.float32,shape=(1,2))
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)
#用会话实现计算
with tf.Session() as sess:
init_op=tf.global_variables_initializer()
sess.run(init_op) #对所有变量初始化,赋初值
print sess.run(y,feed_dict={x:[[0.7,0.5]]})
下面代码是喂入多组数组
#coding:utf-8
import tensorflow as tf
x=tf.placeholder(tf.float32,shape=(None,2))
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)
#用会话实现计算
with tf.Session() as sess:
init_op=tf.global_variables_initializer()
sess.run(init_op) #对所有变量初始化,赋初值
print sess.run(y,feed_dict={x:[[0.7,0.5],[0.2,0.3],[0.3,0.4],[0.4,0.5]]})
三、训练神经网络
3.1反向传播
反向传播:训练模型参数,在所有参数上用梯度下降,使NN模型在训练数据组上的损失函数最小
损失函数(loss):计算得到的预测值y与已知答案y_的差距。均方根误差MSE是常用的损失函数计算方法之一。
M
S
E
(
y
−
,
y
)
=
∑
i
=
1
n
(
y
−
y
−
)
2
n
MSE(y_-,y)=\frac{\sum_{i=1}^n(y-y_-)^2}{n}
MSE(y−,y)=n∑i=1n(y−y−)2
训练方法:以减小loss值为优化目标,有梯度下降、momentum优化器、adam优化器等优化方法。
#梯度下降法
train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
#momentum优化器
train_step=tf.train.MomentumOptimizer(learning_rate).minimize(loss)
#adam优化器
train_step=tf.train.AdamOptimizer(learning_rate).minimize(loss)
学习率:优化器中都需要一个学习率的参数,使用时,如果学习率选择过大会出现震荡不收敛的情况,如果学习率选择过小,会出现收敛速度慢的情况。我们可以选择个 比较小的值填入,比如0.1,0.001。
3.2 神经网络训练实例
随机产生32组生产出的零件的体积和重量,训练3000轮,每500轮输出一次损失函数。代码如下:
#coding:utf-8
import tensorflow as tf
import numpy as np
BATCH_SIZE=8 #每次喂入的数据组数
seed=23455 #随机种子
生成32组数据集和数据集的真实输出
rng=np.random.RandomState(seed)
X=rng.rand(32,2) #数据输入
Y=[[int(x0+x1<1)] for(x0,x1) in X] #输入数据集的正确答案
#定义神经网络输入输出、前向传播过程
x=tf.placeholder(tf.float32,shape=(None,2))
y_=tf.placeholder(tf.float32,shape=(None,2))
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)
#定义损失函数和反向传播方法
loss=tf.reduce_mean(tf.square(y-y_))
train_step=tf.train.GradientDescentOptimizer(0.001).minimize(loss)
#生成对话,训练step轮
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]})
#每500轮训练输出损失函数值
if i%500 ==0:
total_loss=sess.run(loss,feed_dict={x:X,y_:Y})
print loss
print "\n"
print "w1\n",sess.run(w1)
print "w2\n",sess.run(w2)
四、总结
- sess.run的功能有:
- 输出当前的神经网络参数(sess.run(w1))
- 完成参数变量初始化(sess.run(init_op))
- 通过喂给数据输入来计算预测值
- 通过喂给若干组数据(输入和输出)计算当前模型的损失函数值
- 通过喂给若干组数据(输入和输出)训练模型、优化模型参数。
- BATCH_SIZE是每一次训练模型喂入的数据组数,例如BATCH_SIZE=8,STEPS=80,数据组数=32;则每训练4轮就会喂入全部的数据组,总共喂入了20遍原始数据。
中国大学mooc《人工智能实践:Tensorflow笔记》