0

Ich fahre von Theano nach Torch. Also bitte bitte mit mir. In Theano war es irgendwie einfach, die Gradienten der Verlustfunktion selbst eines bestimmten Gewichts zu berechnen. Ich frage mich, wie kann man das in Torch machen?Wie berechnet man den Verlustgradienten in Bezug auf eine beliebige Schicht/Gewicht in Torch?

Angenommen wir den folgenden Code haben, die einige Daten/Etiketten und definiert ein Modell erzeugt:

t = require 'torch' 
require 'nn' 
require 'cunn' 
require 'cutorch' 



-- Generate random labels 
function randLabels(nExamples, nClasses) 
    -- nClasses: number of classes 
    -- nExamples: number of examples 
    label = {} 
    for i=1, nExamples do 
     label[i] = t.random(1, nClasses) 
    end 
    return t.FloatTensor(label) 
end 

inputs = t.rand(1000, 3, 32, 32) -- 1000 samples, 3 color channels 
inputs = inputs:cuda() 
labels = randLabels(inputs:size()[1], 10) 
labels = labels:cuda() 

net = nn.Sequential() 
net:add(nn.SpatialConvolution(3, 6, 5, 5)) 
net:add(nn.ReLU()) 
net:add(nn.SpatialMaxPooling(2, 2, 2, 2)) 
net:add(nn.View(6*14*14)) 
net:add(nn.Linear(6*14*14, 300)) 
net:add(nn.ReLU()) 
net:add(nn.Linear(300, 10)) 
net = net:cuda() 

-- Loss 
criterion = nn.CrossEntropyCriterion() 
criterion = criterion:cuda() 
forwardPass = net:forward(inputs) 
net:zeroGradParameters() 
dEd_WeightsOfLayer1 -- How to compute this? 



forwardPass = nil 
net = nil 
criterion = nil 
inputs = nil 
labels = nil 

collectgarbage() 

Wie kann ich den Gradienten w.r.t Gewichte convolutinal Schicht berechnen?

Antwort

0

Okay, ich fand die Antwort (danke an Alban Desmaison auf Torch7 Google-Gruppe). Der Code in der Frage hat einen Fehler und funktioniert nicht. Also schreibe ich den Code neu. Hier ist, wie Sie die Gradienten in Bezug auf jeden Knoten/Parameter erhalten kann:

t = require 'torch' 
require 'cunn' 
require 'nn' 
require 'cutorch' 



-- A function to generate some random labels 
function randLabels(nExamples, nClasses) 
    -- nClasses: number of classes 
    -- nExamples: number of examples 
    label = {} 
    for i=1, nExamples do 
     label[i] = t.random(1, nClasses) 
    end 
    return t.FloatTensor(label) 
end 

-- Declare some variables 
nClass = 10 
kernelSize = 5 
stride = 2 
poolKernelSize = 2 
nData = 100 
nChannel = 3 
imageSize = 32 

-- Generate some [random] data 
data = t.rand(nData, nChannel, imageSize, imageSize) -- 100 Random images with 3 channels 
data = data:cuda() -- Transfer to the GPU (remove this line if you're not using GPU) 
label = randLabels(data:size()[1], nClass) 
label = label:cuda() -- Transfer to the GPU (remove this line if you're not using GPU) 

-- Define model 
net = nn.Sequential() 
net:add(nn.SpatialConvolution(3, 6, 5, 5)) 
net:add(nn.ReLU()) 
net:add(nn.SpatialMaxPooling(poolKernelSize, poolKernelSize, stride, stride)) 
net:add(nn.View(6*14*14)) 
net:add(nn.Linear(6*14*14, 350)) 
net:add(nn.ReLU()) 
net:add(nn.Linear(350, 10)) 
net = net:cuda() -- Transfer to the GPU (remove this line if you're not using GPU) 

criterion = nn.CrossEntropyCriterion() 
criterion = criterion:cuda() -- Transfer to the GPU (remove this line if you're not using GPU) 

-- Do forward pass and get the gradient for each node/parameter: 

net:forward(data) -- Do the forward propagation 
criterion:forward(net.output, label) -- Computer the overall negative log-likelihood error 
criterion:backward(net.output, label); -- Don't forget to put ';'. Otherwise you'll get everything printed on the screen 
net:backward(data, criterion.gradInput); -- Don't forget to put ';'. Otherwise you'll get everything printed on the screen 

-- Now you can access the gradient values 

layer1InputGrad = net:get(1).gradInput 
layer1WeightGrads = net:get(1).gradWeight 

net = nil 
data = nil 
label = nil 
criterion = nil 

Kopieren und fügen Sie den Code und es funktioniert wie Charme :)

Verwandte Themen