How to shape input for Ragged tensor with LSTM - tensorflow

I'm getting the following error when I try to pass multiple ragged tensors to my model:
ValueError: Layer "sequential_3" expects 1 input(s), but it received 2 input tensors
I suspect it has something to do with the "shape" argument in the Input layer of the model.
Yes, I've reviewed the ragged tensor documentation.
Yes, I've spent many hours scouring the Google-net.
Yes, I've browsed stackoverflow.com related articles.
Yes, I'm most likely noobing it up right now and there is a simple solution.
Below is a reproducible example
(tensorflow 2.7; keras 2.7; python 3.7)
dependencies
import tensorflow as tf
import pandas as pd
import keras
import keras.layers
Dummy Dataset
d0 = pd.DataFrame(data={
"id":[
1,
2, 2,
3, 3, 3,
4, 4, 4, 4,
5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6
],
"date":[
pd.to_datetime("2008-03-31"),
pd.to_datetime("2008-03-31"), pd.to_datetime("2008-06-30"),
pd.to_datetime("2008-03-31"), pd.to_datetime("2008-06-30"), pd.to_datetime("2008-09-30"),
pd.to_datetime("2008-03-31"), pd.to_datetime("2008-06-30"), pd.to_datetime("2008-09-30"), pd.to_datetime("2008-12-31"),
pd.to_datetime("2008-03-31"), pd.to_datetime("2008-06-30"), pd.to_datetime("2008-09-30"), pd.to_datetime("2008-12-31"), pd.to_datetime("2009-03-31"),
pd.to_datetime("2008-03-31"), pd.to_datetime("2008-06-30"), pd.to_datetime("2008-09-30"), pd.to_datetime("2008-12-31"), pd.to_datetime("2009-03-31"), pd.to_datetime("2009-06-30")
],
"date2":[
1,
1, 2,
1, 2, 3,
1, 2, 3, 4,
1, 2, 3, 4, 5,
1, 2, 3, 4, 5, 6
],
"input":[
10,
11, 12,
13, 14, 15,
16, 17, 18, 19,
20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30
],
"target":[
60,
61, 62,
63, 64, 65,
66, 67, 68, 69,
70, 71, 72, 73, 74,
75, 76, 77, 78, 79, 80
],
})
inputs
inputs = []
inputs.append(tf.ragged.constant(d0.groupby("id")["input"].apply(list)))
inputs.append(tf.ragged.constant(d0.groupby("id")["date2"].apply(list)))
target
target = tf.ragged.constant(d0.groupby("id")["target"].apply(list))
model
mod1 = keras.Sequential([
keras.layers.Input(shape=(None, 4), dtype=tf.float32, batch_size=1, ragged=True),
keras.layers.LSTM(units=32, dtype=tf.float32, return_sequences=True, use_bias=False),
keras.layers.Dense(units=32),
keras.layers.Dense(units=1)
])
compile
mod1.compile(
optimizer="adam",
loss="mse",
metrics=["accuracy"]
)
fit
history = mod1.fit(
x=inputs,
y=target,
epochs=1
)
The error occurs during the fit step.

Related

transpose sub-blocks of numpy array

I have a Numpy array which consists of several square sub-blocks. For example:
A = [A_1 | A_2 | ... A_n],
each of them has the same size. I would like to transpose it in the following way:
B = [A_1^T | A_2^T| ... A_n^T].
Is there a way to do it instead of slicing the original array and then transposing each sub-block?
Assuming that A_i has shape (M, M), I can see two scenarios:
Your entire array A is already in shape (N, M, M). In this case, you can transpose the submatrices A_i using np.ndarray.swapaxes or np.ndarray.transpose. Example:
A = np.arange(36).reshape(4, 3, 3)
# 4 submatrices A_0 ... A_3 each with shape (3, 3)
# array([[[ 0, 1, 2],
# [ 3, 4, 5],
# [ 6, 7, 8]],
#
# [[ 9, 10, 11],
# [12, 13, 14],
# [15, 16, 17]],
#
# [[18, 19, 20],
# [21, 22, 23],
# [24, 25, 26]],
#
# [[27, 28, 29],
# [30, 31, 32],
# [33, 34, 35]]])
B = A.swapaxes(1, 2)
# The submatrices are transposed:
# array([[[ 0, 3, 6],
# [ 1, 4, 7],
# [ 2, 5, 8]],
#
# [[ 9, 12, 15],
# [10, 13, 16],
# [11, 14, 17]],
#
# [[18, 21, 24],
# [19, 22, 25],
# [20, 23, 26]],
#
# [[27, 30, 33],
# [28, 31, 34],
# [29, 32, 35]]])
Your entire array A has only two dimensions, i.e. shape (M, N * M). In this case, you can bring your array to three dimensions first, then swap the axes, and then shape your array back to 2 dimensions. Example:
A = np.arange(36).reshape(3, 12)
# array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
# [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
# [24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]])
# A_i: ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^
B = A.reshape(3, 4, 3).swapaxes(0, 2).reshape(3, 12)
# array([[ 0, 12, 24, 3, 15, 27, 6, 18, 30, 9, 21, 33],
# [ 1, 13, 25, 4, 16, 28, 7, 19, 31, 10, 22, 34],
# [ 2, 14, 26, 5, 17, 29, 8, 20, 32, 11, 23, 35]])
# A_i^T: ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^

