Ejemplo n.º 1
0
 def eval_c_grad(layer, content):
     nonlocal loss
     feat = content.features[layer][:, start_[0]:end[0],
                                    start_[1]:end[1]]
     c_grad = self.data[layer] - feat
     loss += lw * content_weight[layer] * norm2(c_grad)
     axpy(lw * content_weight[layer], normalize(c_grad),
          self.diff[layer])
Ejemplo n.º 2
0
 def eval_s_grad(layer, style):
     nonlocal loss
     current_gram = gram_matrix(self.data[layer])
     n, mh, mw = self.data[layer].shape
     feat = self.data[layer].reshape((n, mh * mw))
     gram_diff = current_gram - style.grams[layer]
     s_grad = self._arr_pool.array_like(feat)
     np.dot(gram_diff, feat, s_grad)
     s_grad = s_grad.reshape((n, mh, mw))
     loss += lw * style_weight[layer] * norm2(gram_diff) / len(
         self.styles) / 2
     axpy(lw * style_weight[layer] / len(self.styles),
          normalize(s_grad), self.diff[layer])
Ejemplo n.º 3
0
    def eval_sc_grad_tile(self, img, start, layers, content_layers,
                          style_layers, dd_layers, layer_weights,
                          content_weight, style_weight, dd_weight):
        """Evaluates an individual style+content gradient tile."""
        self.net.blobs['data'].reshape(1, 3, *img.shape[-2:])
        self.data['data'] = img
        loss = 0

        # Prepare gradient buffers and run the model forward
        for layer in layers:
            self.diff[layer] = 0
        self.net.forward(end=layers[0])
        self.data[layers[0]] = np.maximum(0, self.data[layers[0]])

        for i, layer in enumerate(layers):
            lw = layer_weights[layer]
            scale, _ = self.layer_info(layer)
            start_ = start // scale
            end = start_ + np.array(self.data[layer].shape[-2:])

            def eval_c_grad(layer, content):
                nonlocal loss
                feat = content.features[layer][:, start_[0]:end[0],
                                               start_[1]:end[1]]
                c_grad = self.data[layer] - feat
                loss += lw * content_weight[layer] * norm2(c_grad)
                axpy(lw * content_weight[layer], normalize(c_grad),
                     self.diff[layer])

            def eval_s_grad(layer, style):
                nonlocal loss
                current_gram = gram_matrix(self.data[layer])
                n, mh, mw = self.data[layer].shape
                feat = self.data[layer].reshape((n, mh * mw))
                gram_diff = current_gram - style.grams[layer]
                s_grad = self._arr_pool.array_like(feat)
                np.dot(gram_diff, feat, s_grad)
                s_grad = s_grad.reshape((n, mh, mw))
                loss += lw * style_weight[layer] * norm2(gram_diff) / len(
                    self.styles) / 2
                axpy(lw * style_weight[layer] / len(self.styles),
                     normalize(s_grad), self.diff[layer])

            # Compute the content and style gradients
            if layer in content_layers:
                for content in self.contents:
                    eval_c_grad(layer, content)
            if layer in style_layers:
                for style in self.styles:
                    eval_s_grad(layer, style)
            if layer in dd_layers:
                loss -= lw * dd_weight[layer] * norm2(self.data[layer])
                axpy(-lw * dd_weight[layer], normalize(self.data[layer]),
                     self.diff[layer])

            # Run the model backward
            if i + 1 == len(layers):
                self.net.backward(start=layer)
            else:
                self.net.backward(start=layer, end=layers[i + 1])

        return loss, self.diff['data']