I am trying to implement the Deep Image Analogy https://arxiv.org/pdf/1705.01088.pdf 16 paper.
The part that I am unable to get to work is the Deconvolution operation that they used (not the same as deconv layer). The logic is as follows:

Initialise noise
Pass through a subset of layers from VGG
Calculate MSE with an existing activations of the same feature map (of another image)
Backpropagate, and update noise

For a forward pass through a subset of VGG , this is what I am using:
def forward_subnet(self, input_tensor, start_layer, end_layer):
        for i, layer in enumerate(list(self.model)):
            if i >= start_layer and i <= end_layer:
                input_tensor = layer(input_tensor)
        return input_tensor

My ‘deconv’ function looks like this :
def get_deconvoluted_feat(feat,feat_layer_num,iters=13):
    feat = cn_first(feat)
    feat = torch.from_numpy(feat)
    
    if feat_layer_num == 5:
        start_layer,end_layer = 20,29
        noise = np.random.normal(size=(1,512,28*1,28*1),scale=3)
    elif feat_layer_num == 4:
        start_layer,end_layer = 11,20
        noise = np.random.normal(size=(1,256,56*1,56*1),scale=3)
    elif feat_layer_num == 3:
        start_layer,end_layer = 6,11
        noise = np.random.normal(size=(1,128,112*1,112*1),scale=3)
    elif feat_layer_num == 2:
        start_layer,end_layer = 1,6
        noise = np.random.normal(size=(1,64,224*1,224*1),scale=3)
    else:
        print("Invalid layer number")
    
    noise = Variable(torch.from_numpy(noise).float(),requires_grad=True)
    noise = noise.cuda()
    noise = nn.Parameter(noise.data.clone(),requires_grad=True)
    optimizer = optim.LBFGS([noise],max_iter=1350,lr=1)

    if not next(model.model.parameters()).is_cuda:
        model.model = model.model.cuda()
    
    feat = Variable(feat).cuda()
    
    loss = nn.MSELoss(size_average=False)
    def closure():
        optimizer.zero_grad()
        output = model.forward_subnet(input_tensor=noise,start_layer=start_layer,end_layer=end_layer)
        loss_valu = loss(output,feat)
        loss_valu.backward()
        loss_hist.append(loss_valu.data.cpu().numpy())
        return loss_valu

    loss_hist = []
    for i in range(iters):
        optimizer.zero_grad()
        optimizer.step(closure)





    pylab.rcParams['figure.figsize'] = (10, 10)
    plt.plot(loss_hist)
    plt.show()
    noise_cpu = noise.cpu().data.squeeze().numpy()
    del feat 
    del noise
    return cn_last(noise_cpu)

The optimised noise is then passed via Patchmatch (which i am fairly confident works)
The output of my whole framework is(This was done on ADAM optimiser, not LBFGS,using LBFGS gives garbage-ish results):

Unknown-4.png587×578 95.5 KB

as compared to :

Screen Shot 2017-10-28 at 12.54.01 PM.png526×520 279 KB

This is a tensorflow version that works identical to the paper :

  
      
      GitHub
  
  
    

akikan/Visual_attribute_transfer_deep_image_analogy_tensorflow 3

Visual Attribute Transfer through Deep Image Analogyを実装してtwitter botにしたものです。 - akikan/Visual_attribute_transfer_deep_image_analogy_tensorflow


  
  
    
    
  
  


If anybody needs more information , ill be more than happy to provide that.
This is a great project, and I want to port it to pytorch real bad. thanks