pytorch / tutorials

PyTorch tutorials.
https://pytorch.org/tutorials/
BSD 3-Clause "New" or "Revised" License
8.19k stars 4.06k forks source link

Neural style transfer question #123

Closed reiinakano closed 7 years ago

reiinakano commented 7 years ago

Hi, not sure if this is the right place to ask questions, but I'm working through the neural style transfer tutorial and am confused about something.

What is the purpose of the backward method in ContentLoss and StyleLoss?

If we remove the backward method, won't this work as well for the closure function in run_style_transfer?

    def closure():
            # correct the values of updated input image
            input_param.data.clamp_(0, 1)

            optimizer.zero_grad()
            model(input_param)
            style_score = 0
            content_score = 0

            for sl in style_losses:
                style_score += sl.loss
            for cl in content_losses:
                content_score += cl.loss

            run[0] += 1
            if run[0] % 50 == 0:
                print("run {}:".format(run))
                print('Style Loss : {:4f} Content Loss: {:4f}'.format(
                    style_score.data[0], content_score.data[0]))
                print()

            total_score = style_score+content_score
            total_score.backward()

            return total_score

On a related note, won't multiple backward calls in the original code accumulate the gradients for the image? Why is it okay to do this? Am I wrong in assuming that you should only call backward once? I'm new to Pytorch so I apologize if I'm missing anything fundamental. Thanks!

EDIT: Tagging the author @alexis-jacq if you don't mind :)

alexis-jacq commented 7 years ago

as soon as torch does not tell:

"RuntimeError: Trying to backward through the graph second time, but the buffers have already been freed. Please specify retain_variables=True when calling backward for the first time."

then you are not accumulating gradients. It works because the different losses are not sharing any parameters. But you are right, The code could be cleaner with a single call of backward. Actually did this tutorial when I discovered Pytorch, so it has been written with clumsiness. When I will have time, I will make a nicer version.

reiinakano commented 7 years ago

Cool. Thanks!