1,机器学习的目标

从大量数据中学习到高维的抽象特征,使得新输入的x也能在经过模型后,得出一个符合实际情况的y值。在自然界中,若y为离散型,则属于分类问题,y为连续型则属于预测问题。

2,为什么需要大量样本?

若我们提前知道了某一堆样本服从下述线性模型,那么我们就有理由相信输入任意x所构成的点(x,y)都服从该线性模型分布。

                                                                             y = w*x + b

但在现实情况中,我们只能得到一大堆的样本点,即我们不知道w和b的具体值。所以我们需要从这些样本点中求解出上述模型中的w和b。但由于样本中存在不可控制的偏差(&),上述线性模型变成如下形式。导致我们无法通过几组样本就可以得到理想的w和b。

                                                                            y = w*x + b + &

所以,机器学习需要从大量数据中得到一组相对稳定的w和b,使得新来的x,即使在有偏差的前提下也能得到一个偏合理的y值。

3,如何确定当前w和b为最优解?

为了使得新输入的x值也能得到一个偏差不大的y值,我们需要保证样本中的Y值(我们常常所说的标签)和通过模型求解出来的y值,两者之差越小越好。为了量化两者之间的差值,我们通常会使用MSE来进行衡量,具体公式如下:

                                                     MSE = \frac{1}{N}\sum (y-Y)^{2}= \frac{1}{N}\sum ((w*x-b)-Y)^{2}

这里的MSE就是我们常常提到的损失函数(loss function),当然还有其他有用的损失函数,大家在学习旅途中都会慢慢遇到。

有了损失函数,我们就可以把求解Y和y之间差值的最小值转化到求解损失函数的全局最小值或者局部最小值中去。通过不停的迭代和更新w,b。我们就可以得到损失函数的最小值,此时的w和b就是当前所有样本中的最优解。

4,如何求解损失函数的最小值?

通过高等数学中的相关知识,我们知道函数梯度的方向永远是函数值变大的方向,所以,我们只要一直向着梯度方向的反方向寻找就能找到损失函数的最小值。具体的寻找过程如下:

当输入一个样本后,我们就能得到一个损失值,但我们并不知道当前的损失值是否为最小值,所以,我们需要先求出当前损失函数所对应的梯度,然后利用下述公式对模型中的w和b进行更新。

                                                                               w'= w - lr * \frac{\partial loss}{\partial w}

                                                                               b'= b - lr * \frac{\partial loss}{\partial b}

其中:

                                                                    \frac{\partial loss}{\partial w}=\frac{2}{N}\sum ((wx-b)-Y)*x

                                                                    \frac{\partial loss}{\partial b}=\frac{2}{N}\sum ((wx-b)-Y)*1

备注:利用复合函数的链式求导法则对MSE进行求导即可得出

上述操作的本质就是向着损失函数梯度的反方向前进一小步,使得损失函数在得到一个新的最小值时,w和b的新值,即为更新权重,或者反向梯度更新。而具体前进多大的距离,由lr(学习率,衰减因子)决定。若lr过大的话,w'的变化范围会很大,导致更新后的w和b会跳过损失函数的最小值,lr过小的话会造成w,b更新缓慢,学习率低。所以,对于简单的数据集如MNIST,通常设置lr=0.01,对于复杂的数据集如chair100,通常设置lr=0.0001

由于上述两个公式保证了在每一次迭代中,损失函数总是向着最小值的方向移动,所以,通过投喂大量的样本,我们最后就会得到损失函数的最小值或者最小值的近似解。进而得到一组最优的w和b。

总结一下线性回归问题的学习步骤

(1)初始化w,b,并构建一个线性模型

(2)通过求导的方式跟新w,b,并计算当前loss函数值,

(3)不停的投喂样本,不停的重复第二步,直到迭代完所有样本

5,按照上述流程,利用numpy实对二维平面内点的简单线性回归

import numpy as np

# 简单的线性回归

# 定义相关变量
w, b = 0.,0.
# 学习率
lr = 0.0001
points= np.genfromtxt("data.csv", delimiter=",")
N = len(points)
# 所有样本训练的次数
epoch_number = 1000
# 开始训练
for epoch in range(epoch_number):
    current_w, current_b = 0., 0.
    # 计算所有样本的梯度平均值
    for i in range(0, N):
        current_w = current_w + 2/N * (w * points[i,0] - points[i,1])* points[i,0]
        current_b = current_b + 2/N * (w * points[i,0] - points[i,1])
    # 利用所有样本梯度的平均值更新w,b
    w = w - lr * current_w
    b = b - lr * current_b
    # 每隔100步 计算一下当前的损失值
    if epoch % 100 == 0:
        current_loss = 0.
        for i in range(0, N):
            current_loss = current_loss + 1/N * (w * points[i, 0] + b - points[i, 1])**2
        print('epoch :',epoch, 'current_loss:', current_loss)
# 对所有样本迭代完100次后 输出最后的w,b
print('last weight w={0} and b={1}'.format(w,b))

最后输出结果如下

我们可以看到随着训练次数的增加,loss在逐渐减少,并趋于稳定。

开篇:开启Tensorflow 2.0时代

第一章:Tensorflow 2.0 实现简单的线性回归模型(理论+实践)

第二章:Tensorflow 2.0 手写全连接MNIST数据集(理论+实战)

第三章:Tensorflow 2.0 利用高级接口实现对cifar10 数据集的全连接(理论+实战实现)

第四章:Tensorflow 2.0 实现自定义层和自定义模型的编写并实现cifar10 的全连接网络(理论+实战)

第五章:Tensorflow 2.0 利用十三层卷积神经网络实现cifar 100训练(理论+实战)

第六章:优化神经网络的技巧(理论)

第七章:Tensorflow2.0 RNN循环神经网络实现IMDB数据集训练(理论+实践)

第八章:Tensorflow2.0 传统RNN缺陷和LSTM网络原理(理论+实战)

 

 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