我正在尝试提供从2个经过微调的VGG16中提取的特征(每个都在不同的流上),然后针对9个数据对的每个序列,将它们的numpy数组连接起来,并将9个输出的序列(连接)提供给Keras中的双向LSTM。
问题是尝试构建LSTM部件时遇到错误。下面显示了我编写的用于读取RGB流和光学流,提取特征并连接每对的生成器:
def generate_generator_multiple(generator,dir1, dir2, batch_rgb, batch_flow, img_height,img_width):
print("Processing inside generate multiple")
genX1 = generator.flow_from_directory(dir1,
target_size = (img_height,img_width),
class_mode = 'categorical',
batch_size = batch_rgb,
shuffle=False
)
genX2 = generator.flow_from_directory(dir2,
target_size = (img_height,img_width),
class_mode = 'categorical',
batch_size = batch_flow,
shuffle=False
)
while True:
imgs, labels = next(genX1)
X1i = RGB_model.predict(imgs, verbose=0)
imgs2, labels2 = next(genX2)
X2i = FLOW_model.predict(imgs2,verbose=0)
Xi = []
for i in range(9):
Xi.append(np.concatenate([X1i[i+1],X2i[i]]))
Xi = np.asarray(Xi)
if np.array_equal(labels[1:],labels2)==False:
print("ERROR !! problem of labels matching: RGB and FLOW have different labels")
yield Xi, labels2[2]
我期望生成器产生9个数组的序列,因此当我强制循环运行两次时,Xi的形状为:(9,14,7,7,512)
当我使用while True时(如上面的代码),并尝试调用该方法检查其结果,经过3次迭代后,我得到了错误:
ValueError: too many values to unpack (expected 2)
现在,假设生成器没有问题,我尝试将生成器返回的数据馈送到双向LSTM,如下所示:
n_frames = 9
seq = 100
Bi_LSTM = Sequential()
Bi_LSTM.add(Bidirectional(LSTM(seq, return_sequences=True, dropout=0.25, recurrent_dropout=0.1),input_shape=(n_frames,14,7,512)))
Bi_LSTM.add(GlobalMaxPool1D())
Bi_LSTM.add(TimeDistributed(Dense(100, activation="relu")))
Bi_LSTM.add(layers.Dropout(0.25))
Bi_LSTM.add(Dense(4, activation="relu"))
model.compile(Adam(lr=.00001), loss='categorical_crossentropy', metrics=['accuracy'])
但是我仍然收到以下错误:(错误日志有点长)
InvalidArgumentError: Shape must be rank 4 but is rank 2 for 'bidirectional_2/Tile_1' (op: 'Tile') with input shapes: [?,7,512,1], [2].
这似乎是由以下原因引起的:
Bi_LSTM.add(Bidirectional(LSTM(seq, return_sequences=True, dropout=0.25, recurrent_dropout=0.1),input_shape=(n_frames,14,7,512)))
我不再确定问题是我尝试构建LSTM的方式,从生成器返回数据的方式还是定义LSTM输入的方式。
非常感谢您可以提供的任何帮助。
答案 0 :(得分:0)
此错误似乎是由以下行引起的:
public <T> void method(T t) {
if (t instanceof String) {
setString((String) t); // t is an String
} else if (t instanceof Integer) {
setInt((Integer) t); // t is an Integer
}
System.out.println(t.getClass().getName());
}
我对LSTM的输入感到困惑。代替显式给出输入的形状,我们只需要指定输入的尺寸即可。在我的情况下,这是3,因为输入是3D np数组。我的代码仍然有其他问题,但是对于此特定错误,解决方案使用以下方式更改了该部分:
input_shape=(n_frames,14,7,512)
编辑: 进行预测时,由于LSTM需要一维输入,因此我们需要获取预测的平均值。
我的代码中的另一个问题是Xi的形状。在产生它之前,需要对其进行重塑,使其与LSTM预期的输入相匹配。