如果我有:
def f(x):
def g(y):
return x + y
return g
f2 = f(2)
Run Code Online (Sandbox Code Playgroud)
有没有办法找到f2将使用的'x'绑定?我看了检查,但无法判断是否有一些'框架'的东西适用.换句话说,我可以在下面定义一个closedVars():
def closed_vars(anF):
... return ...
assert closedVars(f2) == {'x': 2}
Run Code Online (Sandbox Code Playgroud) 如果我有一个包含一些非局部变量(在闭包中)的函数,我如何访问该变量?我可以修改它吗?如果可以,如何修改?这是此类函数的示例:
def outer():
x = 1
def inner(y):
nonlocal x
return x + y
return inner
inner = outer()
# how do I get / change the value of x inside inner?
Run Code Online (Sandbox Code Playgroud)
(如果这个问题已经在其他地方得到了回答,我深表歉意;我找不到它,所以我想一旦解决了我就会分享答案)
我知道如何在 Keras 中使用附加输入(而不是标准y_true,y_pred对)编写自定义损失函数,请参见下文。我的问题是使用可训练变量(其中一些)输入损失函数,该变量是损失梯度的一部分,因此应该更新。
我的解决方法是:
NXV大小的虚拟输入,其中N是观测值的数量和V附加变量的数量Dense()层dummy_output,以便 Keras 跟踪我的V“体重”V在我的自定义损失函数中使用该层的权重作为我的真实输出层dummy_output对于该层使用虚拟损失函数(仅返回 0.0 和/或权重 0.0),因此我的V“权重”仅通过我的自定义损失函数进行更新我的问题是:是否有更自然的类似 Keras/TF 的方法来做到这一点?因为它感觉很做作,更不用说容易出现错误了。
我的解决方法的示例:
(是的,我知道这是一个非常愚蠢的自定义损失函数,实际上事情要复杂得多)
import numpy as np
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from tensorflow.keras.layers import Dense
from tensorflow.keras.callbacks import EarlyStopping
import tensorflow.keras.backend as K
from tensorflow.keras.layers import Input
from tensorflow.keras import Model
n_col = 10
n_row = …Run Code Online (Sandbox Code Playgroud) 编辑:这个问题已经严重过时了!现在Enum,numba支持并namedtuple提供了开箱即用的功能,它们都为分组常量提供了合理的解决方案。
我在python中做一些移位,想用numba加快速度。为此,我有很多常量整数值,必须以一种易于理解的方式进行处理。我想将它们组合在一起,成为枚举式对象,使所有常量在一个名称空间中,可以通过attribute-get运算符进行访问。当然,我也想让numba理解那里发生的事情,以便它可以通过jit编译保持高速。我首先也是最天真的尝试是这样的:
class SomeConstantsContainer:
SOME_NAME = 0x1
SOME_OTHER_CONSTANT = 0x2
AND_ANOTHER_CONSTANT = 0x4
Run Code Online (Sandbox Code Playgroud)
不幸的是,当我查看注解时,numba似乎不了解值是恒定的,并且总是回落到对python对象的慢速对象访问上。这就是注释所说的:
# $29.2 = global(SomeConstantsContainer: <class 'constants.SomeConstantContainer'>) :: pyobject
# $29.3 = getattr(attr=SOME_VARIABLE, value=$29.2) :: pyobject
Run Code Online (Sandbox Code Playgroud)
我知道我总是会退缩到这样的地方:
from numpy import np
SOME_STUPID_CONSTANT = np.int64(0x1)
ANOTHER_STUPID_CONSTANT = np.int64(0x2)
Run Code Online (Sandbox Code Playgroud)
在那种情况下,jit编译器a)不需要查找容器的属性,b)肯定知道它必须处理一个普通整数。这样写真是太丑了。我可以将所有常量明确标记为整数,或者让容器来做。尽管如此,我确实很想将这些常量归类在容器中,以使内容更加清晰,并且jit编译版本可以理解语法,并且不会在每次使用常量时都花一些时间进行缓慢的python属性查找。有没有更好的主意,如何使第二种方法更像第一种方法,同时又保持较高的执行速度?是否有一些numba可以理解的枚举容器,我只是错过了?
编辑:也使用新的enum容器是没有帮助的:
@enum.unique
class SomeConstantsContainer(enum.IntEnum):
SOME_NAME = 0x1
SOME_OTHER_CONSTANT = 0x2
AND_ANOTHER_CONSTANT = 0x4
Run Code Online (Sandbox Code Playgroud)
这给出:
# $42.3 = global(SomeConstantsContainer: <enum 'SomeConstantsContainer'>) :: pyobject
# $42.4 = getattr(attr=SOME_OTHER_CONSTANT, value=$42.3) :: pyobject
Run Code Online (Sandbox Code Playgroud)