Image processing Keras Conv2D和LSTM的尺寸问题

Image processing Keras Conv2D和LSTM的尺寸问题,image-processing,keras,sequence,video-processing,prediction,Image Processing,Keras,Sequence,Video Processing,Prediction,我试图在Windows10机器上用Python 3.5.2 | Anaconda4.2.0(64位)实现图像序列预测。我有keras和tensorflow的最新版本 每个图像都是160x128。我的培训集是1008个图像,大小为1008x160x128x1。我想做一个简单的网络,有一个卷积层和一个LSTM层,现在,每个图像被卷积以提取特征,然后输入LSTM以了解时间依赖性。输出应为k(在k=1以下的情况下)预测图像,尺寸为160x128。下面是代码以及model.summary() 我的卷积层的

我试图在Windows10机器上用Python 3.5.2 | Anaconda4.2.0(64位)实现图像序列预测。我有keras和tensorflow的最新版本

每个图像都是160x128。我的培训集是1008个图像,大小为1008x160x128x1。我想做一个简单的网络,有一个卷积层和一个LSTM层,现在,每个图像被卷积以提取特征,然后输入LSTM以了解时间依赖性。输出应为k(在k=1以下的情况下)预测图像,尺寸为160x128。下面是代码以及model.summary()

我的卷积层的输出是4维的(无、79、63、32)。因此,我对输出进行了重塑,使其为(无,32,79*63),并且是LSTM层的正确维数(尽管我认为这是在幕后处理的…)。然后,模型编译时不会出现错误(如果我没有进行重塑,则会抛出维度错误)

因为我的训练数据的每个元素每个样本只有一个时间点,所以我不使用卷积层上的时间分布(经过大量研究,似乎这就是解决方案)。然而,我相信对于输出层,所有的样本都聚集在一起,所以有多少样本就有多少时间点,并且要使用时间分布。如果执行此操作,则会出现以下错误:

回溯(最近一次呼叫最后一次): 文件“C:\seqn\u pred\read\u images\u dataset.py”,第104行,在 模型拟合(序列x、序列y、历元=10、批量大小=1、详细度=1) 文件“c:\users\l\anaconda3\lib\site packages\keras\engine\training.py”,第950行,格式为fit 批次大小=批次大小) 文件“c:\users\l\anaconda3\lib\site packages\keras\engine\training.py”,第787行,在用户数据中 异常(前缀='target') 文件“c:\users\l\anaconda3\lib\site packages\keras\engine\training\u utils.py”,第137行,在标准化输入数据中 str(数据形状)) ValueError:检查目标时出错:预期时间_分布_62具有形状(32,1),但获得具有形状(128,160)的数组

我搜索了stackoverflow上的所有相关帖子,并尝试了所有相关的“解决方案”,但都没有成功。当我尝试做units=160*128时,形状(32160*128)与(128160)之间又出现了一个问题。此外,我还尝试将目标数据重塑为1008x(160*128)x1(因为TimeDistributed需要3-d数据以及展平每个目标),以获得另一个错误

ValueError:检查目标时出错:预期时间\u分配\u 64具有形状(32,20480),但获得具有形状(20480,1)的数组

我还尝试在没有时间分布的情况下运行最后一层,但仍然收到与目标形状相关的错误

ValueError:检查目标时出错:预期密集_1具有形状(32,1),但获得具有形状(160,128)的数组

主要问题是卷积层和LSTM层之间以及最终致密层的形状/尺寸。任何帮助都将不胜感激

train_x, test_x = [D2[i] for i in rand_indx], [D2[i] for i in range(N-1) if i not in rand_indx]
train_y, test_y = [D2[i+1] for i in rand_indx], [D2[i+1] for i in range(N-1) if i not in rand_indx]

train_x = np.array(train_x)
train_x = train_x.reshape(len(train_x), n, m,1)
train_y = np.array(train_y)
train_y = train_y.reshape(train_y.shape[0], train_y.shape[1]*train_y.shape[2], 1)

model = Sequential()
#model.add(TimeDistributed(Conv2D(filters = 32, kernel_size = (3,3), strides = (1,1), activation = 'relu', padding = 'valid', input_shape = (1, n, m, 1))))
#model.add(TimeDistributed(MaxPooling2D(pool_size = (3,3))))
#model.add(TimeDistributed(Dropout(0.30)))
#model.add(TimeDistributed(Flatten()))
model.add(Conv2D(filters = 32, kernel_size = (3,3), strides = (1,1), activation = 'relu', padding = 'valid', input_shape = (n, m, 1)))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Dropout(0.30))
model.add(Reshape((32,-1)))
model.add(LSTM(units = 20, activation = 'relu', return_sequences = True))
model.add(Dropout(0.1))
model.add(TimeDistributed(Dense(1, activation = 'relu')))
optim = krs.optimizers.Adam(lr = 0.375)
model.compile(loss = 'mse', optimizer = optim)
model.fit(train_x, train_y, epochs = 10, batch_size = 1, verbose = 1)
model.summary()


我对你在这里想要达到的目标有点困惑。这是我的2美分

输入:(1008160128,1)

输出:(1008160*128)

如果只有一个输出目标,则不应在LSTM层中使用
return\u sequences=True
,也不需要
TimeDistributed
层。最后一位需要更改如下

model.add(Reshape((32,-1)))
model.add(LSTM(units = 20, activation = 'relu'))
model.add(Dropout(0.1))
model.add(Dense(160*128, activation = 'relu'))
如果进行上述更改,则可以使用具有上述输入和输出形状的数据来训练模型

但是,有一个危险信号,你可能需要考虑一下

  • 重塑卷积输出的方式。目的是什么?是否希望每个通道都是模型的单独输入,如果是,则首先需要交换输入轴,以便通道尺寸保持不变。因为你现在做的方式,(在我看来)将一些非常随机的东西发送到LSTM层。这是我提议的改变

您好,当谈到黑白图像时,可能我对“频道”有点困惑。在其他帖子中,我知道channels=3,因为rgb的像素值不同。但是,当通道=1时,它们有什么意义?或者,当你说“频道”时,你的意思可能有所不同?谢谢。我应该补充一点,你的解决方案解决了我的问题,我对此表示感谢。我只是想理解你在说什么,这样我才能更好地理解为什么它会起作用。再次感谢。@user1723196,说得好。是的,你说得对。我没有注意到这一点,所以我向你道歉。然而,我的观点仍然站在万一有一天你决定去RGB而不是灰度。如果您更改为RGB,则执行排列将是一项安全预防措施,并将为您节省大量调试时间。但对于灰度,正如你所说,并不重要。
model.add(Reshape((32,-1)))
model.add(LSTM(units = 20, activation = 'relu'))
model.add(Dropout(0.1))
model.add(Dense(160*128, activation = 'relu'))
model.add(Permute([3,1,2]))
model.add(Dropout(0.30))
model.add(Reshape((32,-1)))