ValueError: Can not squeeze dim[1], expected a dimension of 1 for '{{node binary_crossentropy/weighted_loss/Squeeze}}
ValueError: Can not squeeze dim[1], expected a dimension of 1 for '{{node binary_crossentropy/weighted_loss/Squeeze}}
我正在尝试使用前面的掩蔽层将 LSTM 模型拟合到我的数据中,但出现此错误:
ValueError: Can not squeeze dim[1], expected a dimension of 1, got 4 for '{{node binary_crossentropy/weighted_loss/Squeeze}} = Squeeze[T=DT_FLOAT, squeeze_dims=[-1]](Cast)' with input shapes: [128,4].
这是我的代码:
from tensorflow.keras.layers import LSTM, Dense, BatchNormalization, Masking
from tensorflow.keras.losses import BinaryCrossentropy
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Nadam
import numpy as np
if __name__ == '__main__':
# define stub data
samples, timesteps, features = 128, 4, 99
X = np.random.rand(samples, timesteps, features)
Y = np.random.randint(0, 2, size=(samples))
# create model
model = Sequential()
model.add(Masking(mask_value=0., input_shape=(None, 99)))
model.add(LSTM(100, return_sequences=True))
model.add(BatchNormalization())
model.add(Dense(1, activation='sigmoid'))
optimizer = Nadam(learning_rate=0.0001)
loss = BinaryCrossentropy(from_logits=False)
model.compile(loss=loss, optimizer=optimizer)
# train model
model.fit(
X,
Y,
batch_size=128)
我从 了解到,我不能使用单热编码标签,但我的标签不是单热编码的。
另外,当我移除遮蔽层时,训练有效。
据我了解,这里的一个样本包含 4 个时间步长和 99 个特征。因此 X 的形状是 (128,4,99)
因此,我只需为每个样本提供一个标签,因此 Y 的形状为 (128,)
但似乎 X 和/或 Y 的尺寸不正确,因为 tensorflow 想要更改其尺寸?
我尝试为每个样本的每个时间步提供一个标签(Y = np.random.randint(0, 2, size=(samples, timesteps))
,结果相同。
为什么添加遮罩层会引入此错误?以及如何保留遮蔽层而不出现错误?
系统信息:
- Python版本:3.9.5
- 张量流版本:2.5.0
- OS: Windows
我认为问题不在 Masking
层。由于您在 LSTM
层中将参数 return_sequences
设置为 True
,因此您将获得一个时间步长与输入相同且输出 space 为 100 的序列对于每个时间步,因此形状为 (128, 4, 100)
,其中 128 是批量大小。之后,应用 BatchNormalization
层,最后应用 Dense
层,形成 (128, 4, 1)
形状。问题是您的标签具有 2D 形状 (128, 1)
,而由于 return_sequences
参数,您的模型具有 3D 输出。因此,只需将此参数设置为 False
即可解决您的问题。另见 .
这是一个工作示例:
from tensorflow.keras.layers import LSTM, Dense, BatchNormalization, Masking
from tensorflow.keras.losses import BinaryCrossentropy
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Nadam
import numpy as np
if __name__ == '__main__':
# define stub data
samples, timesteps, features = 128, 4, 99
X = np.random.rand(samples, timesteps, features)
Y = np.random.randint(0, 2, size=(samples))
# create model
model = Sequential()
model.add(Masking(mask_value=0., input_shape=(None, 99)))
model.add(LSTM(100, return_sequences=False))
model.add(BatchNormalization())
model.add(Dense(1, activation='sigmoid'))
optimizer = Nadam(learning_rate=0.0001)
loss = BinaryCrossentropy(from_logits=False)
model.compile(loss=loss, optimizer=optimizer)
# train model
model.fit(
X,
Y,
batch_size=128)
我正在尝试使用前面的掩蔽层将 LSTM 模型拟合到我的数据中,但出现此错误:
ValueError: Can not squeeze dim[1], expected a dimension of 1, got 4 for '{{node binary_crossentropy/weighted_loss/Squeeze}} = Squeeze[T=DT_FLOAT, squeeze_dims=[-1]](Cast)' with input shapes: [128,4].
这是我的代码:
from tensorflow.keras.layers import LSTM, Dense, BatchNormalization, Masking
from tensorflow.keras.losses import BinaryCrossentropy
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Nadam
import numpy as np
if __name__ == '__main__':
# define stub data
samples, timesteps, features = 128, 4, 99
X = np.random.rand(samples, timesteps, features)
Y = np.random.randint(0, 2, size=(samples))
# create model
model = Sequential()
model.add(Masking(mask_value=0., input_shape=(None, 99)))
model.add(LSTM(100, return_sequences=True))
model.add(BatchNormalization())
model.add(Dense(1, activation='sigmoid'))
optimizer = Nadam(learning_rate=0.0001)
loss = BinaryCrossentropy(from_logits=False)
model.compile(loss=loss, optimizer=optimizer)
# train model
model.fit(
X,
Y,
batch_size=128)
我从
据我了解,这里的一个样本包含 4 个时间步长和 99 个特征。因此 X 的形状是 (128,4,99)
因此,我只需为每个样本提供一个标签,因此 Y 的形状为 (128,)
但似乎 X 和/或 Y 的尺寸不正确,因为 tensorflow 想要更改其尺寸?
我尝试为每个样本的每个时间步提供一个标签(Y = np.random.randint(0, 2, size=(samples, timesteps))
,结果相同。
为什么添加遮罩层会引入此错误?以及如何保留遮蔽层而不出现错误?
系统信息:
- Python版本:3.9.5
- 张量流版本:2.5.0
- OS: Windows
我认为问题不在 Masking
层。由于您在 LSTM
层中将参数 return_sequences
设置为 True
,因此您将获得一个时间步长与输入相同且输出 space 为 100 的序列对于每个时间步,因此形状为 (128, 4, 100)
,其中 128 是批量大小。之后,应用 BatchNormalization
层,最后应用 Dense
层,形成 (128, 4, 1)
形状。问题是您的标签具有 2D 形状 (128, 1)
,而由于 return_sequences
参数,您的模型具有 3D 输出。因此,只需将此参数设置为 False
即可解决您的问题。另见
这是一个工作示例:
from tensorflow.keras.layers import LSTM, Dense, BatchNormalization, Masking
from tensorflow.keras.losses import BinaryCrossentropy
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Nadam
import numpy as np
if __name__ == '__main__':
# define stub data
samples, timesteps, features = 128, 4, 99
X = np.random.rand(samples, timesteps, features)
Y = np.random.randint(0, 2, size=(samples))
# create model
model = Sequential()
model.add(Masking(mask_value=0., input_shape=(None, 99)))
model.add(LSTM(100, return_sequences=False))
model.add(BatchNormalization())
model.add(Dense(1, activation='sigmoid'))
optimizer = Nadam(learning_rate=0.0001)
loss = BinaryCrossentropy(from_logits=False)
model.compile(loss=loss, optimizer=optimizer)
# train model
model.fit(
X,
Y,
batch_size=128)