RStudio 3.5.2计算6万对28*28矩阵张量积时报内存耗尽错误求助
问题场景
在RStudio 3.5.2版本环境下,计算60000对28*28矩阵的张量积时,控制台抛出Error: vector memory exhausted (limit reached?)错误。
- 设备配置为搭载16GB RAM的MacBook Pro,按硬件容量判断本不该出现内存不足的问题
- 此前尝试用mclapply并行计算方案,仍未解决该报错
- 目前程序无法运行到代码最后一行的张量积计算步骤,需要对应的调试思路与可落地解决方案
附:用户编写的全部可复现代码
install.packages("keras") library(keras) install_keras() install_keras(method = "conda") library(keras) mnist <- dataset_mnist() str(mnist) trainx <- mnist$train$x trainy <- mnist$train$y testx <- mnist$test$x testy <- mnist$test$y trainxr <- trainx trainxg <- trainx trainxb <- trainx testxr <- testx testxg <- testx testxb <- testx #训练数据处理 i <- 1 for(i in i:60000){ randomr <- sample (0:255, 1) randomg <- sample (0:255, 1) randomb <- sample (0:255, 1) trainxr[i,,] <- (randomr/255)*(trainx[i,,]/255) trainxg[i,,] <- (randomg/255)*(trainx[i,,]/255) trainxb[i,,] <- (randomb/255)*(trainx[i,,]/255) i <- i+1 } #测试数据处理 j <- 1 for(j in j:10000){ randomr <- sample (0:255, 1) randomg <- sample (0:255, 1) randomb <- sample (0:255, 1) testxr[j,,] <- (randomr/255)*(testx[j,,]/255) testxg[j,,] <- (randomg/255)*(testx[j,,]/255) testxb[j,,] <- (randomb/255)*(testx[j,,]/255) j <- j+1 } #训练数据后续处理 k <- 1 for(k in k:60000){ randomminus <- sample (0:255, 1) matrixminus <- matrix((randomminus/255):(randomminus/255), nrow = 28, ncol = 28) trainxr[k,,] <- trainxr[k,,] - matrixminus trainxr[k,,] <- abs(trainxr[k,,]) trainxg[k,,] <- trainxg[k,,] - matrixminus trainxg[k,,] <- abs(trainxg[k,,]) trainxb[k,,] <- trainxb[k,,] - matrixminus trainxb[k,,] <- abs(trainxb[k,,]) k <- k+1 } #测试数据后续处理 l <- 1 for(l in l:10000){ randomminus <- sample (0:255, 1) matrixminus <- matrix((randomminus/255):(randomminus/255), nrow = 28, ncol = 28) trainxr[l,,] <- trainxr[l,,] - matrixminus trainxr[l,,] <- abs(trainxr[l,,]) trainxg[l,,] <- trainxg[l,,] - matrixminus trainxg[l,,] <- abs(trainxg[l,,]) trainxb[l,,] <- trainxb[l,,] - matrixminus trainxb[l,,] <- abs(trainxb[l,,]) l <- l+1 } #张量积计算 stepone <- matrix(1:1, nrow=21952, ncol=28) steptwo <- matrix(1:1, nrow=28, ncol=28) trainxtensor_a <- trainxr %x% trainxg
问题核心原因与调试解决方案
- 最核心的报错触发点来自张量积的计算逻辑错误:
trainxr和trainxg都是维度为60000×28×28的三维数组,直接用%x%运算符计算两个数组的克罗内克积,会生成维度为(600002828)×(600002828)的超大矩阵,单这部分内存占用就达到TB级别,完全超出硬件可承载范围,并不是设备16G RAM容量不足导致的。 - 代码本身存在多处逻辑冗余与bug,会额外放大内存占用:
- 测试数据后续处理的循环里,错误把对
testxr/testxg/testxb的修改写成了对trainxr/trainxg/trainxb的重复赋值,导致训练数据被无意义反复修改,生成大量临时对象占用内存。 - 循环内生成的
matrixminus本身无实际作用:因为生成逻辑是(randomminus/255):(randomminus/255),本质是单个标量重复填充成28×28的矩阵,完全没必要逐次循环新建该矩阵,直接用标量值做减法即可。 - 逐行循环的写法效率极低,循环过程中会频繁生成、回收临时内存块,造成不必要的内存碎片化,完全可以用R的向量化操作替代逐行for循环。
- 测试数据后续处理的循环里,错误把对
- 调整张量积的计算策略:你实际需要的是每对样本对应的单个28×28矩阵和另一张同尺寸矩阵的张量积,不是两个三维数组的全局克罗内克积。单对矩阵的张量积结果是784×784的矩阵,60000对结果如果一次性全部加载进内存,总占用约280GB,也远超16G RAM的承载能力,需要采用分块计算的方式:每次只处理100-200个样本对,计算完成后立刻将结果写入磁盘存储,释放当前块占用的内存,再处理下一块。
- 调整R的内存限制:macOS环境下3.5版本的R默认单向量可分配的内存上限很低,经常会在远未达到16G总内存占用时就触发
vector memory exhausted报错,可以通过R启动参数调高单对象的内存分配阈值,关闭这个无意义的限制。 - 优化并行计算方案:之前用mclapply没有解决问题,本质是每个并行子进程都会完整加载一份全量训练数据副本,开多进程会快速占满16G内存。并行计算时需要控制进程数不超过2个,且严格采用分块计算逻辑,避免每个进程都加载全量数据。
内容的提问来源于stack exchange,提问作者R7S
相关产品推荐
相关产品推荐

