梯度上升和随机梯度上升

news2024/9/24 17:10:57

目录

梯度上升算法:

代码:

随机梯度上升算法:

代码:

实验:

做图代码:

疑问:

1.梯度上升算法不适应大的数据集,改用随机梯度上升更合适。

2.改进过的随机梯度算法,w vs epoch曲线出现波动。

代码实现时遇到的问题

1.对随机的理解,随机过的样本不再参与随机?

 2.数组越界

实验结果: 


Logistic回归实现二分类:http://t.csdnimg.cn/eEEjF

学习资料:Peter Harrington 机器学习实战

梯度上升算法:

如下,每更新一次权重需要计算所有样本(train_X)和权重乘积的sigmoid值。

对于m行n列特征矩阵和n行权重,迭代次数epoch,计算复杂度为O(n*m*epoch),w迭代次数为epoch.

代码:

def grad(train_X,train_y):
    # 100*3
    m,n = len(train_X[:,0]),len(train_X[0])
    #3x1 
    weight=np.ones((n,1))
    #迭代系数
    epoch=500
    for i in range(epoch):
        # mxn nx1 ->m*1
        y_=sigmoid(np.dot(train_X,weight))
        # m*1
        loss = train_y -y_
        a = 0.01
        # 3*1 
        weight = weight - np.dot(a*train_X.transpose(),loss)
    return weight

随机梯度上升算法:

每计算一次样本更新一次权重。

代码:

def grad(train_X,train_y):
    # 100*3
    m,n = len(train_X[:,0]),len(train_X[0])
    #3x1 
    weight=np.ones((n,1))
    # 每个样本更新权重一次,故使用m
    for i in range(m):
        # mxn nx1 ->m*1
        # y_=sigmoid(np.dot(train_X,weight))
        # 1xn nx1 -->1x1
        #(3,)表示只有一个维度,在这个维度上有三个数字
        y_=sigmoid(sum(np.dot(train_X[i].reshape(1,n),weight)))
        # 1x1
        loss = train_y[i] -y_
        a = 0.01
        # nx1 1xn 1x1 nx1 1x1
        weight = weight + a*np.dot(train_X[i].transpose().reshape(n,1),loss.reshape(1,1))
    return weight

使用这种方法实现的分类效果相较之前效果变差了,应该是w迭代次数不够,为了查看何时收敛,查看w和epoch的变化关系图。

梯度上升随机梯度上升

实验:

使用随机梯度算法:研究w和epoch的关系,epoch表示迭代数据集的次数.

ln(\frac{y}{1-y})=wx+b=w_{1}x1+w_{2}x2+b

w1,b,w2分别为权重为w[0],w[1],w[2]。

可以看出w0收敛很快,w1和w2需要更多时间才能实现收敛.

 

 

发现w大概到epoch=200处收敛,设置遍历数据集200次得到新图像基本和梯度算法基本一致:

做图代码:

def grad(train_X,train_y):
    # 100*3
    m,n = len(train_X[:,0]),len(train_X[0])
    #3x1 
    weight=np.ones((n,1))
    #迭代系数
    epoch=500
    w=[]
    # lineArr.append(float(currLine[i]))
    #100x100次
    for j in range(epoch):
        for i in range(m):
            # mxn nx1 ->m*1
            # y_=sigmoid(np.dot(train_X,weight))
            # 1xn nx1 -->1x1
            #(3,)表示只有一个维度,在这个维度上有三个数字
            y_=sigmoid(sum(np.dot(train_X[i].reshape(1,n),weight)))
            # 1x1
            loss = train_y[i] -y_
            a = 0.01
            # nx1 1xn 1x1 nx1 1x1
            weight = weight + a*np.dot(train_X[i].transpose().reshape(n,1),loss.reshape(1,1))
        w.append(weight)
    w0=[row[0] for row in w]
    w1=[row[1] for row in w]
    w2=[row[2] for row in w]
    epochlist =list(range(1,epoch+1,1))
    plt.plot(epochlist,w0)    

    plt.xlabel('gradw')
    plt.ylabel('epoch')
    plt.legend()
    plt.title("w[0] vs epoch")
    plt.show()

    plt.plot(epochlist,w1)    

    plt.xlabel('gradw')
    plt.ylabel('epoch')
    plt.legend()
    plt.title("w[1] vs epoch")
    plt.show()

    plt.plot(epochlist,w2)    

    plt.xlabel('gradw')
    plt.ylabel('epoch')
    plt.legend()
    plt.title("w[2] vs epoch")
    plt.show()
    return weight

疑问:

1.梯度上升算法不适应大的数据集,改用随机梯度上升更合适。

书中提到:数据量大的话不太方便,所以想到每计算一次样本更新一次权重,也就是随机梯度上升算法。但是计算每个样本迭代的权重,再遍历全部样本,不就是把矩阵乘法拆开算吗,我不理解,感觉没有提升运算效率的作用。

