为了账号安全,请及时绑定邮箱和手机立即绑定

keras model.predict 中的大数据量

keras model.predict 中的大数据量

智慧大石 2023-06-06 17:32:43
我有一个 CNN,我这样定义:inputs = keras.Input(shape=(1024,1))x=inputs# 1st convolutional blockx = keras.layers.Conv1D(16, kernel_size=(3), name='Conv_1')(x)x = keras.layers.LeakyReLU(0.1)(x)      x = keras.layers.MaxPool1D((2), name='MaxPool_1')(x)x = keras.layers.Flatten(name='Flatten')(x)# Classifierx = keras.layers.Dense(64, name='Dense_1')(x)x = keras.layers.ReLU(name='ReLU_dense_1')(x)x = keras.layers.Dropout(0.2)(x)x = keras.layers.Dense(64, name='Dense_2')(x)x = keras.layers.ReLU(name='ReLU_dense_2')(x)我在一个 google colab 会话中训练它,然后我打开经过训练的模型并使用 keras'model.predict(dataarr)来预测结果。问题是我希望能够使用大量数据来进行预测,但数据保存在 .txt 文件中,这些文件变得非常大(>8GB),因此 google colab 没有足够的内存来打开文件并将所有数据读取到一个数组中。处理这个问题的最佳方法是什么?我正在用 C++ 生成数据,我不是专家,但必须可以在我写出数据时将其转换为二进制数据,并在我读取数据时将其转换回来。这是一个明智的选择吗?或者有没有办法让 keras 批量预测,假设 .txt 文件中的每组 1024 行都独立于下一组?
查看完整描述

1 回答

?
墨色风雨

TA贡献1853条经验 获得超6个赞

那么什么是输入形状?

shape:形状元组(整数),不包括批量大小。例如,shape=(32,) 表示预期输入将是 32 维向量的批次。这个元组的元素可以是 None;“无”元素表示形状未知的维度。

这是什么意思?你的输入层keras.Input(shape=(1024,1))说,你要输入 1024 个一维向量向量,所以 1024 个值。正如你所理解的那样,输入层中有 1024 个神经元。然而,单个神经元不适用于输入序列(即线),但可以组合来自前一层神经元的输入及其权重或输入的单个值。提供的每个下一个值(从序列开始)只是另一个独立评估。然而,卷积层是特定类型的神经网络,它使用过滤器并试图在提供的数据中寻找模式,期望始终具有相同形状的数据,例如相同大小的图像或信号部分。

如果您想提供形状不一致的数据,您有两种选择:

  1. 将数据分成多个批次以适合输入形状并选择合理的批次大小以适合您的 RAM,但这可能会导致信息丢失,因为您的数据可能具有连续性,在拆分时会丢失

  2. 使用另一种适用于顺序数据的神经网络——循环神经网络,例如 LSTM。这些网络将编码的字符/单词/值作为单个输入,并通过网络处理它并部分记忆数据。LSTM 网络广泛用于文本分类,不需要像大多数 NN 那样输入静态大小。如果您使用带有键集的数据,例如自然文本、源代码等,您还应该考虑通过哈希映射对数据进行编码(如果还没有这样做的话)。您可以节省空间,并且 NN 的工作方式更直观与数值数据。

作为旁注,如果你没有非常强大的机器,你根本不想用如此庞大的数据训练/测试/执行神经网络(期望你有多个这样大小的文件),数据训练的时间复杂度这样的尺寸太高了,你可能永远无法得到训练有素的模型。

编辑 经过OP的进一步解释:

以上仍然适用,但在这种情况下不适用,将其保留在那里,因为它可能对其他人有帮助。

关于OPs问题,还是应该应用batch loading。RAM 不会变得更大,因此需要将数据集拆分成块。即一次加载 100 或 1000 行不应该加载那么多 RAM - 你应该尝试找出你的机器的限制在哪里。您可以使用以下代码加载行:

with open("log.txt") as infile:

    for line in infile:

        do_something_with(line)

该文件将在处理后关闭,垃圾收集器将从内存中释放行。您可以堆叠行以ndarray将它们处理到predict()方法中。batch_size如果不预测单个样本,您还需要提供。

编辑 2:

你真正需要在这里做的是一次加载 n 行,完成它的线程。您打开文件并加载 n 个块,例如我在示例数据中提供了我选择的 2 个块,您可以使用您需要的任何数字,例如 1000。

from itertools import zip_longest

import numpy as np


n = 2  # Or whatever chunk size you want

with open("file.txt", 'rb') as f:

    for n_lines in zip_longest(*[f]*n, fillvalue=b''):

      arr = np.char.decode(np.array(n_lines),encoding='utf_8')

      print(arr)

我在示例文件中使用的数据如下:


1dsds

2sdas

3asdsa

4asdsaad

5asdsaad

6dww

7vcvc

8uku

9kkk1

我选择了奇数和 2 作为块大小,所以你可以看到它附加了空数据,函数的输出如下:


['1dsds\n' '2sdas\n']

['3asdsa\n' '4asdsaad\n']

['5asdsaad\n' '6dww\n']

['7vcvc\n' '8uku\n']

['9kkk1' '']

此代码一次加载 2 行,然后您可以根据需要删除换行符[s.replace('\n' , '') for s in arr]


要成功使用返回的数据,请使用yield并迭代此函数:


from itertools import zip_longest

import numpy as np


def batcher(filename: str):

    n = 2  # Or whatever chunk size you want

    with open(filename, 'rb') as f:

        for n_lines in zip_longest(*[f]*n, fillvalue=b''):

          #decode the loaded byte arrays to strings 

          arr = np.char.decode(np.array(n_lines),encoding='utf_8')

          yield arr.astype(np.float)

for batch_i, arr in enumerate(batcher("file.txt")):

    out = model.predict(arr.reshape( your_shape_comes_here ))

    #do what you need with the predictions


查看完整回答
反对 回复 2023-06-06
  • 1 回答
  • 0 关注
  • 87 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信