目标:学会神经网络优化过程,使用正则化减少过拟合,使用优化器更新网络参数
这里先介绍几个需要掌握的函数
条件语句为真返回A,假返回B
tf.where(条件语句,真返回A,假返回B)
返回一个[0,1]之间的随机数,若维度为空,则返回标量
np.random.RandomState.rand(维度)
将两个数组按垂直方向叠加
np.vstack(数组1,数组2)
三个函数经常一起使用,生成网格坐标线
.mgrid[] 返回若干组维度相同的等差数组,每一组有起始值、结束值和步长,起始值和结束值是前闭后开区间
.ravel() 把多维数组变成一维数组,相当于把点前的数组拉直
np.mgrid[起始值:结束值:步长 , 起始值:结束值:步长 , ...]
x.ravel() #把多维数组变成一维数组,相当于把点前的数组拉直
np.c_[数组1 , 数组2 , ...] #使返回的间隔数值点配对
在实际应用中,可以先用较大的学习率,快速找到较优值,然后逐步减小学习率,使模型找到最优解,在训练后期稳定。
当前轮数:是一个变量,可以用当前迭代了多少次数据集(epoch),或者当前一共迭代了多少次batch(global_step)表示
多少轮衰减一次:是迭代多少次数据集/迭代多少次batch更新一次学习率,决定了学习率更新频率
激活函数输出值的范围
缺点
为解决Relu函数负区间为0,引起神经元死亡问题而设计的。
理论上来讲,Leaky Relu有Relu的所有优点,外加不会有Dead Relu问题,但是在实际操作当中并没有完全证明Leaky Relu总是好于Relu
√(2/当前层输入特征个数)
为标准差的正态分布loss_mse = tf.reduce_mean(tf.square(y_-y))
tf.losses.categorical_crossentropy(y_,y)
在执行分类问题时,通常先用softmax函数让结果符合概率分布,然后再计算交叉熵损失函数,这里给出一个可以同时计算概率分布和交叉熵的函数。(也就是输出先过softmax函数,再计算y和y_的交叉熵损失函数)
tf.nn.softmax_cross_entropy_with_logits(y_,y)
欠拟合:模型不能有效拟合数据集,对现有数据集学习的不够彻底
过拟合:模型对当前数据拟合的太好,但对从未见过的新数据,难以做出正确的判断,模型缺乏泛化力。
欠拟合解决方法
过拟合解决方法
首先明确几个参数
下面介绍五种参数优化器
#sgd
w1.assign_sub(lr * grads[0]) #参数w自更新
b1.assign_sub(lr * grads[1]) #参数b自更新
在SGD基础上增加了一阶动量
代码
beta是超参数,经验值0.9
m_w,m_b = 0,0
beta = 0.9
# sgd-momentun
m_w = beta * m_w + (1 - beta) * grads[0]
m_b = beta * m_b + (1 - beta) * grads[1]
w1.assign_sub(lr * m_w)
b1.assign_sub(lr * m_b)
v_w,v_b = 0,0
# adagrad
v_w += tf.square(grads[0])
v_b += tf.square(grads[1])
w1.assign_sub(lr * grads[0] / tf.sqrt(v_w))
b1.assign_sub(lr * grads[1] / tf.sqrt(v_b))
v_w,v_b = 0,0
beta = 0.9
# rmsprop
v_w = beta * v_w + (1 - beta) * tf.square(grads[0])
v_b = beta * v_b + (1 - beta) * tf.square(grads[1])
w1.assign_sub(lr * grads[0] / tf.sqrt(v_w))
b1.assign_sub(lr * grads[1] / tf.sqrt(v_b))
同时结合SGDM一阶动量和RMSProp二阶动量
有修正公式
代码
m_w,m_b = 0,0
v_w,v_b = 0,0
beta1,beta2 = 0.9,0.999
delta_w,delta_b = 0,0
global_step = 0
# adam
m_w = beta1 * m_w + (1 - beta1) * grads[0]
m_b = beta1 * m_b + (1 - beta1) * grads[1]
v_w = beta2 * v_w + (1 - beta2) * tf.square(grads[0])
v_b = beta2 * v_b + (1 - beta2) * tf.square(grads[1])
m_w_correction = m_w / (1 - tf.pow(beta1,int(global_step)))
m_b_correction = m_b / (1 - tf.pow(beta1,int(global_step)))
v_w_correction = v_w / (1 - tf.pow(beta2,int(global_step)))
v_b_correction = v_b / (1 - tf.pow(beta2,int(global_step)))
w1.assign_sub(lr * m_w_correction / tf.sqrt(v_w_correction))
b1.assign_sub(lr * m_b_correction / tf.sqrt(v_b_correction))