使用异常处理、*args 和 **kwargs 删除函数的无穷大值
Removing infinity values of a function using exception handling, *args, and **kwargs
我目前正在阅读 Joel Grus 的 Data Science from Scratch 一书,我 运行 研究了一个我不太了解的函数:
def safe(f):
def safe_f(*args, **kwargs):
try:
return f(*args, **kwargs)
except:
return float('inf')
return safe_f
在梯度下降算法中调用安全函数以删除无穷大值。
def minimize_batch(target_fn, gradient_fn, theta_0, tolerance=0.000001):
step_sizes = [100, 10, 1, 0.1, 0.001, 0.0001, 0.00001]
theta = theta_0
target_fn = safe(target_fn)
value = target_fn(theta)
while True:
gradient = gradient_fn(theta)
next_thetas = [step(theta, gradient, -step_size) for step_size in step_sizes]
next_theta = min(next_thetas, key=target_fn)
next_value = target_fn(next_theta)
if abs(value - next_value) < tolerance:
return theta
else:
theta, value = next_theta, next_value
我明白保险箱在做什么,但我不明白它是如何的。例如,如果 target_fn 没有输入,safe 如何计算 target_fn?做什么是安全的,它知道如何删除无穷大值?
撇开梯度下降不谈,这个安全函数是否适用于在无数地方未定义的疯狂函数?
如果我们一步一步替换变量名,可能会帮助您理解:
target_fn = safe(target_fn)
表示safe
中的f
是target_fn
:
def safe(target_fn):
def safe_f(*args, **kwargs):
try:
return target_fn(*args, **kwargs)
except:
return float('inf')
return safe_f
和:
target_fn = safe_f
即我们将最初绑定到 target_fn
的函数替换为我们刚刚在 装饰器函数 safe
中创建的函数 safe_f
,保留对原始函数的访问权 f
,通过 闭包。
所以参数是通过*args, **kwargs
传递的(参见What does ** (double star) and * (star) do for parameters?):
next_value = target_fn(next_theta)
解决为:
def safe_f(next_theta):
try:
return target_fn(next_theta)
except:
return float('inf')
即return 使用参数 next_theta
调用原始 target_fn
的结果,或者,如果这样做时出现任何错误,float('inf')
.
would this safe
function work on a crazy functions that was undefined at uncountably many places?
因为它使用 *args, **kwargs
你可以用它来包装 any 函数,它会安静地抑制 any 引发的错误由函数和 return float('inf')
代替——但这并不总是令人满意的!装饰函数还有许多其他用途,通常使用 @decorator
语法(例如 class 和 静态方法 和 属性 classes);参见例如What are some common uses for Python decorators?
我目前正在阅读 Joel Grus 的 Data Science from Scratch 一书,我 运行 研究了一个我不太了解的函数:
def safe(f):
def safe_f(*args, **kwargs):
try:
return f(*args, **kwargs)
except:
return float('inf')
return safe_f
在梯度下降算法中调用安全函数以删除无穷大值。
def minimize_batch(target_fn, gradient_fn, theta_0, tolerance=0.000001):
step_sizes = [100, 10, 1, 0.1, 0.001, 0.0001, 0.00001]
theta = theta_0
target_fn = safe(target_fn)
value = target_fn(theta)
while True:
gradient = gradient_fn(theta)
next_thetas = [step(theta, gradient, -step_size) for step_size in step_sizes]
next_theta = min(next_thetas, key=target_fn)
next_value = target_fn(next_theta)
if abs(value - next_value) < tolerance:
return theta
else:
theta, value = next_theta, next_value
我明白保险箱在做什么,但我不明白它是如何的。例如,如果 target_fn 没有输入,safe 如何计算 target_fn?做什么是安全的,它知道如何删除无穷大值?
撇开梯度下降不谈,这个安全函数是否适用于在无数地方未定义的疯狂函数?
如果我们一步一步替换变量名,可能会帮助您理解:
target_fn = safe(target_fn)
表示safe
中的f
是target_fn
:
def safe(target_fn):
def safe_f(*args, **kwargs):
try:
return target_fn(*args, **kwargs)
except:
return float('inf')
return safe_f
和:
target_fn = safe_f
即我们将最初绑定到 target_fn
的函数替换为我们刚刚在 装饰器函数 safe
中创建的函数 safe_f
,保留对原始函数的访问权 f
,通过 闭包。
所以参数是通过*args, **kwargs
传递的(参见What does ** (double star) and * (star) do for parameters?):
next_value = target_fn(next_theta)
解决为:
def safe_f(next_theta):
try:
return target_fn(next_theta)
except:
return float('inf')
即return 使用参数 next_theta
调用原始 target_fn
的结果,或者,如果这样做时出现任何错误,float('inf')
.
would this
safe
function work on a crazy functions that was undefined at uncountably many places?
因为它使用 *args, **kwargs
你可以用它来包装 any 函数,它会安静地抑制 any 引发的错误由函数和 return float('inf')
代替——但这并不总是令人满意的!装饰函数还有许多其他用途,通常使用 @decorator
语法(例如 class 和 静态方法 和 属性 classes);参见例如What are some common uses for Python decorators?