reshape numpy array, do a transformation and do the inverse reshape

Here is my problem :
I’m trying to do a operation on a numpy array after reshaping it.
But after this operation, I want to reshape again my array to get my original shape with the same indexing.
So I want to find the appropriate "inverse reshape" so that inverse_reshape(reshape(a))==a
length = 10
a = np.arange(length^2).reshape((length,length))
#a.spape = (10,10)
b = (a.reshape((length//2, 2, -1, 2))
.swapaxes(1, 2)
.reshape(-1, 2, 2))
#b.shape = (25,2,2)
b = my_function(b)
#b.shape = (25,2,2) still the same shape
# b --> a ?
I know that the numpy reshape funtion doesn’t copy the array, but the swapaxes one does.
How can I get the appropriate reshaping ?
Simply reverse the order of the the a=>b conversion.
The original made:
In [53]: a.reshape((length//2, 2, -1, 2)).shape
Out[53]: (5, 2, 5, 2)
In [54]: a.reshape((length//2, 2, -1, 2)).swapaxes(1,2).shape
Out[54]: (5, 5, 2, 2)
In [55]: b.shape
Out[55]: (25, 2, 2)
So we need to get b back to the 4d shape, swap the axes back, and reshape to original a shape:
In [56]: b.reshape(5,5,2,2).swapaxes(1,2).reshape(10,10)
Out[56]:
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
[80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])

Why doesn't this numpy slicing operation, which I don't have a good name for, not work?

I do not understand why my slicing operation does not work. My intention is to apply the slice [::2] to each sub array of a so that the size of x is (3, 5), but things don't go as expected.
a = np.arange(0,30)
a.shape = (3, -1)
x = a[:][::2]
a : array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]])
The actual output is
x: array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]])
The desired output is
x : array([0, 2, 4, 6, 8],
[10, 12, 14, 16, 18],
[20, 22, 24, 26, 28])
Typo:
x = a[:,::2]
Otherwise you select the full array on the first dimension, and then do the same again, one the first dimension, not the second.

Convert 2d tensor to 3d in tensorflow

I need to convert 2d tensor to a 3d tensor. how can I transfer this in tensor flow.
[[30, 29, 19, 17, 12, 11],
[30, 27, 20, 16, 5, 1],
[28, 25, 17, 14, 7, 2],
[28, 26, 21, 14, 6, 4]]
to this
[[[0,30], [0,29], [0,19], [0,17], [0,12], [0,11]],
[[1,30], [1,27], [1,20], [1,16],[1,5], [1,1]],
[[2,28], [2,25], [2,17], [2,14], [2,7], [2,2]],
[[3,28], [3,26], [3,21], [3,14], [3,6], [3,4]]]
Thanks! I am doing this to implement asked in How to select rows from a 3-D Tensor in TensorFlow? #kom
Here's a workaround to achieve the 3D tensor from 2D tensor
a = tf.constant([[30, 29, 19, 17, 12, 11],
[30, 27, 20, 16, 5, 1],
[28, 25, 17, 14, 7, 2],
[28, 26, 21, 14, 6, 4]], dtype=tf.int32)
a = tf.expand_dims(a, axis=2)
b = tf.constant(np.asarray([i*np.ones(a.shape[1]) for i in range(0, a.shape[0])], dtype=np.int32), dtype=tf.int32)
b = tf.expand_dims(b, axis=2)
final_ids = tf.concat([b, a], axis=2)

Tensorflow multiplication broadcasting within batches

We know that tf.multiply can broadcast like this:
import tensorflow as tf
import numpy as np
a = tf.Variable(np.arange(12).reshape(3, 4))
b = tf.Variable(np.arange(4))
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
sess.run(tf.multiply(a, b))
This will give us
[[0, 1, 4, 9],
[0, 5, 12, 21],
[0, 9, 20, 33]]
But my question is, what should I do if both a and b are in batches? That is,
a = tf.Variable(np.arange(24).reshape(2, 3, 4))
b = tf.Variable(np.arange(8).reshape(2, 4))
Then how can I get the result of multiplying (broadcasting) the vector onto the matrix in each batch? Like the following answer:
[[[0, 1, 4, 9],
[0, 5, 12, 21],
[0, 9, 20, 33]],
[[48, 65, 84, 105],
[64, 85, 108, 133],
[80, 105, 132, 161]]]
Thanks!
Broadcasting first adds singleton dimensions to the left until rank is matched. In first case that adds batch dimension. But in second case you already have batch dimension so you need to insert singleton dimension manually in the second position:
a = tf.reshape(tf.range(24), (2, 3, 4))
b = tf.reshape(tf.range(8), (2, 4))
sess.run(tf.mul(a, tf.expand_dims(b, 1)))