02 LinerRegression

2023-05-16

问题引入:这就是个简单的线性回归函数的计算问题

现在我们已知一次函数 y = 4x + 9,bias为一个服从标准正态分布的随机随机数值。那么通过 y = 4x + 9 + bias,当我们给定一系列x值:x1,x2,...,xn值后,我们可以得到一组离散的点集(x1, y1),(x2, y2),...,(x3, y3)。很明显这些点一定是围绕着y = 4x + 9 这条直线波动的。

上面的思维是我们已知直线方程 y = 4x +9 而后推导出一组离散点集(x,y)。那我们如何反过来,即通过观测得到的离散点集推测出 y = 4x + 9 ?

我们假设这些离散点符合一次方程 y = wx + b,我们需要做的就是推测出w的最大可能值与b的最大可能值,这是两个未知数,两个变量

由上一篇文章得出,想要推导未知变量的值,有以下步骤:

  1. 假定变量的初始值 w0、b0
  2. 确定总损失函数的表达形式
  3. 将总的损失函数拆解,计算各自的梯度
  4. 通过各自梯度得到用于更新变量值的平均梯度

但本文是两个未知变量,上一篇文章只是一个未知变量,何解?

  • 初始值的假定很简单,随心而定即可
  • totaolLoss = \sum_{i=1}^{n}\left \{ \left ( w_0x_i+b_0 \right ) - y_i \right \}^2
  • baseLoss = \left \{ \left ( w_0x_i+b_0 \right ) - y_i \right \}^2,不同之处在于,此时不再只是求导,而是求偏导,即:\frac{\partial baseLoss}{\partial w}\frac{\partial baseLoss}{\partial b}
  • 然后计算出各自的平均偏导梯度,与学习率相乘,各自更新各自的变量互不打扰即可

思路依然确立,接下来就是代码实现的问题了。需要实现的功能如下:

  1. 获得围绕直线 y = 4x + 9波动的离散点集
  2. 计算total_loss值
  3. 计算平均偏导梯度值
  4. 设置学习率,配合平均偏导梯度值完成一次对参数值 w,b 的更新
  5. 重复上述步骤 n 次,n即为训练次数

完整实例代码:

'''
0. 主要目的是通过随机点集,预测其对应的线性回归方程
1. 生成围绕线性方程 y=4*x+9 波动的离散坐标点的点集
2. 通过梯度求解线性回归方程 y=w*x+b 中的w,b最可能的近似值
3. 希望预测的a, b值各自接近4 和 9
'''
def producePoints(num):
    '''
    :param num: 指定生成随机点的个数
    :return data: 返回随机点坐标的集合[(x1,y1), (x2,y2)...]
    '''
    import torch #不导入torch,numpy用不了我直接无语
    import numpy as np
    points_x = [i+np.random.rand() for i in range(1, num+1)] #np.random.rand(d0, d1)生成[0, 1)之间的随机浮点数或者N维浮点数组
    points_y = [4*points_x[i]+9+np.random.rand() for i in range(num)] #这样的出的y值并不满足y=4*x+9, 另外加的np.random.rand()相当于是噪声

    points = zip(points_x, points_y)
    return list(points)

def compute_error_for_given_points(w, b, points):
    '''
    通过给定当前预测的w, b值计算各个点预测值与真实值之间的平均误差
    :param w: 当前预测的w值
    :param b: 当前预测的b的值
    :param points: 当前获得离散坐标点的点集
    :return:  由预测的w , b值获取各个点预测Y值与真实Y值之间的误差平方和的平均值: double
    '''
    totalError = 0
    for point in points:
        x, y = point[0], point[1]
        totalError += (w*x+b - y) ** 2  #(w*x+b - y) ** 2代表当前的w,b取值在(x, y)这个点处预测的Y值即w*x+b与真实值Y值的即y之间的误差的平方
    return totalError/len(points) #对误差取平均

def step_gradient(current_w, current_b, points, learningRate):
    '''
    根据误差函数loss = (w*x+b - y) ** 2,计算w, b于每个点上的梯度情况,从而更新w, b值
    :param current_w: 当前预测的w值
    :param current_b: 当前预测的b值
    :param points: 当前给定的离散坐标点的点集
    :param learningRate: 当前给定的学习率
    :return: 新预测的w, b值:[w, b]
    '''
    gradient_w_total = 0 # loss函数在w方向上每个点的梯度之和
    gradient_b_total = 0
    for point in points:
        x, y = point[0], point[1]
        gradient_w_total += 2 * x * (current_w*x+current_b - y) #loss函数对w求导
        gradient_b_total += 2 * (current_w*x+current_b - y) #loss函数对b求导
    gradient_w_average = gradient_w_total / len(points) #loss函数在所有点梯度的平均值
    gradient_b_average = gradient_b_total / len(points)
    new_w = current_w - (gradient_w_average * learningRate) #计算新的w的值
    new_b = current_b - (gradient_b_average * learningRate)
    return [new_w, new_b]

