神经网络的复杂度
1.空间复杂度
层数 = 隐藏层的层数 + 1个输出层
总参数 = 总w + 总b
2.时间复杂度
乘加运算次数 = 总w
指数衰减学习率
指数衰减学习率 = 初始学习率 * 学习率衰减率^(当前轮数/多少轮衰减一次)
- 初始学习率:最初的学习率
- 学习率衰减率:学习率按照这个比例指数衰减
- 当前轮数:可以用当前迭代了多少次数据集也就是epoch表示,也可以用当前迭代了多少次batch表示
- 多少轮衰减一次:迭代多少次更新一次学习率,决定了学习率更新的频率
例: poch = 50 r_base = 0.2 r_decay = 0.99 r_step = 1 or epoch in range(epoch): lr = lr_base * lr_decay ** (epoch/lr_step) with tf.GradientTape() as tape: loss = tf.square(w + 1) grads = tape.gradient(loss, w) w.assign_sub(lr * grads)
激活函数
线性函数表达力不够
优秀的激活函数:
非线性:只有激活函数是非线性时,
才不会被单层网络所替代,
使得多层网络有了意义,
而多层网络可逼近所有函数
可微性:优化器大多使用梯度下降法更新参数,
若激活函数不可微,就不能更新参数
单调性:当激活函数是单调的,能保证单层网络的损失函数是凸函数,更容易收敛
近似恒等性:f(x) ≈ x
当参数初始值为随机小数时,神经网络更稳定
igmoid函数
f.nn.sigmoid(x)
anh函数
f.nn.tanh(x)
elu函数
f.nn.relu(x)
eaky Relu函数
f.nn.leaky_relu(x)
对初学者的建议:
首选relu激活函数
学习率设置较小值
输入特征标准化,即让输入特征满足以0为均值,1为标准差的正态分布
初始参数中心化,即让随机生成的参数满足以0为均值,√(2/当前层输入特征个数)为标差的正态分布
损失函数loss:
前向传播预测结果y与已知标准答案y_的差距
神经网络的优化目标就是找到某套参数,
使得预测结果与标准答案无限接近,即loss值最小
主流loss有三种:
均方误差
oss_mse = tf.reduce_mean(tf.square(y_ - y))
交叉熵
交叉熵越大,两个概率分布越远
交叉熵越小,两个概率分布越近
f.losses.categorical_crossentropy(y_, y)
执行分类问题时,
ensorflow给出了同时计算概率分布和交叉熵的函数
f.nn.softmax_cross_entropy_with_logits(y_, y)
欠拟合与过拟合
欠拟合:模型不能有效拟合数据集
过拟合:模型对数据拟合太好,
但缺乏泛化力,对新数据难以做出判断
欠拟合的解决方法:
增加输入特征项
增加网络参数
减少正则化参数
过拟合的解决方法:
数据清洗
增大训练集
采用正则化
增大正则化参数
正则化减少过拟合:
给w加权重,抑制训练中的噪声
通常只对w使用,不对b使用
oss = loss(y_, y) + regularizer * loss(w)
oss(y_, y):原loss值
egularizer:参数w在总loss中的比重
oss(w):对所有w求和(L1正则化)
对所有w的平方求和(L2正则化)
1正则化大概率会使很多参数变为0
可用来稀疏参数,降低模型复杂度
2正则化会使参数接近0但不等于0
可用来减小参数的数值
有效缓解数据集中因噪声引起的过拟合
例:
with tf.GradientTape() as tape:
。。。
# 寄存所有w L2正则化后的结果
loss_regularization = []
# 将w 做L2正则化处理,并即存在loss_regularization中
loss_regularization.append(tf.nn.l2_loss(w1))
loss_regularization.append(tf.nn.l2_loss(w2))
# 计算参数w L2正则化后的总和
loss_regularization = tf.reduce_sum(loss_regularization)
loss = loss + 0.03 * loss_regularization
优化器更新网络参数