TensorFlow如何插入未知张量?及LSTM模型输入数据序列化实现
问题1:TensorFlow中如何插入未知张量?
首先得搞清楚你说的“插入未知张量”其实分两种情况:一种是往已有张量里插一个形状不确定的张量,另一种是先搞个带未知维度的张量,再往里塞元素。下面分别给你唠唠:
1. 往已有张量里插形状未知的张量
如果要插的张量形状是运行时才确定的(比如动态批量的情况),用tf.concat或者tf.insert都能搞定:
- 要是插在首尾,直接用
tf.concat拼接就行,比如在第0维(样本维度)插入:
import tensorflow as tf # 原张量,形状是(None, 6)——样本数未知,每个样本6个特征 original_tensor = tf.placeholder(tf.float32, shape=[None, 6]) # 待插入的张量,同样样本数未知 insert_tensor = tf.placeholder(tf.float32, shape=[None, 6]) # 在原张量前面插入新张量(其实是拼接) result = tf.concat([insert_tensor, original_tensor], axis=0)
- 要是想插在中间某个位置,用
tf.insert就行,哪怕原张量维度是None也没关系,TensorFlow会在运行时自动处理:
# 比如要插在第2个样本的位置 insert_pos = tf.constant(2, dtype=tf.int32) result = tf.insert(original_tensor, insert_pos, insert_tensor, axis=0)
2. 创建带未知维度的张量并插元素
如果是要先搞个动态的容器,逐步往里加元素,那tf.TensorArray绝对是首选——它专门用来处理动态序列,支持随时插入、读取元素:
# 初始化一个空的TensorArray,允许动态扩容 ta = tf.TensorArray(dtype=tf.float32, size=0, dynamic_size=True) # 插入第一个元素,形状可以是未知的 ta = ta.write(0, tf.placeholder(tf.float32, shape=[None])) # 再插第二个 ta = ta.write(1, tf.placeholder(tf.float32, shape=[None])) # 最后转成普通张量 result_tensor = ta.stack()
问题2:为LSTM模型序列化输入数据
看你的代码,应该是想把形状(6,6)的输入转换成LSTM要求的**[批量大小,时间步数,特征数]**格式对吧?毕竟LSTM的输入必须是三维的,咱一步一步来:
先看你的原始数据:
input_x = np.array([[1,2,1,2,1,2],[3,4,3,4,3,4],[10,20,1,2,1,2],[30,40,3,4,3,4],[100,200,1,2,1,2],[300,400,3,4,3,4]]) # shape: (6,6)
情况1:把样本按固定时间步分组
你设了n_steps=2,如果是想把6个样本分成3组,每组2个时间步,最终形状变成(3,2,6),那根本不用循环插入,直接用reshape就能搞定,简单又高效:
import numpy as np import tensorflow as tf input_x = np.array([[1,2,1,2,1,2],[3,4,3,4,3,4],[10,20,1,2,1,2],[30,40,3,4,3,4],[100,200,1,2,1,2],[300,400,3,4,3,4]]) batch_size = 6 n_steps = 2 # 直接reshape成LSTM需要的格式:(批量数, 时间步数, 特征数) # 这里批量数是6//2=3,所以用-1让numpy自动计算 lstm_input = input_x.reshape((-1, n_steps, input_x.shape[1])) print(lstm_input.shape) # 输出 (3, 2, 6)
情况2:构造滑动窗口序列
如果你的需求是做滑动窗口(比如每个序列包含连续的2个样本,滑动步长为1),最终形状是(5,2,6),那可以用numpy的滑动窗口工具:
lstm_input_slide = np.lib.stride_tricks.sliding_window_view(input_x, window_shape=(n_steps, input_x.shape[1])).squeeze(axis=1) print(lstm_input_slide.shape) # 输出 (5, 2, 6)
情况3:在样本间插入未知张量
要是你代码里的np.insert是想在样本之间插一些特殊张量(比如填充值),那可以结合第一个问题的方法来做。比如在每2个样本后插一个全0的张量:
# 要插入的全0张量,形状(1,6) insert_tensor = np.zeros((1, input_x.shape[1])) x_copy = input_x.copy() # 计算插入位置:第2、5、8个位置 insert_positions = [n_steps*(i+1) + i for i in range(int(batch_size/n_steps))] for pos in insert_positions: if pos <= len(x_copy): x_copy = np.insert(x_copy, pos, insert_tensor, axis=0) print(x_copy.shape) # 输出 (9,6),插了3个全0样本
如果要在TensorFlow里做同样的操作,用tf.insert就行:
x = tf.convert_to_tensor(input_x, dtype=tf.float32) insert_tensor = tf.zeros((1, tf.shape(x)[1]), dtype=tf.float32) insert_positions = tf.constant([2,5,8], dtype=tf.int32) x_copy = tf.insert(x, insert_positions, insert_tensor, axis=0)
内容的提问来源于stack exchange,提问作者rosefun
相关产品推荐
相关产品推荐

