我正在尝试创建一个能够识别人类情绪的模型。开始时我的代码和RAM都运行正常:
但当我尝试对图像进行归一化时,RAM突然急剧上升
然后Colab就崩溃了:
这是导致Colab崩溃的代码块:
import osimport matplotlib.pyplot as pltimport cv2data = []for emot in os.listdir('./data/'): for file_ in os.listdir(f'./data/{emot}'): img = cv2.imread(f'./data/{emot}/{file_}', 0) img = cv2.bitwise_not(img) img /= 255.0 # <--- 这是导致Colab崩溃的行 data.append([img, emotions.index(emot)])
如果我移除img /= 255.0
,它就不会崩溃,但我的图像就无法归一化了!:
我甚至尝试在另一个代码块中进行归一化:
for i in range(len(data)): data[i][0] = np.array(data[i][0]) / 255.0
但它不起作用,仍然会崩溃
回答:
我想通过一个例子来解释。首先让我们看一下下面的代码。
import numpy as npx = np.random.randint(0, 255, size=(100, 32, 32), dtype=np.int16)print('Present data type', x.dtype)# 你所做的y = x/255print('Present data type', y.dtype)# 你应该做的z = (x/255).astype(np.float16)print('Present data type', z.dtype)
输出:
Present data type int16Present data type float64Present data type float16
如果你仔细看,当我对x
变量进行除法并声明y=x/255
时,数据类型变为了float64
。如果你对NumPy数组的int
数据类型进行除法,默认情况下它会被类型转换为float64
。通常,’float64’占用的内存更大。因此,在对int
类型的NumPy矩阵进行除法时,应该始终将其转换为更短的数据类型,尤其是对于大型数据集。
如果你执行的代码在没有img /= 255.0
块的情况下流畅运行,那么这就是原因。在除法之后,你应该将img
变量类型转换为最低可能的float
类型,比如np.float16
或np.float32
。然而,np.float16
有一些限制,并且TensorFlow并不完全支持它(TensorFlow会将其转换为32位浮点数),你可以使用np.float32
数据类型。
因此,尝试在img /= 255.0
行之后添加img.astype(np.float16)
或img.astype(np.float32)
。
修改后的代码如下,
import osimport matplotlib.pyplot as pltimport cv2data = []for emot in os.listdir('./data/'): for file_ in os.listdir(f'./data/{emot}'): img = cv2.imread(f'./data/{emot}/{file_}', 0) img = cv2.bitwise_not(img) img = (img/255.0).astype(np.float16) # <--- 这是建议的修改 data.append([img, emotions.index(emot)])