How to interleave assign 4 subtensor to a larger tensor?

RJ. Lo

I want to get larger tensor by 4 subtensor with interleaved index.

Here is my question:

Four input with shape [batch x 2m x 2n x 1];

Output shape is [batch x 4m x 4n x 1];

index_y_0_1 = [0,1,4,5,8,9...], index_y_2_3 = [2,3,6,7,10,11...]

index_x_0_1 = [0,1,4,5,8,9...], index_x_2_3 = [2,3,6,7,10,11...]

Output[index_y_0_1 ,index_x_0_1 ] = Input0

Output[index_y_0_1 ,index_x_2_3 ] = Input1

Output[index_y_2_3 ,index_x_0_1 ] = Input2

Output[index_y_2_3 ,index_x_2_3 ] = Input3

Here is my question with python code:

import numpy as np

UpperLeft = np.ones((3,2,4,1))
UpperRight = np.ones((3,2,4,1))*2
BottonLeft = np.ones((3,2,4,1))*3
BottonRight = np.ones((3,2,4,1))*4

output = np.zeros((UpperLeft.shape[0], UpperLeft.shape[1]*2, UpperLeft.shape[2]*2, 1))

assert(output.shape[1]%4 == 0)
assert(output.shape[2]%4 == 0)

# UpperLeft Assignment
start_y = 0
start_x = 0
output[:,(start_y + 0)::4, (start_x + 0)::4, :] = UpperLeft[:,0::2, 0::2, :]
output[:,(start_y + 0)::4, (start_x + 1)::4, :] = UpperLeft[:,0::2, 1::2, :]
output[:,(start_y + 1)::4, (start_x + 0)::4, :] = UpperLeft[:,1::2, 0::2, :]
output[:,(start_y + 1)::4, (start_x + 1)::4, :] = UpperLeft[:,1::2, 1::2, :]

# UpperRight Assignment
start_y = 0
start_x = 2
output[:,(start_y + 0)::4, (start_x + 0)::4, :] = UpperRight[:,0::2, 0::2, :]
output[:,(start_y + 0)::4, (start_x + 1)::4, :] = UpperRight[:,0::2, 1::2, :]
output[:,(start_y + 1)::4, (start_x + 0)::4, :] = UpperRight[:,1::2, 0::2, :]
output[:,(start_y + 1)::4, (start_x + 1)::4, :] = UpperRight[:,1::2, 1::2, :]

# BottonLeft Assignment
start_y = 2
start_x = 0
output[:,(start_y + 0)::4, (start_x + 0)::4, :] = BottonLeft[:,0::2, 0::2, :]
output[:,(start_y + 0)::4, (start_x + 1)::4, :] = BottonLeft[:,0::2, 1::2, :]
output[:,(start_y + 1)::4, (start_x + 0)::4, :] = BottonLeft[:,1::2, 0::2, :]
output[:,(start_y + 1)::4, (start_x + 1)::4, :] = BottonLeft[:,1::2, 1::2, :]

# BottonRight Assignment
start_y = 2
start_x = 2
output[:,(start_y + 0)::4, (start_x + 0)::4, :] = BottonRight[:,0::2, 0::2, :]
output[:,(start_y + 0)::4, (start_x + 1)::4, :] = BottonRight[:,0::2, 1::2, :]
output[:,(start_y + 1)::4, (start_x + 0)::4, :] = BottonRight[:,1::2, 0::2, :]
output[:,(start_y + 1)::4, (start_x + 1)::4, :] = BottonRight[:,1::2, 1::2, :]

show_out = output[0,:,:,0]

How can I do this on tensorflow? Thanks!

jdehesa

You can have a function that interleaves tensors across one axis like this.

import tensorflow as tf

# Interlaves tensors across one axis
def interleave(tensors, size=1, axis=-1):
    # Reshape tensors
    tensors_res = []
    for tensor in tensors:
        s = tf.shape(tensor)
        new_s = tf.concat([s[:axis], [s[axis] // size, size], s[axis:][1:]], axis=0)
        tensors_res.append(tf.reshape(tensor, new_s))
    # Concatenate across new dimension
    if isinstance(axis, (tf.Tensor, tf.Variable)):
        selected_axis = tf.cond(tf.less(axis, 0), lambda: axis - 1, lambda: axis)
        concat_axis = tf.cond(tf.less(axis, 0), lambda: axis, lambda: axis + 1)
    else:
        selected_axis = (axis - 1) if axis < 0 else axis
        concat_axis = axis if axis < 0 else (axis + 1)
    tensors_concat = tf.concat(tensors_res, axis=concat_axis)
    # Reshape concatenation
    concat_s = tf.shape(tensors_concat)
    res_s = tf.concat([concat_s[:selected_axis], [-1], concat_s[concat_axis:][1:]], axis=0)
    return tf.reshape(tensors_concat, res_s)

Then you can use this to interleave first across one dimension and the across the other.

import tensorflow as tf

with tf.Graph().as_default(), tf.Session() as sess:
    # Input data
    UpperLeft = tf.ones((3, 2, 4, 1))
    UpperRight = tf.ones((3, 2, 4, 1)) * 2
    BottomLeft = tf.ones((3, 2, 4, 1)) * 3
    BottomRight = tf.ones((3, 2, 4, 1)) * 4
    # Interleave across axis 2
    Upper = interleave([UpperLeft, UpperRight], size=2, axis=2)
    Bottom = interleave([BottomLeft, BottomRight], size=2, axis=2)
    # Interleave across axis 1
    Result = interleave([Upper, Bottom], size=2, axis=1)
    # Show result
    print(sess.run(Result)[0, :, :, 0])
    # [[1. 1. 2. 2. 1. 1. 2. 2.]
    #  [1. 1. 2. 2. 1. 1. 2. 2.]
    #  [3. 3. 4. 4. 3. 3. 4. 4.]
    #  [3. 3. 4. 4. 3. 3. 4. 4.]]

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Subtensor of a Tensorflow tensor (C++)

How to get subtensor by irregular index?

How to convert a matrix of torch.tensor to a larger tensor?

How to assign values to a tensor by index?

How to assign NaN to tensor element?

how to assign the element of tensor from other tensor in tensorflow

How to assign even/odd indices for tensor in tensorflow

How to efficiently assign to a slice of a tensor in TensorFlow

how to assign a value to the 'Tensor' object in Keras?

How to assign a tensor in Tensorflow like Pytorch?

How to interleave arrays in julia

How to interleave streams (with backpressure)

How to conditionally assign values to tensor [masking for loss function]?

How does one interleave 4D tensors along the width & height dimensions in tensorflow?

Assign a name to a tensor?

How do I assign a 2D subset of my tensor with another 2D tensor in Keras?

How to assign a 1d tensor to a 2d tensor using a mask matrix in tensorflow?

How to interleave a String with a character sequence

How to interleave vector of strings with a string

How to de-interleave a vector?

How to interleave numpy.ndarrays?

How to interleave 3 lists in OCaml

Interleave 4 lists of same length python

Interleave 4 byte ints to 8 byte int

TensorFlow assign Tensor to Tensor with array indexing

Assign part of a tensor to the corresponding places in another tensor

Custom loss function with a larger predefined tensor

Python: How to convert array of 4 digits to a larger number, bitwise?

How to dlopen a side module larger than 4KB?