LSTM 错误 - 'logits and labels must have the same shape'
LSTM error - 'logits and labels must have the same shape'
我已经在此处搜索了有关该错误的其他主题,但无法找出问题所在。我正在尝试使用具有两个预测变量和三个结果的玩具数据集创建一个 LSTM,将输出层设置为 sigmoid,以便每个结果标签提供 0-1 之间的概率。我的代码:
import pandas as pd
import numpy as np
import tensorflow as tf
#create toy dataset
d = {'custID': [101,101,101,102,102,102,103,103,103],
'X1': [1,1,1,0,0,0,1,1,0],
'X2': [0,1,0,1,1,1,1,1,0],
'y1': [0,0,1,0,1,1,0,0,1],
'y2': [0,1,1,0,0,1,1,0,1],
'y3':[0,0,0,0,0,1,0,1,0]}
data = pd.DataFrame(data=d)
#seperate preds (X) from outcome (y)
X = data[['custID','X1','X2']]
y = data[['custID','y1','y2','y3']]
X.set_index('custID', inplace=True)
y.set_index('custID', inplace=True)
#reshape
X = X.values.reshape(3,3,2)
print(X)
y = y.values.reshape(3,3,3)
print(y)
#create LSTM
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(6, input_shape=(3,2)),
tf.keras.layers.LSTM(12, return_sequences = False),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(3, activation='sigmoid')
])
model.compile(optimizer=tf.keras.optimizers.Adam(),loss='binary_crossentropy')
model.fit(X,y, epochs=10)
这会产生错误(*ValueError:logits 和标签必须具有相同的形状 ((None, 3) vs (None, 3, 3)))。如果我将输出层激活设置为 softmax,它会起作用,但这会产生所有 3 个标签总和为 1 的概率,而不是每个标签的概率。
修复 'same shape' 问题
我想你想把你的模型改成这个
#create LSTM
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(6, input_shape=(3,2)),
tf.keras.layers.LSTM(12, return_sequences=True),
tf.keras.layers.Dense(3, activation='sigmoid')
])
如果我们查看模型摘要
model.summary()
我们得到以下输出
Layer (type) Output Shape Param #
=================================================================
dense_16 (Dense) (None, 3, 6) 18
_________________________________________________________________
lstm_8 (LSTM) (None, 3, 12) 912
_________________________________________________________________
dense_17 (Dense) (None, 3, 3) 39
=================================================================
Total params: 969
Trainable params: 969
Non-trainable params: 0
我们可以看到数据确实以正确的形状流动
显示此模型有效
让我们采用上面的模型并对其进行训练
model.compile(optimizer=tf.keras.optimizers.Adam(),loss='binary_crossentropy')
dataSet = tf.data.Dataset.from_tensors((X,y)).repeat(1000)
model.fit(dataSet, epochs=5)
Returns以下训练结果
Epoch 1/5
1000/1000 [==============================] - 2s 2ms/step - loss: 0.2522
Epoch 2/5
1000/1000 [==============================] - 2s 2ms/step - loss: 0.0142
Epoch 3/5
1000/1000 [==============================] - 2s 2ms/step - loss: 0.0048
Epoch 4/5
1000/1000 [==============================] - 2s 2ms/step - loss: 0.0023
Epoch 5/5
1000/1000 [==============================] - 2s 2ms/step - loss: 0.0012
看起来训练起来棒极了!
我认为主要问题是 return_sequence=False
,它基本上摆脱了您的第二维数据。 Flatten
是不必要的,如果您修复了 return_sequence,则 Flatten 会导致另一个问题。
如果这能解决您的问题,请告诉我
我已经在此处搜索了有关该错误的其他主题,但无法找出问题所在。我正在尝试使用具有两个预测变量和三个结果的玩具数据集创建一个 LSTM,将输出层设置为 sigmoid,以便每个结果标签提供 0-1 之间的概率。我的代码:
import pandas as pd
import numpy as np
import tensorflow as tf
#create toy dataset
d = {'custID': [101,101,101,102,102,102,103,103,103],
'X1': [1,1,1,0,0,0,1,1,0],
'X2': [0,1,0,1,1,1,1,1,0],
'y1': [0,0,1,0,1,1,0,0,1],
'y2': [0,1,1,0,0,1,1,0,1],
'y3':[0,0,0,0,0,1,0,1,0]}
data = pd.DataFrame(data=d)
#seperate preds (X) from outcome (y)
X = data[['custID','X1','X2']]
y = data[['custID','y1','y2','y3']]
X.set_index('custID', inplace=True)
y.set_index('custID', inplace=True)
#reshape
X = X.values.reshape(3,3,2)
print(X)
y = y.values.reshape(3,3,3)
print(y)
#create LSTM
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(6, input_shape=(3,2)),
tf.keras.layers.LSTM(12, return_sequences = False),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(3, activation='sigmoid')
])
model.compile(optimizer=tf.keras.optimizers.Adam(),loss='binary_crossentropy')
model.fit(X,y, epochs=10)
这会产生错误(*ValueError:logits 和标签必须具有相同的形状 ((None, 3) vs (None, 3, 3)))。如果我将输出层激活设置为 softmax,它会起作用,但这会产生所有 3 个标签总和为 1 的概率,而不是每个标签的概率。
修复 'same shape' 问题
我想你想把你的模型改成这个
#create LSTM
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(6, input_shape=(3,2)),
tf.keras.layers.LSTM(12, return_sequences=True),
tf.keras.layers.Dense(3, activation='sigmoid')
])
如果我们查看模型摘要
model.summary()
我们得到以下输出
Layer (type) Output Shape Param #
=================================================================
dense_16 (Dense) (None, 3, 6) 18
_________________________________________________________________
lstm_8 (LSTM) (None, 3, 12) 912
_________________________________________________________________
dense_17 (Dense) (None, 3, 3) 39
=================================================================
Total params: 969
Trainable params: 969
Non-trainable params: 0
我们可以看到数据确实以正确的形状流动
显示此模型有效
让我们采用上面的模型并对其进行训练
model.compile(optimizer=tf.keras.optimizers.Adam(),loss='binary_crossentropy')
dataSet = tf.data.Dataset.from_tensors((X,y)).repeat(1000)
model.fit(dataSet, epochs=5)
Returns以下训练结果
Epoch 1/5
1000/1000 [==============================] - 2s 2ms/step - loss: 0.2522
Epoch 2/5
1000/1000 [==============================] - 2s 2ms/step - loss: 0.0142
Epoch 3/5
1000/1000 [==============================] - 2s 2ms/step - loss: 0.0048
Epoch 4/5
1000/1000 [==============================] - 2s 2ms/step - loss: 0.0023
Epoch 5/5
1000/1000 [==============================] - 2s 2ms/step - loss: 0.0012
看起来训练起来棒极了!
我认为主要问题是 return_sequence=False
,它基本上摆脱了您的第二维数据。 Flatten
是不必要的,如果您修复了 return_sequence,则 Flatten 会导致另一个问题。
如果这能解决您的问题,请告诉我