[英]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 的特定類型,它使用過濾器並試圖在提供的數據中找到模式,期望始終具有相同形狀的數據,例如相同大小的圖像或信號部分。
如果您想提供形狀不一致的數據,您有兩種選擇:
附帶說明一下,如果您沒有非常強大的機器,您根本不想用如此龐大的數據訓練/測試/執行 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.