python - 使用 reticulate 从 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,
initial_position=rosenbrock_start,
tolerance=1e-12)
rosenbrock_start = tf.constant([2.,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, y = coord[..., 0], coord[..., 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)
这会产生预期的输出:
(<tf.Tensor: shape=(), dtype=float32, numpy=49.0>, <tf.Tensor: shape=(2,), dtype=float32, numpy=array([154., -40.], dtype =float32)>)
解决方案
tfp.math.value_and_gradient
会将列表解压缩为多个参数,并对每个参数进行区分。你必须换成np.array
or 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 图中。
推荐阅读
- audio - 如何替换视频文件一部分的视频轨道?
- sapui5 - 将 SAPUI5 网络图导出为 PDF
- sublimetext3 - sublime text 3 写形状和贴纸 (,,)
- c# - 如何使用 jquery 从视图中的项目列表中获取值
- php - 从表中获取值并将该值提交到另一个表mysql php
- android - Xamarin:更新 NuGet 包后无法构建:Xamarin.Build.DownloadsAaRProgGuard 失败
- python - 用python循环往后退一步
- webrtc - 有没有办法在统一计划中向收发器添加自定义属性
- postgresql - Postgres:将 ON CONFLICT 与 CASE 一起使用
- ios - 如何调整 UITextView 的大小,当达到某个值时,它会根据内容和固定宽度自动调整其宽度和高度?