nonlocal关键字声明

nonlocal关键字声明

作用

使得内层函数可以使用/修改外层函数的变量

值得注意的是,在未使用nonlocal声明时

  • 对于外层函数中的可变对象,内层函数即可访问,也可以修改

    def outer():
        x, y = [1], [2]
    
        def inner(z):
            x.append(1)
            print(x)
            print(z)
    
        return inner
    
    
    outer()([3])
    
    
    [1, 1]
    [3]
    
  • 对于外层函数中的不可变对象,如数字、字符串,只能访问,不能修改

    def outer():
        x, y = 1, 2
    
        def inner(z):
            print(x)
            x += 1
            print(x)
            print(z)
    
        return inner
    
    
    outer()(3)
    
    
    UnboundLocalError: local variable 'x' referenced before assignment
    

    可以发现:

    两个print(x)均未被执行

    即,只要在内部函数中尝试修改外部函数中的不可变变量,那么在调用内部函数时,就会直接报错,而不是一句一句执行,直到遇到错误的那行代码

使用nonlocal声明时

def outer():
    x, y = 1, 2

    def inner(z):
        nonlocal x
        x += 1
        print(x)
        print(z)

    return inner


outer()(3)
2
3

应用场景

如果外层函数中的变量被内层函数使用,并且内层函数是外层函数的返回值,就会形成闭包,有以下特点:

  • 被内层函数使用的外层函数变量,在外层函数调用完毕后不会被销毁,而是与内层函数共同组成闭包,隐藏在闭包里面,这里姑且称为外层残余变量
  • 只有通过调用作为外层函数返回值的内层函数才能访问/修改这些被封存在闭包里面的外层残余变量,这是唯一途径,也是”闭“的含义
    • 如果外层残余变量为不可变对象,那么可以通过nonlocal关键字声明进行修改
    • 如果外层残余变量为可变对象,那么可以直接进行修改
  • 闭包可以看作一个分多步调用的函数
    1. 首先调用外层函数
    2. 然后调用返回的内层函数

stable baselines3是一个深度强化学习算法库,提供以下方法供用户自定义学习率更新策略,链接

链接的意思就是,所有算法都支持传入一个以固定参数progress_remaining为输入的闭包函数作为学习率更新策略,随训练进程,progress_remaining自动从 1 → 0 1\rightarrow 0 10,RL Zoo 里面实现了一个线性衰减的学习率更新策略,示例如下:

from typing import Callable

from stable_baselines3 import PPO


def linear_schedule(initial_value: float) -> Callable[[float], float]:
    """
    Linear learning rate schedule.

    :param initial_value: Initial learning rate.
    :return: schedule that computes
      current learning rate depending on remaining progress
    """
    def func(progress_remaining: float) -> float:
        """
        Progress will decrease from 1 (beginning) to 0.

        :param progress_remaining:
        :return: current learning rate
        """
        return progress_remaining * initial_value

    return func

# Initial learning rate of 0.001
model = PPO("MlpPolicy", "CartPole-v1", learning_rate=linear_schedule(0.001), verbose=1)
model.learn(total_timesteps=20_000)

下面,我们使用nonlocal关键字实现一个更加复杂的多步衰减学习率策略,即指定初始学习率、衰减次数、衰减率,随训练进程在特定步数自动乘以衰减因子衰减lr

import numpy as np
from matplotlib import pyplot as plt


def multi_step_decay_schedule(init_value, decay_times=9, gamma=0.7):
    lr = init_value
    progress_nodes = np.linspace(1 - 1 / (1 + decay_times), 0, decay_times, endpoint=False)
    progress_mask = np.full(decay_times, True, dtype=bool)

    def func(progross_remaining):
        # lr是float不可变对象,需要更新lr作为返回值,因此用nonlocal声明
        # progress_mask、progress_nodes为可变对象,无需nonlocal声明
        nonlocal lr
        for i in range(decay_times):
            if progress_mask[i] and abs(progress_nodes[i] - progross_remaining) < 1e-3:
                progress_mask[i] = False
                # 将学习率乘以gamma
                lr = lr * gamma
        return lr

    return func


