第四节--导数复习以及多线性回归

39 篇文章 0 订阅
8 篇文章 0 订阅

一、导数复习

1、正切 tan
定义:tanθ=y/x 如下图
在这里插入图片描述
2、导数
在这里插入图片描述
在这里插入图片描述
3、偏导数
偏导数:当有多元函数是,针对于不同的自变量,描述函数变化率的公式。
在这里插入图片描述

二、梯度下降的几个问题

1、梯度下降
梯度下降是一种非常通用的优化算法,能够为大范围的问题找到最优解。梯度下降的中心思想就是迭代的调整参数从而使损失函数最小化。

假设你迷失在山上的浓雾之中,你能感觉到的只有你脚下路面的坡度。快速到达山脚的一个策略就是沿着最陡的方向下坡。这就是梯度下降的做法:通过测量参数向量θ相关的误差函数的局部梯度,并不断沿着降低梯度的方向调整,直到梯度降为0,到达最小值。

具体来说,首先使用一个随机的θ值(这被称为随机初始化),然后逐步改良,每次踏出一步,每一步都尝试降低一点损失函数(如MSE),直到算法收敛出一个最小值。
2、梯度下降的方向

  • 梯度下降的方向1:只要对损失函数求导,θ的变化方向永远趋近于损失函数的最小值。
  • 梯度下降的方向2: 如果θ已经在最低点,那么梯度将不会发生变化。

3、梯度下降的步长

  • 梯度下降的步长1:梯度下降中一个重要参数是每一步的步长,这取决于超参数的学习率。
  • 梯度下降的步长2:梯度下降的步长会逐渐变小。

3、如何应对梯度下降的局部最小值问题

  1. 对于MSE来说,因为损失函数是个凸函数,所以不存在局部最小值,只有一个全局最小值。
  2. 通过随机初始化θ,可以避开局部最小值。
  3. 对于多变量,高维度的值,就算在某个维度上陷入和局部最小值,但是还能从别的维度跳出。

三、多变量线性回归

1、多变量线性回归引入
模型:
之前: hθ(x) = θ0 + θ1x
现在: hθ(x) = θ0 + θ1x1 + θ2x2 + … + θnxn
为了保证模型的统一性,我们给模型加上x0 ,并使 x0 = 1。
多项型回归代码案例:

"""
多项式回归
"""

import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression

m = 100
X = 6 * np.random.rand(m, 1) - 3
y = 0.5 * X ** 2 + X + 2 + np.random.randn(m, 1)

plt.plot(X, y, 'b.')
# plt.show()

d = {1: 'g-', 2: 'r+', 10: 'y*'}
for i in d:
    # include_bias 可以理解为w0 =False 意思就是不要w0
    poly_features = PolynomialFeatures(degree=i, include_bias=False)
    """
    fit 和 fit_transform的区别
    fit: 简单来说,就是求得训练集X的均值,方差,最大值,最小值这些训练集X固有的属性
    fit_transform: 首先fit,然后在此基础上,进行标准化,降维,归一化等操作
    """
    X_poly = poly_features.fit_transform(X)
    print(X[0])
    print(X_poly[0])
    # print(X_poly[:, 0])

    lin_reg = LinearRegression()
    lin_reg.fit(X_poly, y)
    # print(lin_reg.intercept_, lin_reg.coef_)

    y_predict = lin_reg.predict(X_poly)
    plt.plot(X_poly[:, 0], y_predict, d[i])

plt.show()

2、多元梯度下降方法
模型: hθ(x) = θT x = θ0x0 + θ1x1 + θ2x2 + … + θnxn
参数: θ0 θ1…θn
损失函数:在这里插入图片描述
梯度下降公式:在这里插入图片描述
一元与多元梯度下降对比:
在这里插入图片描述
3、特征缩放(归一化)
一般情况下我们我们使用特征缩放,把特征值会缩放到接近 -1 ≤ xi ≤ 1的区域。
 左图的梯度下降算法直接走向最小值,可以快速到达。而在右图中,先是沿着与全局最小值方向近乎垂直的方向前进,接下来是一段几乎平坦的长长的山谷。最终还是会抵达最小值,但是这需要花费大量的时间
