本文主要是介绍TensorFlow学习笔记之三(神经网络的优化),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 1. 使用激活函数去线性化(为什么要用激活函数)
- 实验证明线性模型的局限性
- 常用激活函数
- 2. 神经网络复杂度:用网络层数和网络参数的个数表示
- 3. 损失函数(loss):预测值(y)与已知答案(y_)的差距
- 均方误差mse
- 交叉熵ce(Cross Entropy):表征两个概率分布之间的距离
- 4. softmax()函数:让n分类问题的n个输出(y1,y2, ...yn)满足概率分布
- 5. 学习率(learning_rate):决定每次参数更新的幅度
- 6. 滑动平均
- 7. 正则化
1. 使用激活函数去线性化(为什么要用激活函数)
TensorFlow游乐场:http://playground.tensorflow.org
对于上一篇的网络TensorFlow笔记之二可以抽象为如下形式,
[ y ] = [ a 1 , 1 a 1 , 2 a 1 , 3 ] ∗ [ w 1 , 1 ( 2 ) w 2 , 1 ( 2 ) w 2 , 1 ( 2 ) ] = [ x 1 x 2 ] ∗ [ w 1 , 1 ( 1 ) w 1 , 2 ( 1 ) w 1 , 3 ( 1 ) w 2 , 1 ( 1 ) w 2 , 2 ( 1 ) w 2 , 3 ( 1 ) ] ∗ [ w 1 , 1 ( 2 ) w 2 , 1 ( 2 ) w 2 , 1 ( 2 ) ] \begin{gathered} \begin{bmatrix} y \end{bmatrix} \end{gathered}=\begin{gathered} \begin{bmatrix} a_{1,1} & a_{1,2} & a_{1,3} \end{bmatrix} \end{gathered} *\begin{gathered} \begin{bmatrix} w^{(2)}_{1,1}\\w^{(2)}_{2,1}\\w^{(2)}_{2,1} \end{bmatrix} \end{gathered}= \begin{gathered} \begin{bmatrix} x_{1} & x_{2} \end{bmatrix} \end{gathered} *\begin{gathered} \begin{bmatrix} w^{(1)}_{1,1} & w^{(1)}_{1,2} & w^{(1)}_{1,3} \\ w^{(1)}_{2,1} & w^{(1)}_{2,2} & w^{(1)}_{2,3} \end{bmatrix} \end{gathered}* \begin{gathered} \begin{bmatrix} w^{(2)}_{1,1}\\w^{(2)}_{2,1}\\w^{(2)}_{2,1} \end{bmatrix} \end{gathered} [y]=[a1,1a1,2a1,3]∗⎣⎢⎡w1,1(2)w2,1(2)w2,1(2)⎦⎥⎤=[x1x2]∗[w1,1(1)w2,1(1)w1,2(1)w2,2(1)w1,3(1)w2,3(1)]∗⎣⎢⎡w1,1(2)w2,1(2)w2,1(2)⎦⎥⎤
其中,令:
W ′ = W ( 1 ) W ( 2 ) = [ w 1 , 1 ( 1 ) w 1 , 2 ( 1 ) w 1 , 3 ( 1 ) w 2 , 1 ( 1 ) w 2 , 2 ( 1 ) w 2 , 3 ( 1 ) ] ∗ [ w 1 , 1 ( 2 ) w 2 , 1 ( 2 ) w 2 , 1 ( 2 ) ] = [ w 1 ′ w 2 ′ ] W^{'}=W^{(1)}W^{(2)}= \begin{gathered} \begin{bmatrix} w^{(1)}_{1,1} & w^{(1)}_{1,2} & w^{(1)}_{1,3} \\ w^{(1)}_{2,1} & w^{(1)}_{2,2} & w^{(1)}_{2,3} \end{bmatrix} \end{gathered}* \begin{gathered} \begin{bmatrix} w^{(2)}_{1,1}\\w^{(2)}_{2,1}\\w^{(2)}_{2,1} \end{bmatrix} \end{gathered}= \begin{gathered} \begin{bmatrix} w^{'}_{1}\\w^{'}_{2} \end{bmatrix} \end{gathered} W′=W(1)W(2)=[w1,1(1)w2,1(1)w1,2(1)w2,2(1)w1,3(1)w2,3(1)]∗⎣⎢⎡w1,1(2)w2,1(2)w2,1(2)⎦⎥⎤=[w1′w2′]
这样,就可以得出
[ y ] = [ x 1 x 2 ] ∗ [ w 1 ′ w 2 ′ ] = w 1 ′ x 1 + w 2 ′ x 2 \begin{gathered} \begin{bmatrix} y \end{bmatrix} \end{gathered}= \begin{gathered} \begin{bmatrix} x_{1} & x_{2} \end{bmatrix} \end{gathered} * \begin{gathered} \begin{bmatrix} w^{'}_{1}\\w^{'}_{2} \end{bmatrix} \end{gathered}=w^{'}_{1}x_{1}+w^{'}_{2}x_{2} [y]=[x1x2]∗[w1′w2′]=w1′x1+w2′x2
可以看出,该网络虽然有两层,但是它在本质上与单层神经网络没有区别,因为它可以被一个单层网络表示。由此可以推断,如果只是每个神经元只是单纯的线性变换,多层的全连接网络与单层的全连接网络的表达能力没有区别(通过矩阵运算,最终都会变成一个矩阵)。它们最终都是y是关于x1和x2的一个线性模型,而且线性模型解决问题的能力是有限的,这就是线性模型的最大局限性。
实验证明线性模型的局限性
本次实验在TensorFlow游乐场中进行。
情景模拟:现在根据x1(零件长度与平均长度的差)和x2(零件质量与平均质量的差)来判断一个零件是否合格(二分类问题)。因此,当一个零件的长度和质量越接近平均值(x1和x2接近零),那么这个零件越可能合格。那么它可能呈现如下分布
图中蓝色的点代表合格的零件(x1和x2接近零)。黄色的点代表不合格的(x1或x2偏大)。
将激活函数选择线性模型。训练100轮后
发现并不能很好的将零件区分开来。
将激活函数选择ReLu,训练100轮。
可以发现模型很好的将零件区分开来了。
常用激活函数
2. 神经网络复杂度:用网络层数和网络参数的个数表示
由于输入层只接受数据,不做计算故输入层不算层数。
3. 损失函数(loss):预测值(y)与已知答案(y_)的差距
网络优化目标:loss最小。
常用loss:
- mse(Mean Squared Error) 均方误差
- 自定义
- ce(Cross Entropy)交叉熵
均方误差mse
当预测值(y)与已知答案(y_)越接近
–>均方误差MSE(y_, y)越接近0
–>损失函数的值越小
–模型预测效果越好
预测酸奶模型
# 预测import tensorflow as tf
import numpy as npBATCH_SIZE = 8
seed = 23455# 基于seed产生随机数
rng = np.random.RandomState(seed=seed)
X = rng.rand(32, 2)
Y_ = [[x1+x2+(rng.rand()/10.0-0.05)] for (x1, x2) in X]
Y = [[int(x0 + x1 <1)] for (x0, x1) in X]# 1、定义神经网络的输入、参数和输出,定义前向传播过程
x = tf.placeholder(tf.float32,shape=(None, 2)) # 知道每组有两个特征变量,但是不知道多少组,用None占位
y_ = tf.placeholder(tf.float32,shape=(None, 1)) # 存放真实的结果值,合格为1,w1 = tf.Variable(tf.random_normal([2, 1], stddev=1, seed=1))y = tf.matmul(x, w1)# 2、定义损失函数以及反向传播方法
loss = tf.reduce_mean(tf.square(y-y_)) # 使用均方误差计算loss
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss) # 学习率为0.001,并让损失函数让减小的方向优化# 3、生成会话,训练STEPS轮
with tf.Session() as sess:# 3.1、初始化参数值init_op = tf.global_variables_initializer()sess.run(init_op)print("w1:\n", sess.run(w1))print("\n")# 3.2、训练模型STEPS = 30000for i in range(STEPS):# 3.2.1 每轮确定读取数据集的游标start = (i*BATCH_SIZE) % 32end = start + BATCH_SIZE# 3.2.2 喂入数据,开始训练sess.run(train_step, feed_dict={x: X[start:end], y_: Y_[start:end]})# 3.2.3 每500轮输出一次loss值if i % 500 == 0:print("每500轮输出一次w1的值\n")print(sess.run(w1), "\n")total_loss = sess.run(loss, feed_dict={x: X, y_: Y})print("After % dtraining step(s), cross entropy on all data is % g" % (i, total_loss))print("w1:\n", sess.run(w1))
交叉熵ce(Cross Entropy):表征两个概率分布之间的距离
H ( y , y ) = − Σ y − ∗ l o g y H(y_,y) = -Σy_-*log y H(y,y)=−Σy−∗logy
4. softmax()函数:让n分类问题的n个输出(y1,y2, …yn)满足概率分布
∀ x P ( X = x ) ∈ [ 0 , 1 ] 且 ∑ x P ( X = x ) = 1 s o f t m a x ( y [ ] ) {\forall}x P(X = x) \in [0,1] 且 \sum_{x} P(X = x) =1 softmax(y[]) ∀xP(X=x)∈[0,1]且x∑P(X=x)=1softmax(y[])
前面已经讲过,损失函数是用来衡量模型预测值与真实值之间的差值。即模型好坏的标准。一个模型越好,它的损失函数越小。因此,
神经网络的优化=减小损失函数
5. 学习率(learning_rate):决定每次参数更新的幅度
w n + 1 = w n − l e a r n i n g r a t e w_{n+1}=w_{n}-learning_rate wn+1=wn−learningrate
6. 滑动平均
滑动平均(影子值):记录了每个参数一段时间内过往值得平均,增加了模型的泛化性。
针对所有的参数:w和b(类似给参数加了影子,参数变化,影子缓慢追随)
影子初始值=参数初始值
影子(滑动平均值) = 衰减率 * 影子 + (1-衰减率)* 参数
衰减率 = min{MOVING_AVERAGE_DECAY, (1+轮数)/(10+轮数)}
栗子:
MOVING_AVERAGE_DECAY(超参数:训练之前设置的参数)为0.99,
参数w1初始值为0
w1的滑动平均初始值为0
轮数global_step=0
w1 = 1
w1滑动平均值 = 0
衰减率 = min(0.99, 1/10)=0.1
w1滑动平均值 = 0.1 * 0 +(1-0.1) *1 = 0.9
所以,第0轮过后,w1的滑动平均值更新为0.9
global_step=100
w1 = 10
w1滑动平均值 = 0.9
衰减率 = min(0.99, 101/110)=0.918
w1滑动平均值 = 0.918 * 0.9 +(1-0.918) *10 = 0.8262 + 0.82 = 1.6482(误差由于四舍五入引起)
7. 正则化
正则化的意义是为了防止过拟合。
这篇关于TensorFlow学习笔记之三(神经网络的优化)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!