if __name__ == "__main__":
    lr_schedule = multi_step_decay_schedule(0.1)
    progross_remaining = np.arange(1, 0, -0.001)
    lr = [lr_schedule(p) for p in progross_remaining]
    plt.plot(progross_remaining[::-1], lr)
    plt.show()

衰减过程:https://img-blog.csdnimg.cn/img_convert/4c19d63a3d9d7ffe963d4f92a7a1e910.png

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

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

相关文章

历史最佳二季度表现后,爱奇艺想为用户提供更多价值

以爱奇艺为首&#xff0c;随着长视频平台相继转变运营思路&#xff0c;走向盈利目标&#xff0c;最早完成蜕变的爱奇艺&#xff0c;已开始迈向下一阶段。 近日&#xff0c;爱奇艺发布了截至6月30日的2023年第二季度财报。除了依然亮眼的内容表现、业绩成果外&#xff0c;爱奇艺…

1.Flink源码编译

目录 1.环境版本 1.1 jdk 1.2.maven 1.3.node 1.4.scala 2.下载flink源码 3.编译源码 4.idea打开flink源码 5.运行wordcount 1.环境版本 软件地址 链接&#xff1a;https://pan.baidu.com/s/1ZxYydR8rBfpLCcIdaOzxVg 提取码&#xff1a;12xq 1.1 jdk 1.2 maven 1.…

Bean 作用域和生命周期

前言&#xff1a; &#x1f4d5;作者简介&#xff1a;热爱编程的小七&#xff0c;致力于C、Java、Python等多编程语言&#xff0c;热爱编程和长板的运动少年&#xff01; &#x1f4d8;相关专栏Java基础语法&#xff0c;JavaEE初阶&#xff0c;数据库&#xff0c;数据结构和算法…

GPT4模型架构的泄漏与分析

迄今为止&#xff0c;GPT4 模型是突破性的模型&#xff0c;可以免费或通过其商业门户&#xff08;供公开测试版使用&#xff09;向公众提供。它为许多企业家激发了新的项目想法和用例&#xff0c;但对参数数量和模型的保密却扼杀了所有押注于第一个 1 万亿参数模型到 100 万亿参…

【Mac】编译Spring 源码和Idea导入

今天我们开始Spring源码的阅读之旅。阅读Spring的源码的第一步当然是编译Spring源码。首先我们要去GitHub上将spring源码给clone下来。 笔者编译环境如下&#xff1a; Spring版本&#xff1a;5.28 https://github.com/spring-projects/spring-framework/tree/v5.2.8.RELEASE …

LoadRunner操作教程

日升时奋斗&#xff0c;日落时自省 目录 1、Virtual User Generator &#xff08;VUG&#xff09; 1.1、WebTours系统 1.1.1、WebTours启动 1.1.2、WebTours配置 1.2、脚本录制 1.3、编译 1.4、脚本运行 1.5、加强脚本 1.5.1、事务插入 1.5.2、插入集合点 1.5.3、参…

【C++ 学习 ⑰】- 继承(下)

目录 一、派生类的默认成员函数 二、继承与友元 三、继承与静态成员 四、复杂的菱形继承及菱形虚拟继承 五、继承和组合 一、派生类的默认成员函数 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认构造函数&#xff0c;那么必须在派生…

Python基础学习第一天:关于Python的简单介绍

前言 最近一批批大一新生都要开始踏入校园了&#xff0c;计算机专业 emmm…如果有需要学习python的&#xff0c;尤其是还没开学的&#xff0c;确实可以开始找找资料看看python了&#xff0c;如果是自己本来就对python感兴趣&#xff0c;更应该需要看看了&#xff0c;毕竟学校到…

阿里云 Serverless 应用引擎 2.0,正式公测!

阿里云 Serverless 应用引擎 SAE2.0 正式公测上线&#xff01;全面升级后的 SAE2.0 具备极简体验、标准开放、极致弹性三大优势&#xff0c;应用冷启动全面提效&#xff0c;秒级完成创建发布应用&#xff0c;应用成本下降 40% 以上。 此外&#xff0c;阿里云还带来容器服务 Se…

无涯教程-聚类算法 - Mean-Shift

