如何在 Tensorflow 中重新批处理张量?
How do I re-batch a tensor in Tensorflow?
我有一个通过 CNN 将数据传递到 LSTM 的模型。但是在LSTM阶段之前我不得不重新组织CNN的输出,如下:
输入:(600, 512, 1) --(CNN)--> (600, 32)
这个 (600, 32) 张量由两个参数 k(window 大小)和 s(步长)修改,这两个参数都是整数,它们决定了以下张量的形状(我将调用进程 're-batching'):
重新批次:(600, 32) --> (146, 20, 32)
这些维度是使用感受野方程从 k 和 s 获得的:
此处n_in=600,n_out求值为146,k=20,p=0,s=4。
然后可以将这个新张量输入到 LSTM 中,因为形状是(batch_size、时间步长、特征),所以模型从那里继续...
我的问题是我不知道如何 're-batch' 这个张量而不破坏我的模型的向后传递。我尝试创建一个空数组 - np.empty(shape_of_lstm_input) - 并用所需数据迭代填充批处理轴的每个元素,但转换为 numpy 数组会导致在尝试最小化时丢失信息丢失,如以下警告消息所示:
WARNING:tensorflow:Gradients do not exist for variables ['list of all parameters in my CNN'] when minimizing the loss.
所以我尝试遵循相同的过程,但我认为使用 tf.zeros(shape_of_lstm_input) 可以解决缺少梯度的问题,但我却收到此错误消息:
TypeError: 'tensorflow.python.framework.ops.EagerTensor' object does not support item assignment
有谁知道这个问题是否存在解决方案?我不确定后向传递将如何处理前向传递中的这个 're-batching' 张量。
您似乎在尝试从数据中创建滑动 window。这是一种简单的方法:
import tensorflow as tf
def sliding_window(x, window_size, stride, axis=0):
n_in = tf.shape(x)[axis]
n_out = (n_in - window_size) // stride + 1
# Just in case n_in < window_size
n_out = tf.math.maximum(n_out, 0)
r = tf.expand_dims(tf.range(n_out), 1)
idx = r * stride + tf.range(window_size)
return tf.gather(x, idx, axis=axis)
# Test
x = tf.reshape(tf.range(30), [10, 3])
print(x.numpy())
# [[ 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]]
y = sliding_window(x, 4, 2)
print(y.numpy())
# [[[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]]
#
# [[ 6 7 8]
# [ 9 10 11]
# [12 13 14]
# [15 16 17]]
#
# [[12 13 14]
# [15 16 17]
# [18 19 20]
# [21 22 23]]
#
# [[18 19 20]
# [21 22 23]
# [24 25 26]
# [27 28 29]]]
我有一个通过 CNN 将数据传递到 LSTM 的模型。但是在LSTM阶段之前我不得不重新组织CNN的输出,如下:
输入:(600, 512, 1) --(CNN)--> (600, 32)
这个 (600, 32) 张量由两个参数 k(window 大小)和 s(步长)修改,这两个参数都是整数,它们决定了以下张量的形状(我将调用进程 're-batching'):
重新批次:(600, 32) --> (146, 20, 32)
这些维度是使用感受野方程从 k 和 s 获得的:
此处n_in=600,n_out求值为146,k=20,p=0,s=4。
然后可以将这个新张量输入到 LSTM 中,因为形状是(batch_size、时间步长、特征),所以模型从那里继续...
我的问题是我不知道如何 're-batch' 这个张量而不破坏我的模型的向后传递。我尝试创建一个空数组 - np.empty(shape_of_lstm_input) - 并用所需数据迭代填充批处理轴的每个元素,但转换为 numpy 数组会导致在尝试最小化时丢失信息丢失,如以下警告消息所示:
WARNING:tensorflow:Gradients do not exist for variables ['list of all parameters in my CNN'] when minimizing the loss.
所以我尝试遵循相同的过程,但我认为使用 tf.zeros(shape_of_lstm_input) 可以解决缺少梯度的问题,但我却收到此错误消息:
TypeError: 'tensorflow.python.framework.ops.EagerTensor' object does not support item assignment
有谁知道这个问题是否存在解决方案?我不确定后向传递将如何处理前向传递中的这个 're-batching' 张量。
您似乎在尝试从数据中创建滑动 window。这是一种简单的方法:
import tensorflow as tf
def sliding_window(x, window_size, stride, axis=0):
n_in = tf.shape(x)[axis]
n_out = (n_in - window_size) // stride + 1
# Just in case n_in < window_size
n_out = tf.math.maximum(n_out, 0)
r = tf.expand_dims(tf.range(n_out), 1)
idx = r * stride + tf.range(window_size)
return tf.gather(x, idx, axis=axis)
# Test
x = tf.reshape(tf.range(30), [10, 3])
print(x.numpy())
# [[ 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]]
y = sliding_window(x, 4, 2)
print(y.numpy())
# [[[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]]
#
# [[ 6 7 8]
# [ 9 10 11]
# [12 13 14]
# [15 16 17]]
#
# [[12 13 14]
# [15 16 17]
# [18 19 20]
# [21 22 23]]
#
# [[18 19 20]
# [21 22 23]
# [24 25 26]
# [27 28 29]]]