def gradient_descent_runner(start_w, start_b, points, learningRate, iterations_num):
    '''
    给定初始的w, b,离散点点集, 学习率,迭代次数,不停的更新w, b值
    :param start_w: 起始的w值
    :param start_b: 起始的b值
    :param points: 离散点的点集
    :param learningRate: 学习率
    :param iterations_num: 梯度下降的次数
    :return: 经过指定迭代次数后得到的w, b的值
    '''
    current_w = start_w
    current_b = start_b
    for i in range(iterations_num):
        print("第{:>6d}次梯度迭代".format(i))
        current_w, current_b = step_gradient(current_w, current_b, points, learningRate)
    return [current_w, current_b]

if __name__ == '__main__':
    start_w = 0
    start_b = 0
    points = producePoints(100)
    learningRate = 0.0001
    iterations_num = 100000 #经过测试,这个训练步数得到的结果还行

    final_w, final_b = gradient_descent_runner(start_w, start_b, points, learningRate, iterations_num)
    final_error = compute_error_for_given_points(final_w, final_b, points)

    print("最终的w值为:{} 最终的b值为:{} 最终的平均误差为:{}".format(final_w, final_b, final_error))

运行结果:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

02 LinerRegression 的相关文章

  • 字符串加密(牛客)

    题目描述 xff1a 有一种技巧可以对数据进行加密 xff0c 它使用一个单词作为它的密匙 下面是它的工作原理 xff1a 首先 xff0c 选择一个单词作为密匙 xff0c 如TRAILBLAZERS 如果单词中包含有重复的字母 xff0
  • 统计每个月兔子的总数(牛客)

    题目描述 xff1a 有一只兔子 xff0c 从出生后第3个月起每个月都生一只兔子 xff0c 小兔子长到第三个月后每个月又生一只兔子 xff0c 假如兔子都不死 xff0c 问每个月的兔子总数为多少 xff1f 输入描述 xff1a 输入
  • 购物单(牛客)(01背包+分组背包+有依赖的背包)

    题目描述 xff1a 王强今天很开心 xff0c 公司发给N元的年终奖 王强决定把年终奖用于购物 xff0c 他把想买的物品分为两类 xff1a 主件与附件 xff0c 附件是从属于某个主件的 xff0c 下表就是一些主件与附件的例子 xf
  • gmssl 生成SM2证书、加密、解密、签名、验签

    1 生成SM2密钥对 gmssl ecparam genkey name sm2p256v1 out sm2keypair pem text 2 查看SM2密钥对 gmssl ec in sm2keypair pem text 3 生成自签
  • 求小球落地5次后所经历的路程和第五次反弹的高度(牛客)

    题目描述 xff1a 假设一个球从任意高度自由落下 xff0c 每次落地后反跳回原高度的一半 再落下 求它在第5次落地时 xff0c 共经历多少米 第5次反弹多高 xff1f 最后的误差判断是小数点6位 输入描述 xff1a 输入起始高度
  • 输入一行字符,分别统计出包含英文字符、空格、数字和其他字符的个数(牛客)

    题目描述 xff1a 输入一行字符 xff0c 分别统计出包含英文字母 空格 数字和其它字符的个数 输入描述 xff1a 输入一行字符串 xff0c 可以有空格 1qazxsw23 edcvfr45tgbn hy67uj m ki89ol
  • 字符串合并处理(牛客)

    题目描述 xff1a 按照指定规则对输入的字符串进行处理 详细描述 xff1a 将输入的两个字符串合并 对合并后的字符串进行排序 xff0c 要求为 xff1a 下标为奇数的字符和下标为偶数的字符分别从小到大排序 这里的下标意思是字符在字符
  • 蛇形矩阵(牛客)

    题目描述 xff1a 蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形 输入描述 xff1a 输入正整数N xff08 N不大于100 xff09 5 输出描述 xff1a 输出一个N行的蛇形矩阵 1 3 6 10 15 2 5 9
  • 图片整理(牛客)

    题目描述 xff1a Lily上课时使用字母数字图片教小朋友们学习英语单词 xff0c 每次都需要把这些图片按照大小 xff08 ASCII码值从小到大 xff09 排列收好 请大家给Lily帮忙 xff0c 通过C语言解决 输入描述 xf
  • 单词倒排(牛客)

    题目描述 xff1a 对字符串中的所有单词进行倒排 说明 xff1a 1 构成单词的字符只有26个大写或小写英文字母 xff1b 2 非构成单词的字符均视为单词间隔符 xff1b 3 要求倒排后的单词间隔符以一个空格表示 xff1b 如果原
  • 字符串运用-密码截取(牛客)

    题目描述 xff1a xff08 最大回文序列 xff09 Catcher是MCA国的情报员 xff0c 他工作时发现敌国会用一些对称的密码进行通信 xff0c 比如像这些ABBA xff0c ABA xff0c A xff0c 12332
  • 字符串加解密(牛客)

    题目描述 xff1a 1 对输入的字符串进行加解密 xff0c 并输出 2加密方法为 xff1a 当内容是英文字母时则用该英文字母的后一个字母替换 xff0c 同时字母变换大小写 如字母a时则替换为B xff1b 字母Z时则替换为a xff
  • 表达式求值(牛客)

    题目描述 xff1a 给定一个字符串描述的算术表达式 xff0c 计算出结果值 输入字符串长度不超过100 xff0c 合法的字符包括 43 xff0c 0 9 xff0c 字符串内容的合法性及表达式语法的合法性由做题者检查 本题目只涉及整
  • 02 vue框架内部的各种指令和axios操作的代码详解

    目录 前言 第一个完整的Vue程序 el xff1a 挂载点 和 data xff1a 数据对象 v text指令 v html指令 v on指令 v show指令 v if指令 v bind指令 v for指令 v on指令补充 v mo
  • kill 与killall

    查询命令所属软件包 rpm qf usr bin killall psmisc 22 20 15 el7 x86 64 rpm qf usr bin kill util linux 2 23 2 65 el7 9 1 x86 64 命令参数
  • 第1章-1 从键盘输入两个数,求它们的和并输出 (30分)

    本题目要求读入2个整数A和B xff0c 然后输出它们的和 输入格式 在一行中给出一个被加数 在另一行中给出一个加数 输出格式 在一行中输出和值 输入样例 在这里给出一组输入 例如 xff1a 18 48 输出样例 在这里给出相应的输出 例
  • 第1章-2 从键盘输入三个数到a,b,c中,按公式值输出 (30分)

    在同一行依次输入三个值a b c xff0c 用空格分开 xff0c 输出 b b 4 a c的值 输入格式 在一行中输入三个数 输出格式 在一行中输出公式值 输入样例 在这里给出一组输入 例如 xff1a 3 4 5 输出样例 在这里给出
  • 第1章-3 输出“Python语言简单易学” (10分)

    输入格式 无 输出格式 输出一句短语 xff0c Python语言简单易学 如果包含汉字 xff0c 用 34 print s encode 34 utf 8 34 34 输出 如 xff1a s 61 34 人生苦短 xff0c 我学Py
  • 第2章-1 计算 11+12+13+...+m (30分)

    输入一个正整数m 20 lt 61 m lt 61 100 xff0c 计算 11 43 12 43 13 43 43 m 的值 输入格式 在一行输入一个正整数m 输出格式 在一行中按照格式 sum 61 S 输出对应的和S 输入样例 在这

