如何用相同的逻辑编写等效的Tensorflow代码?

时间:2018-02-14 16:15:09

标签: python tensorflow

myx=np.array([2.4,0.2,0.5,1.6])
myy=np.array([10.1,3.2,7.5,8.6,1,0.1,11,18])

我想编写一个程序,使用贪心算法将“myx”的每个元素与“myy”匹配。匹配将是1:1,卡尺距离<= 0.5,无需更换。 算法很简单:

import numpy as np

myx=np.array([2.4,0.2,0.5,1.6])
myy=np.array([10.1,3.2,7.5,8.6,1,0.1,11,1.4])

Xxx=np.transpose(np.repeat(myx[:, np.newaxis], myy.size , axis=1))
Yyy=np.repeat(myy[:, np.newaxis], myx.size , axis=1)
# define a caliper 
calp=0.5

matches = {}
dist = np.abs(Xxx-Yyy)
print('Before loop distance matrix',dist)
for m in range(0, myx.size):
    if (np.nanmin(dist[:,m]) <= calp) or not calp:
        matches[m] = np.nanargmin(dist[:,m])  
        dist[matches[m],:]=None
print('Match Pairs:',matches)
print('After loop distance matrix',dist)

问题是我不想在“np”或“panda”中使用任何东西,但只想使用Tensorflow框架。我已经写了部分程序,但发现它比我最初的想法更难。有人能帮我吗?顺便说一句,这是我第一次尝试使用tensorflow ..

import math
import numpy as np
import tensorflow as tf


#myx = np.random.uniform(low=0.5, high=3.5, size=(5000,))
#myy=np.random.uniform(low=0.8, high=5.0, size=(50000,))

myx=np.array([2.4,0.2,0.5,1.6])
myy=np.array([10.1,3.2,7.5,8.6,1,0.1,11,18])


Xxx=np.transpose(np.repeat(myx[:, np.newaxis], myy.size , axis=1))
Yyy=np.repeat(myy[:, np.newaxis], myx.size , axis=1)

X = tf.placeholder(tf.float64, shape=(myy.size,myx.size))
Y = tf.placeholder(tf.float64, shape=(myy.size,myx.size))
# define a caliper 
calp=tf.constant(0.5,tf.float64)

with tf.device('/cpu:0'):

    dist = tf.abs(tf.subtract(X,Y))

    # Use an explicit shape for `i`.
    i = tf.placeholder(dtype='int64', shape=[])

    # Add a second unused argument to `condition()`.
    def condition(i, *arg):
        return i <= myx.size-1
    # Add a second unused argument to `b()`.
    def b(i, temp, _):

        tfslic = dist[0:myy.size, i]

        # Drop the `axis` argument from `tf.reduce_min()`
        minVal=tf.reduce_min(tfslic)

        y = tf.cond(
            tf.less_equal(minVal, calp),
            # Reshape the output of `tf.argmin()` to be a scalar.
            lambda: tf.argmin(tfslic, 0),
            # Explicitly convert the false-branch value to `tf.int64`.
            lambda: tf.constant(99999, dtype=tf.int64))
    '''
    :::::::::::::PROBLEM START HERE:::::::::::
    For each tf.while_loop, with index "i"
    if the minimum value of distance matrix dist[,i] <= caliper
    then output the first min value index occurs i.e. (y,i)

    Then set dist[y,]=[None, None, None, None]   

    Given the example matix "myx","myy";
    The while loop should output match pair indx [[0,None],[1,5],[2,4],[3,None]]
    '''
        varDist=tf.Variable(dist)

        temp = tf.cond(
            tf.less_equal(minVal, calp),
            # Set dist matrix row y to [None, None, None, None].
            lambda: tf.assign(varDist[y,],[9999.,9999.,9999.,9999.]),
            # Do nothing.
            lambda: tf.Variable(dist))


        return i+1, y, temp

    # Add a dummy initial value for the second loop variable.
    # Rename the first return value to `i_out` to avoid clashing with `i` above.
    i_out, r, dist= tf.while_loop(condition, b, [i, dist, tf.constant(0, dtype=tf.int64)])


sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
dmat = sess.run(dist, feed_dict={X:Xxx, Y: Yyy,i:0})
sess.close()

print(dmat)

1 个答案:

答案 0 :(得分:0)

让我重新提出问题,看看我是否正确理解。问题是,对于x中的每个元素myx,找到myy中与x最接近的元素,如果距离小于a myx则匹配它们卡尺。

匹配结果也可以表示为一个列表(长度与myy相同),如果最小,则此列表中的每个元素都是-1npstyle()中的索引距离大于卡尺。

如果您同意上述重构,那么有一种解决问题的方法,如函数tf_style()中所示,可以很容易地转换为import numpy as np import tensorflow as tf def npstyle_0(): myx=np.array([2.4,0.2,0.5,1.6]) myy=np.array([10.1,3.2,7.5,8.6,1,0.1,11,1.4]) Xxx = np.transpose(np.repeat(myx[:, np.newaxis], myy.size, axis=1)) Yyy = np.repeat(myy[:, np.newaxis], myx.size, axis=1) # define a caliper calp = 0.5 matches = {} dist = np.abs(Xxx - Yyy) print('Before loop distance matrix', dist) for m in range(0, myx.size): if (np.nanmin(dist[:, m]) <= calp) or not calp: matches[m] = np.nanargmin(dist[:, m]) dist[matches[m], :] = None print('Match Pairs:', matches) print('After loop distance matrix', dist) def npstyle(): myx=np.array([2.4,0.2,0.5,1.6]) myy=np.array([10.1,3.2,7.5,8.6,1,0.1,11,1.4]) # myx=np.array([3.0, 0.2, 4.0]) # myy=np.array([10.1, 3.2, 0.1, 7.5]) Xxx=np.transpose(np.repeat(myx[:, np.newaxis], myy.size, axis=1)) Yyy=np.repeat(myy[:, np.newaxis], myx.size , axis=1) # define a caliper calp=0.5 dist = np.abs(Xxx-Yyy) argmin = np.nanargmin(dist, 0) print('Before loop distance matrix', dist) match_dist = dist[argmin, np.arange(myx.size)] match_bool = match_dist <= calp matches = np.where(match_bool, np.nanargmin(dist, 0), -1) print matches print 'end np style.' def tf_style(): X = tf.placeholder(tf.float64, shape=(None,)) # setting (None,) allows to give an array of any length. Y = tf.placeholder(tf.float64, shape=(None,)) shape_x, shape_y = tf.shape(X)[0], tf.shape(Y)[0] Xxx = tf.reshape(tf.tile(X, [shape_y]), (shape_y, shape_x)) Yyy = tf.reshape(tf.tile(Y, [shape_x]), (shape_x, shape_y)) calp = 0.5 dist = tf.abs(Xxx - tf.transpose(Yyy)) argmin = tf.argmin(dist, axis=0, output_type=tf.int32) match_dist = tf.diag_part(tf.gather(dist, argmin)) match_bool = tf.less_equal(match_dist, calp) matches = tf.where(match_bool, argmin, tf.fill([shape_x], -1)) # ========= session of tensorflow =========== # gpu config # gpu_options = tf.GPUOptions(allow_growth=False) # config = tf.ConfigProto(log_device_placement=False, gpu_options=gpu_options) # sess = tf.Session(config) sess = tf.Session() feed_dict = {X: [2.4,0.2,0.5,1.6], Y: [10.1,3.2,7.5,8.6,1,0.1,11,1.4]} [a, b, d, e] = sess.run([Xxx, Yyy, dist, matches], feed_dict=feed_dict) print a print b print d print e if __name__ == '__main__': # npstyle_0() npstyle() tf_style()

{{1}}