簡體   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