根据条件更改张量流张量的值

时间:2019-04-30 20:01:47

标签: python numpy tensorflow

我正在尝试重新创建我在tensorflow中编写的numpy代码片段,但我一直在努力寻找正确/最佳的tensorflow操作。

考虑以下numpy解决方案:

import numpy as np

# Initialize a random numpy array:
my_dummy = np.random.random((6, 2, 2, 10))
print(my_dummy)

> [[[[0.6715164  0.58915908 0.36607568 0.73404715 0.69455375 0.52177771
      0.91810873 0.85010461 0.37485212 0.35634401]
     [0.55885052 0.13041019 0.89774818 0.3363019  0.66634638 0.32054576
      0.46174629 0.59975141 0.02283781 0.02997967]]

      ....

                                                                   ]]]]

# Create random floats, based on channel 0 of my dummy:
random_floats = np.random.random(my_dummy.shape[0])
print(random_floats)

> [0.89351759 0.76734892 0.36810602 0.08513434 0.65511941 0.61297472]

# Create a mask with ones and a shape based on my_dummy:
my_mask = np.ones((my_dummy.shape[0], 1, 1, my_dummy.shape[-1]))
print(my_mask)

> [[[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]


  [[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]


  [[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]


  [[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]


  [[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]


  [[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]]

# Initialize a rate parameter:
my_rate = 0.5

# Based on my_rate, change the array accordingly:
my_mask[my_rate > random_floats] = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
print(my_mask)

[[[[1. 0. 1. 0. 1. 0. 1. 0. 1. 0.]]]


 [[[1. 0. 1. 0. 1. 0. 1. 0. 1. 0.]]]


 [[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]


 [[[1. 0. 1. 0. 1. 0. 1. 0. 1. 0.]]]


 [[[1. 0. 1. 0. 1. 0. 1. 0. 1. 0.]]]


 [[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]]]

# Multiply my_dummy with the new mask:
np.multiply(my_dummy, my_mask)

array([[[[0.6715164 , 0.58915908, 0.36607568, 0.73404715, 0.69455375,
          0.52177771, 0.91810873, 0.85010461, 0.37485212, 0.35634401],
         [0.55885052, 0.13041019, 0.89774818, 0.3363019 , 0.66634638,
          0.32054576, 0.46174629, 0.59975141, 0.02283781, 0.02997967]],

        [[0.22358676, 0.74959561, 0.11109368, 0.56021714, 0.2767754 ,
          0.55156506, 0.15488703, 0.25738564, 0.18588607, 0.57593545],
         [0.15804289, 0.87858207, 0.12890992, 0.78828551, 0.52467083,
          0.45117698, 0.2605117 , 0.46659721, 0.855278  , 0.29630581]]],


       [[[0.381445  , 0.        , 0.48308211, 0.        , 0.5136352 ,
          0.        , 0.84428703, 0.        , 0.20532641, 0.        ],
         [0.696645  , 0.        , 0.84184568, 0.        , 0.01369105,
          0.        , 0.27683334, 0.        , 0.59356542, 0.        ]],

        [[0.5281193 , 0.        , 0.82336821, 0.        , 0.63435181,
          0.        , 0.12824084, 0.        , 0.35045286, 0.        ],
         [0.02205884, 0.        , 0.22927706, 0.        , 0.45538199,
          0.        , 0.81220918, 0.        , 0.46427429, 0.        ]]],


         .....

                                                                   ]]]])

在tensorflow中,我这样做了(警告,很多导入,我尝试了很多事情,不再确定是否全部都是必要的,只是想确保可以立即重现):


from keras.engine.base_layer import InputSpec
from tensorflow.python.util import deprecation
from tensorflow.python.framework import ops
from tensorflow.python.eager import context
from tensorflow.python.framework import tensor_shape
from tensorflow.python.framework import tensor_util
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import random_ops
from tensorflow.python.ops import math_ops
from tensorflow.python.platform import tf_logging as logging
import numbers

import numpy as np
import tensorflow as tf

from tensorflow.python.framework import ops
from tensorflow.python.ops import random_ops
from tensorflow.python.ops import math_ops
from keras import backend as K

# Create my_dummy and convert to tensor object:
my_dummy = np.random.random((6, 2, 2, 4))
my_dummy = ops.convert_to_tensor(my_dummy)
my_dummy.get_shape()

> TensorShape([Dimension(6), Dimension(2), Dimension(2), Dimension(4)])

# Create random floats, like before and inspect tensor with Keras (instead of running a tf session):
random_floats = random_ops.random_uniform([my_dummy.get_shape().as_list()[0]], dtype=my_dummy.dtype)
K.eval(random_floats)

> array([0.74018297, 0.76996447, 0.52047441, 0.28215968, 0.91457724,
       0.64637448])

# Like before, create a mask with ones, like before shape (almost completely) based on my_dummy:
my_mask = tf.ones([my_dummy.get_shape()[0], 1, 1, my_dummy.get_shape()[-1]], dtype=x.dtype)
K.eval(my_mask)

> array([[[[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]],


        [[[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]],


        [[[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]],


        [[[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]],


        [[[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]],


        [[[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]]])

不幸的是,这是我所坚持的。我没有找到一种基于比率值更改my_mask Tensor对象中条目的方法。我尝试过的一件事是tf.where:

tf.where(rate > random_floats, my_mask, tf.constant([1, 0, 1, 0, 1, 0, 1, 0, 1, 0], dtype = my_dummy.dtype))

但收到错误:

ValueError: Shapes must be equal rank, but are 4 and 1 for 'Select_1' (op: 'Select') with input shapes: [6], [6,1,1,10], [10].

感谢您的任何建议/帮助:)

1 个答案:

答案 0 :(得分:1)

张量流基本上相同。为方便起见,显示较小的形状数据:

import tensorflow as tf

value_to_assign = tf.constant([[1., 0., 1., 0., 1.]])
rate = tf.constant(.5)
dummy = tf.random_normal(shape=(4, 1, 1, 5))
# random_floats = tf.random_normal(shape=(tf.shape(dummy)[0], ))
random_floats = tf.constant([0.4, 0.6, .7, .2]) # <--using const values to illustrate

init_val = tf.ones((tf.shape(dummy)[0], 1, 1, tf.shape(dummy)[-1]))
mask = tf.Variable(init_val,
                   trainable=False)

indices = tf.where(tf.equal(True, rate > random_floats))
tiled = tf.tile(value_to_assign,
                multiples=[tf.shape(indices)[0], 1])[:, tf.newaxis, tf.newaxis, :]
mask = tf.scatter_nd_update(mask,
                            indices=indices,
                            updates=tiled)
res = mask * dummy

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print('MASK')
    print(sess.run(mask))
    print('DUMMY')
    print(sess.run(dummy))
    print('RESULT')
    print(sess.run(res))
MASK
[[[[1. 0. 1. 0. 1.]]]


 [[[1. 1. 1. 1. 1.]]]


 [[[1. 1. 1. 1. 1.]]]


 [[[1. 0. 1. 0. 1.]]]]
DUMMY
[[[[-1.2031308  -1.6657363  -1.5552464   0.8540495   0.37618718]]]


 [[[-0.4468031   0.46417323 -0.3764856   1.1906835  -1.4670093 ]]]


 [[[ 1.2066191  -1.4767337  -0.9487017  -0.49180242 -0.33098853]]]


 [[[-0.1621628   0.61168176  0.10006899  0.7585997  -0.23903783]]]]
RESULT
[[[[ 1.7753109   0.         -0.5451439  -0.         -0.53782284]]]


 [[[ 0.08024058 -1.8178499   1.183356    1.0895957  -0.9272436 ]]]


 [[[-0.5266396  -2.0316153  -1.0043124  -1.1657876   0.6106227 ]]]


 [[[-0.46503183  0.          0.01983969 -0.          0.58563703]]]]