首页 文章

将多个输入样本映射到Keras中的单个输出样本

提问于
浏览
1

我正在使用Keras开发一个项目,该项目具有大量输入数据和较少量的输出/标签数据(即图像) . 输入 - 输出数据的映射是连续且一致的,即前1000个输入样本对应于第一图像,第二1000个输入样本对应于第二图像,依此类推 .

由于输出数据是图像,因此需要大量内存,因此在numpy阵列中具有相同图像的数千个不必要的副本 . 我正在寻找一种在numpy数组中使用“软”链接的方法,这样索引只是映射到一个较小的数组,但是我找不到一种可接受的方法 .

编辑:我应该在这里添加更多信息,因为我可能没有正确解释上面的情况 .

我正在处理的项目拍摄视频,分割音频和视频,使用音频输入,并使用视频中的各个帧作为输出 . 在“rawest”形式中,网络将具有单个输入(一个音频样本)和一组卷积层以形成输出 .

当然,可用的输入点数(比如48kHz音频每秒48,000个样本)会大大影响输出点的数量(~24 fps) . 即时简单选项(如果我的输出数据是较小的形式,我将采取的选项)将只是复制数组中的数据和pony到额外的RAM使用 . 不幸的是,这不是一个选项,因为它需要将数组增加大约2000倍,对于已经很大的数据集,它会非常快地生成OOM .

希望's a better explanation of the situation that I' m in . 到目前为止,我考虑/试图的一个选项是重载numpy数组类中的一些函数,例如 getitem ,目的只是将索引映射到一个较小的数组 . 我放弃了这个,因为我认为是使用更小的批次,并尽可能地复制图像,训练,并移动到下一组图像 . 虽然这很麻烦(感觉就像放弃了) .

我认为最好的选择,我接下来要尝试的是使用ldavid建议的Keras的TimeDistributed函数 . 如果我理解正确,我可以使用它将输入样本“批处理”为一组具有相同大小的输出数据的样本 .

1 回答

  • 1

    我相信这可以通过 TimeDistributed 实现,并对结果取平均值 .

    's a lot of missing information in your question, but I will assume your input'的形状是 (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
    

相关问题