处理大量文件的错误代码逻辑

时间:2019-03-21 22:22:06

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

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

  

我的电脑规格:英特尔酷睿I5第八代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)

1 个答案:

答案 0 :(得分:0)

尽管我不是造成您问题的根本原因,但我会根据我在处理大型数据集方面的经验添加一些注释。

  1. 其中的CSV文本文件在磁盘空间,内存(字符串)和处理(读取,解析和转换为其他类型)方面非常昂贵。每次pandas读取CSV文件时,它都会逐行读取,解析下一个并构造python对象。这很耗时。
  2. 大文本文件(特别是大.csv文件)不适用于熊猫。我确实不能指出确切的原因,但是我无法使用16GB内存机器将超过2GB的csv文件加载到数据帧中。
  3. 良好的数据序列化总是比常规序列化更好。但是,pickle是一种非常通用的python对象序列化方法,可以很好地处理多种类型的对象。当然,它具有漏洞bla bla bla。对于纯粹的python研究工作,这是一种保存对象的绝佳 easy 方法。熊猫的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)

请告诉我这是否可以解决您的问题。 看来这是一个小问题,但我知道进行调试可能很耗时。

P.S。 由于您使用魔术,因此我假设您使用Jupyter。 您的机器是+/-台笔记本电脑;我建议关闭jupyter笔记本/实验室中所有正在运行的内核,并在处理大数据时仅使用一个。