NumPy 中 .concatenate() 的 ArrayMemoryError

问题描述 投票:0回答:1

我正在学习如何创建神经网络,并且我已经制作了一个用于训练的神经网络,可以区分猫和狗。当我用 100 张猫和狗的照片训练神经网络时,它的准确度较低 (0.50)。现在我已经下载了包含 10,000 张猫照片和相同数量狗照片的 Google 数据集。我对文件进行标准化,将它们转换为 .npy 并开始训练神经网络。结果,在操作的前20秒就出现了这些警告:

2024-01-07 15:09:51.166129: I tensorflow/core/util/port.cc:113] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
WARNING:tensorflow:From C:\Users\artyo\AppData\Local\Programs\Python\Python311\Lib\site-packages\keras\src\losses.py:2976: The name tf.losses.sparse_softmax_cross_entropy is deprecated. Please use tf.compat.v1.losses.sparse_softmax_cross_entropy instead.

但是在我看来这并不是特别重要,这些警告之前就已经出现过,并不影响工作。但经过大约 15-20 分钟的工作(一直没有发生任何事情,只有 Python 进程需要大约 13 GB RAM),神经网络输出以下内容:

Traceback (most recent call last):
  File "e:\Unity\!!neuro\projects\catsAndDogs100\main.py", line 15, in <module>
    train_data = np.concatenate((cats_train_data, dogs_train_data), axis=0)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
numpy.core._exceptions._ArrayMemoryError: Unable to allocate 10.1 GiB for an array with shape (9000, 224, 224, 3) and data type float64

据我了解,这与缺乏某种记忆有关,甚至在训练之前,在将数组与猫和狗组合时,就会出现此错误。启动程序时,神经网络文件所在磁盘上有 200 GB 可用空间,系统磁盘上有 150 GB 可用空间,启动时大约有 14 GB 可用 RAM。我已经尝试将数据集中的图像数量从 12,500 个减少到 9900 个,结果,仅错误文本中“无法访问”的千兆字节数减少了。 带连接的代码:

# Загрузка данных кошек для обучения
cats_train_data = [np.load("E:\\Unity\\!!neuro\\datasets\\catsAndDogs100\\finishedCats1\\" + filename) for filename in os.listdir("E:\\Unity\\!!neuro\\datasets\\catsAndDogs100\\finishedCats1\\")]
cats_train_labels = np.zeros(len(cats_train_data))  # Метки для кошек

# Загрузка данных собак для обучения
dogs_train_data = [np.load("E:\\Unity\\!!neuro\\datasets\\catsAndDogs100\\finishedDogs1\\" + filename) for filename in os.listdir("E:\\Unity\\!!neuro\\datasets\\catsAndDogs100\\finishedDogs1\\")]
dogs_train_labels = np.ones(len(dogs_train_data))   # Метки для собак

# Объединение данных и меток для обучения
train_data = np.concatenate((cats_train_data, dogs_train_data), axis=0)
train_labels = np.concatenate((cats_train_labels, dogs_train_labels), axis=0)

我尝试减少数据集中的数据量,也尝试给予进程 python.exe 高优先级,并在俄语版本的 Stackoverflow 上提出这个问题,但那里没有人回答我。

python arrays numpy neural-network concatenation
1个回答
0
投票

我整理了一个小代码示例,展示了如何在部分集上进行训练,这样它们就不需要一次全部加载到内存中。

  1. 选择满足您系统限制的批量大小
  2. 识别数据并用标签收集所有数据并将其打乱
  3. 根据总大小和批次大小确定使用多少批次
  4. 迭代纪元时间(以维持通常 keras 提供的开箱即用的多纪元训练)
  5. 迭代每个批次,根据需要加载图像,并将模型拟合到其中

我从张量流的网站复制了神经网络分类器的基本设置。在您的情况下,您将不会使用

N
,并且您将使用注释中的代码列出训练数据,该代码基于您上面的示例。我刚刚下载了随机的猫和狗图像来验证代码是否有效。您可能还需要编辑循环中加载数据以处理您的文件的行。

import numpy as np
from PIL import Image
import tensorflow as tf
import random

N = 90
batch_size = 10
rng = np.random.default_rng(seed=42)
epochs = 5

cat_file_set = [(0, 'cat.jpg')] * N  # (0, x) for x in list(os.listdir("E:\\ ... Cats1\\"))
dog_file_set = [(1, 'dog.jpg')] * N  # (1, x) for x in list(os.listdir(E:\\ ... Dogs1\\"))
file_set = cat_file_set + dog_file_set
random.shuffle(file_set)
total_batches = int(np.ceil(len(file_set) / batch_size))

# https://www.tensorflow.org/tutorials/quickstart/beginner
model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(224, 224, 3)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10)
])
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
model.compile(optimizer='adam', loss=loss_fn, metrics=['accuracy'])

for epochnum in range(epochs):
    for batchnum in range(total_batches):
        bslice = file_set[batchnum * batch_size: (batchnum + 1) * batch_size]
        train_data = np.array([np.array(Image.open(x[1])) for x in bslice])
        train_labels = np.array([x[0] for x in bslice])
        model.fit(train_data, train_labels, epochs=1)
# model.evaluate(train_data, train_labels, verbose=2)

如果您有任何疑问,请告诉我。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.