一、预备知识
1.tf.where(条件语句,真返回A,假返回B)
2.np.random.RandomState.rand(维度) 返回一个[0,1)之间的随机数
3.np.vstack(数组1,数组2) 将两个数组按垂直方向叠加
4.np.mgrid[ 起始值 : 结束值 : 步长 ,起始值 : 结束值 : 步长 , … ][起始值 结束值) x.ravel( ) 将x变为一维数组,“把 . 前变量拉直” np.c_[ 数组1,数组2, … ],使返回的间隔数值点配对 例:
二、复杂度和学习率
复杂度的表示:
指数衰减学习率:
三、激活函数
在之前关于深度学习的文章中我已经写过为什么要使用激活函数(非线性函数)
1.激活函数应具备的特点:
2.激活函数的输出范围:
![](https://i-blog.csdnimg.cn/direct/712669a6ba0e4a758eb23caaa25d1a8c.png)
![](https://i-blog.csdnimg.cn/direct/af12dad923884f12ac05523b93360225.png)
![](https://i-blog.csdnimg.cn/direct/012f7406e4064b4cbbe5ce905de0fe2a.png)
建议:
1.首选relu激活函数;
2. 学习率设置较小值;
3.输入特征标准化,即让输入特征满足以0为均值, 1为标准差的正态分布;
四、损失函数
1.均方误差
实例:
import tensorflow as tf
import numpy as np
SEED = 23455
rdm = np.random.RandomState(seed=SEED) # 生成[0,1)之间的随机数
x = rdm.rand(32, 2)
y_ = [[x1 + x2 + (rdm.rand() / 10.0 - 0.05)] for (x1, x2) in x] # 生成噪声[0,1)/10=[0,0.1); [0,0.1)-0.05=[-0.05,0.05)
x = tf.cast(x, dtype=tf.float32)
w1 = tf.Variable(tf.random.normal([2, 1], stddev=1, seed=1))
epoch = 15000
lr = 0.002
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())
2.自定义 :
可以看到自定义后两个参数都大于1,通过自定义实现了我们想要的预测函数往多了预测。
3.交叉熵损失函数
在解决分类问题时,我们通常将softmax与交叉熵损失函数结合使用
tf.nn.softmax_cross_entropy_with_logits(y_, y)
五、缓解过拟合
欠拟合的解决方法:增加输入特征项 ;增加网络参数 ;减少正则化参数
![](https://i-blog.csdnimg.cn/direct/701ed52058d74c7ab52299887bac9783.png)
正则化实现代码 :
# 采用均方误差损失函数mse = mean(sum(y-out)^2)
loss_mse = tf.reduce_mean(tf.square(y_train - y))
# 添加l2正则化
loss_regularization = []
# tf.nn.l2_loss(w)=sum(w ** 2) / 2
loss_regularization.append(tf.nn.l2_loss(w1))
loss_regularization.append(tf.nn.l2_loss(w2))
# 求和
# 例:x=tf.constant(([1,1,1],[1,1,1]))
# tf.reduce_sum(x)
# >>>6
loss_regularization = tf.reduce_sum(loss_regularization)
loss = loss_mse + 0.03 * loss_regularization # REGULARIZER = 0.03
六、优化器
计算步骤:
1.SGD(随机梯度下降)
实现代码 :
w1.assign_sub(lr * grads[0])
b1.assign_sub(lr * grads[1])
2. SGDM(含momentum的SGD),在SGD基础上增加一阶动量
实现代码:
#初始化m_w, m_b
m_w, m_b = 0, 0
beta = 0.9
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)
3.Adagrad,在SGD基础上增加二阶动量
实现代码:
v_w, v_b = 0, 0
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))
4. RMSProp,SGD基础上增加二阶动量
实现代码 :
v_w, v_b = 0, 0
beta = 0.9
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))
5. Adam, 同时结合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 #每次循环时会+1
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))