如前所述&#xff0c;它是在无监督学习中使用的另一种强大的聚类算法&#xff0c;与K均值聚类不同&#xff0c;它不做任何假设&#xff0c;因此&#xff0c;它是一种非参数算法。 均值平移算法基本上是通过将数据点移向最高密度的数据点(即群集质心)来迭代地将数据点分配给群集…

【日常积累】Linux中vi/vim的使用

概述 vim是由vi发展演变过来的文本编辑器&#xff0c;因其具有语法高亮显示、多视窗编辑、代码折叠、支持插件等功能&#xff0c;由于其功能相比vi来说更加强大&#xff0c;所以在实际工作中的使用更加广泛。 vim工作模式 Vim具有多种工作模式&#xff0c;常用的工作模式有&…

去除wps段落柄,删除空白页

如图&#xff0c;有一个段落柄在左端&#xff0c;无法删除&#xff0c;只能编辑。 导致本来是8页内容&#xff0c;现在是9页&#xff0c;多了一空白页 后面新建一个空白页&#xff0c;发现默认会自带一个段落柄&#xff0c;所以有可能这个段落柄是不能消除的&#xff0c;那么如…

【LeetCode-面试经典150题-day15】

目录 104.二叉树的最大深度 100.相同的树 226.翻转二叉树 101.对称二叉树 105.从前序与中序遍历序列构造二叉树 106.从中序与后序遍历序列构造二叉树 117.填充每个节点的下一个右侧节点指针Ⅱ 104.二叉树的最大深度 题意&#xff1a; 给定一个二叉树 root &#xff0c;返回其…

智能井盖传感器,物联网智能井盖系统

随着城市人口的不断增加和城市化进程的不断推进&#xff0c;城市基础设施的安全和可靠性变得愈发重要&#xff0c;城市窨井盖作为城市基础设施重要组成部分之一&#xff0c;其安全性事关城市安全有序运行和居民生产生活安全保障。 近年来&#xff0c;各地都在加强城市窨井盖治理…

【C/C++】多态的概念 | 虚函数 | 虚函数指针

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

STM32 BOOT 启动配置 ISP升级 介绍

启动配置 在STM32F10xxx里&#xff0c;可以通过BOOT[1:0]引脚选择三种不同启动模式。 启动模式选择引脚启动模式说明BOOT1BOOT0X0主闪存存储器主闪存存储器被选为启动区域01系统存储器系统存储器被选为启动区域11内置SRAM内置SRAM被选为启动区域 在系统复位后&#xff0c; S…

Kafka核心原理第一弹——更新中

架构原理 一、高性能读写架构原理——顺序写零拷贝 首先了解两个专业术语&#xff0c;研究kafka这个东西&#xff0c;你必须得搞清楚这两个概念&#xff0c;吞吐量&#xff0c;延迟。 写数据请求发送给kafka一直到他处理成功&#xff0c;你认为写请求成功&#xff0c;假设是…

WOFOST模型与PCSE模型应用

目录 第一章 理论基础 农作物生长模型概述 第二章 数据准备 第三章 WOFOST模型基础 第四章 PythonCropSimulationEnvironment 第五章 案例拓展 更多应用 实现作物产量的准确估算对于农田生态系统响应全球变化、可持续发展、科学粮食政策制定、粮食安全维护都至关重要。传…

怎么把pdf转换成jpg格式?

怎么把pdf转换成jpg格式&#xff1f;在我们日常的办公过程中&#xff0c;PDF文件是一个经常被使用来传输文件的格式。它能够确保我们的文件内容不会混乱&#xff0c;并以更加完美的方式呈现出来。然而&#xff0c;PDF文件也存在一些缺陷。例如&#xff0c;它无法直接编辑&#…

linux和python轻松实现短信和邮件的秒发!四大实战脚本大揭秘!

引言 作为Linux和Python技术持续学习者&#xff0c;我们不仅要了解基础知识&#xff0c;还需要实际运用技术解决问题。本文将分享四个实用的Python和Linux运维脚本&#xff0c;帮助我们轻松实现短信和邮件的秒发功能。 要求环境 一台运行Linux操作系统的服务器&#xff08;可以…