李宏毅机器学习笔记p3-p4


前言

经过上一篇章的学习,我们得知了有很多种深度学习,比如监督学习,无监督学习,强化学习等,监督学习算是深度学习的入门第一手,所以我们先学习监督学习中的回归


一:Regression回归

定义:前期学习(通过很多正确的输入和输出——>找到一个函数function),然后再输入特征x,输出一个结果。
步骤
1.先选择模型
2.通过损失函数判断和结果的接近程度
3.通过梯度下降不断修正模型

1.线性模型

单个特征:
y = b + w x y = b + wx y=b+wx
多个特征:
y = b + ∑ w i x i y = b + \sum {{w_i}{x_i}} y=b+wixi

x:各种特征;w:各个特征的权重; b:偏移量。
多个特征——>联系到向量和矩阵,可以方便计算。

2.损失函数

作用:通过损失函数来评判模型的好坏
损失函数有很多种,一般是用均方误差交叉熵误差等。

均方误差
E = 1 2 ∑ k ( y k − t k ) 2 E = \frac{1}{2}\sum\limits_k {{{({y_k} - {t_k})}^2}} E=21k(yktk)2
其中, E {E} E针对单个数据的损失函数, y k {y_k} yk表示神经网络的输出, t k {t_k} tk表示监督数据,k表示数据的维数。
交叉熵误差
E = − ∑ k t k log ⁡ y k E = - \sum\limits_k {{t_k}\log {y_k}} E=ktklogyk
其中, E {E} E针对单个数据的损失函数, y k {y_k} yk表示神经网络的输出, t k {t_k} tk表示正确解标签,只有正确解标签处的值才为1,其他都为0.

在老师讲课过程中,主要以均方误差来表示损失函数。
例如:统计10组原始数据 ( y ^ − f ( x n c p ) ) 2 {(\hat y - f({x^n}_{cp}))^2} (y^f(xncp))2之和,和越小越好。
意思就是算出预测出来的值和真实的值的差越小越好。
L ( f ) = ∑ n = 1 10 ( y ^ n − f ( x n c p ) ) 2 L(f) = \sum\limits_{n = 1}^{10} {{{({{\hat y}^n} - f({x^n}_{cp}))}^2}} L(f)=n=110(y^nf(xncp))2
f ( x ) = y f(x) = y f(x)=y
y = b + w x c p y = b + w{x_{cp}} y=b+wxcp
将上文的三个式子总和可得最终损失函数Loss function:
L ( w , b ) = ∑ n = 1 10 ( y ^ n − f ( b + w x c p n ) ) 2 L(w,b) = \sum\limits_{n = 1}^{10} {{{({{\hat y}^n} - f(b + w{x_{cp}}^n))}^2}} L(w,b)=n=110(y^nf(b+wxcpn))2
拓展:此处 f ( x ) = y f(x) = y f(x)=y较为省略,更应该的是此处加一个激活函数,应更正为 f ( x ) = h ( y ) f(x) =h(y) f(x)=h(y)

3.梯度下降

为了使损失函数最小,结果更优,我们需要不断调整参数 ( w , b ) (w,b) (w,b),这里我们就用到梯度下降的方法。
先从只有一个参数w入手,任何可微分的L都可以
w ∗ = arg ⁡ min ⁡ x L ( w ) {w^*} = \arg \mathop {\min }\limits_x L(w) w=argxminL(w)
1.随机选出一个初始的点w0;
2.然后再计算切线斜率 d L d w ∣ w = w 0 \frac{{d{\rm{L}}}}{{d{\rm{w}}}}{|_{{\rm{w}} = {{\rm{w}}_0}}} dwdLw=w0,然后大于0往左移动,小于零往右移动。
3.跨步距离——学习率 η \eta η:事先定好的数值
4.移动: − η d L d w ∣ w = w 0 -\eta \frac{{d{\rm{L}}}}{{d{\rm{w}}}}{|_{{\rm{w}} = {{\rm{w}}_0}}} ηdwdLw=w0
5.更新w0——> ω n + 1 = ω n − η d L d w ∣ w = w 0 {\omega _{n + 1}} = {\omega _n} - \eta \frac{{d{\rm{L}}}}{{d{\rm{w}}}}{|_{{\rm{w}} = {{\rm{w}}_0}}} ωn+1=ωnηdwdLw=w0
6.重复234.直到找到最低点
但是找到的只能说找到局部最小值而不是全局最小值。

两个参数:
同理,只不过是把导数变成偏导数。
∇ L = [ ∂ L ∂ w ∂ L ∂ b ] g r a d i e n t \nabla L = {\left[ {\begin{matrix}{} {\frac{{\partial L}}{{\partial w}}}\\ {\frac{{\partial L}}{{\partial b}}} \end{matrix}} \right]_{gradient}} L=[wLbL]gradient
可以想想一个山坡,然后向最低的方向滚,然后通过往偏导方向走,那肯定是数值下降最快的方向。

但找到局部最优解,不一定是全局最优解。
但如果是在线性模型中,那肯定是局部最优解就是全局最优解。

二、验证模型好坏

过拟合

