1

Ich habe ein konvolutionelles neuronales Netzwerk, dessen Ausgabe ein 4-Kanal-2D-Bild ist. Ich möchte Sigmoid-Aktivierungsfunktion auf die ersten beiden Kanäle anwenden und dann BCECRiterion verwenden, um den Verlust der erzeugten Bilder mit den Grundwahrheiten zu computerisieren. Ich möchte die quadratische Verlustfunktion auf die letzten beiden Kanäle anwenden und schließlich die Gradienten berechnen und Backprop durchführen. Ich möchte auch die Kosten des quadratischen Verlustes für jeden der beiden letzten Kanäle mit einem gewünschten Skalar multiplizieren.Wie kann man verschiedene Kostenfunktionen auf verschiedene Ausgangskanäle eines Faltungsnetzwerkes anwenden?

So sind die Kosten hat die folgende Form:

cost = crossEntropyCh[{1, 2}] + l1 * squaredLossCh_3 + l2 * squaredLossCh_4 

Die Art, wie ich darüber denke tun, ist wie folgt:

criterion1 = nn.BCECriterion() 
criterion2 = nn.MSECriterion() 

error = criterion1:forward(model.output[{{}, {1, 2}}], groundTruth1) + l1 * criterion2:forward(model.output[{{}, {3}}], groundTruth2) + l2 * criterion2:forward(model.output[{{}, {4}}], groundTruth3) 

Aber ich glaube nicht, das ist die richtige ist Ich mache drei separate Backprop-Schritte, einen für jede der Kostenbedingungen. Also frage ich mich, kann mir jemand eine bessere Lösung geben, dies in Torch zu tun?

Antwort

2

SplitTable und ParallelCriterion könnte für Ihr Problem hilfreich sein.

Auf Ihre aktuelle Ausgabeschicht folgt nn.SplitTable, die Ihre Ausgabekanäle aufteilt und Ihren Ausgabentensor in eine Tabelle umwandelt. Sie können verschiedene Funktionen auch kombinieren, indem Sie ParallelCriterion verwenden, damit jedes Kriterium auf den entsprechenden Eintrag der Ausgabetabelle angewendet wird.

Für Details, empfehle ich Ihnen, Dokumentation der Fackel über Tabellen zu lesen.

Nach den Kommentaren habe ich das folgende Code-Segment hinzugefügt, das die ursprüngliche Frage löst.

M = 100 
C = 4 
H = 64 
W = 64 
dataIn = torch.rand(M, C, H, W) 

layerOfTables = nn.Sequential() 
-- Because SplitTable discards the dimension it is applied on, we insert 
-- an additional dimension. 
layerOfTables:add(nn.Reshape(M,C,1,H,W)) 
-- We want to split over the second dimension (i.e. channels). 
layerOfTables:add(nn.SplitTable(2, 5)) 

-- We use ConcatTable in order to create paths accessing to the data for 
-- numereous number of criterions. Each branch from the ConcatTable will 
-- have access to the data (i.e. the output table). 
criterionPath = nn.ConcatTable() 
-- Starting from offset 1, NarrowTable will select 2 elements. Since you 
-- want to use this portion as a 2 dimensional channel, we need to combine 
-- then by using JoinTable. Without JoinTable, the output will be again a 
-- table with 2 elements. 
criterionPath:add(nn.Sequential():add(nn.NarrowTable(1, 2)):add(nn.JoinTable(2))) 
-- SelectTable is simplified version of NarrowTable, and it fetches the desired element. 
criterionPath:add(nn.SelectTable(3)) 
criterionPath:add(nn.SelectTable(4)) 

layerOfTables:add(criterionPath) 

-- Here goes the criterion container. You can use this as if it is a regular 
-- criterion function (Please see the examples on documentation page). 
criterionContainer = nn.ParallelCriterion() 
criterionContainer:add(nn.BCECriterion()) 
criterionContainer:add(nn.MSECriterion()) 
criterionContainer:add(nn.MSECriterion()) 

Da ich fast alle möglichen Tabellenoperationen verwendet habe, sieht es ein bisschen eklig aus. Dies ist jedoch die einzige Möglichkeit, dieses Problem zu lösen. Ich hoffe, dass es Ihnen und anderen hilft, das gleiche Problem zu haben. So sieht das Ergebnis aus:

dataOut = layerOfTables:forward(dataIn) 
print(dataOut) 
{ 
    1 : DoubleTensor - size: 100x2x64x64 
    2 : DoubleTensor - size: 100x1x64x64 
    3 : DoubleTensor - size: 100x1x64x64 
} 
+0

Ich glaube nicht, dass dies der richtige Weg ist. Wenn ich nn.SplitTable (2) zu meiner Ausgabe hinzufüge, gibt es mir eine Tabelle mit 4 Elementen. Jedes Element enthält ein 2D-Bild. Ich möchte jedoch eine Kostenfunktion auf die ersten beiden Elemente der Tabelle anwenden, eine weitere Kostenfunktion auf den dritten Kanal und eine weitere Kostenfunktion auf die letzte. Wie würdest du das umsetzen? – Amir

+0

Lassen Sie uns das Problem etwas einfacher machen: Angenommen, ich habe ein Faltungsdecoder-Netzwerk, das einen Tensor mit der Größe [M x C x H x W] ausgibt, wobei M die Losgröße ist, C die Anzahl der Kanäle (ein Vielfaches von 2) und H = W ist eine ganze Zahl. Ich möchte die Ausgabe in eine Tabelle mit zwei Elementen teilen, wobei jedes Element die Größe [M x C/2 x H x W] hat. Ich denke, es ist möglich, mit nn.SplitTable() fertig zu werden, aber ich habe es nicht richtig gemacht. Nach dem Aufteilen der Tensoren möchte ich zwei Kostenfunktionen anwenden (dieser Teil ist einfach). Kannst du mir ein paar Hinweise geben? – Amir

Verwandte Themen