我正在使用 keras 和 tensorflow 构建一个用于时间序列二元分类的神经网络模型。这就是我的输入的样子,形状为 (124,4,591):
| Col 1 | Col 2 | Col 3 | Col 4 |
Row 1 | [x1, ..., x591] | [x1, ..., x591] | [x1, ..., x591] | [x1, ..., x591] |
Row 2 | [x1, ..., x591] | [x1, ..., x591] | [x1, ..., x591] | [x1, ..., x591] |
Row 3 | [x1, ..., x591] | [x1, ..., x591] | [x1, ..., x591] | [x1, ..., x591] |
我将数据分为 X_train
、X_test
、y_train
和 y_test
。我还使用 LabelEncoder()
和 将标签从
.['True', 'False']
编码为 [0, 1]
OneHotEncoder()
x = np.stack((np.vstack(x[:,0]),np.vstack(x[:,1]),np.vstack(x[:,2]),np.vstack(x[:,3])))
x = x.reshape((124,4,591))
y = table_raw_ptpt['Binding Known']
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size = 0.3, random_state = 0)
X_train.shape
返回(86, 4, 591)。
标签编码:
label_encoder = LabelEncoder()
integer_encoded_train = label_encoder.fit_transform(array(y_train))
integer_encoded_test = label_encoder.fit_transform(array(y_test))
onehot_encoded_y_train = OneHotEncoder(sparse=False)
integer_encoded_train = integer_encoded_train.reshape(len(integer_encoded_train), 1)
onehot_encoded_y_train = onehot_encoded_y_train.fit_transform(integer_encoded_train)
onehot_encoded_y_test = OneHotEncoder(sparse=False)
integer_encoded_test = integer_encoded_test.reshape(len(integer_encoded_test), 1)
onehot_encoded_y_test = onehot_encoded_y_test.fit_transform(integer_encoded_test)
onehot_encoded_y_train.shape
返回(86, 2)。
这是我的神经网络:
model = Sequential()
model.add(Dense(86, activation='relu', input_shape=(4,591)))
model.add(Dense(43, activation='relu'))
model.add(Dense(20, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss = 'binary_crossentropy',
optimizer = 'adam',
metrics = ['accuracy'])
model.summary()
它有效。但是当我尝试安装 X_train 时,出现错误:
Error when checking target: expected dense_227 to have shape (1,) but got array with shape (2,)
提到的层是输出层。据我了解,输出形状不正确。我尝试在各层之间使用 Flattern()
,甚至尝试了 Reshape(1,)
。但由于我是这方面的初学者,我不完全理解必须添加什么来控制神经网络中的数据形状以获得我需要的输出。
我设法让它与 softmax
一起工作,但我也需要 sigmoid
才能工作,这样我就可以在之后进行最终预测(True 或 False/1 或 0) )。
谢谢。
最佳答案
问题在于如何处理地面实况数据 y
。以下模型使用真实数据处理随机数据,您必须将 y
编码为具有 4 个值的 one-hot ,并将此 one-hot 编码分配给地面实况向量 y
其形状必须为 (124,4,1),注意 4 (我在这里使用 124 个样本)
因此 y
必须具有 4 个维度 y1、y2、y3、y4
。下面显示了如何对成对的地面真值逻辑值 00, 01, 10,11
进行编码并将其分配给 4 维目标向量 y
:
0 0 -> 0001 -> y1=0, y2=0, y3=0, y4=1
0 1 -> 0010 -> y1=0, y2=0, y3=1, y4=0
1 0 -> 0100 -> y1=0, y2=1, y3=0, y4=0
1 1 -> 1000 -> y1=1, y2=0, y3=0, y4=0
这种逻辑值的处理可以用Karnaugh-Veitch图(https://en.wikipedia.org/wiki/Karnaugh_map)来说明,图中的每个方 block 相当于一个one-hot编码的逻辑值。
您必须编写一个函数,将逻辑值 00,01,10,11
的组合转换为维度 4 的单热编码特征向量,例如上面
使用像这样编码的y
,可以像这样构建模型
from random import randint
from random import seed
import math
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
# generating random data, replace this with your data
X = np.random.rand(124,4,591)
y = np.random.randint(2,size=(124,4)) # replace this with your ground truth feature vector
y=y.reshape(124,4,1)
# https://stackoverflow.com/questions/44704435/error-when-checking-model-input-expected-lstm-1-input-to-have-3-dimensions-but
model = Sequential()
model.add(Dense(86, activation='relu', input_shape=(4,591)))
model.add(Dense(43, activation='relu'))
model.add(Dense(20, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary()
model.fit(X, y, epochs=1, batch_size=10)
关键是 y
具有与 X
相同的第二维,即 4,这可以通过像上面那样对基本事实的逻辑值进行编码来实现
上面的代码中没有这样做,因为我不知道你的数据,在代码中使用了正确维度的随机数据
关于python - 以 3D 张量时间序列作为输入的二元分类 Keras 神经网络模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52073938/