当有很多个数据点的时候,去拟合这个函数值。一元N次线性模型一般较为强大。
在这里插入图片描述
但是我们可以看到,并不是次数越高,就拟合效果越好,有时候过于追求每个点的精度,反而丢失了全局,造成过拟合问题。

优化

1.模型的拆分

将四个线性模型合并到一个线性模型中,只需要将对应模型板块的 δ \delta δ为1,不对应的为0,就可以避免混入其他线性模型中。
所以对于上文的线性拟合,如果知道其种类,把它分成三个线性模型,说不定可以得到更加精确的模型。
在这里插入图片描述

2.加入更多的参数,更多的input

设更多参数,加入更多input—>容易过拟合;
怎么办?
1.可以删掉相关性较小的input
2.加入正则化,重新定义我们的loss function

3.正则化

L = ∑ n ( y ^ n − ( b + ∑ w i x i ) ) 2 + λ ∑ ( w i ) 2 L = \sum\limits_n {{{({{\hat y}^n} - (b + \sum {{w_i}{x_i}} ))}^2} + \lambda \sum {{{({w_i})}^2}} } L=n(y^n(b+wixi))2+λ(wi)2
加入 λ ∑ ( w i ) 2 {\lambda \sum {{{({w_i})}^2}} } λ(wi)2说明期望w越小越好
w越小越好——>比较平滑的——>output对输入的变化是不太敏感的。比较稳定——>可以避免一些干扰项的影响
λ \lambda λ越大的时候,说明我们越考虑函数的平滑。但也不能太平滑,所以我们需要不断的调整 λ \lambda λ

三、代码的学习

我于是对代码进行了研读。
用numpy的np.asarray来使列表变为数组。
我能理解lr的不断变动或许效果不是很好
所以将lr_b和lr_w分开
但我不大理解学习率用这种方式特化:
lr_b = lr_b + b_grad ** 2
lr_w = lr_w + w_grad ** 2
我想提前了解一下这种特化学习率的方法。
后经队长的指导,我了解到了原来是Adagrad方面的知识。
如果学习率固定,那针对不同的地方,学习率可能作用效果不同。
大致就是:
随着迭代次数增加,让学习率变小
初始迭代时,使用较大的学习率加速下降
迭代几次后,减小学习率防止振荡和越过
当然adagrad的相关知识之后也会学到,但是通过代码的调整,我提前了解到了adagrad的作用。在此感谢队长和相关伙伴的指导。

import numpy as np
import matplotlib.pyplot as plt
import time
from pylab import mpl

# matplotlib没有中文字体,动态解决
plt.rcParams['font.sans-serif'] = ['Simhei']  # 显示中文
mpl.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题

#x_data正确输入数据 y_data 正确输出数据
x_data = [338., 333., 328., 207., 226., 25., 179., 60., 208., 606.]
y_data = [640., 633., 619., 393., 428., 27., 193., 66., 226., 1591.]
#用numpy将列表转化为数组
x_d = np.asarray(x_data)
y_d = np.asarray(y_data)


x = np.arange(-200, -100, 1)
y = np.arange(-5, 5, 0.1)
Z = np.zeros((len(x), len(y)))
X, Y = np.meshgrid(x, y)

# 求损失函数loss
for i in range(len(x)):
    for j in range(len(y)):
        b = x[i]
        w = y[j]
        Z[j][i] = 0  # meshgrid吐出结果:y为行,x为列
        for n in range(len(x_data)):
            Z[j][i] += (y_data[n] - b - w * x_data[n]) ** 2
        Z[j][i] /= len(x_data)

# 线性回归
b = -120
w = -4
lr = 1
#迭代次数
iteration = 100000

b_history = [b]
w_history = [w]

#把w和b的学习率分来
lr_b = 0
lr_w = 0

start = time.time()
for i in range(iteration):
    b_grad = 0.0
    w_grad = 0.0
    for n in range(len(x_data)):
        b_grad = b_grad - 2.0 * (y_data[n] - n - w * x_data[n]) * 1.0
        w_grad = w_grad - 2.0 * (y_data[n] - n - w * x_data[n]) * x_data[n]
#不理解???lr_b的变动
    lr_b = lr_b + b_grad ** 2
    lr_w = lr_w + w_grad ** 2
    # update param
    b -= lr / np.sqrt(lr_b) * b_grad
    w -= lr / np.sqrt(lr_w) * w_grad

    b_history.append(b)
    w_history.append(w)


# plot the figure
plt.contourf(x, y, Z, 50, alpha=0.5, cmap=plt.get_cmap('jet'))  # 填充等高线
plt.plot([-188.4], [2.67], 'x', ms=12, mew=3, color="orange")
plt.plot(b_history, w_history, 'o-', ms=3, lw=1.5, color='black')
plt.xlim(-200, -100)
plt.ylim(-5, 5)
plt.xlabel(r'$b$')
plt.ylabel(r'$w$')
plt.title("线性回归")

plt.show()


总结

提示:今天主要学习了回归里面的线性模型,损失函数,还有梯度下降。还学到了过拟合以及防止过拟合的正则化。但其讲的时候省略了激活函数这一块知识。还研读了一下其代码,在他人的帮助下提前对adagrqd对知识有了一定的了解。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值