pystiche.loss

class pystiche.loss.Loss(*, encoder=None, input_guide=None, score_weight=1.0)

Bases: pystiche.core._modules.Module, abc.ABC

Abstract base class for all losses.

abstract forward(input_image)

Defines the computation performed at every call.

Should be overridden by all subclasses.

Note

Although the recipe for forward pass needs to be defined within this function, one should call the Module instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.

Return type

Union[Tensor, LossDict]

set_input_guide(guide)
Return type

None

class pystiche.loss.RegularizationLoss(*, encoder=None, input_guide=None, score_weight=1.0)

Bases: pystiche.loss._loss.Loss

Abstract base class for all regularization losses.

abstract calculate_score(input_repr)
Return type

Tensor

abstract input_enc_to_repr(enc)
Return type

Tensor

class pystiche.loss.ComparisonLoss(*, encoder=None, input_guide=None, target_image=None, target_guide=None, score_weight=1.0)

Bases: pystiche.loss._loss.Loss

Abstract base class for all comparison losses.

abstract calculate_score(input_repr, target_repr, *, ctx)
Return type

Tensor

abstract input_enc_to_repr(enc, ctx)
Return type

Tensor

set_target_image(image, *, guide=None)
Return type

None

abstract target_enc_to_repr(enc)
Return type

Tuple[Tensor, Optional[Tensor]]

Container

class pystiche.loss.LossContainer(named_losses, *, input_guide=None, target_image=None, target_guide=None, score_weight=1.0)

Generic container for Loss’es.

If called with an image, it will be passes it to all immediate losses and returns a pystiche.LossDict scaled with score_weight.

Parameters
  • named_losses (Sequence[Tuple[str, Loss]]) – Named immediate losses that will be called if OperatorContainer is called.

  • score_weight (float) – Score weight of the loss. Defaults to 1.0.

class pystiche.loss.MultiLayerEncodingLoss(mle, layers, encoding_loss_fn, *, layer_weights='mean', input_guide=None, target_image=None, target_guide=None, score_weight=1.0)

Convenience container for multiple Loss’es operating on different layers of the same pystiche.enc.MultiLayerEncoder.

Parameters
  • mle (MultiLayerEncoder) – Multi-layer encoder.

  • layers (Sequence[str]) – Layers of the mle that the children losses operate on.

  • encoding_loss_fn (Callable[[Encoder, float], Loss]) – Callable that returns a loss given a pystiche.enc.SingleLayerEncoder extracted from the mle and its corresponding layer weight.

  • layer_weights (Union[str, Sequence[float]]) – Weights passed to encoding_loss_fn. If "sum", each layer weight is set to 1.0. If "mean", each layer weight is set to 1.0 / len(layers). If sequence of float``s its length has to match ``layers’ length. Defaults to "mean".

  • score_weight (float) – Score weight of the loss. Defaults to 1.0.

Examples

>>> mle = pystiche.enc.vgg19_multi_layer_encoder()
>>> layers = ("relu1_1", "relu2_1", "relu3_1", "relu4_1", "relu5_1")
>>> loss = pystiche.loss.MultiLayerEncodingLoss(
...     mle,
...     layers,
...     lambda encoder, layer_weight: pystiche.loss.GramLoss(
...         encoder, score_weight=layer_weight
...     ),
... )
>>> input = torch.rand(2, 3, 256, 256)
>>> target = torch.rand(2, 3, 256, 256)
>>> loss.set_target_image(target)
>>> score = loss(input)
class pystiche.loss.MultiRegionLoss(regions, region_loss_fn, *, region_weights='sum', input_guide=None, target_image=None, target_guide=None, score_weight=1.0)

Convenience container for multiple Loss’es operating in different regions.

Parameters
  • regions (Sequence[str]) – Regions.

  • region_loss_fn (Callable[[str, float], Loss]) – Callable that returns a children loss given a region and its corresponding weight.

  • region_weights (Union[str, Sequence[float]]) – Weights passed to region_loss_fn. If "sum", each region weight is set to 1.0. If "mean", each region weight is set to 1.0 / len(layers). If sequence of float``s its length has to match ``regions’ length. Defaults to "mean".

  • score_weight (float) – Score weight of the loss. Defaults to 1.0.

Examples

>>> mle = pystiche.enc.vgg19_multi_layer_encoder()
>>> layers = ("relu1_1", "relu2_1", "relu3_1", "relu4_1", "relu5_1")
>>> def encoding_loss_fn(encoder, layer_weight):
...     return pystiche.loss.GramLoss(encoder, score_weight=layer_weight)
>>> regions = ("sky", "landscape")
>>> def region_loss_fn(region, region_weight):
...     return pystiche.loss.MultiLayerEncodingLoss(
...         mle,
...         layers,
...         encoding_loss_fn,
...         score_weight=region_weight,
...     )
>>> loss = pystiche.loss.MultiRegionLoss(regions, region_loss_fn)
>>> loss.set_regional_target_image("sky", torch.rand(2, 3, 256, 256))
>>> loss.set_regional_target_image("landscape", torch.rand(2, 3, 256, 256))
>>> input = torch.rand(2, 3, 256, 256)
>>> score = loss(input)
set_regional_input_guide(region, guide)