左图的梯度下降算法直接走向最小值,可以快速到达。而在右图中,先是沿着与全局最小值方向近乎垂直的方向前进,接下来是一段几乎平坦的长长的山谷。最终还是会抵达最小值,但是这需要花费大量的时间。

特征缩放是为了确保i特征在一个数量级上。
4、学习率
我们通常通过损失u函数来确保梯度下降在正常工作。
4.1、如果损失函数下降的幅度小于10-3,那我们就说损失函数已经收敛了
或者使用自动收敛测试。
4.2、当损失函数上升的时候,证明梯度下降方法没有正常工作,这时候可以使用小一点的学习率α

对于足够小的学习率α而言,损失函数应该每次都下降
但是如果学习率α太小,收敛的速度将会很慢。

5、随机梯度下降
代码案例:

"""
随机梯度下降
"""
import numpy as np
import random

X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]
# print(X_b)

n_epochs = 500
a0 = 0.1
decay_rate = 1

m = 100
num = [i for i in range(100)]

def learning_schedule(epoch_num):
    return (1 / (decay_rate * epoch_num + 1)) * a0

theta = np.random.randn(2, 1)

# epoch 是轮次的意思,意思是用m个样本做一轮迭代
for epoch in range(n_epochs):
    # 生成100个不重复的随机数
    rand = random.sample(num, 100)
    for i in range(m):
        random_index = rand[i]
        xi = X_b[random_index:random_index+1]
        yi = y[random_index:random_index+1]
        gradients = xi.T.dot(xi.dot(theta)-yi)
        learning_rate = learning_schedule(epoch+1)
        theta = theta - learning_rate * gradients

print(theta)

6、“Batch” Gradient Descent 批梯度下降
代码案例:

"""
线性回归实现梯度下降的批处理(batch_gradient_descent )
"""
import numpy as np


X1 = 2 * np.random.rand(100, 1)
X2 = 4 * np.random.rand(100, 1)
X3 = 6 * np.random.rand(100, 1)

y = 4 + 3 * X1 + 4 * X2 + 5 * X3 + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X1, X2, X3]

learning_rate = 0.01
# 通常在做机器学习的时候,一般不会等到他收敛,因为太浪费时间,所以会设置一个收敛次数
n_iterations = 1000
m = 100

# 1.初始化theta, w0...wn
theta = np.random.randn(4, 1)
# print(theta)
count = 0
num = [i for i in range(100)]

for epoch in range(100):
    # 生成了100个不重复的随机数
    import random
    rand = random.sample(num, 100)
    for i in range(m):
        random_index = rand[i]
        xi = X_b[random_index:random_index+1]
        yi = y[random_index:random_index+1]
        print(xi, yi)
        gradients = xi.T.dot(xi.dot(theta)-yi)
        theta = theta - learning_rate * gradients
        # 利用损失函数监控模型
        loss = 1/(2 * m) * np.sum((X_b.dot(theta)-y) ** 2)
        count += 1
        # print(count, loss)





#4. 不会设置阈值,之间设置超参数,迭代次数,迭代次数到了,我们就认为收敛了
for iteration in range(n_iterations):
    count += 1
    # 2. 接着求梯度gradient
    gradients = 1/m * X_b.T.dot(X_b.dot(theta)-y)
    # print(gradients)
    # 3. 应用公式调整theta值, theta_t + 1 = theta_t - grad * learning_rate
    theta = theta - learning_rate * gradients
    # # 利用损失函数监控模型
    loss = 1/(2 * m) * np.sum((X_b.dot(theta)-y) ** 2)
    print(count, loss)

# print(count)
print(theta)

7、‘Mini-batch’梯度下降

  • 如果 mini-batch 大小 = m : 那他就是批梯度下降。
  • 如果 mini-batch 大小 = 1 : 那他就是随机梯度下降。(代码在上第六点随机下降)。
  • 如果 mini-batch 1 < 大小 < m :那他就是‘Mini-batch’随机梯度下降。

当:mini-batch= m
代码案例:

