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

2024-09-28 20:53:45 发布

您现在位置:Python中文网/ 问答频道 /正文

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,无需更换。 算法很简单:

^{pr2}$

问题是我不想在“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)

Tags: thetolambdanoneloopsizevaluedist
1条回答
网友
1楼 · 发布于 2024-09-28 20:53:45

让我重新表述一下这个问题,看看我是否理解正确。问题是,对于myx中的每个元素x,找到myy中最接近x的元素,如果距离小于卡尺,则将其匹配。在

匹配结果也可以表示为一个列表(长度与myx)相同,该列表中的每个元素都是myy或{}中的索引,如果最小距离大于卡尺。在

如果您同意上面的重新表述,那么有一种解决问题的等效方法,如函数npstyle()所示,可以很容易地转换为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()

相关问题 更多 >