использование tf.where () для выбора 3d-тензора с помощью 2D-условий и замены элементов в 2D-индексах ключами и значениями - PullRequest
0 голосов
/ 05 декабря 2018

В заголовке 2 вопроса.Меня смущают оба вопроса, потому что тензор потока - это такой статический язык программирования (я действительно хочу вернуться либо к pytorch, либо к цепочке).

Я привожу 2 примера.пожалуйста, ответьте мне в кодах тензорного потока или предоставив соответствующие ссылки на функции.

1) tf.where ()

data0 = tf.zeros([2, 3, 4], dtype = tf.float32)
data1 = tf.ones([2, 3, 4], dtype = tf.float32)
cond = tf.constant([[0, 1, 1], [1, 0, 0]])
# cond.shape == (2, 3)
# tf.where() works for 1d condition with 2d data, 
# but not for 2d indices with 3d tensor
# currently, what I am doing is:
#    cond = tf.stack([cond] * 4, 2)
data = tf.where(cond > 0, data1, data0)
# data should be [[0., 1., 1.], [1., 0., 0.]]

(я не знаю, как транслировать cond в 3d тензор)

2) изменить элемент в 2d тензоре

# all dtype == tf.int64
t2d = tf.Variable([[0, 1, 2], [3, 4, 5]])
k, v = tf.constant([[0, 2], [1, 0]]), tf.constant([-2, -3])
# TODO: change values at positions k to v
# I cannot do [t2d.copy()[i] = j for i, j in k, v]
t3d == [[[0, 1, -2], [3, 4, 5]],
        [[0, 1, 2], [-3, 4, 5]]]

Заранее большое спасибо.XD

1 Ответ

0 голосов
/ 05 декабря 2018

Это два совершенно разных вопроса, и они, вероятно, должны были быть опубликованы как таковые, но в любом случае.

1)

Да, вам необходимо вручную передать все входные данные на [tf.where] (https://www.tensorflow.org/api_docs/python/tf/where], если они разные. Для чего стоит, существует (старый) открытый вопрос об этом , но пока неявное вещание не было реализовано. Вы можетеиспользуйте tf.stack, как вы предлагаете, хотя tf.tile, вероятно, будет более очевидным (и может сэкономить память, хотя я не уверен, как это реализовано на самом деле):

cond = tf.tile(tf.expand_dims(cond, -1), (1, 1, 4))

Или просто с помощью tf.broadcast_to:

cond = tf.broadcast_to(tf.expand_dims(cond, -1), tf.shape(data1))

2)

Это один из способов сделать это:

import tensorflow as tf

t2d = tf.constant([[0, 1, 2], [3, 4, 5]])
k, v = tf.constant([[0, 2], [1, 0]]), tf.constant([-2, -3])
# Tile t2d
n = tf.shape(k)[0]
t2d_tile = tf.tile(tf.expand_dims(t2d, 0), (n, 1, 1))
# Add aditional coordinate to index
idx = tf.concat([tf.expand_dims(tf.range(n), 1), k], axis=1)
# Make updates tensor
s = tf.shape(t2d_tile)
t2d_upd = tf.scatter_nd(idx, v, s)
# Make updates mask
upd_mask = tf.scatter_nd(idx, tf.ones_like(v, dtype=tf.bool), s)
# Make final tensor
t3d = tf.where(upd_mask, t2d_upd, t2d_tile)
# Test
with tf.Session() as sess:
    print(sess.run(t3d))

Выход:

[[[ 0  1 -2]
  [ 3  4  5]]

 [[ 0  1  2]
  [-3  4  5]]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...