随机推荐

  • 第2章-2 计算分段函数[1] (10分)

    本题目要求计算下列分段函数f x 的值 xff1a 输入格式 输入在一行中给出实数x 输出格式 在一行中按 f x 61 result 的格式输出 xff0c 其中x与result都保留一位小数 输入样例1 10 输出样例1 f 10 0
  • 第2章-3 阶梯电价 (15分)

    为了提倡居民节约用电 xff0c 某省电力公司执行 阶梯电价 xff0c 安装一户一表的居民用户电价分为两个 阶梯 xff1a 月用电量50千瓦时 xff08 含50千瓦时 xff09 以内的 xff0c 电价为0 53元 千瓦时 xff1
  • 第2章-4 特殊a串数列求和 (20分)

    给定两个均不超过9的正整数a和n xff0c 要求编写程序求a 43 aa 43 aaa 43 43 43 aa a xff08 n个a xff09 之和 输入格式 xff1a 输入在一行中给出不超过9的正整数a和n 输出格式 xff1a
  • 第2章-5 求奇数分之一序列前N项和 (15分)

    本题要求编写程序 xff0c 计算序列 1 43 1 3 43 1 5 43 的前N项之和 输入格式 输入在一行中给出一个正整数N 输出格式 在一行中按照 sum 61 S 的格式输出部分和的值S xff0c 精确到小数点后6位 题目保证计
  • 第2章-6 求交错序列前N项和 (15分)

    本题要求编写程序 xff0c 计算交错序列 1 2 3 43 3 5 4 7 43 5 9 6 11 43 的前N项之和 输入格式 输入在一行中给出一个正整数N 输出格式 在一行中输出部分和的值 xff0c 结果保留三位小数 输入样例 5
  • 第2章-7 产生每位数字相同的n位数 (30分)

    读入2个正整数A和B xff0c 1 lt 61 A lt 61 9 1 lt 61 B lt 61 10 产生数字AA A 一共B个A 输入格式 在一行中输入A和B 输出格式 在一行中输出整数AA A 一共B个A 输入样例1 在这里给出一
  • lsusb

    用法 xff1a lsusb hUsage lsusb options List USB devices v verbose Increase verbosity show descriptors s bus devnum Show onl
  • 第2章-8 转换函数使用 (30分)

    输入一个整数和进制 xff0c 转换成十进制输出 输入格式 在一行输入整数和进制 输出格式 在一行十进制输出结果 输入样例 在这里给出一组输入 例如 xff1a 45 8 输出样例 在这里给出相应的输出 例如 xff1a 37 a b 61
  • 第2章-9 比较大小 (10分)

    本题要求将输入的任意3个整数从小到大输出 输入格式 输入在一行中给出3个整数 xff0c 其间以空格分隔 输出格式 在一行中将3个整数从小到大输出 xff0c 其间以 gt 相连 输入样例 4 2 8 输出样例 2 gt 4 gt 8 nu
  • 第2章-10 输出华氏-摄氏温度转换表 (15分)

    输入2个正整数lower和upper xff08 lower upper 100 xff09 xff0c 请输出一张取值范围为 lower xff0c upper 且每次增加2华氏度的华氏 摄氏温度转换表 温度转换的计算公式 xff1a C
  • 第2章-11 求平方与倒数序列的部分和 (15分)

    本题要求对两个正整数m和n xff08 m n xff09 编写程序 xff0c 计算序列和m 2 43 1 m 43 m 43 1 2 43 1 m 43 1 43 43 n 2 43 1 n 输入格式 输入在一行中给出两个正整数m和n
  • 第2章-12 输出三角形面积和周长 (15分)

    本题要求编写程序 xff0c 根据输入的三角形的三条边a b c xff0c 计算并输出面积和周长 注意 xff1a 在一个三角形中 xff0c 任意两边之和大于第三边 三角形面积计算公式 xff1a area 61 s s a s b s
  • 第2章-13 分段计算居民水费 (10分)

    为鼓励居民节约用水 xff0c 自来水公司采取按用水量阶梯式计价的办法 xff0c 居民应交水费y xff08 元 xff09 与月用水量x xff08 吨 xff09 相关 xff1a 当x不超过15吨时 xff0c y 61 4x 3
  • 第2章-14 求整数段和 (15分)

    给定两个整数A和B xff0c 输出从A到B的所有整数以及这些数的和 输入格式 xff1a 输入在一行中给出2个整数A和B xff0c 其中 100 A B 100 xff0c 其间以空格分隔 输出格式 xff1a 首先顺序输出从A到B的所
  • 第3章-1 3-1.大于身高的平均值 (10分)

    中小学生每个学期都要体检 xff0c 要量身高 xff0c 因为身高可以反映孩子的生长状况 现在 xff0c 一个班的身高已经量好了 xff0c 请输出其中超过平均身高的那些身高 程序的输入为一行数据 xff0c 其中以空格分隔 xff0c
  • Cudnn与Pytorch的安装

    win键搜索cmd xff0c 右键选择管理员 xff0c 运行命令 xff1a conda install pytorch torchvision cuda100 c pytorch 注意 xff1a 这是CUDA10 0版本的pytor
  • Pycharm的字体大小设置 与 如何取消自动更新

    Pycharm的字体大小有两种设置比较舒服 第一种是ctrl 43 滑轮的上下滚动调节 xff0c 但是调节过后的效果具有时效性 xff0c 也就是当你再次打开Pycharm后 xff0c 字体大小又变回了基础设置的大小 第二种直接调整基础
  • “-1” 文件删除

    无法删除以短连接符开头 1 的文件 rm rf 1 或 rm rf 34 1 34 问题原因 xff1a 短连接符会被当作选项解析 解决方式有两种 xff1a 一种加前缀使用相对或绝对路径 xff1b 一种使用 标识选项解析结束 xff08
  • 01 梯度下降、学习率、损失函数

    概念引入 基于一个自变量x xff0c 比如时间 xff0c 我们可以得到其对应的观测值y xff0c 比如温度值 不停的观测 xff0c 我们可以得到一系列的真实对应关系 xff1a 时间 xff0c 温度的真实值 xff0c 即 x1
  • 02 LinerRegression

    问题引入 xff1a 这就是个简单的线性回归函数的计算问题 现在我们已知一次函数 y 61 4x 43 9 xff0c bias为一个服从标准正态分布的随机随机数值 那么通过 y 61 4x 43 9 43 bias xff0c 当我们给定