【问题标题】:Wrong code logic for processing large number of files处理大量文件的错误代码逻辑
【发布时间】:2019-08-12 21:07:25
【问题描述】:

我是 python 和图像处理的初学者和新手。对于一个大学项目,我试图训练一种地区语言的字符识别。我有一个非常庞大的数据集(大约 90000 张图像)。下面的代码部分用于将图像提取到数据集。但是,当我运行代码时,它会耗尽我的 8gb RAM 并且我的电脑会死机。这可能是由于处理了大量图像。

我的 PC 规格:Intel Core I5 第 8 代 8GB RAM NVIDIA Geforce GTX 1060 6GB。

是否有任何解决方法以便我可以在我的 PC 上运行它?任何帮助将不胜感激。

%matplotlib inline


root_dir = os.getcwd()
img_dir = os.path.join(root_dir, 'images')

pixels = np.array(['pixel_{:04d}'.format(x) for x in range(1024)])
flag = True

for char_name in sorted(os.listdir(img_dir)):
    char_dir = os.path.join(img_dir, char_name)
    img_df = pd.DataFrame(columns=pixels)

    for img_file in sorted(os.listdir(char_dir)):
        image = pd.Series(imageio.imread(os.path.join(char_dir, img_file)).flatten(), index=pixels)
        img_df = img_df.append(image.T, ignore_index=True)

    img_df = img_df.astype(np.uint8)
    img_df['character'] = char_name

    img_df.to_csv('data.csv', index=False, mode='a', header=flag)
    flag=False

    print('=', end='')


df = pd.read_csv('data.csv')

df['character_class'] = LabelEncoder().fit_transform(df.character)
df.drop('character', axis=1, inplace=True)
df = df.astype(np.uint8)

【问题讨论】:

  • 我看到您正在使用数据框。您实际使用什么库进行培训?也许它不必接受一个充满图像的巨大数据框。
  • 我实际上是在尝试使用这个link
  • 我看到你手动创建了一个进度条。你应该寻找tqdm 包,它会让你的生活更轻松。
  • 如果我错了,请原谅我,但是将大量内容附加到 .csv 文件非常消耗内存。我会保存在单独的 CSV 中。最终,我会使用泡菜,因为它比字符串更快的序列化。
  • 我的问题是代码试图首先将所有图像读入 RAM 然后处理它们,而不是读取一个图像,处理它,删除加载的图像,读取下一个图像,处理它,等等。

标签: python python-3.x python-2.7 dataset ocr


【解决方案1】:

虽然我不是您问题的根本原因,但我会根据我处理大型数据集的经验添加一些注释。

  1. 文本文件,其中包括 CSV,在磁盘空间、内存(字符串)和处理(读取、解析和转换为其他类型)方面非常昂贵。每次pandas 读取一个 CSV 文件,它都会逐行读取,解析下一个并构造 python 对象。这很耗时。
  2. 大文本文件,特别是大的 .csv 文件,不适用于 pandas。我真的无法指出确切的原因,但我无法将超过 2GB 的 csv 文件加载到具有 16GB 内存机器的数据帧中。
  3. 良好的数据序列化总是比一般的好。但是,pickle 是一种非常通用的 python 对象序列化方法,它可以很好地处理多种类型的对象。当然,它有漏洞,bla bla bla。对于纯 Python 研究工作,这是保存对象的简单方法。 Panda 的 DataFrame 将它与其他方式集成以保存您的对象。使用 `df.to_pickle('/path/to/file.pkl')
  4. 大文件是单点故障。我认为最好有多个文件并为您的任务使用合适的数据阅读器。

话虽如此,这是我的

%matplotlib inline


root_dir = os.getcwd()
img_dir = os.path.join(root_dir, 'images')

pixels = np.array(['pixel_{:04d}'.format(x) for x in range(1024)])
flag = True
chars = sorted(os.listdir(img_dir))

for char_name in chars:
    char_dir = os.path.join(img_dir, char_name)
    img_df = pd.DataFrame(columns=pixels)

    for img_file in sorted(os.listdir(char_dir)):
        image = pd.Series(imageio.imread(os.path.join(char_dir, img_file)).flatten(), index=pixels)
        img_df = img_df.append(image.T, ignore_index=True)

    img_df = img_df.astype(np.uint8)
    img_df['character'] = char_name

    img_df.to_pickle(f'{char_name}_data.pkl')
    flag=False

    print('=', end='')


df = pd.concat([pd.read_pickle(f'{char_name}_data.pkl') for char_name in chars],axis=0)

df['character_class'] = LabelEncoder().fit_transform(df.character)
df.drop('character', axis=1, inplace=True)
df = df.astype(np.uint8)

或者,您仍然可以通过附加数据框并保存最终文件来使用单个文件:

%matplotlib inline


root_dir = os.getcwd()
img_dir = os.path.join(root_dir, 'images')

pixels = np.array(['pixel_{:04d}'.format(x) for x in range(1024)])
df = pd.DataFrame(columns=['character'] + pixels.tolist())
for char_name in sorted(os.listdir(img_dir)):
    char_dir = os.path.join(img_dir, char_name)
    img_df = pd.DataFrame(columns=pixels)

    for img_file in sorted(os.listdir(char_dir)):
        image = pd.Series(imageio.imread(os.path.join(char_dir, img_file)).flatten(), index=pixels)
        img_df = img_df.append(image.T, ignore_index=True)

    img_df = img_df.astype(np.uint8)
    img_df['character'] = char_name
    df.append(image_df)
    print('=', end='')

df.to_pickle('data.pkl')
df = pd.read_pickle('data.pkl')

df['character_class'] = LabelEncoder().fit_transform(df.character)
df.drop('character', axis=1, inplace=True)
df = df.astype(np.uint8)

如果这能解决您的问题,请告诉我。 这似乎是一个小问题,但我知道调试这类事情可能很耗时。

附: 由于您使用魔法,我假设您使用 Jupyter。 您的机器是 +/- 一台笔记本电脑;我建议关闭你的 jupyter notebook/lab 中所有正在运行的内核,在处理大数据时只使用一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多