[PyTorch][chapter 4][李宏毅深度学习][Gradient Descent]

前言:

    

目录:

      1:  梯度下降原理

      2:  常见问题

      3: 梯度更新方案

      4: 梯度下降限制


一  梯度下降原理

       机器学习的目标找到最优的参数,使得Loss 最小

          

        

  为什么顺着梯度方向loss 就能下降了。主要原理是泰勒公式。

  假设损失函数为h(x) 

h(x_{t+1})=h(x_t)+h^{'}(x_t)(x_{t+1}-x_t)+\frac{h^{"}(x_t)(x_{t+1}-x_t)^2}{2}+...

 忽略二阶导数, 当x_{t+1}-x_t=-h^{'}(x_t) 时候

 h(x_{t+1})=h(x_t)-h^{'}(x_t)^2 \leq h(x_t)

因为要考虑二阶导数,所以损失函数一般都选凸函数,二阶为0,一阶导数有驻点的函数.


二  常见问题

      1: 学习率learning rate

            红线: 学习率太小,收敛速度非常慢

            绿线 :  学习率太大,无法收敛.

             有什么自动调整学习率的算法?


三  梯度更新方案

     3.1   vanilla gradient descent

    \eta^{t}=\frac{\eta}{\sqrt{t+1}}

      学习率除以时间的开方:

     训练开始:loss 远离极小值点,所以使用大的学习率
     几次迭代后,我们接近极小值点,所以使用小的学习率

      3.2 Adagrad

      不同参数不同的学习率,设置不同的学习率,假设w 是权重系数里面的一个参数。

            w^{t+1}=w^t-\frac{\eta^t}{\sigma^t}g^t

                 =w^t-\frac{\eta}{\sqrt{\sum_{i=0}^{t}(g^i)^2}}g^t

其中

                 \eta^{t}=\frac{\eta}{\sqrt{t+1}}

                \sigma^t=\sqrt{\frac{1}{t+1}\sum_{i=0}^{t}(g^i)^2}

  

例:

   为什么要不同参数设置不同的学习率:

   如下图,不同维度的梯度是不一样的,如果使用同一个学习率会使得

某些维度出现学习率过大或者过小问题,导致收敛速度过慢或者网络震荡问题.


 

      

   问题2: 为什么要除以\sqrt{\sum_{i=0}^{t}(g^i)^2}

      这个参数相当于二次微分。

     如下图:

                     一次微分小的我们希望学习率大一点,能够快速收敛.

                    一次微分大的我们希望其学习率小一点,防止网络震荡.

                    我们通过采样历史微分结果相加,学习率除以该参数就达到该效果。

3.3   stochastic gradient descent(随机梯度下降法)

     假设我们有20个样本

    每轮迭代:

    梯度下降法: 计算20个样本,计算20个样本的梯度,通过平均值更新梯度

    随机梯度下降法: 随机选取一个样本,计算1个样本梯度,更新梯度

    优点: 速度快

   3.4  batchnormalization

       作用:

            使得不同维度上面数据分布一致。

            常用方案 batchnormalization:

              数据集 假设有m个样本,每个数据的维度为n

                \begin{bmatrix} x_1^1 & x_2^1 &... &x_n^1 \\ x_1^2 & x_2^2 &... &x_n^2 \\ & & & \\ x_1^m & x_2^m &... &x_n^m \end{bmatrix}

             对每个维度求其均值u_i,,以及方差\sigma_i

              x_i^{r}=\frac{x_i^{r}-u_i}{\sigma_i}

             

      如下图: y=w_1x_1+w_2x_2+b

         

    主要作用:

例子:

  假设

     y=w_1x_1+w_2x_2+b

      l=\frac{1}{2}(\hat{y}-y)^2

     则

      \bigtriangledown w_1=(y-\hat{y})x_1

      \bigtriangledown w_2=(y-\hat{y})x_2

    如x_1,x_2 相差很大的时候,同样的loss,会导致不同维度

梯度变化相差非常大,当使用随机梯度下降时候,不同的出发点

收敛速度会相差很大。但是使用batchnormalization 方案后,

无论从哪个出发点出发,都不会影响收敛速度.

    

     


四  梯度下降限制

   4.1  任务说明:

    根据前9小时的数据,预测下一个小时的PM2.5值

    

4.2 数据集

   

    


使用丰原站的观测记录,分成 train set 跟 test set,train set 是丰原站每个月的前 20 天所有资料。test set 则是从丰原站剩下的资料中取样出来。
train.csv: 每个月前 20 天的完整资料。
test.csv : 从剩下的资料当中取样出连续的 10 小时为一笔,前九小时的所有观测数据当作 feature,第十小时的 PM2.5 当作 answer。一共取出 240 笔不重複的 test data,请根据 feature 预测这 240 笔的 PM2.5。
Data 含有 18 项观测数据 AMB_TEMP, CH4, CO, NHMC, NO, NO2, NOx, O3, PM10, PM2.5, RAINFALL, RH, SO2, THC, WD_HR, WIND_DIREC, WIND_SPEED, WS_HR。

 

工程两个文件:

dataLoader.py

main.py


import pandas as pd
import numpy as np
import math


def get_testData(mean_x,std_x):
    #[4320 个数据,18个fetature 为一组,所有共有240个testData]
    print("\n mean_x",mean_x)
    testdata = pd.read_csv('data/test.csv',header=None, encoding = 'big5')
    
    test_data = testdata.iloc[:, 2:]
    test_data = test_data.copy()
    test_data[test_data == 'NR'] = 0
 
    test_data = test_data.to_numpy()
    #print("\n ---",test_data[0])
    test_x = np.empty([240, 18*9], dtype = float)
    for i in range(240):
        a = test_data[18 * i: 18* (i + 1), :].reshape(1, -1)
        #print("\n i ",i, a.shape)
        test_x[i, :] = test_data[18 * i: 18* (i + 1), :].reshape(1, -1)
      
    for i in range(len(test_x)):
        for j in range(len(test_x[0])):
            if std_x[j] != 0:
                test_x[i][j] = (test_x[i][j] - mean_x[j]) / std_x[j]
   
    test_x = np.concatenate((np.ones([240, 1]), test_x), axis = 1).astype(float)
    
    print("\n test_x",test_x.shape)
    return test_x
    

def load_data():
    
    data = pd.read_csv('data/train.csv', encoding='big5')
 
    
    #提取第三列后面的资料
    data = data.iloc[:,3:]
    data[data=='NR']=0
    raw_data = data.to_numpy() #[4320,24]
    #print(raw_data.shape)
    #print(data.head(18))
    return raw_data

def extract_traindata(month_data):
    '''
    用前9小时的18个特征预测 预测第10小时的PM2.5

    
    ----------
    month_data : TYPE
       key:   month
       item:  day1[24小时],data2[24小时],...data20[24小时]
    Returns
    -------
    x : TYPE
        DESCRIPTION.
    y : TYPE
        DESCRIPTION.

    '''
    #每个月480小时(20天),每9小时形成一个data,共有471data,所以训练集有12*471各数据
    #因为作业要求用前9小时,前9小时有18各feature
    x = np.empty([12*471,18*9],dtype=float)
    y = np.empty([12*471,1],dtype=float)
    
    for month in range(12):
        for day in range(20):
            for hour in range(24):
                
                if day ==19 and hour>14: 
                    continue
                else:
                    #每个小时的18项数据
                    data_start = day*24+hour
                    data_end = data_start+9
                    x[month*471+data_start,:]=month_data[month][:,data_start:data_end].reshape(1,-1)#前9小时
                    # pm标签值
                    y[month*471+data_start,0]=month_data[month][9,data_end] #第10个小时
    return x,y
                    
def  data_normalize(x):
    # 4.归一化
    mean_x = np.mean(x, axis = 0) #求列方向的均值
    std_x = np.std(x, axis = 0) #1列方向的方差
    print("\n shape ",x.shape)

    m,n =x.shape
    
 
    for i in range(m): #12 * 471
        for j in range(n): #18 * 9 
            if std_x[j] != 0:
                x[i][j] = (x[i][j] - mean_x[j]) / std_x[j]
    return x,mean_x,std_x


def train_load(x,y):
    x_train_set = x[: math.floor(len(x) * 0.8), :]
    y_train_set = y[: math.floor(len(y) * 0.8), :]
    x_validation = x[math.floor(len(x) * 0.8): , :]
    y_validation = y[math.floor(len(y) * 0.8): , :]
    print(x_train_set)
    (y_train_set)
    print(x_validation)
    print(y_validation)
    print(len(x_train_set))
    print(len(y_train_set))
    print(len(x_validation))
    print(len(y_validation))


def extract_features(raw_data):
    '''

    Parameters
    ----------
    raw_data : TYPE
        行:12个月,每月20天,每天18个特征。 [AMB_TEMP,CH4,CO,NMHC,NO,NO2,NOx,O3,PM10,PM2.5,RAINFALL,RH,SO2,THC,WD_HR,WIND_DIREC,WIND_SPEED,WS_HR]
        列:24小时 

    Returns
    -------
    month_data : TYPE
        12个月的词典
        比如针对AMB_TEMP 特征: 原来分成20行(每行24小时), 现在放在一行: 20(天)*24(小时)

    '''

    
    month_data ={}
    for month in range(12):
        #
        sample = np.empty([18,480])    
        for day in range(20):
            sample[:, day * 24 : (day + 1) * 24] = raw_data[18 * (20 * month + day) : 18 * (20 * month + day + 1), :]
        month_data[month] = sample
    return month_data
    
def  load_trainData():
    
    #原始的数据集[ 12个月:每个月20天: 每天24小时,18个特征 ]
    raw_data = load_data()
    month_data  = extract_features(raw_data)
    x,y = extract_traindata(month_data)
    x,mean_x,std_x = data_normalize(x)
    
    return x,y,mean_x,std_x

# -*- coding: utf-8 -*-
"""
Created on Fri Dec  1 16:36:16 2023

@author: chengxf2
"""

# -*- coding: utf-8 -*-
"""
Created on Thu Nov 30 17:49:04 2023

@author: chengxf2
"""


import numpy as np
import csv
from  dataLoader import load_trainData
from  dataLoader import  get_testData

def predict(test_x):
    w = np.load('weight.npy')
    y = np.dot(test_x, w)
  
    with open('submit.csv', mode='w', newline='') as submit_file:
        csv_writer = csv.writer(submit_file)
        header = ['id', 'value']
        print(header)
        csv_writer.writerow(header)
        for i in range(240):
            row = ['id_' + str(i), y[i][0]]
            csv_writer.writerow(row)
            #print(row)
    submit_file.close()
    



def train(x,y):
    #w=[b,w]  
    #y = Xw
    dim = 1+18 * 9 #加上1个偏置
    w = np.zeros([dim, 1])
    x = np.concatenate((np.ones([12 * 471, 1]), x), axis = 1).astype(float)
    
    
    learning_rate = 1e-4
    iter_time = 1000
    adagrad = np.zeros([dim, 1])
    eps = 1e-6
    
    for t in range(iter_time):
        bias = np.dot(x, w) - y
        loss = np.sqrt(np.sum(np.power(bias, 2))/471/12)#rmse
        
        if(t%100==0):
            print("\n \n %d"%t,"\t loss: %6.3f"%loss)
        gradient = 2 * np.dot(x.transpose(), bias) #dim*1
        adagrad += gradient ** 2
        w = w - learning_rate * gradient / np.sqrt(adagrad + eps)
    np.save('weight.npy', w)
    
if __name__ == "__main__":
    x,y,mean_x,std_x = load_trainData()
    
    train(x,y)
    test_x =get_testData(mean_x,std_x)
    predict(test_x)

参考:

Hung-yi Lee

https://blog.csdn.net/Sinlair/article/details/127100363

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

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

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

k8s部署单机模式的minio

k8s部署单机模式的minio 一、说明二、yaml内容三、步骤3.1 创建资源3.2 查看启动日志3.2 查看svc并访问控制台 一、说明 项目使用minio,准备在k8s环境部署一套minio试用。 1.关于minio的原理和概念参考: https://mp.weixin.qq.com/s?__bizMzI3MDM5NjgwNg&mid…

zabbix6.4监控交换机发现ICMP报错Ping item must have target or host interface specified

报错信息: 查看监控项: 修改键值: 保存再次检查,发现又报错/usr/sbin/fping: [2] No such file or directory 原因是,zabbix-server上没有安装fping工具 解决方法:yum install fping -y 之后数据采集正常…

Retrofit的转换器

一、前言 1.为什么要使用Retrofit转换器 在我们接受到服务器的响应后,目前无论是OkHttp还是Retrofit都只能接收到String字符串类型的数据,在实际开发中,我们经常需要对字符串进行解析将其转变为一个JavaBean对象,比如服务器响应…

12、pytest上下文友好的输出

官方实例 # content of test_assert2.py import pytestdef test_set_comparison():set1 set("1308")set2 set("8035")assert set1 set2def test_dict_comparison():dict_1 {name:陈畅,sex:男}dict_2 {name:赵宁,sex:女}assert dict_1 dict_2def tes…

神经网络常用归一化和正则化方法解析(一)

🎀个人主页: https://zhangxiaoshu.blog.csdn.net 📢欢迎大家:关注🔍点赞👍评论📝收藏⭐️,如有错误敬请指正! 💕未来很长,值得我们全力奔赴更美好的生活&…

代理IP和网络加速器的区别有哪些

随着互联网的普及,越来越多的人开始使用网络加速器来提高网络速度。然而,很多人并不清楚代理IP和网络加速器之间的区别。本文将详细介绍两者的概念及区别。 一、代理IP 代理IP是一种通过代理服务器进行网络连接的方式。在使用流冠代理IP时,用…

伴随高性能多级网关和多级分布式缓存架构应用实战经验

随着互联网业务的快速发展,对于高性能网络架构的需求越来越迫切。在这篇文章中,我们将介绍高性能多级网关和多级分布式缓存架构在实际应用中的经验,并提供相关示例代码。 一、高性能多级网关的设计与实现 高性能多级网关是一个重要的网络架构…

软件外包公司的核心竞争力

软件外包公司的核心竞争力可以涵盖多个方面,这取决于公司的战略、专业领域和市场定位。以下是一些可能构成软件外包公司核心竞争力的因素,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1…

js中hasOwnProperty() 方法详解

hasOwnProperty 会返回一个布尔值,判断对象中是否存在该属性,不是继承属性,和原型链上的属性,是对象自身的属性,有返回true,没有返回false hasOwnProperty() 方法是 Object 的原型方法(也称实例方法),它定义在 Object.prototype 对象之上&am…

动能资讯 | 智慧汽车—城市NOA迎爆发

在特斯拉引领的 TransformerBev 架构驱动下,智驾算法趋近于端到端的智驾大模型,使得智能驾驶开始步入城市 NOA 新时代。 消费者认知增强,未来市场空间广阔。伴随城市 NOA 在 23-24 年的落地和普及、L3 法规在年内的落地,行业 0-1…

众里寻她千百度:使用Excalidraw一句话绘制进销存系统采购入库流程

引言: 本文将介绍如何使用Excalidraw这一在线绘图工具来绘制进销存系统中的采购入库流程,帮助您更好地理解和优化采购流程。 正文: 1. 打开Excalidraw网站: 在浏览器中输入"https://excalidraw.com",打开Ex…

聚观早报 |真我GT5 Pro细节曝光;iQOO Neo9系列参数曝光

【聚观365】12月5日消息 真我GT5 Pro细节曝光 iQOO Neo9系列参数曝光 抖音商城双12好物节 蔚来正式获得独立造车资质 三星Galaxy S24 Ultra手写笔获认证 真我GT5 Pro细节曝光 今年的顶级旗舰大比拼也进入最后的高潮,剩余还未亮相的骁龙8 Gen3旗舰新机目前也基…

个体诊所电子处方系统哪个好用,推荐一款可以自由设置配方模板能够填写病历可以查询历史病历的门诊处方笺软件

一、前言 1、功能实用,操作简单,不会电脑也会操作,软件免安装,已内置数据库。 2、中医西医均可用此软件开电子处方,支持病历记录查询,药品进出库管理,支持配方模板一键导入电子处方。 二、电子…

Java 基础学习(五)面向对象编程-对象和类

1 类和对象 1.1 面向对象概述 1.1.1面向对象简史 面向对象编程思想最初的起源可以追溯到1960年的Simula语言,这被认为是第一个支持面向对象编程概念的语言。Simula引入了类、对象、继承等概念,将数据和操作进行封装。Simula的创始人奥利-约翰达尔&…

【数电笔记】09-逻辑代数的基本定律、常用公式

目录 说明: 逻辑代数的基本定律 1. 常量间的运算 2. 逻辑变量与常量的运算 3. 与普通代数相似的定律 4. 摩根定律(反演律) 5. 等式证明方法例题 逻辑代数的常用公式 1. 吸收律 2. 冗余律 3. 示例应用 4. 关于异或运算的一些公式 …

uniapp得app云打包问题

获取appid,具体可以查看详情 也可以配置图标,获取直接生成即可 发行 打包配置 自有证书测试使用时候不需要使用 编译打包 最后找到安装包apk安装到手机 打包前,图片命名使用要非中文,否则无法打包成功会报错

聊聊 Jetpack Compose 原理 -- Compose 是如何将数据转换成 UI 的?

Compose 是一个声明式的 UI 框架,提供了很多开箱即用的组件,比如 Text()、Button、Image() 等等,Compose 会经过几个不同的阶段,最终渲染出 UI 界面。 此转换过程分为【三个阶段】: 组合: 显示什么布局&a…

Dynamics 365 关闭新特性“试用新外观“

微软总是喜欢悄默默上线一些新功能,比如之前的高级设置直接跳转Power apps的管理后台,被骂了一周改回来了。 这次又搞了个试用新外观,但一般这种都是有关闭的地方的,去Power Platform中的环境设置中找了半天没找到。 最终在应用的…

缓冲区溢出及原理

缓冲区缓冲区溢出缓冲区溢出的 C 程序实例缓冲区溢出错误的危害Linux IA32 的进程映像缓冲区溢出的原理 缓冲区 缓冲区是一块用于存取数据的 内存,其位置和长度(大小)在编译时确定 或 在程序运行时动态分配。 缓冲区通常用于存储临时数据&am…