学习笔记,梯度下降(非向量实现)

在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent)是最常用的方法之一。

 一、梯度


在微积分里,对多元函数参数求偏导,把求得的各个参数的偏导数以向量的形式写出来,就是梯度。如果是一元函数,梯度就是偏导。

例如,f(x1,x2),分别求偏导,梯度向量就是(∂f/∂x1, ∂f/∂x2)

梯度向量的意义:从几何意义上来讲,就是函数变化增加(上升)最快的方向。

 二、梯度下降

 

在机器学习算法中,在最小化损失函数时,可以通过梯度下降来一步步的迭代求解,得到最小化的损失函数和模型参数

相关概念:

1、步长(Learning rate),又称学习率,它决定了在梯度下降迭代过程中,每一步沿着梯度负方向前进的长度。

2、假设函数(hypothesis function): 在监督学习中,为了你和输入样本,而是用假设函数,记作h_{\theta}(x)比如对于单个特征的m个样本(x^{(i)}, y^{(i)})(i=1,2,...,m)可以采用拟合函数如下:h_{\theta}(x) = \theta_0+\theta_1x

3、损失函数(Lost function):为了评估模型的好坏,通常用损失函数来度量拟合的程度。损失函数最小化,意味着拟合最好,对应的模型参数为最好。在线性回归中,损失函数通常为均方误差。对于m个样本(x_i,y_i)(i=1,2,...m)(x_i,y_i)(i=1,2,...m)(x_i, y_i)(i=1,2,...,m),损失函数为

J(\theta_0, \theta_1) = \frac{1}{2m} \sum\limits_{i=1}^{m}(h_\theta(x_i) - y_i)^2

梯度

对于线性回归,假设函数为h_\theta(x_1, x_2, ...x_n) = \theta_0 + \theta_{1}x_1 + ... + \theta_{n}x_{n},其中\theta_i (i=0,1,2,...,n)为模型参数,x_i(I=1,2,...,n)为每个样本的n个特征。我们增加一个x_0 = 1,则上面可以简化为

h_\theta(x_0, x_1, ...x_n) = \sum\limits_{i=0}^{n}\theta_{i}x_{i}

对于上述函数,损失函数为

J(\theta_0, \theta_1..., \theta_n) = \frac{1}{2m}\sum\limits_{j=1}^{m}(h_\theta(x_0^{(j)}, x_1^{(j)}, ...x_n^{(j)}) - y_j)^2

\theta_i求偏导为

\frac{\partial}{\partial\theta_i}J(\theta_0, \theta_1..., \theta_n)= \frac{1}{m}\sum\limits_{j=0}^{m}(h_\theta(x_0^{(j)}, x_1^{(j)}, ...x_n^{(j)}) - y_j)x_i^{(j)}

由于样本中没有x_0,上式中令所有x_0^{j}为1

\theta的更新表达式为

\theta_i = \theta_i - \alpha\frac{1}{m}\sum\limits_{j=0}^{m}(h_\theta(x_0^{(j)}, x_1^{(j)}, ...x_n^{j}) - y_j)x_i^{(j)}

上式中,\alpha为步长

 

三、代码实现,非矩阵形式

#二元线性回归梯度下降,函数直接实现

import numpy as np


SEED = 23455
rdm = np.random.RandomState(seed=SEED)

#参数初始化,随机的效果比全为0的好
theta0 = rdm.rand() * 10
theta1 = rdm.rand()* 10
theta2 = rdm.rand()* 10

# theta0 = 0
# theta1 = 0
# theta2 = 0
epochs = 24001
alpha = 0.001


#模拟生成数据
X = rdm.rand(32, 2) #32行,2列
print(X)
X = X * 10;
#模型,加入随机噪声
Y = [[x1 + x2 + 8 + (rdm.rand() - 0.5)] for (x1, x2) in X]

print(X)
print(Y)

#代价函数
def cost(X, Y, theta0, theta1, theta2):
    loss = 0
    m = len(Y)
    for i in range(m):
        loss += (theta0 + theta1*X[i,0] + theta2*X[i,1] - Y[i])**2
    loss = loss/(2*m)
    return loss

#梯度下降
def grad_des(X,Y, theta0, theta1, theta2, alpha, epochs):
    m = len(Y)
    for z in range(epochs):
        theta0_grad = 0
        theta1_grad = 0
        theta2_grad = 0
        for i in range(m):
            theta0_grad += (theta0 + theta1*X[i,0] + theta2*X[i,1] - Y[i])
            theta1_grad += (theta0 + theta1*X[i,0] + theta2*X[i,1] - Y[i])*X[i,0]
            theta2_grad += (theta0 + theta1*X[i,0] + theta2*X[i,1] - Y[i])*X[i,1]
        theta0_grad = theta0_grad/m
        theta1_grad = theta1_grad/m
        theta2_grad = theta2_grad/m
        theta0 -= alpha*theta0_grad
        theta1 -= alpha*theta1_grad
        theta2 -= alpha*theta2_grad
        if z % 100 == 0:
            print('epochs={}.theta0={},theta1={},theta2={},loss={}'.format(z, theta0, theta1, theta2,
                                                                   cost(X, Y, theta0, theta1, theta2)))
    return theta0,theta1,theta2


print('begin...theta0={},theta1={},theta2={},loss={}'.format(theta0,theta1,theta2,cost(X,Y,theta0,theta1,theta2)))
print('running...')
theta0,theta1,theta2 = grad_des(X,Y,theta0,theta1,theta2,alpha,epochs)


 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞天红猪侠001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值