【问题标题】:Error calculating gradient on function imported from R using reticulate使用 reticulate 从 R 导入的函数计算梯度时出错
【发布时间】:2021-07-04 15:47:59
【问题描述】:

我现在正在解决一个问题,我正在尝试使用 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.])

错误是:

TypeError: 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)

这会产生预期的输出:

(, )

【问题讨论】:

    标签: python r tensorflow reticulate tensorflow-probability


    【解决方案1】:

    tfp.math.value_and_gradient 会将列表解压缩为多个参数,并对每个参数进行区分。您必须使用 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 图中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-08
      • 2020-07-16
      • 2021-11-30
      • 2017-08-14
      • 2021-10-14
      • 2016-07-01
      • 2021-04-01
      • 1970-01-01
      相关资源
      最近更新 更多