2.改进过的随机梯度算法,w vs epoch曲线出现波动。

我感觉这个第一个随机梯度上升法完全没有体现随机性,随机应该随机抽取训练集的的子集来更新回归系数吧。

 书里有提到随机梯度算法的改进:

2.1.学习率随着迭代次数增加应该减小,能缓解高频波动。(不过我的实验在第一个梯度上升没有出现高频波动,改进后反而出现了。)

2.2.随机抽取样本进行类别预测,loss计算和更新权重。

randIndex是0-len(dataIndex)的随机值;去掉dataIndex[randIndex]的值

但是这个randIndex和dataIndex为什么这么写,不太理解.

def grad(train_X,train_y):
    m,n = len(train_X[:,0]),len(train_X[0])

    weight=np.ones((n,1))
    epoch=50
    w=[]
    for j in range(epoch):
        #[0,1,2,,,m-1]对应train_X的索引
        dataIndex = list(range(m))
        for i in range(m):
            #随着迭代次数增加,减小学习率
            alpha = 4/(1.0+j+i)+0.0001 
            #在dataIndex中取随机样本的索引
            
            randIndex = int(random.uniform(0,len(dataIndex)))
           
            y_=sigmoid(sum(np.dot(train_X[randIndex].reshape(1,n),weight)))
            loss = train_y[i] -y_
            weight = weight + alpha*np.dot(train_X[i].transpose().reshape(n,1),loss.reshape(1,1))
            #去掉计算过的样本
            del(dataIndex[randIndex])
       
    return weight

代码实现时遇到的问题

1.对随机的理解,随机过的样本不再参与随机?

从dataIndex中随机取值,作为随机数;去掉dataIndex中被选过的值,即随机过的样本不再参与随机了。

randIndex = random.choice(dataIndex)
dataIndex.remove(randIndex)

 2.数组越界

代码错误:取0-len(dataIndex)的值作为索引,拿到randIndex的随机值;但是去掉索引为randIndex对应的值

dataIndex=[0,1,2,,,80] len=81 假设去掉了dataIndex[79]=79,

dataIndex=[0,1,2,,,78,80] len=80 取79 randIndex=dataIndex[79]=80 去掉randIndex[80]数组越界

就可能出现越界:

randIndex = dataIndex[int(random.uniform(0,len(dataIndex)))]
del(dataIndex[randIndex])

实验结果: 

w和epoch关系:

w1,w2收敛速度更慢了,w0的波动非常明显,感觉效果比改进前还差,这算法我学不明白。
 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1285184.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1.nacos注册与发现及源码注册流程

目录 概述nacos工程案例nacos服务注册案例版本说明本地启动 nacos-server搭建 spring cloud alibaba 最佳实践服务注册案例服务订阅案例 nacos注册源码流程源码关键点技巧 结束 概述 通过本文,学会如何确定项目组件版本(减少可能出现的jar包冲突),nacos…

【Python】创建简单的Python微服务Demo与FastAPI

创建简单的Python微服务Demo与FastAPI 在微服务架构中,通过FastAPI框架创建一个简单的Python微服务Demo涉及多个步骤,包括定义服务、使用框架、进行通信等。在这篇文章中,我们将使用FastAPI框架创建两个简单的微服务,它们通过RES…

12月5日星期二今日早报简报微语报早读

12月5日星期二,农历十月廿三,早报微语早读。 1、国家卫健委:各地基层医卫机构要全面向儿童开放,不得拒诊; 2、五月天演唱会被指假唱,上海文旅局执法总队:已要求五月天演唱会主办方配合调查&am…

The Sandbox 携手 Sandsoft,与 Nuqtah 合作推动沙特阿拉伯的 Web3 发展

新的合作伙伴关系将增强创作者的能力,促进区块链生态系统的包容性。 The Sandbox 及其合作伙伴 Sandsoft 是移动游戏开发商和发行商,也是 AAA 人才驱动的投资者,他们非常高兴地宣布与 Nuqtah 建立新的合作伙伴关系,Nuqtah 是中东和…

MybatisPlus中的使用Wrapper自定义SQL

一、条件构造器 条件构造器提供了一种更加简洁和直观的方式来构建复杂的查询条件。它提供了一组静态方法,用于构建各种类型的查询条件,包括等于、不等于、大于、小于、包含等。使用条件构造器可以避免手动拼接SQL语句的麻烦,提高代码的可读性…

树莓派Python程序开机自启动(Linux下Python程序开机自启动)

前一阵子用python编写了一个驱动I2C程序读写屏幕,输出IP的小程序,程序编好后需要树莓派使能程序开机自启动。其实这些方法对任何Linux系统都适用。 方法一:此方法的缺点是不进入默认pi的账号,甚至不开hdmi开启桌面的话&#xff0…

关于栈的简单理解

