Hi,
Few things:


self.G.div(input.nelement()) here, div is not an inplace operation, div_ would be inplace (all inplace operation have an _ postscript). So this line is not actually doing anything. You migh want to replace it with self.G = self.G.div(input.nelement()).
When using pytorch, you don’t need to worry about how the backward pass should work. Just write your forward pass doing exactly what you want to do without unpacking Variables. And then just call .backward() on your final loss and it will do a backward corresponding exactly to what you did while computing this loss.
Never unpack Variables otherwise the backward pass cannot be computed: this line self.target.data.resize_as_(self.G.cpu().data).copy_(self.G.cpu().data) should just be self.target = self.G. Similarly, self.target.data.resize_as_(self.G.cpu().data).copy_(self.G.cpu().data).mul_(self.blend_weight.cpu()) should just be self.target = self.G * self.blend_weight. And self.target.data.add(self.blend_weight.cpu(), self.G.data) shuold be self.target = self.target + self.blend_weight * self.G.
I am not sure why you call .cpu(), but that does not look like it is needed here, the criterion can be computed on GPU without any issue.