Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将softmax应用于跨维度矩阵中的非零元素_Python_Tensorflow - Fatal编程技术网

Python 将softmax应用于跨维度矩阵中的非零元素

Python 将softmax应用于跨维度矩阵中的非零元素,python,tensorflow,Python,Tensorflow,也许这是微不足道的,但也许不是。我花了太多的时间试图找出如何使这项工作。代码如下: # batch x time x events batch = 2 time = 3 events = 4 tensor = np.random.rand(batch, time, events) tensor[0][0][2] = 0 tensor[0][0][3] = 0 tensor[0][1][3] = 0 tensor[0][2][1] = 0 tensor[0][2][2] = 0 tensor

也许这是微不足道的,但也许不是。我花了太多的时间试图找出如何使这项工作。代码如下:

# batch x time x events
batch = 2
time = 3
events = 4
tensor = np.random.rand(batch, time, events)

tensor[0][0][2] = 0
tensor[0][0][3] = 0

tensor[0][1][3] = 0

tensor[0][2][1] = 0
tensor[0][2][2] = 0
tensor[0][2][3] = 0

tensor[1][0][3] = 0

non_zero = ~tf.equal(tensor, 0.)

s = tf.Session()
g = tf.global_variables_initializer()
s.run(g)

s.run(non_zero)
我正在尝试将
tf.nn.softmax
应用于每个
time
维度的非零值。但是,当我使用
tf.boolean_mask
时,它实际上会将所有非零值聚集在一起。那不是我想要的。我想保留尺寸

以下是张量的屏幕截图:

因此,
tf.nn.softmax
应该只应用于这些组,并且应该将它们“放回”原来的位置。有人知道怎么做吗

编辑:

在你们的帮助下,我几乎找到了我需要的解决方案。但我仍然错过了一步。将每个时间维度上的softmax分配给非零值:

def apply_sparse_softmax(time_vector):
    non_zeros = ~tf.equal(time_vector, 0.)

    sparse_softmax = tf.nn.softmax(tf.boolean_mask(time_vector, non_zeros))
    new_time_vector = sparse_softmax * tf.cast(non_zeros, tf.float64) # won't work because dimensions are different
    return time_vector
还请注意,此解决方案应处理整个时间维度都为零的情况。然后它应该保持不变。

可能的重复:

借助于
tf.map\u fn
tf.where

session.run(tf.map_fn(
     lambda x : tf.where(x > 0, tf.nn.softmax(x,axis=2,name="pidgeon"), x), tensor))

测试
np.random.seed(1992)


这是我使用
numpy
tensorflow
的方法:

> tensor 
array([[[0.2891092 , 0.76259227, 0.        , 0.        ],
        [0.93660715, 0.18361367, 0.07234135, 0.        ],
        [0.23128076, 0.        , 0.        , 0.        ]],

       [[0.45708066, 0.76883403, 0.7584804 , 0.        ],
        [0.51019332, 0.73361557, 0.87442305, 0.66796383],
        [0.9297317 , 0.22428208, 0.69184613, 0.06162719]]])
查找非零元素的掩码 检索非零值 对非零值应用softmax 使用应用于非零元素的softmax更新张量
好的,我从tenticon的重复链接和他的答案中找到了一个解决方案。尽管当整个时间向量为零时,这会失败。所以我仍然需要解决这个问题。很高兴听到你的建议。但解决办法如下:

def sparse_softmax(T):
    # Creating partition based on condition:
    condition_mask = tf.cast(tf.greater(T, 0.), tf.int32)
    partitioned_T = tf.dynamic_partition(T, condition_mask, 2)
    # Applying the operation to the target partition:
    partitioned_T[1] = tf.nn.softmax(partitioned_T[1])

    # Stitching back together, flattening T and its indices to make things easier::
    condition_indices = tf.dynamic_partition(tf.range(tf.size(T)), tf.reshape(condition_mask, [-1]), 2)
    res_T = tf.dynamic_stitch(condition_indices, partitioned_T)
    res_T = tf.reshape(res_T, tf.shape(T))

    return res_T

my_softmax = tf.map_fn(lambda batch: 
                       tf.map_fn(lambda time_vector: sparse_softmax(time_vector), batch, dtype=tf.float64)
                       , tensor, dtype=tf.float64)
我提出的另一个解决方案在整个向量为零时仍然存在问题:

def softmax(tensor):
#     tensor_ = tf.placeholder(dtype=tf.float64, shape=(4,))

    non_zeros = ~tf.equal(tensor, 0.)
    sparse_softmax = tf.nn.softmax(tf.boolean_mask(tensor, non_zeros))
    sparse_softmax_shape = tf.shape(sparse_softmax)[0]
    orig_shape = tf.shape(tensor)[0]
    shape_ = orig_shape-sparse_softmax_shape
    zeros = tf.zeros(shape=shape_, dtype=tf.float64)
    new_vec = tf.concat([sparse_softmax, zeros], axis=0)

    return new_vec
但这不起作用。。。。i、 当向量全为零时,这应该返回零向量,相反,我得到了某种空张量的整形误差

