梯度下降法拟合直线

给定300个样本点(x, y)。拟合直线:

设直线方程为y = w*x + b

其中:x,y是给定的样本点,作为训练集。w和b是待拟合的参数。

该问题可以转化为,优化函数 f(w, b) = y - w*x - b

使用平方损失,转化为优化:f(w, b) = (y - w*x -b)^2

求w的梯度为: grad_w = -x * 2(y - w*x -b)

求b的梯度为:grad_b = -1 * 2(y - w*x -b)

再使用:

w = w - lr * grad_w

b = b - lr * grad_b

优化这两个变量。

import numpy as np
import random
import cv2


def fit_line_by_grad():
    gt_x = range(300)
    gt_y = [2*x+4 + 20 * np.random.random() for x in gt_x]
    print("train sample: {}".format(len(gt_x)))

    # y = w * x + b ==> f(w, b) = y - w * x -b ==> f(w, b) = (y - w * x -b)^2
    # ==> grad_w = -x * 2 (y - w * x -b), grad_b = -1 * 2 (y - w * x -b)
    iteration = 10000
    lr = 0.000001
    w = 0.0001
    b = 0
    for i in range(iteration):
        i = i % len(gt_x)
        x = gt_x[i]
        y = gt_y[i]
        grad_w = - x * 2 * (y - w * x -b)
        grad_b = -1 * 2 * (y - w * x -b)

        w = w - lr * grad_w
        b = b - lr * grad_b
    print("y = {}*x + {}".format(w, b))

    img = np.zeros([500, 500, 3], dtype=np.uint8)
    for gt in zip(gt_x, gt_y):
        x, y = [int(i) for i in gt]
        cv2.circle(img, (x, y), 3, (0, 255, 0), 1)
    fit1 = (0, int(w * 0 + b))
    fit2 = (300, int(w * 300 + b))
    cv2.line(img, fit1, fit2, (0, 0, 255), 3)
    cv2.namedWindow("res", 0)
    cv2.imshow("res", img)
    key = cv2.waitKey(0)
    if key == 27:
        exit()


fit_line_by_grad()

最终的拟合效果为:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值