Invokes set_input_guide() on the operator of the given region.

Parameters
  • region (str) – Region.

  • guide (Tensor) – Input guide of shape \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} 1 \times 1 \times H \times W\).

Return type

None

set_regional_target_image(region, image, guide=None)

Invokes set_target_image() on the operator of the given region.

Parameters
  • region (str) – Region.

  • image (Tensor) – Input guide of shape \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} B \times C \times H \times W\).

  • guide (Optional[Tensor]) –

Return type

None

class pystiche.loss.PerceptualLoss(content_loss, style_loss, regularization=None, *, content_image=None, content_guide=None, style_image=None, style_guide=None)

Perceptual loss comprising content and style loss as well as optionally a regularization.

Parameters
regional_content_guide(region=None)

Regional content guide.

Parameters

region (Optional[str]) – Region to get the content guide from.

Return type

Optional[Tensor]

regional_style_image(region=None)

Regional style image.

Parameters

region (Optional[str]) – Region to get the style image from.

Return type

Optional[Tensor]

set_content_guide(guide, *, region=None)

Sets the content guide.

Parameters
  • guide (Tensor) – Content guide.

  • region (Optional[str]) – Optional region to set the guide for. If omitted, the guide will be applied to all regions.

Return type

None

set_style_image(image, *, guide=None, region=None)

Sets the style image and guide.

Parameters
  • image (Tensor) – Style image.

  • guide (Optional[Tensor]) – Style guide.

  • region (Optional[str]) – Optional region to set the image and guide for. If omitted, the image and guide will be applied to all regions.

Return type

None

Regularization

class pystiche.loss.TotalVariationLoss(*, exponent=2.0, input_guide=None, score_weight=1.0)

Bases: pystiche.loss._loss.RegularizationLoss

The total variation loss is a regularizer used to suppress checkerboard artifacts by penalizing the gradient of the image. It is calculated by

\[\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \mean[\limits_{i,j}] \parentheses{\parentheses{x_{i,j+1} - x_{i,j}}^2 + \parentheses{x_{i+1,j} - x_{i,j}}^2}^{\frac{\beta}{2}}\]

where \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} x\) denotes the image and \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} i,j\) index a specific pixel.

Note

Opposed to the paper, the implementation calculates the grand average \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \mean\) opposed to the grand sum \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \sum\) to account for different sized images.

Parameters
  • exponent (float) – Parameter \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \beta\) . A higher value leads to more smoothed results. Defaults to 2.0.

  • score_weight (float) – Score weight of the operator. Defaults to 1.0.

Examples

>>> loss = pystiche.loss.TotalVariationLoss()
>>> input = torch.rand(2, 3, 256, 256)
>>> score = loss(input)

See also

The total variation loss was introduced by Mahendran and Vedaldi in [MV2015] .

Comparison

class pystiche.loss.FeatureReconstructionLoss(encoder, *, input_guide=None, target_image=None, target_guide=None, score_weight=1.0)

Bases: pystiche.loss._loss.ComparisonLoss

The feature reconstruction loss is the de facto standard content loss. It measures the mean squared error (MSE) between the encodings of an input_image \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \hat{I}\) and a target_image \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} I\) :

\[\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \mean \parentheses{\Phi\of{\hat{I}} - \Phi\of{I}}^2\]

Here \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \Phi\of{\cdot}\) denotes the encoder.

Note

Opposed to the paper, the implementation calculates the grand average \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \mean\) opposed to the grand sum \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \sum\) to account for different sized images.

Parameters
  • encoder (Encoder) – Encoder \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \Phi\).

  • score_weight (float) – Score weight of the operator. Defaults to 1.0.

Examples

>>> mle = pystiche.enc.vgg19_multi_layer_encoder()
>>> encoder = mle.extract_encoder("relu4_2")
>>> loss = pystiche.loss.FeatureReconstructionLoss(encoder)
>>> input = torch.rand(2, 3, 256, 256)
>>> target = torch.rand(2, 3, 256, 256)
>>> loss.set_target_image(target)
>>> score = loss(input)

See also

The feature reconstruction loss was introduced by Mahendran and Vedaldi in [MV2015] , but its name was coined by Johnson, Alahi, and Fei-Fei in [JAL2016] .

class pystiche.loss.GramLoss(encoder, *, normalize=True, input_guide=None, target_image=None, target_guide=None, score_weight=1.0)

Bases: pystiche.loss._loss.ComparisonLoss

The gram loss is a style loss based on the correlation of feature map channels. It measures the mean squared error (MSE) between the channel-wise Gram matrices of the encodings of an input_image \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \hat{I}\) and a target_image \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} I\):