def softmax_(tensor):

    zeros = tf.cast(tf.equal(tensor, 0.), tf.float64)
    cond_ = tf.reduce_sum(zeros)

    def true_fn():
        non_zeros = ~tf.equal(tensor, 0.)
        sparse_softmax = tf.nn.softmax(tf.boolean_mask(tensor, non_zeros))
        sparse_softmax_shape = tf.shape(sparse_softmax)[0]
        orig_shape = tf.shape(tensor)[0]
        shape_ = orig_shape-sparse_softmax_shape
        zeros = tf.zeros(shape=shape_, dtype=tf.float64)
        new_vec = tf.concat([sparse_softmax, zeros], axis=0)

        return new_vec

    def false_fn():

        return tf.zeros(shape=tf.shape(tensor), dtype=tf.float64)

    return tf.cond(tf.equal(cond_, tf.cast(tf.shape(tensor)[0], tf.float64)), false_fn, true_fn)
仍然无法使它适用于全零向量。很高兴听到您的解决方案


编辑:实际上,最后一段代码正是我想要的工作方式。

这不是我想要做的。这将在所有批次中应用softmax。我需要跨时间维度的非零值执行softmax,几乎是@tenticon所做的,但是跨另一个维度(他跨事件维度所做的)好的。这很简单。我稍后会更新这个。我现在不在电脑上。另一件事,在你的最后一点“更新
tensor
…”中,你使用的是numpy索引,这显然不能在tensorflow中工作几乎是我需要的:)我需要这样的smth:
np.exp(0.86018176)/(np.exp(0.86018176)+np.exp(0.4214685))
而更改
轴并不能解决问题:)也许我可以将张量转换为沿最后一个维度执行softmax,如您的示例:)事实上,您的解决方案似乎不等于1。也可以跨越最后一个维度。例如,
0.338
+
0.439
!=1.0. 因此转置解决方案不起作用,感谢链接,但他们在那里做的是将softmax应用于所有批次,因此我想类似于
map\u fn
的方法与他们的解决方案结合起来可能对我有用
# apply softmax
soft_max = tf.nn.softmax(non_zero_val)

# convert to numpy
with tf.Session() as sess:
    soft_max_np = soft_max.eval()

> soft_max_np
array([0.04394964, 0.07056453, 0.08397696, 0.03954934, 0.0353846 ,
       0.04148019, 0.05198816, 0.07100635, 0.07027497, 0.05482403,
       0.06854914, 0.07891397, 0.06419332, 0.08340156, 0.0411909 ,
       0.06574485, 0.0350075 ])
tensor[non_zero_mask] = soft_max_np

tensor
array([[[0.04394964, 0.07056453, 0.        , 0.        ],
        [0.08397696, 0.03954934, 0.0353846 , 0.        ],
        [0.04148019, 0.        , 0.        , 0.        ]],

       [[0.05198816, 0.07100635, 0.07027497, 0.        ],
        [0.05482403, 0.06854914, 0.07891397, 0.06419332],
        [0.08340156, 0.0411909 , 0.06574485, 0.0350075 ]]])
def sparse_softmax(T):
    # Creating partition based on condition:
    condition_mask = tf.cast(tf.greater(T, 0.), tf.int32)
    partitioned_T = tf.dynamic_partition(T, condition_mask, 2)
    # Applying the operation to the target partition:
    partitioned_T[1] = tf.nn.softmax(partitioned_T[1])

    # Stitching back together, flattening T and its indices to make things easier::
    condition_indices = tf.dynamic_partition(tf.range(tf.size(T)), tf.reshape(condition_mask, [-1]), 2)
    res_T = tf.dynamic_stitch(condition_indices, partitioned_T)
    res_T = tf.reshape(res_T, tf.shape(T))

    return res_T

my_softmax = tf.map_fn(lambda batch: 
                       tf.map_fn(lambda time_vector: sparse_softmax(time_vector), batch, dtype=tf.float64)
                       , tensor, dtype=tf.float64)
def softmax(tensor):
#     tensor_ = tf.placeholder(dtype=tf.float64, shape=(4,))

    non_zeros = ~tf.equal(tensor, 0.)
    sparse_softmax = tf.nn.softmax(tf.boolean_mask(tensor, non_zeros))
    sparse_softmax_shape = tf.shape(sparse_softmax)[0]
    orig_shape = tf.shape(tensor)[0]
    shape_ = orig_shape-sparse_softmax_shape
    zeros = tf.zeros(shape=shape_, dtype=tf.float64)
    new_vec = tf.concat([sparse_softmax, zeros], axis=0)

    return new_vec
def softmax_(tensor):

    zeros = tf.cast(tf.equal(tensor, 0.), tf.float64)
    cond_ = tf.reduce_sum(zeros)

    def true_fn():
        non_zeros = ~tf.equal(tensor, 0.)
        sparse_softmax = tf.nn.softmax(tf.boolean_mask(tensor, non_zeros))
        sparse_softmax_shape = tf.shape(sparse_softmax)[0]
        orig_shape = tf.shape(tensor)[0]
        shape_ = orig_shape-sparse_softmax_shape
        zeros = tf.zeros(shape=shape_, dtype=tf.float64)
        new_vec = tf.concat([sparse_softmax, zeros], axis=0)

        return new_vec

    def false_fn():

        return tf.zeros(shape=tf.shape(tensor), dtype=tf.float64)

    return tf.cond(tf.equal(cond_, tf.cast(tf.shape(tensor)[0], tf.float64)), false_fn, true_fn)