Lea*_*ner 13 python numpy image image-processing
我一直在尝试处理两个包含大约40000-50000个图像的巨大文件.但每当我尝试将我的数据集转换为numpy数组时,我都会遇到内存错误.我只有大约8GB的内存并不是很多,但是,因为我缺乏python的经验,我想知道是否有任何方法可以通过使用一些我不知道的python库来解决这个问题,或者可能是优化我的代码?我想听听你对此事的看法.
我的图像处理代码:
from sklearn.cluster import MiniBatchKMeans
import numpy as np
import glob
import os
from PIL import Image
from sklearn.decomposition import PCA
image_dir1 = "C:/Users/Ai/Desktop/KAGA FOLDER/C/train"
image_dir2 = "C:/Users/Ai/Desktop/KAGA FOLDER/C/test1"
Standard_size = (300,200)
pca = PCA(n_components = 10)
file_open = lambda x,y: glob.glob(os.path.join(x,y))
def matrix_image(image):
"opens image and converts it to a m*n matrix"
image = Image.open(image)
print("changing size from %s to %s" % (str(image.size), str(Standard_size)))
image = image.resize(Standard_size)
image = list(image.getdata())
image = map(list,image)
image = np.array(image)
return image
def flatten_image(image):
"""
takes in a n*m numpy array and flattens it to
an array of the size (1,m*n)
"""
s = image.shape[0] * image.shape[1]
image_wide = image.reshape(1,s)
return image_wide[0]
if __name__ == "__main__":
train_images = file_open(image_dir1,"*.jpg")
test_images = file_open(image_dir2,"*.jpg")
train_set = []
test_set = []
"Loop over all images in files and modify them"
train_set = [flatten_image(matrix_image(image))for image in train_images]
test_set = [flatten_image(matrix_image(image))for image in test_images]
train_set = np.array(train_set) #This is where the Memory Error occurs
test_set = np.array(test_set)
Run Code Online (Sandbox Code Playgroud)
小编辑:我正在使用64位python
假设每个像素有一个4字节的整数,那么你试图在(4*300*200*50000 /(1024)**3)中保存大约11.2 GB的数据.对于2字节整数的一半.
你有几个选择:
而不是从列表复制到numpy,这将暂时使用两倍的内存量,如下所示:
test_set = [flatten_image(matrix_image(image))for image in test_images]
test_set = np.array(test_set)
Run Code Online (Sandbox Code Playgroud)
做这个:
n = len(test_images)
test_set = numpy.zeros((n,300*200),dtype=int)
for i in range(n):
test_set[i] = flatten_image(matrix_image(test_images[i]))
Run Code Online (Sandbox Code Playgroud)
由于您的文件是JPEG并且您有300x200图像,因此对于24位彩色图像,您每个文件大约需要1.4 MB,而且总体上至少要高达40.2 GB:
In [4]: import humanize # `pip install humanize` if you need it
In [5]: humanize.naturalsize(300*200*24, binary=True)
Out[5]: '1.4 MiB'
In [6]: humanize.naturalsize(300*200*24*30000, binary=True)
Out[6]: '40.2 GiB'
Run Code Online (Sandbox Code Playgroud)
如果你有灰度,你可能有8位图像,响应为13.4 GB:
In [7]: humanize.naturalsize(300*200*8, binary=True)
Out[7]: '468.8 KiB'
In [8]: humanize.naturalsize(300*200*8*30000, binary=True)
Out[8]: '13.4 GiB'
Run Code Online (Sandbox Code Playgroud)
这仅适用于一个副本.根据操作,这可能会变得更大.
您总是可以在具有更多内存的服务器上租用一些时间.
从RAM量来看这些并不是考虑哪种服务器最适合您的工作负载的唯一方法.提供商之间还存在其他差异,包括IOPS,内核数量,CPU类型等.
训练模型后,您不需要全套训练数据.删除内存不足的内容.在Python中,这意味着不保留对数据的引用.奇怪的野兽,是的.
这可能意味着设置您的训练数据并在仅返回您需要的功能中创建模型.
让我们想象一下,你可以将它全部存储在内存中.您可以在此处进行的一项改进是直接从PIL图像转换为numpy数组.不复制现有数组,它是原始数据的视图.但是,看起来您需要在向量空间中展平.
image = Image.open(image)
print("changing size from %s to %s" % (str(image.size), str(Standard_size)))
image = image.resize(Standard_size)
np_image = np.asarray(image).flatten()
Run Code Online (Sandbox Code Playgroud)
编辑:实际上,这有助于您的代码的可维护性,但无助于性能.您可以单独对函数中的每个图像执行此操作.垃圾收集器会扔掉旧东西.继续前进,没有什么可看的.