2016-04-03 18 views
3

私のマシンのGPUには2 GBのメモリがあります。初めて次のコードを実行すると、エラーは発生しません。しかし、コードを2回実行すると、メモリエラーが発生します。私ができる唯一のことは、短時間の対策として、torch.Tensor.float()を使ってfloat32にデータをキャストすることです。ただし、問題が引き続き発生し、プロセスの実行後に占有メモリが解放されないか、実行中にプロセスが終了します。これはマシンRAMの場合も同様です。 Torchのメモリリークを防ぐ方法やメモリを解放する方法はありますか?TorchでGPUのメモリリークの問題を処理する方法は?

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ビットパラメータ値を持つ必要は実際には存在しないがトーチをdoubleとしてネットワークパラメータを初期化するのはなぜ?浮動小数点(32ビット)パラメータベクトルを使用してモデルを初期化するにはどうすればよいですか?

私は副次的な質問に対する答えを見つけました。私は私がやっていたマシン上でCUDA 7.5 CUDA 6.5からアップグレードすることで問題を(ほぼ)解決することができ

torch.setdefaulttensortype('torch.FloatTensor') 

答えて

1

:あなたは簡単にあなたのコードの先頭に次を使用してfloatとしてトーチのデフォルトのデータ型を作ることができます上記の実験。さて、ほとんどの場合、GPUの実行中にプログラムがクラッシュするとメモリが解放されます。しかし、時にはそれは起こらず、マシンを再起動する必要があります。

また、私は、プログラムが正常に実行されたときにプログラムがGPUのメモリをクリアを確認するために、以下の操作を行います。

net = nil 
trainset = nil 
testset = nil 
pred = nil 
inputGrad = nil 
criterion = nil 

collectgarbage()