R调用keras的to_categorical函数时触发MemoryError内存分配错误
报错根因
Error in py_call_impl(callable, dots$args, dots$keywords) : MemoryError: Unable to allocate 5.88 TiB for an array with shape (275703, 5863139) and data type float32
触发该错误的核心原因如下:
to_categorical用于将一维整数标签转换为独热编码矩阵,默认以输入数组的最大值+1作为总类别数。你直接传入了data的第2~4列二维数组作为输入,函数会将数组内所有值统一识别为标签值计算总类别数- 你的输入标签中存在极大值,最终计算得到的总类别数高达5863139,275703条样本对应的独热编码矩阵需要5.88TiB存储空间,远超普通设备内存上限,直接触发内存溢出
解决方法
根据你的实际业务场景选择对应方案即可:
- 如果第2~4列是3个独立分类任务的标签,不要整表传入函数,逐列单独做独热编码转换
示例代码:# 逐列转换训练集标签 trainLabels_1 <- to_categorical(trainingtarget[,1]) trainLabels_2 <- to_categorical(trainingtarget[,2]) trainLabels_3 <- to_categorical(trainingtarget[,3]) # 逐列转换测试集标签 testLabels_1 <- to_categorical(testtarget[,1]) testLabels_2 <- to_categorical(testtarget[,2]) testLabels_3 <- to_categorical(testtarget[,3]) - 如果第2~4列是回归任务的连续值标签,不需要做独热编码,直接使用原始数值作为训练标签即可,无需调用
to_categorical - 如果标签是分类值但取值为无连续意义的大编码(如ID类字段),先将原始标签重编码为从0开始的连续整数,再做独热编码,可大幅降低内存占用
示例代码:# 以第1列标签为例做重编码,其余列同理操作 all_label_vals <- unique(c(trainingtarget[,1], testtarget[,1])) label_mapping <- setNames(0:(length(all_label_vals)-1), as.character(all_label_vals)) trainingtarget[,1] <- label_mapping[as.character(trainingtarget[,1])] testtarget[,1] <- label_mapping[as.character(testtarget[,1])] # 转换独热编码,指定总类别数避免额外开销 trainLabels_1 <- to_categorical(trainingtarget[,1], num_classes = length(all_label_vals)) - 如果分类实际类别数确实很大(超过1000类),直接放弃独热编码,改用深度学习框架的嵌入层(Embedding Layer)直接输入整数标签,完全避免生成超大独热矩阵的内存开销
内容的提问来源于stack exchange,提问作者ranveerdhakal
相关产品推荐
相关产品推荐