\[\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \mean \parentheses{\fun{gram}{\Phi\of{\hat{I}}} - \fun{gram}{\Phi\of{I}}}^2\]

Here \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \Phi\of{\cdot}\) denotes the encoder and \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \fun{gram}{\cdot}\) denotes pystiche.gram_matrix().

Note

Opposed to the paper, the implementation calculates the grand average \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \mean\) opposed to the grand sum \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \sum\) to account for different sized images.

Parameters
  • encoder (Encoder) – Encoder \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \Phi\left( \cdot \right)\).

  • normalize (bool) – If True, normalizes the Gram matrices to account for different sized images. See pystiche.gram_matrix() for details. Defaults to True.

  • score_weight (float) – Score weight of the operator. Defaults to 1.0.

Examples

>>> mle = pystiche.enc.vgg19_multi_layer_encoder()
>>> encoder = mle.extract_encoder("relu4_2")
>>> loss = pystiche.loss.GramLoss(encoder)
>>> input = torch.rand(2, 3, 256, 256)
>>> target = torch.rand(2, 3, 256, 256)
>>> loss.set_target_image(target)
>>> score = loss(input)

See also

The feature reconstruction loss was introduced by Gatys, Ecker, and Bethge in [GEB2016] .

class pystiche.loss.MRFLoss(encoder, patch_size, *, stride=1, target_transforms=None, input_guide=None, target_image=None, target_guide=None, score_weight=1.0)

Bases: pystiche.loss._loss.ComparisonLoss

The MRF loss is a style loss based on Markov Random Fields (MRFs). It measures the mean squared error (MSE) between neural patches extracted from the encodings of an input_image \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \hat{I}\) and a target_image \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} I\):

\[\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \mean \parentheses{p_n\of{\Phi\of{\hat{I}}} - p_{MCS\of{n}}\of{\Phi\of{\hat{I}}}}^2\]

Since the number of patches might be different for both images and the order of the patches does not correlate with the order of the enclosed style element, for each input neural patch \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} n\) a fitting target neural patch is to selected based on the maximum cosine similarity \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} MCS\of{n}\) with pystiche.cosine_similarity().

Note

Opposed to the paper, the implementation calculates the grand average \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \mean\) opposed to the grand sum \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \sum\) to account for different sized images.

Parameters
  • encoder (Encoder) – Encoder \(\newcommand{\parentheses}[1]{\left( #1 \right)} \newcommand{\brackets}[1]{\left[ #1 \right]} \newcommand{\mean}[1][]{\overline{\sum #1}} \newcommand{\fun}[2]{\text{#1}\of{#2}} \newcommand{\of}[1]{\parentheses{#1}} \newcommand{\dotproduct}[2]{\left\langle #1 , #2 \right\rangle} \newcommand{\openinterval}[2]{\parentheses{#1, #2}} \newcommand{\closedinterval}[2]{\brackets{#1, #2}} \Phi\) .

  • patch_size (Union[int, Sequence[int]]) – Spatial size of the neural patches.

  • stride (Union[int, Sequence[int]]) – Distance between two neural patches.

  • target_transforms (Optional[Iterable[Module]]) – Optional transformations to apply to the target image before the neural patches are extracted. Defaults to None.

  • score_weight (float) – Score weight of the operator. Defaults to 1.0.

Examples

>>> mle = pystiche.enc.vgg19_multi_layer_encoder()
>>> encoder = mle.extract_encoder("relu4_2")
>>> patch_size = 3
>>> loss = pystiche.loss.MRFLoss(encoder, patch_size)
>>> input = torch.rand(2, 3, 256, 256)
>>> target = torch.rand(2, 3, 256, 256)
>>> loss.set_target_image(target)
>>> score = loss(input)

See also

The MRF loss was introduced by Li and Wand in [LW2016].

static scale_and_rotate_transforms(num_scale_steps=1, scale_step_width=0.05, num_rotate_steps=1, rotate_step_width=10.0)

Generate a list of scaling and rotations transformations.

See also

The output of this method can be used as parameter target_transforms of MRFLoss to enrich the space of target neural patches:

target_transforms = MRFOperator.scale_and_rotate_transforms()
loss = pystiche.loss.MRFLoss(..., target_transforms=target_transforms)
Parameters
  • num_scale_steps (int) – Number of scale steps. Each scale is performed in both directions, i.e. enlarging and shrinking the motif. Defaults to 1.

  • scale_step_width (float) – Width of each scale step. Defaults to 5e-2.

  • num_rotate_steps (int) – Number of rotate steps. Each rotate is performed in both directions, i.e. clockwise and counterclockwise. Defaults to 1.

  • rotate_step_width (float) – Width of each rotation step in degrees. Defaults to 10.0.

Return type

List[ScaleAndRotate]

Returns

(num_scale_steps * 2 + 1) * (num_rotate_steps * 2 + 1) transformations in total comprising every combination given by the input parameters.