1. 参数计算
层数 = 隐藏层 + 1个输出层,所以上图为2层NN
总参数 = 总w + 总b
上图,输入层到隐藏层的参数:3×4+4;隐藏层到输出层的参数:4×2+2;共26个。
指数衰减学习率
可以先用较大的学习率,快速得到较优解,然后逐步减小学习率,使模型在训练后期稳定。
指数衰减学习率 = 初始学习率 × 学习率衰减率(当前轮数 / 多少轮衰减一次)
一般在epoch循环里面更新。
2. 激活函数
①Sigmoid函数
![](https://i-blog.csdnimg.cn/blog_migrate/6d49d1d83bfe34eb2b8d8c3c3c85a73b.png)
![](https://i-blog.csdnimg.cn/blog_migrate/eb8156082ca60c3e4a4996d6861425bb.png)
特点:(1)容易造成梯度消失 (深层神经网络在更新参数时,需要从输出层到输入层逐层链式 求导,而sigmoid函数的取值范围是0~0.25之间,链式求导需要多层导数逐层相乘,结 果趋近于0,出现梯度消失,结果无法更新)
(2)输出非0的均值,收敛慢
(3)幂运算复杂,训练时间长
②Tanh函数
![](https://i-blog.csdnimg.cn/blog_migrate/7b36f340a77cd18ca1329e8f52209899.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c87db14df506156a43b4150b922ae4d7.png)
特点:(1)容易造成梯度消失
(2)输出非0的均值,收敛慢
(3)幂运算复杂,训练时间长
③Relu函数
![](https://i-blog.csdnimg.cn/blog_migrate/9838096b126a82ace50bcdf0aaf8b544.png)
![](https://i-blog.csdnimg.cn/blog_migrate/0174b294db9eaa7837eb9fecf432bb28.png)
优点: 缺点:
(1)解决了梯度消失的问题(在正区间) (1)输出非0均值,收敛慢
(2)只需判断输入是否大于0,计算速度快 (2)Dead Relu问题,某些神经元可能永远不
(3)收敛速度远快于Sigmoid和Tanh 能被激活,导致相应参数永远不能被更 新。
④Leaky Relu函数
![](https://i-blog.csdnimg.cn/blog_migrate/5c37d26527000971b3edbee1fe930193.png)
![](https://i-blog.csdnimg.cn/blog_migrate/78e9fc6a93ca0e177a88d9efba5f7d31.png)
理论上Leaky Relu具有Relu的所有优点,外加不会有Dead Relu问题,但是在实际操作中,并没有完全证明Leaky Relu总是好于Relu。
2. 损失函数
NN优化目标:loss最小
①均方误差mse:
loss_mse = tf.reduce_mean( tf.square(y_-y))
案例:预测酸奶销量
建模前,应预先采集的数据有:每日x1、x2和销量y_(即已知答案,最佳情况:产量=销量)
拟造数据集X,Y:y_= x1 + x2 噪声:-0.05 ~ +0.05 拟合可以预测销量的函数
import tensorflow as tf
import numpy as np
SEED = 23455
rdm = np.random.RandomState(seed = SEED)
x = rdm.rand(32,2) # 生成0-1之间的随机数
y_ = [[x1 + x2 + rdm.rand()/10 - 0.5] for x1,x2 in x]
x = tf.cast(x, tf.float32)
w1 = tf.Variable(tf.random.normal([2,1], stddev=1, seed = 1))
lr = 0.002
epoch = 15000
for epoch in range(epoch):
with tf.GradientTape() as tape:
y = tf.matmul(x, w1)
loss_mse = tf.reduce_mean(tf.square(y_ - y))
grads = tape.gradient(loss_mse, w1)
w1.assign_sub(lr * grads)
if epoch%500 ==0 :
print("After %d training steps,w1 is " % (epoch))
print(w1.numpy(),"\n")
print("Final w1 is",w1.numpy())
②改进:自定义损失函数
如预测商品销量,预测多了,损失成本;预测少了,损失利益。
tf.reduce_sum(tf.where(tf.greater(y,y_), COST(y-y_),PROFIT(y_-y)))
③交叉熵损失函数:表征两个概率分布之间的距离
tf.losses.categorical_crossentropy(y_,y)
④softmax与交叉熵结合
输出先于softmax,再计算y与y_的交叉熵损失函数
y_ = np.array([[1,0,0],[0,1,0],[0,0,1],[1,0,0],[0,1,0]])
y = np.array([[12,3,2],[3,10,1],[1,2,5],[4,6.5,1.2],[3,6,1]])
y_pre = tf.nn.softmax(y)
loss_ce1 = tf.losses.categorical_crossentropy(y_,y_pre)
loss_ce2 = tf.nn.softmax_cross_entropy_with_logits(y_,y)
print("分布计算的结果:\n",loss_ce1)
print("结合计算的结果:\n",loss_ce2)
3. 过拟合和欠拟合
欠拟合解决方法: 过拟合解决方法:
增加输入特征 数据清洗
增加网络参数 增大训练集
减少正则化参数 采用正则化、增大正则化参数
正则化缓解过拟合
正则化在损失函数中引入模型复杂度指标,利用给w加权值,弱化了训练噪声(一般不正则化b)
正则化的选择
L1正则化大概率会使很多参数变为0,因此该方法课通过稀疏参数,即减少参数的数量,降低复杂度。
L2正则化会使参数很接近0但不为0,因此该方法可通过减小参数值的大小降低复杂度