我正在使用Keras进行项目,该项目具有大量输入数据和较少量的输出/标签数据(即图像)。输入 - 输出数据的映射是连续且一致的,即前1000个输入样本对应于第一图像,第二个1000个输入样本对应于第二图像,依此类推。
由于输出数据是图像,因此需要大量内存,因此在numpy数组中有相同图像的数千个不必要的副本。 我一直在寻找一种方式来使用" soft" numpy数组中的链接,这样索引只是映射到一个较小的数组,但我找不到一种可接受的方法。
编辑:我应该在这里添加更多信息,因为我可能没有在上面正确解释这种情况。
我正在进行的项目拍摄视频,分割音频和视频,使用音频进行输入,并使用视频中的各个帧作为输出。在" rawest"在形式上,网络将具有单个输入(一个音频样本)和一组卷积层以形成输出。
当然,可用的输入点数(比如48kHz音频每秒48,000个样本)会大大影响输出点的数量(~24 fps)。即时简单选项(以及我输出数据较小时的选项I)将只复制数组中的数据,并将pony复制到额外的RAM使用情况。不幸的是,这不是一个选项,因为它需要将数组增加大约2000倍,对于已经很大的数据集,它会非常快地生成OOM。
希望对我所处的情况有更好的解释。到目前为止,我考虑过/尝试过的一个选项是重载numpy数组类中的某些函数,例如: getitem ,目的是将索引映射到较小的数组。我放弃了这个,因为我确定Keras的后端只是从numpy中取出一个连续的块然后使用它。 我考虑的另一个选择是使用更小的批次,并尽可能地复制图像,训练并移动到下一组图像。虽然这很麻烦(感觉就像放弃了)。
我认为最好的选择,以及我接下来尝试的选项,是使用ldavid对Keras'的建议。 TimeDistributed函数。如果我理解正确,我可以用它来批处理"输入采样到一组具有相同输出数据大小的样本。
答案 0 :(得分:2)
我相信这可以通过TimeDistributed
和平均结果来实现。
您的问题中有很多缺少的信息,但我会假设您的输入形状为(batch_size, 224, 224, 3)
,输出形状为(batch_size, 7, 7, 512)
,以说明如何完成此操作。
假设您拥有可以为一个输出分配一个输入的模型(假设它是VGG19):
from keras import Input, Model, backend as K
from keras.applications import VGG16
from keras.layers import TimeDistributed, Lambda
input_shape = (224, 224, 3)
vgg19 = VGG16(input_shape=input_shape,
include_top=False,
weights=None)
您可以将此模型传播到1000个图像中的每一个,并将输出组合起来:
x = Input(shape=(1000, 224, 224, 3))
y = TimeDistributed(vgg19)(x) (None, 1000, 7, 7, 512)
y = Lambda(lambda inputs: K.mean(inputs, axis=1))(y) (None, 7, 7, 512)
model = Model(x, y)
model.compile(loss='mse', optimizer='adam')
由于您要对1,000个输入图像求平均值,因此当您在不同数量的样本之间分配时,此模型也应该有用(例如input_shape=(batch_size, 30, 224, 224, 3)
)。
使用MNIST的工作示例,每个标签有10个输入图像:
import numpy as np
from keras import Input, Model, backend as K
from keras.datasets import mnist
from keras.layers import TimeDistributed, Lambda, Conv2D
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = (np.repeat(x.reshape(x.shape[0], 1, 28, 28, 1), 10, axis=1)
for x in (x_train, x_test))
# samples in x_train are repeated 10 times, shape=(60000, 10, 28, 28, 1)
y_train, y_test = (np.tile(y.reshape(y.shape[0], 1, 1, 1), (1, 3, 3, 16))
for y in (y_train, y_test))
# samples in y_train are repeated (3, 3, 16) times, shape=(60000, 3, 3, 16)
x = Input((28, 28, 1))
y = Conv2D(16, 3, strides=9, activation='relu')(x)
base_model = Model(x, y)
x = Input(shape=(10, 28, 28, 1))
y = TimeDistributed(base_model)(x)
y = Lambda(lambda inputs: K.mean(inputs, axis=1))(y)
model = Model(x, y)
model.compile(loss='mse',
optimizer='adam')
print('initial train loss:', model.evaluate(x_train, y_train, verbose=2))
print('initial test loss:', model.evaluate(x_test, y_test, verbose=2))
model.fit(x_train, y_train,
batch_size=1024,
epochs=10,
verbose=2)
print('final train loss:', model.evaluate(x_train, y_train, verbose=2))
print('final test loss:', model.evaluate(x_test, y_test, verbose=2))
initial train loss: 891.6627651529948
initial test loss: 931.27085390625
Epoch 1/10
- 2s - loss: 383.4519
...
Epoch 10/10
- 2s - loss: 27.5036
final train loss: 27.394255329386393
final test loss: 27.324540267944336