[英]How to implement element-wise 1D interpolation in Tensorflow?
I would like to apply 1D interploation to each element of a tensor in Tensorflow.我想对 Tensorflow 中张量的每个元素应用一维插值。
For example, if it is a matrix, we can use interp1d
.例如,如果它是一个矩阵,我们可以使用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]]
If we have a tensor q
,如果我们有一个张量q
,
q = tf.placeholder(shape=[2,2], dtype=tf.float32)
How can I have equivalent element-wise 1D interpolation?我怎样才能有等效的逐元素一维插值? Could anyone help?有人可以帮忙吗?
I am using a wrapper for this: 我正在使用一个包装器:
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)
Not the best solution. 不是最好的解决方案。 Hoping that tensor flow will implement more of the functionality within numpy and scipy ... 希望张量流将在numpy和scipy中实现更多的功能......
I have written a simple tensorflow function that might be useful. 我编写了一个可能有用的简单张量流函数。 Unfortunately, this is will only do one value at a time. 不幸的是,这一次只能做一个值。 However, if it is interesting, this might be something that might be improved upon ... 但是,如果它很有意思,这可能会在......之后得到改善。
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
This creates a resultant tensor, given a couple of tensors. 在给定几个张量的情况下,这会产生一个合成张量。 Here is an example implementation. 这是一个示例实现。 First create a graph ... 首先创建一个图表......
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()
Now you can use it like so: 现在您可以像这样使用它:
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))
And you will get the desired result ... 你会得到理想的结果......
Here's an alternate approach in TF2 which will use multiple values at once, x and xi must both be monotonically increasing:这是 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)
Test:测试:
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, :]
Result:结果:
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.