"""
随机梯度下降
"""
import numpy as np
import random

X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]
# print(X_b)

n_epochs = 500
t0, t1 = 5, 50

m = 100
num = [i for i in range(100)]

def learning_schedule(t):
    return t0 / (t + t1)

theta = np.random.randn(2, 1)

batch_num = 5
batch_size = m // 5


# epoch 是轮次的意思,意思是用m个样本做一轮迭代
for epoch in range(n_epochs):
    # 生成100个不重复的随机数
    for i in range(batch_num):
        start = i*batch_size
        end = (i+1)*batch_size
        xi = X_b[start:end]
        yi = y[start:end]
        gradients = 1/batch_size * xi.T.dot(xi.dot(theta)-yi)
        learning_rate = learning_schedule(epoch*m + i)
        theta = theta - learning_rate * gradients

print(theta)

三中梯度下降的总结:
在这里插入图片描述
随机梯度下降会丧失向量带来的加速,所以我们不会太用随机梯度下降。
如何选择:

  • 训练集比较小: 使用批梯度下降(小于2000个)。
  • 训练集比较大:使用Mini-bitch梯度下降 一般的Mini-batch size 是64,128,256, 512,1024
    Mini-batch size要适用CPU/GPU的内存。

8、Lass 回归
Lasso回归和岭回归类似,不同的是,Lasso可以理解为在线性回归基础上加入一个L1正则项,同样来限制W不要过大。其中λ>0,通过确定λ的值可以使得模型在偏差和方差之间达到平衡,随着λ的增大,模型的方差减小,偏差增大。

"""
Lasso 回归

Lasso用的是l1的正则化
"""
import numpy as np
from sklearn.linear_model import Lasso
from sklearn.linear_model import SGDRegressor

X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)

lasso_reg = Lasso(alpha=0.15)
lasso_reg.fit(X, y)
print(lasso_reg.predict([[1.5]]))
print(lasso_reg.coef_)

sgd_reg = SGDRegressor(penalty='l1', n_iter=1000)
sgd_reg.fit(X, y.ravel())
print(sgd_reg.predict([[1.5]]))
print(sgd_reg.coef_)

9、岭回归
针对高方差,即过拟合的模型,解决办法之一就是对模型进行正则化:限制参数大小(由于本篇博客所提到的岭回归和Lasso都是正则化的特征选择方法,所以对于其他解决过拟合的方法不多赘述)当线性回归过拟合时,权重系数wj就会非常的大,岭回归就是要解决这样的问题。岭回归(Ridge Regression)可以理解为在线性回归的损失函数的基础上,加,入一个L2正则项,来限制W不要过大。其中λ>0,通过确定λ的值可以使得模型在偏差和方差之间达到平衡,随着λ的增大,模型的方差减小,偏差增大。
代码案例:

"""
岭回归
岭回归运用了L2正则化
"""
import numpy as np
from sklearn.linear_model import Ridge
from sklearn.linear_model import SGDRegressor


X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)

# alpha是惩罚项里的alpha, solver处理数据的方法,auto是根据数据自动选择,svd是解析解,sag就是随机梯度下降
ridge_reg = Ridge(alpha=1, solver='auto')
# 学习过程
ridge_reg.fit(X, y)
# 预测
print(ridge_reg.predict([[1.5], [2], [2.5]]))
# 打印截距
print(ridge_reg.intercept_)
# 打印系数
print(ridge_reg.coef_)

"""
岭回归和sgd & penalty=2是等价的
"""
sgd_reg = SGDRegressor(penalty='l2')
sgd_reg.fit(X, y.ravel())
print(sgd_reg.predict([[1.5], [2], [2.5]]))
# 打印截距
print("W0=", sgd_reg.intercept_)
# 打印系数
print("W1=", sgd_reg.coef_)

10、学习率衰减
在做Mini-batch的时候,因为噪声的原因,可能训练结果不是收敛的,而是在最低点周围晃动,如果我们要解决这个问题,那我们就需要减少学习率,让他在尽量小的范围内晃动。

1 epoch = 1 次遍历所有的数据。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值