1. 栈(Stack) 1.1 文字讲解 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则&a…

IP5316 2.4A 充电、2.4 A 放电、集成 DCP 功能移动电源 SOC

IP5316 2.4A 充电、 2.4 A 放电、集成 DCP 功能移动电源 SOC 简介: IP5316 是一款集成升压转换器、锂电池充电管理、电池电量指示的多功能电源管理 SOC,为移动电源提供完整的电源解决方案。得益于 IP5316 的高集成度与丰富功能,使其在应用时…

零信任组件和实施

零信任是一种安全标准,其功能遵循“从不信任,始终验证”的原则,并确保没有用户或设备受信任,无论他们是在组织网络内部还是外部。简而言之,零信任模型消除了信任组织安全边界内任何内容的概念,而是倡导严格…

外包干了2个月,技术明显退步了...

先说一下自己的情况,大专生,19年通过校招进入广州某软件公司,干了接近5年的功能测试,今年11月份,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测…

JS实现成才网注册系统(网页数据验证)

主代码 <!DOCTYPE htmlPUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml"><head><meta http-equiv"Conten…

OpenGL ES 帧缓冲对象介绍和使用示例

一、介绍 1. 帧缓冲对象 默认情况下&#xff0c;OpenGL渲染的目标是屏幕&#xff0c;但如果你不想直接渲染到屏幕上&#xff0c;还需要对渲染结果做某些后期处理、渲染到纹理、阴影映射等操作&#xff0c;便可以使用帧缓冲对象&#xff0c;实现离屏渲染。 帧缓冲对象&#x…

DC电源模块的常见故障有哪些?

BOSHIDA DC电源模块的常见故障有哪些&#xff1f; DC电源模块是电子设备中常见的电源供应模块&#xff0c;它可以将交流电转化为直流电供给设备使用。然而&#xff0c;由于长期的使用和外界环境等因素的影响&#xff0c;DC电源模块也会出现各种故障。下面我们来介绍一下常见的…

【go语言开发】编写单元测试

本文主要介绍使用go语言编写单元测试用例&#xff0c;首先介绍如何编写单元测试&#xff0c;然后介绍基本命令的使用&#xff0c;最后给出demo示例 文章目录 前言命令示例 前言 在go语言中编写单元测试时&#xff0c;使用说明 测试文件命名&#xff1a;在 Go 语言中&#xff0…

蓝桥杯网络安全组竞赛

竞赛规则及说明 选拔赛时长&#xff1a;4h 决赛时长&#xff1a;4h 竞赛形式&#xff1a;线上比赛&#xff1a; 个人赛&#xff1a;一人一机&#xff0c;全程机考 大赛制定竞赛系统&#xff0c;在时间内提交答案到比赛系统&#xff0c;超时无法提交 机器环境&#xff1a; 电脑…

CSRF之pikachu靶场DW

1&#xff0c;登录皮卡丘靶场&#xff0c;get请求&#xff1b; 2&#xff0c;抓包并修改标记后的个人信息 最后放通一下&#xff0c;发现账号信息被修改 2&#xff0c;post请求 1提交post数据并使用bp抓包 2.利用工具改包&#xff0c;并生成url 3&#xff0c;点击提交后&#…

应用在触摸开关触控屏中的电容式触摸芯片

触摸开关是一种电子开关&#xff0c;使用时轻按开关按钮即可打开开关。松开手时&#xff0c;开关断开&#xff0c;内部结构由金属弹片受力弹动断开或者由电容值&#xff0c;电阻值等电气参数改变而控制。触摸开关一般是指应用触摸感应芯片原理设计的一种墙壁开关&#xff0c;是…

ArkUI组件--Button组件

1.声明Button组件 Button(label?:ResourceStr) #label是按钮上显示的文本 ①label是文字类型 所写文字会在按钮上显示 ②不输入label内容&#xff0c;需要额外定义一些描述。例如插入图片&#xff08;需要定义图片属性&#xff09; Button(){Image($r(app.media.xxx)).wi…

风靡万千软件开发者:揭秘华为研发代码大模型是如何实现的?

作者&#xff1a;陈泰红 秉持“自己的降落伞&#xff0c;自己先跳”的原则&#xff0c;由公司装备部门牵头&#xff0c;携手华为云PaaS作为基础能力提供方&#xff0c;与公司各产品线共同研发面向产业的代码大模型。在研发过程中&#xff0c;我们已取得初步成果&#xff0c;为…

LeetCode:1038. 从二叉搜索树到更大和树(反向中序遍历 C++、Java)

目录 1038. 从二叉搜索树到更大和树 题目描述&#xff1a; 实现代码与解析&#xff1a; dfs 原理思路&#xff1a; 1038. 从二叉搜索树到更大和树 题目描述&#xff1a; 给定一个二叉搜索树 root (BST)&#xff0c;请将它的每个节点的值替换成树中大于或者等于该节点值的所…