python - 使用 Masking 为 tf.data.Dataset 找到正确的形状馈入 LSTM
问题描述
我正在执行时间序列分类任务,但找不到正确的使用方法tf.data.Dataset
。我可以使用 numpy 数组创建一个工作模型,如下面的代码所示(数据已经预先用零填充到最大长度为 180):
tf_data.shape, labels.shape
> ((225970, 180, 1), (225970,))
所以我有 180 个时间步长的 225970 个实例和 1 个特征。我可以按如下方式拟合模型。这可以正常工作并创建适当的输出/预测:
model = keras.Sequential(
[
layers.Masking(mask_value=0, input_shape=(180,1)),
layers.LSTM(16),
layers.Dense(1, activation='sigmoid')
]
)
model.compile(
optimizer='adam',
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=['accuracy']
)
model.fit(tf_data, labels, epochs=5)
但是,当我尝试以下使用时tf.data.Dataset.from_tensors
:
tf_dataset = tf.data.Dataset.from_tensors((tf_data, labels.astype(int)))
tf_dataset = tf_dataset.shuffle(buffer_size=1024).batch(64)
model_v1 = keras.Sequential(
[
layers.Input(shape=(180,1), batch_size=64),
layers.Masking(mask_value=0),
layers.LSTM(16),
layers.Dense(1, activation='sigmoid')
]
)
model_v2 = keras.Sequential(
[
layers.Masking(mask_value=0, shape=(180,1), batch_size=64),
layers.LSTM(16),
layers.Dense(1, activation='sigmoid')
]
)
<model_v1 or model_v2>.compile(
optimizer='adam',
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=['accuracy']
)
<model_v1 or model_v2>.fit(tf_dataset, epochs=10, steps_per_epoch=30)
我遇到了错误
model_v1 - ValueError: Error when checking input: expected input_48 to have 3 dimensions, but got array with shape (None, 225970, 180, 1)
model_v2 - ValueError: Error when checking input: expected masking_70_input to have 3 dimensions, but got array with shape (None, 225970, 180, 1)
谁能解释我需要对我的 tensorflow 数据集或我的模型做些什么,以确保它可以与 numpy 数组一起工作,tf.data.Dataset
而不仅仅是 numpy 数组?
解决方案
你应该tf.data.Dataset.from_tensor_slices
改用,
tf_dataset = tf.data.Dataset.from_tensor_slices((tf_data, labels.astype(int)))
根据方法的官方文档tf.data.Dataset.from_tensors
,
from_tensors
生成仅包含单个元素的数据集。要将输入张量切成多个元素,请from_tensor_slices
改用。
虽然官方文档tf.data.Dataset.from_tensor_slices
说,
给定的张量沿它们的第一维进行切片。此操作保留输入张量的结构,删除每个张量的第一个维度并将其用作数据集维度。所有输入张量的第一个维度必须具有相同的大小。
该*.from_tensor_slices
方法对输入张量进行切片,并将给定数组(在我们的例子中为张量)视为 225970 个数据实例。这允许分别调用方法,例如*.shuffle
和*.batch()
which shuffle 和 batch 数据实例。
我们可以通过一个例子来理解这一点。首先让我们生成一些虚拟数据实例。
x = np.random.rand( 2500 , 180 , 1 )
y = np.random.rand( 2500 , 1 )
与*.from_tensors
,
tensor_ds = tf.data.Dataset.from_tensors( ( x , y ) )
for sample in tensor_ds.take( 1 ):
print( sample[ 0 ].shape )
print( sample[ 1 ].shape )
输出是,
(2500, 180, 1)
(2500, 1)
和*.from_tensor_slices
,
tensor_ds = tf.data.Dataset.from_tensor_slices( ( x , y ) )
for sample in tensor_ds.take( 1 ):
print( sample[ 0 ].shape )
print( sample[ 1 ].shape )
输出是,
(180, 1)
(1,)
推荐阅读
- python - 如何在散点图上映射鼠标位置?
- mysql - 如何为 go-sqlmock 正确设置 Mock Row 和 Query
- c# - 为什么我的视图将空数据发布到控制器
- javascript - 根据数据库中的值动态设置背景颜色
- mongodb - 通过 mongodb vs 授权令牌中的字段授权资源(例如图像)访问?
- firebase - 多次上传 Vue / firebase 时出错(未定义或空引用)
- stripe-payments - 如果您不使用 Stripe Elements,如何调用 Stripe.createPaymentMethod?
- reactjs - 如何使用 useReducer 更新对象内的数组
- beautifulsoup - 如何通过BeautifulSoup通过IP地址扫描绕过非html IP
- javascript - javascript - 在文本框上传递值