Monday, February 26, 2018

How to write equivalent Tensorflow code with same logic?

Leave a Comment
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]) 

I want to write a program that match each element of “myx” to “myy” using a greedy algorithm. The match will be 1:1, with caliper distance <=0.5, without replacement. The algorithm is simple:

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) 

The problem is I don’t want to use anything in “np” or “panda”, but want to use Tensorflow framework only. I have written part of the program, but find out it’s hard than I originally thoughts. Can someone help me? By the way, this is the first time I try to use 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 Answers

Answers 1

Let me reformulate the question to see if I correctly understood. The problem is to, for each element x in myx, find the element in myy which is the closest to x, and match them if the distance is less than a caliper.

The results of matching can also be expressed as a list (of the same length as myx), each element in this list is the index in myy or -1 if the smallest distance is larger than the caliper.

If you agree with the reformulation above, then there is an equivalent way to solve the problem, as presented in the function npstyle(), which can be translated to tf_style() very easily.

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() 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment