簡體   English   中英

如何在 Tensorflow 中實現逐元素一維插值?

[英]How to implement element-wise 1D interpolation in Tensorflow?

我想對 Tensorflow 中張量的每個元素應用一維插值。

例如,如果它是一個矩陣,我們可以使用interp1d

from scipy.interpolate import interp1d
q = np.array([[2, 3], [5, 6]])   # query
x = [1, 3, 5, 7, 9]              # profile x
y = [3, 4, 5, 6, 7]              # profile y
fn = interp1d(x, y)
# fn(q) == [[ 3.5, 4.], [5., 5.5]]

如果我們有一個張量q

q = tf.placeholder(shape=[2,2], dtype=tf.float32)

我怎樣才能有等效的逐元素一維插值? 有人可以幫忙嗎?

我正在使用一個包裝器:

import numpy as np
import tensorflow as tf
from scipy.interpolate import interp1d


x = [1, 3, 5, 7, 9]
y = [3, 4, 5, 6, 7]
intFn = interp1d(x, y)

def fn(m):
    return intFn(m).astype(np.float32)

q = tf.placeholder(shape=[2,2], dtype=tf.float32)
q1 = np.array([[2, 3], [5, 6]]).astype(np.float32)

f1 = tf.py_func(fn, [q], tf.float32)

with tf.Session() as sess:
    init = tf.global_variables_initializer()
    sess.run(init)
    result = sess.run(f1, feed_dict={q:q1})

print(result)

不是最好的解決方案。 希望張量流將在numpy和scipy中實現更多的功能......

編輯:

我編寫了一個可能有用的簡單張量流函數。 不幸的是,這一次只能做一個值。 但是,如果它很有意思,這可能會在......之后得到改善。

def interpolate( dx_T, dy_T, x, name='interpolate' ):

    with tf.variable_scope(name):

        with tf.variable_scope('neighbors'):

            delVals = dx_T - x
            ind_1   = tf.argmax(tf.sign( delVals ))
            ind_0   = ind_1 - 1

        with tf.variable_scope('calculation'):

            value   = tf.cond( x[0] <= dx_T[0], 
                              lambda : dy_T[:1], 
                              lambda : tf.cond( 
                                     x[0] >= dx_T[-1], 
                                     lambda : dy_T[-1:],
                                     lambda : (dy_T[ind_0] +                \
                                               (dy_T[ind_1] - dy_T[ind_0])  \
                                               *(x-dx_T[ind_0])/            \
                                               (dx_T[ind_1]-dx_T[ind_0]))
                             ))

        result = tf.multiply(value[0], 1, name='y')

    return result

在給定幾個張量的情況下,這會產生一個合成張量。 這是一個示例實現。 首先創建一個圖表......

tf.reset_default_graph()
with tf.variable_scope('inputs'):
    dx_T = tf.placeholder(dtype=tf.float32, shape=(None,), name='dx')
    dy_T = tf.placeholder(dtype=tf.float32, shape=(None,), name='dy')
    x_T  = tf.placeholder(dtype=tf.float32, shape=(1,), name='inpValue')

y_T  = interpolate( dx_T, dy_T, x_T, name='interpolate' )
init = tf.global_variables_initializer()

現在您可以像這樣使用它:

x = [1, 3, 5, 7, 9]              # profile x
y = [3, 4, 5, 6, 7]              # profile y
q = np.array([[2, 3], [5, 6]])

with tf.Session() as sess:
    sess.run(init)

    for i in q.flatten():
        result = sess.run(y_T, 
                    feed_dict={ 
                        'inputs/dx:0'       : x,
                        'inputs/dy:0'       : y,
                        'inputs/inpValue:0' : np.array([i])
                    })

        print('{:6.3f} -> {}'.format(i, result))

你會得到理想的結果......

這是 TF2 中的另一種方法,它將一次使用多個值,x 和 xi 必須都是單調遞增的:

def interp1(x, xi, y):
    j   =   tf.argsort(tf.concat((x, xi), axis=-1))
    k   =   tf.range(len(j))
    q   =   tf.scatter_nd(j[:, tf.newaxis], k, k.shape)

    lxi =   len(xi)

    r   =   q[-lxi:]-tf.range(0, lxi)
    r   =   tf.where(xi == x[-1], q[-1:] - lxi, r)

    x2  =   tf.gather(x, r)
    x1  =   tf.gather(x, r-1)
    y2  =   tf.gather(y, r)
    y1  =   tf.gather(y, r-1)

    u   =   (xi-x1)/(x2-x1)
    if not tf.rank(u) == tf.rank(y1):
        u   =   tf.expand_dims(u, axis=-1)

    yi  =   (1.0-u)*y1 + u*y2

    return tf.where(y1 == y2, y1, yi)

測試:

x   =   tf.range(0, 4, 1, dtype=tf.float64)
xi  =   tf.concat((tf.range(0, 3, .3, dtype=tf.float64), x[-1:]),  axis=-1)
y   =   x[:, tf.newaxis]+x[tf.newaxis, :]

結果:

interp1(x, xi, y)
<tf.Tensor: shape=(11, 4), dtype=float64, numpy=
array([[0. , 1. , 2. , 3. ],
       [0.3, 1.3, 2.3, 3.3],
       [0.6, 1.6, 2.6, 3.6],
       [0.9, 1.9, 2.9, 3.9],
       [1.2, 2.2, 3.2, 4.2],
       [1.5, 2.5, 3.5, 4.5],
       [1.8, 2.8, 3.8, 4.8],
       [2.1, 3.1, 4.1, 5.1],
       [2.4, 3.4, 4.4, 5.4],
       [2.7, 3.7, 4.7, 5.7],
       [3. , 4. , 5. , 6. ]])>
interp1(x, xi, y[0])
<tf.Tensor: shape=(11,), dtype=float64, numpy=array([0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3. ])>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM