簡體   English   中英

keras model.predict 中的大數據量

[英]Large data quantities in keras model.predict

我有一個這樣定義的 CNN:

inputs = keras.Input(shape=(1024,1))
x=inputs

# 1st convolutional block
x = 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)

# Classifier
x = 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 session 中訓練它,然后我打開訓練好的 model 並使用 keras 的model.predict(dataarr)來預測結果。

問題是我希望能夠使用大量數據來進行預測,但是數據保存在 .txt 文件中,這些文件變得非常大(> 8GB),因此 google colab 沒有足夠的內存來打開文件並將所有數據讀入單個數組。

處理這個問題的最佳方法是什么? 我在 C++ 中生成數據,我不是專家,但必須可以在我寫出數據時將數據轉換為二進制,並在讀取時將其轉換回來。 這是一個明智的選擇嗎? 或者有沒有辦法讓 keras 批量預測,因為 .txt 文件中的每組 1024 行都獨立於下一組?

那么什么是輸入形狀?

來自keras 文檔

shape :形狀元組(整數),不包括批量大小。 例如,shape=(32,) 表示預期輸入將是一批 32 維向量。 這個元組的元素可以是 None; “無”元素表示形狀未知的尺寸。

這是什么意思? 您的輸入層keras.Input(shape=(1024,1))說,您將輸入 1024 個一維向量的向量,即 1024 個值。 如您正確理解的那樣,輸入層中有 1024 個神經元。 然而,單個神經元不適用於輸入序列(即行),但可以組合來自前一層的神經元的輸入及其權重或輸入上的單個值。 提供的每個下一個值(從序列中)只是另一個獨立的評估。 在此處閱讀有關神經元的更多信息。 然而,卷積層是 NN 的特定類型,它使用過濾器並試圖在提供的數據中找到模式,期望始終具有相同形狀的數據,例如相同大小的圖像或信號部分。

如果您想提供形狀不一致的數據,您有兩種選擇:

  1. 將數據拆分成批次以適合輸入形狀並選擇合理的批次大小以適合您的 RAM,但這可能會導致信息丟失,因為您的數據可能具有連續性,在拆分時會丟失
  2. 使用另一種適用於序列數據的神經網絡——循環神經網絡,例如 LSTM。 這些網絡將編碼的字符/單詞/值作為單個輸入,並通過網絡處理它,並部分記憶數據。 LSTM 網絡廣泛用於文本分類,不需要像大多數 NN 那樣輸入 static 大小。 如果您使用帶有一組鍵的數據,例如自然文本、源代碼等,您還應該考慮通過 hash map 對數據進行編碼用數值數據。

附帶說明一下,如果您沒有非常強大的機器,您根本不想用如此龐大的數據訓練/測試/執行 NN(期望您有多個具有如此大小的文件),數據訓練的時間復雜度這么大的尺寸太高了,你可能永遠也得不到訓練有素的 model。

編輯經過OP的進一步解釋:

以上仍然適用,但在這種情況下不適用,將其留在那里,因為它可能對其他人有幫助。

關於 OPs 問題,仍然應該應用批量加載。 RAM 不會變得更大,因此需要將數據集分成塊。 一次加載即 100 或 1000 行不應加載太多 RAM - 您應該嘗試找出您的機器的限制在哪里。 您可以使用以下代碼加載行:

with open("log.txt") as infile:
    for line in infile:
        do_something_with(line)

處理后文件將關閉,垃圾收集器將從 memory 中釋放行。 您可以在ndarray中堆疊行以將它們處理到predict()方法。 如果不預測單個樣本,您還需要提供batch_size

編輯2:

您真正需要在這里做的是一次加載 n 行,完成它的線程在這里 您打開文件並加載 n x 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 作為塊大小,因此您可以看到它附加了空數據,function 的 output 如下:

 ['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並迭代此 function:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM