用张量流中的条件减少总和 [英] Reduce sum with condition in tensorflow

查看:22
本文介绍了用张量流中的条件减少总和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到了一个带有随机行的 2D 张量.在应用 tf.math.greater()tf.cast(tf.int32) 之后,我剩下一个带有 0 和 1 的张量.我现在想在该矩阵上应用 reduce sum 但有一个条件:如果至少有一个 1 和一个 0 跟随我想删除所有后面的 1 以及,这意味着 1 0 1 应该导致1 而不是 2.

I am given a 2D Tensor with stochastic rows. After applying tf.math.greater() and tf.cast(tf.int32) I am left with a Tensor with 0's and 1's. I now want to apply reduce sum onto that matrix but with a condition: If there was at least one 1 summed and a 0 follows I want to remove all following 1 aswell, meaning 1 0 1 should result in 1 instead of 2.

我试图用 tf.scan() 解决问题,但我还没有想出一个能够处理起始 0 的函数,因为该行可能看起来像: 0 0 0 1 0 1一个想法是将矩阵的下半部分设置为 1(bc 我知道从对角线开始的所有内容都将始终为 0),然后运行像 tf.scan() 这样的函数来过滤掉斑点(请参阅下面的代码和错误消息).

I have tried to solve the Problem with tf.scan(), but I was not able to come up with a function yet that is able to handle starting 0's, because the row might look like: 0 0 0 1 0 1 One idea was to set the lower part of the matrix to one (bc I know everything left from the diagonal will always be 0) and then have a function like tf.scan() run to filter out the spots (see code and error message below).

设 z 为 tf.cast 后的矩阵.

helper = tf.matrix_band_part(tf.ones_like(z), -1, 0)
z = tf.math.logical_or(tf.cast(z, tf.bool), tf.cast(helper,tf.bool))
z = tf.cast(z, tf.int32)
z = tf.scan(lambda a, x: x if a == 1 else 0 ,z)

导致:

ValueError: Incompatible shape for value ([]), expected ([5])

推荐答案

IIUC,这是一种无需扫描或循环即可完成所需操作的方法.它可能有点复杂,实际上是对列进行两次迭代(一个 cumsum 和一个 cumprod),但是作为矢量化操作,我认为它可能更快.代码是 TF 2.x 但在 TF 1.x 中运行相同(显然除了最后一行).

IIUC, this is one way to do what you want without scanning or looping. It may be a bit convoluted, and is actually iterating the columns twice (one cumsum and one cumprod), but being vectorized operations I think it is probably faster. Code is TF 2.x but runs the same in TF 1.x (except for the last line obviously).

import tensorflow as tf

# Example data
a = tf.constant([[0, 0, 0, 0],
                 [1, 0, 0, 0],
                 [0, 1, 1, 0],
                 [0, 1, 0, 1],
                 [1, 1, 1, 0],
                 [1, 1, 0, 1],
                 [0, 1, 1, 1],
                 [1, 1, 1, 1]])
# Cumsum columns
c = tf.math.cumsum(a, axis=1)
# Column-wise differences
diffs = tf.concat([tf.ones([tf.shape(c)[0], 1], c.dtype), c[:, 1:] - c[:, :-1]], axis=1)
# Find point where we should not sum anymore (cumsum is not zero and difference is zero)
cutoff = tf.equal(a, 0) & tf.not_equal(c, 0)
# Make mask
mask = tf.math.cumprod(tf.dtypes.cast(~cutoff, tf.uint8), axis=1)
# Compute result
result = tf.reduce_max(c * tf.dtypes.cast(mask, c.dtype), axis=1)
print(result.numpy())
# [0 1 2 1 3 2 3 4]

这篇关于用张量流中的条件减少总和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