繁体   English   中英

使用网状从 R 导入的 function 上计算梯度时出错

[英]Error calculating gradient on function imported from R using reticulate

我现在正在解决一个问题,我正在尝试使用 Python 中 Tensorflow 概率的优化器来解决我已经在 ZE1E1D3D40573127E9EE0480CAF1283 中定义的简单优化问题。

以下是步骤:

步骤 1:定义原始 Python 问题以解决 Rosenbrock 香蕉 function:

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 中定义一个相同的 function:

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 function 定义 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 个

我尝试调查是否向 function 输入了错误的内容,但实现与我的本机实现相同:

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)

这将产生预期的 output:

(<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会将列表解压缩为多个 arguments 并相对于它们中的每一个进行区分。 您必须包含np.arraytf.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 图中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM