@albanD

Why do you pass the image to an optimizer?

I’m using this setup for things like neural style transfer and DeepDream visualization, which requires a single image:
    img = nn.Parameter(img)
    num_iterations = 1000

    num_calls = [0]
    def feval():
        num_calls[0] += 1
        optimizer.zero_grad()
        net(img) # Run input through CNN
        loss = 0

        for mod in loss_list:
            loss += mod.loss # Get loss from layers with nn.MSELoss() loss variable

        loss.backward()

        print('Iteration', num_calls[0], 'loss', loss.item())
        return loss

    optimizer = optim.Adam([img], lr = learning_rate)
    while num_calls[0] <= num_iterations:
         optimizer.step(feval)

This strategy was done a lot in the original Torch7, and “feval” was what the “closure” function was called back then.

Keep in mind that optimizer’s steps are not differentiable and no gradients will be able to flow back.

So, how would I make this mini network that I created using Functional.Conv2d work then?
    weight_val = nn.Parameter(torch.randn(num_channels,2,1,1))
    tensor = F.conv2d(tensor, weight_val).tanh()
    for i in range(num_layers):
        weight_val = nn.Parameter(torch.randn(num_channels,num_channels,1,1))
        tensor = F.conv2d(tensor, weight_val).tanh()
    weight_val = nn.Parameter(torch.randn(3,num_channels,1,1))
    tensor = F.conv2d(tensor, weight_val).sigmoid()

I was originally using a class (with nn.Conv2d), but that didn’t seem to work.