如何解决使用网状计算从 R 导入的函数的梯度时出错
我现在正在解决一个问题,我试图在 Python 中使用 Tensorflow 概率中的优化器来解决我已经在 R 中定义的简单优化问题。
步骤如下:
步骤 1:定义解决 Rosenbrock 香蕉函数的原始 Python 问题:
import contextlib
import functools
import os
import time
import numpy as np
import pandas as pd
import scipy as sp
from six.moves import urllib
from sklearn import preprocessing
import tensorflow.compat.v2 as tf
tf.enable_v2_behavior()
import tensorflow_probability as tfp
def make_val_and_grad_fn(value_fn):
@functools.wraps(value_fn)
def val_and_grad(x):
return tfp.math.value_and_gradient(value_fn,x)
return val_and_grad
@contextlib.contextmanager
def timed_execution():
t0 = time.time()
yield
dt = time.time() - t0
print('Evaluation took: %f seconds' % dt)
def np_value(tensor):
"""Get numpy value out of possibly nested tuple of tensors."""
if isinstance(tensor,tuple):
return type(tensor)(*(np_value(t) for t in tensor))
else:
return tensor.numpy()
def run(optimizer):
optimizer() # Warmup.
with timed_execution():
result = optimizer()
return np_value(result)
def run(optimizer):
optimizer() # Warmup.
with timed_execution():
result = optimizer()
return np_value(result)
@make_val_and_grad_fn
def rosenbrock_test(coord):
x,y = coord[...,0],coord[...,1]
return((5.0-x)**2 + 10.0 * (y-x**2)**2)
optim_results = tfp.optimizer.lbfgs_minimize(
rosenbrock_test,initial_position=rosenbrock_start,tolerance=1e-12)
rosenbrock_start = tf.constant([2.,2.])
optim_results = tfp.optimizer.lbfgs_minimize(
rosenbrock_test,2.])
print('L-BFGS Results')
print('Converged:',optim_results.converged)
print('Location of the minimum:',optim_results.position)
print('Number of iterations:',optim_results.num_iterations)
第 2 步:在 R 中定义一个相同的函数:
rosenbrock_for_r <- function(coord){
x <- coord[1]
y <- coord[2]
return( (5-x)^2 + 10 * (y-x^2)^2 ) }
rosenbrock_for_r(c(2,2))
第 3 步:为 R 函数定义 Python 包装器:
def rosenbrock_R(coord):
return(r.rosenbrock_for_r(coord))
这一步出现错误:
temp = [2.0,2.0]
tfp.math.value_and_gradient(rosenbrock_R,[2.,2.])
错误是:
类型错误:rosenbrock_R() 需要 1 个位置参数,但给出了 2 个
我已经尝试调查我是否向函数输入了错误的内容,但实现与我的本机实现相同:
def rosenbrock_alt(coord):
x,1]
return((5.0-x)**2 + 10.0 * (y-x**2)**2)
temp = tf.constant([2.0,2.0])
tfp.math.value_and_gradient(rosenbrock_alt,temp)
这会产生预期的输出:
(
解决方法
tfp.math.value_and_gradient
会将列表解包为多个参数,并针对每个参数进行比较。您必须用 np.array
或 tf.convert_to_tensor
换行。
此外,目前还不清楚您将如何获得 rosenbrock_for_r
的渐变。您可能必须使用类似
@tf.custom_gradient
def f(x):
def df(df_x):
return r.grad_rosenbrock(x,df_x)
return r.rosenbrock_for_r(x),df # or x.numpy() but that will be eager-only
您可以使用 tf.py_function
将 Eager/r 代码嵌入到 TF 图中。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。