Keras LSTM 错误 - Logits 和标签应该具有相同的形状
Posted
技术标签:
【中文标题】Keras LSTM 错误 - Logits 和标签应该具有相同的形状【英文标题】:Keras LSTM error - Logits and labels should have the same shape 【发布时间】:2021-07-11 04:39:36 【问题描述】:我正在尝试使用 Keras LSTM 进行二进制分类。
我的输入数据是 2340 条记录 * 254 个特征。
输出为 1*2340。
下面是我的代码。
X_res = np.array(X_res)
X_res = np.reshape(X_res,([1,2340,254]))
y_res = np.array(y_res)
y_res = np.reshape(y_res,([1,2340]))
y_test = np.array(y_test)
y_test = np.reshape(y_test,([1,314]))
model = keras.Sequential()
model.add(keras.layers.LSTM(32 ,input_dim = 254,return_sequences=True))
model.add(keras.layers.LSTM(100))
model.add(keras.layers.Dense(100, activation='sigmoid'))
model.add(keras.layers.Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=[tf.keras.metrics.Recall()])
model.fit(X_res, y_res, epochs= 5)
但是我无法克服错误:
ValueError:logits 和标签必须具有相同的形状((None, 1) vs (None, 2340))
【问题讨论】:
你的输出层必须是 Dense(2340, ...) 感谢工作!但我预测的 Y 的形状是 (1,2340),与 Y_train 相同。如何根据我的 X_test 使其成为正确的形状 【参考方案1】:您需要更改最后一层以匹配所需的输出形状(从 1 到 2340)。通过运行下面的示例代码,您会看到它在实践中是如何工作的:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
#let's simulate...
X_res=np.random.rand(2340,254)
y_res=np.random.rand(1,2340)
y_test=np.random.rand(1,314)
X_res = np.array(X_res)
X_res = np.reshape(X_res,([1,2340,254]))
y_res = np.array(y_res)
y_res = np.reshape(y_res,([1,2340]))
y_test = np.array(y_test)
y_test = np.reshape(y_test,([1,314]))
model = keras.Sequential()
model.add(keras.layers.LSTM(32 ,input_dim = 254,return_sequences=True))
model.add(keras.layers.LSTM(100))
model.add(keras.layers.Dense(100, activation='sigmoid'))
model.add(keras.layers.Dense(2340, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=[tf.keras.metrics.Recall()])
model.summary()
#test a littlebit before training...
test_input=tf.ones((1,2340,254))
print("Test result of original model: ",model(test_input).numpy())
#train...
model.fit(X_res, y_res, epochs= 5)
#test after training...just to show the shapes of inputs and outputs. Change the number of inputs you want to test to see the effect...
how_many_inputs_you_want_to_test=1
X_test=np.random.rand(how_many_inputs_you_want_to_test,2340,254)
print("Input shape: ", X_test.shape)
y_pred = (model.predict(X_test) > 0.5).astype("int32")
print("Output shape: ",y_pred.shape)
【讨论】:
感谢您的回答!不过,我还有一个额外的问题。当我尝试使用模型进行预测时,y_pred 的形状是 (1,2340) 而不是 (1,314)。我正在使用以下语句。 X_test = np.array(X_test) , X_test = np.reshape(X_test,([1,314,254])) , y_pred = (model.predict(X_test) > 0.5).astype("int32") 注意输入的形状是否正确。我在包括代码在内的原始答案中添加了简短的“训练后测试”部分,在这个例子中你可以看到正确的形状格式,还可以看到测试用例的增加如何增加相应的输出大小。 如果我的测试数据是 314 条记录 * 254 条特征,我怎么可能将其重塑为(314 * 2340 * 254)?? 不可能,我将添加另一个答案,该答案给出了您的案例中的重塑示例。请注意,在重塑张量时,重塑前张量和重塑后张量的大小需要适当。在转换中遵循逻辑; “如果我有一个 2x2 块的拼图,可以将其重塑为“1x4”块拼图或“4x1”块拼图,但例如不要变成“3x2”大小的拼图,因为块数不够。跨度> 【参考方案2】:建议如何在这个问题案例中重塑张量:
#About tensors and reshaping
import tensorflow as tf
#The tensor need to be reshaped:
example_tensor=tf.ones((314,254))
try:
#The reshaping is done by the command:
example_tensor_reshaped=tf.reshape(example_tensor,[314,2340,254])
except:
print("Sorry, this conversion is not possible!")
#----> which produce an error!
#Why? Because the reshaping is possible only with compatible sizes, for example conversion:
print("...thus let's try again with a different conversion...")
#The tensor need to be reshaped:
example_tensor=tf.ones((314,254*2340))
#The reshaping is done by the command:
example_tensor_reshaped=tf.reshape(example_tensor,[314,2340,254])
#----> which happens succesfully!
print("The shape of reshaped tensor: ",example_tensor_reshaped.shape)
【讨论】:
以上是关于Keras LSTM 错误 - Logits 和标签应该具有相同的形状的主要内容,如果未能解决你的问题,请参考以下文章
keras中的二元交叉熵和带有logits的二元交叉熵有啥区别?