学会神经网络优化过程,使用正则化减少过拟合,使用优化器更新网络参数
预备知识
神经网络复杂度
指数衰减学习率
激活函数
损失函数
欠拟合与过拟合
正则化减少过拟合
优化器更新网络参数
tf.where(条件语句,真返回A,假返回B)
如
a=tf.constant([1,2,3,1,1])
b=tf.constant([0,1,3,4,5])
c=tf.where(tf.greater(a,b),a,b)#若a>b,返回a对应位置的元素,否则返回b对应位置的元素
print("c:",c)
输出
np.random.RandomState.rand(维度) # 维度为空,则返回标量
返回一个[0,1)之间的随机数
rdm=np.random.RandomState()
a=rdm.rand()
b=rdm.rand(2,3)
print("a:",a)
print("b:",b)
输出
np.vstack(数组1,数组2)
将两个数组按垂直方向叠加
a=np.array([1,2,3])
b=np.array([4,5,6])
c=np.vstack((a,b))
print("c:\n",c)
np.mgrid[],.ravel(),np.c_[]
np.mgrid[起始值:结束值:步长,起始值:结束值:步长,…]
生成一个网格数组,[起始值,结束值)
x.ravel()
将x变为一维数组,把.前变量拉直
np.c_[数组1,数组2…]
使返回的间隔数值点配对
#生成等间隔数值点
x,y=np.mgrid[1:3:1,2:4:0.5]#,前的决定行数:2,后的决定列数:4
#将x,y拉直,并合并配对为二维张量,生成二维坐标点
grid=np.c_[x.ravel(),y.ravel()]
print("x:\n",x)
print("y:\n",y)
print('grid:\n',grid)
神经网络复杂度
指数衰减学习率
可以先使用较大的学习率,快速得到较优解,然后逐步减小学习率,使模型在训练后期稳定
指数衰减学习率=初始学习率*学习率衰减率**(当前论述/多少论衰减一次)
w = tf.Variable(tf.constant(5, dtype=tf.float32))
epoch = 40
LR_BASE = 0.2 # 最初学习率
LR_DECAY = 0.99 # 学习率衰减率
LR_STEP = 1 # 喂入多少轮BATCH_SIZE后,更新一次学习率
for epoch in range(epoch): # for epoch 定义顶层循环,表示对数据集循环epoch次,此例数据集数据仅有1个w,初始化时候constant赋值为5,循环40次迭代。
lr = LR_BASE * LR_DECAY ** (epoch / LR_STEP)
with tf.GradientTape() as tape: # with结构到grads框起了梯度的计算过程。
loss = tf.square(w + 1)
grads = tape.gradient(loss, w) # .gradient函数告知谁对谁求导
w.assign_sub(lr * grads) # .assign_sub 对变量做自减 即:w -= lr*grads 即 w = w - lr*grads
print("After %s epoch,w is %f,loss is %f,lr is %f" % (epoch, w.numpy(), loss, lr))
输出
1.非线性
2.可微性
3.单调性
4.近似恒等性:f(x)≈x,当参数初始化为随机小值时,神经网络更稳定
1.激活函数输出为有限值时,基于梯度的优化方法更稳定
2.激活函数输出为无限值时,建议调小学习率
tf.nn.sigmoid(x)
特点:
1.易造成梯度消失
2.输出非0均值,收敛慢
3.幂运算复杂,训练时间长
tf.math.tanh(x)
特点:
1.输出是0的均值
2.易造成梯度消失
3.幂运算复杂,训练时间长
tf.nn.relu(x)
优点:
1.解决了梯度消失问题(正区间内)
2.只需判断输入是否大于0,计算速度快
3.收敛速度远快于sigmoid和tanh
缺点:
1.输出非0均值,收敛慢
2.deadRelu问题:某些神经元可能永远不会被激活,导致相应的参数永远不能被更新
tf.nn.leaky_relu(x)
Leaky relu不会有deadRelu问题,但实际 *** 作中,使用relu还是更多一点
有三种损失函数:mse,自定义,交叉熵(ce)
均方误差:
loss_mse=tf.reduce_mean(tf.square(y-y_))
交叉熵:
表征两个概率分布之间的距离,越小越好
tf.losses.categorical_crossentropy(y_,y)
一般计算交叉熵之前需要先softmax一下:
y_pro=tf.nn.softmax(y)
loss_ce1=tf.losses.categorical_crossentropy(y_,y_pro)
tensorflow提供一个函数可以代替以上两句:
tf.nn.softmax_cross_entropy_with_logits(y_,y)
loss_ce2=tf.nn.softmax_cross_entropy_with_logits(y_,y)
欠拟合与过拟合
若自己预测的图线不平滑,则是过拟合
1.增加输入特征项
2.增加网络参数
3.减少正则化参数
1.数据清洗:减小噪声
2.增大训练集
3.采用正则化
4.增大正则化参数
正则化在损失函数中引入模型复杂度指标,利用给w加权值,弱化了训练数据的噪声(一般不正则化b)
loss=loss(y_,y)+regularizer*loss(w)
第一部分是之前所求的损失函数,如mse,ce等
第二部分中regularizer是超参数,给出w在总loss中的比例,即正则化权重
Loss(w)有两种计算方法:
L1正则化可使很多参数变为零,因此该方法可通过稀疏参数,降低复杂度
L2正则化可使参数接近零但不为零,因此该方法可通过减小参数值的大小降低复杂度
待优化参数w,损失函数loss,学习率lr,每次迭代一个batch,t表示当前batch迭代的总次数
1.计算t时刻损失函数关于当前参数的梯度
2.计算t时刻一阶动量m_t 和二阶动量V_t
3.计算t时刻下降梯度
4.计算t+1时刻参数:
一阶动量:与梯度相关的函数
二阶动量:与梯度平方相关的函数
#实现梯度更新w1=w1-lr*w1_gradb=b-lr*b_grad
w1.assign_sub(lr*grads[0])#参数w1自更新
b1.assign_sub(lr*grads[1])#参数b自更新
SGDM优化器,在SGD基础上增加了一阶动量
β是超参数,经验值是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)
adagrad优化器,在SGD基础上增加二阶动量
#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))
RMSProp优化器,在SGD基础上增加二阶动量
#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))
adam优化器,同时结合SGDM一阶动量和RMSProp二阶动量
#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))
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)