首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何处理火炬中的GPU内存泄漏问题?

如何处理火炬中的GPU内存泄漏问题?
EN

Stack Overflow用户
提问于 2016-04-03 20:29:12
回答 1查看 1.6K关注 0票数 4

我的机器的GPU有2GB的内存。当我第一次运行以下代码时,不会出现错误。但是,当我第二次运行代码时,我会得到内存错误。作为一种短期的补救措施,我唯一能做的就是使用torch.Tensor.float()将数据转换到torch.Tensor.float()中。但是,问题仍然存在,进程完成后没有释放占用的内存,或者进程在运行时终止。这也是机器RAM的情况。如何防止火炬中的记忆泄漏或释放记忆?

代码语言:javascript
复制
require 'nn'
require 'image'
require 'cunn'
require 'paths'



collectgarbage(); collectgarbage()
if (not paths.filep("cifar10torchsmall.zip")) then
    os.execute('wget -c https://s3.amazonaws.com/torch7/data/cifar10torchsmall.zip')
    os.execute('unzip cifar10torchsmall.zip')
end
trainset = torch.load('cifar10-train.t7')
testset = torch.load('cifar10-test.t7')
classes = {'airplane', 'automobile', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck'}

setmetatable(trainset, 
    {__index = function(t, i) 
                    return {t.data[i], t.label[i]} 
                end}
);
trainset.data = trainset.data:double() -- convert the data from a ByteTensor to a DoubleTensor.

function trainset:size() 
    return self.data:size(1) 
end

mean = {} -- store the mean, to normalize the test set in the future
stdv  = {} -- store the standard-deviation for the future
for i=1,3 do -- over each image channel
    mean[i] = trainset.data[{ {}, {i}, {}, {}  }]:mean() -- mean estimation
    print('Channel ' .. i .. ', Mean: ' .. mean[i])
    trainset.data[{ {}, {i}, {}, {}  }]:add(-mean[i]) -- mean subtraction

    stdv[i] = trainset.data[{ {}, {i}, {}, {}  }]:std() -- std estimation
    print('Channel ' .. i .. ', Standard Deviation: ' .. stdv[i])
    trainset.data[{ {}, {i}, {}, {}  }]:div(stdv[i]) -- std scaling
end


testset.data = testset.data:double()   -- convert from Byte tensor to Double tensor
for i=1,3 do -- over each image channel
    testset.data[{ {}, {i}, {}, {}  }]:add(-mean[i]) -- mean subtraction    
    testset.data[{ {}, {i}, {}, {}  }]:div(stdv[i]) -- std scaling
end

trainset.data = trainset.data:cuda()
testset.data = testset.data:cuda()

net = nn.Sequential()
net:add(nn.SpatialConvolution(3, 6, 5, 5)) -- 3 input image channels, 6 output channels, 5x5 convolution kernel
net:add(nn.ReLU())                       -- non-linearity 
net:add(nn.SpatialMaxPooling(2,2,2,2))     -- A max-pooling operation that looks at 2x2 windows and finds the max.
net:add(nn.SpatialConvolution(6, 16, 5, 5))
net:add(nn.ReLU())                       -- non-linearity 
net:add(nn.SpatialMaxPooling(2,2,2,2))
net:add(nn.View(16*5*5))                    -- reshapes from a 3D tensor of 16x5x5 into 1D tensor of 16*5*5
net:add(nn.Linear(16*5*5, 120))             -- fully connected layer (matrix multiplication between input and weights)
net:add(nn.ReLU())                       -- non-linearity 
net:add(nn.Linear(120, 84))
net:add(nn.ReLU())                       -- non-linearity 
net:add(nn.Linear(84, 10))                   -- 10 is the number of outputs of the network (in this case, 10 digits)
net:add(nn.LogSoftMax())  
net = net:cuda()

criterion = nn.ClassNLLCriterion()
criterion = criterion:cuda()



pred = net:forward(trainset.data)
outputEr = criterion:forward(pred, trainset.label:cuda())
net:zeroGradParameters()
outputGrad = criterion:backward(pred, trainset.label:cuda())
collectgarbage()
inputGrad = net:backward(trainset.data, outputGrad)

附带问题:为什么火炬将网络参数初始化为双倍,尽管GPU在计算双精度操作方面非常慢,而且几乎所有的神经网络应用程序都不需要64位参数值?如何使用浮动(32位)参数向量初始化模型?

我找到了这个问题的答案。您可以在代码开始时使用以下代码轻松地将torch的默认数据类型设置为浮动:

代码语言:javascript
复制
torch.setdefaulttensortype('torch.FloatTensor')
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-08 00:15:44

我可以解决这个问题(几乎)从CUDA 6.5升级到CUDA 7.5在机器上,我正在做上述实验。现在,在大多数情况下,当程序崩溃时,运行GPU内存将被释放。然而,有时它不会发生,我不得不重新启动机器。

此外,为了确保程序在程序成功运行时清除GPU内存,我将执行以下操作:

代码语言:javascript
复制
net = nil
trainset = nil
testset = nil
pred = nil
inputGrad = nil
criterion = nil

collectgarbage()
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36390776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档