I have to implement a Convolutional Neural Network, that takes a kinect image (1640480) and return a 1 x8 tensor predicting the class to which the object belongs and a 1 x 4 tensor, predicting the bounding box around the image, if its present.
Please help me how can I implement a suitable model to give two outputs and how to calculate loss and backpropagate in that case?
Also, i have just around 6000 training images, how can I achieve the best possible results with limited number of training images??
Some examples of such projects would be highly helpful.
Multiple outputs is pretty straightforward. Just return mutiple values in the
forward() method of your net.
def forward(self, x):
# Do your stuff here
x1 = F.log_softmax(x) # class probabilities
x2 = ... # bounding box calculation
return x1, x2
Using these two outputs, you can define two different loss functions and just add them.
out1, out2 = model(data)
loss1 = criterion1(out1, target1)
loss2 = criterion2(out2, target2)
loss = loss1 + loss2
please dont tag folks generically, it’s not helpful
I am sorry for that
Actually , I still don
t understand your idea about tag folks, does it mean the forward function from ptrblcks example sets tow return value or his loss function uses tow loss addition ？ can you explain it in detail ？ can you give a example code ？
Thank you very much
Hi, can we pack the returned tensors in list format? Such as:
list = [x1, x2]
Or, we must return tensor class type in forward method?
Yes, you can also return a list. Here is a small dummy example:
self.fc1 = nn.Linear(1, 1)
def forward(self, x):
y = self.fc1(x)
return [y, x]
model = MyModel()
x = torch.randn(1, 1)
outputs = model(x)
Thank you so much for your quick help!
I was going through the keras documentation
As you can see this is an example of multi-output multi input model.The thing in this example is that the auxiliary output has a loss function .This output is then further used in the model to compute the main_output.
How can I implement some thing like this in Pytorch
You could just re-write the forward pass in your model similar to this:
def forward(self, main_input, aux_input):
main_input = self.embedding_1(main_input)
main_input = self.lstm(main_input, (self.hidden, self.state))
aux = self.aux_output(main_input)
aux_input = self.input_layer(aux_input)
x = torch.cat((aux_input, main_input))
x = F.relu(self.dense_1(x))
x = F.relu(self.dense_2(x))
x = F.relu(self.dense_3(x))
x = self.main_output(x)
return x, aux
Oh okay .Thanks a lot.
Can I also use two different loss functions one on auxiliary_output and one on main_output as shown in the keras link and then add them in the end.
Sure, that should also work!
Let me know, if you encounter any problems.
I would like to do the same, but accumulate loss in a loop as my model’s forward function returns a list of outputs.
My question is, how do I initialize the “loss” variable so that I can accumulate in a loop?
If your model returns multiple outputs, you could calculate the loss separately for each output and then just accumulate it:
output1, output2, output3 = model(data)
loss1 = criterion1(output1, target1)
loss2 = criterion2(output2, target2)
loss3 = criterion3(output3, target3)
loss = loss1 + loss2 + loss3
outputs = model(data)
loss = 0
for output, target, criterion in zip(outputs, targets, criteria):
loss = loss + criterion(output, target)
Little confused about the accumulation “+”:
So when I write loss = loss1 + loss2, the network knows that I want loss1 to backpropagate through output1, and loss2 to go thru output2, the sequence matters, am I right?
The addition is treated as any other operation in your model, so Autograd will calculate the gradients based on the derivative of the loss accumulation.
If the outputs are independent, your assumption is correct.
hey , i have a problem with “Assertion `cur_target >= 0 && cur_target < n_classes’ failed. at /pytorch/aten/src/THNN/generic/ClassNLLCriterion.c:97” which is still persisting even i tried many solutions found on internet.
Could you print the target values of your current batch inside the training loop and check, if they are all in the range
If you run the code with
num_workers=0, the last printed target should be the one causing this error.
It start counting from 1.