1. StyleTransferSweep
  2. Resolution 300.0
    1. 9.091 - 90.909
    2. 16.183 - 83.817
    3. 27.154 - 72.846
    4. 41.850 - 58.150
    5. 58.150 - 41.850
    6. 72.846 - 27.154
    7. 83.817 - 16.183
  3. Resolution 490.0
    1. 9.091 - 90.909
    2. 16.183 - 83.817
    3. 27.154 - 72.846
    4. 41.850 - 58.150
    5. 58.150 - 41.850
    6. 72.846 - 27.154
    7. 83.817 - 16.183
  4. Resolution 800.0
    1. 9.091 - 90.909
    2. 16.183 - 83.817
    3. 27.154 - 72.846
    4. 41.850 - 58.150
    5. 58.150 - 41.850
    6. 72.846 - 27.154
    7. 83.817 - 16.183

StyleTransferSweep

Paints a series of images, each to match the content of one while using:
  1. A linear combination of two styles
  2. Random noise initialization
  3. Standard VGG16 layers
  4. Operators to match content and constrain and enhance style
  5. Progressive resolution increase
The parameters for each frame are fixed and randomly initialized, but the style used sweeps between two reference images over the animation.

Code from StyleTransferSweep.scala:70 executed in 0.00 seconds (0.000 gc):

    () => {
      implicit val _ = log
      // First, basic configuration so we publish to our s3 site
      log.setArchiveHome(URI.create(s"s3://$s3bucket/${getClass.getSimpleName.stripSuffix("$")}/${log.getId}/"))
      log.onComplete(() => upload(log): Unit)
      // Fetch input images (user upload prompts) and display rescaled copies
      log.p(log.jpg(ImageArtUtil.load(log, contentUrl, maxResolution), "Input Content"))
      log.p(log.jpg(ImageArtUtil.load(log, styleAUrl, (maxResolution * Math.sqrt(magnification)).toInt), "Input Style A"))
      log.p(log.jpg(ImageArtUtil.load(log, styleBUrl, (maxResolution * Math.sqrt(magnification)).toInt), "Input Style B"))
  
  
  
      val canvases = (1 to frames).map(_ => new AtomicReference[Tensor](null)).toList
      // Execute the main process while registered with the site index
      val registration = registerWithIndexGIF_Cyclic(canvases.map(_.get()), delay = delay)
      try {
        animate(contentUrl, initUrl, canvases, log.eval(() => (0 to frames- 1).map(f => {
          var coeffA = Math.pow(separation, (f.toDouble / frames) - 0.5)
          var coeffB = 1.0 / coeffA
          val mag = coeffA + coeffB
          coeffA = coeffA / mag
          coeffB = coeffB / mag
          f"${coeffA * 100}%.3f - ${coeffB * 100}%.3f" -> {
            val styleLayers = List(
              // We select all the lower-level layers to achieve a good balance between speed and accuracy.
              VGG16.VGG16_0,
              VGG16.VGG16_1a,
              VGG16.VGG16_1b1,
              VGG16.VGG16_1b2,
              VGG16.VGG16_1c1,
              VGG16.VGG16_1c2,
              VGG16.VGG16_1c3
            )
            new VisualStyleNetwork(
              // This primary component accounts for style A
              styleLayers = styleLayers,
              styleModifiers = List(
                // These two operators are a good combination for a vivid yet accurate style
                new GramMatrixEnhancer().scale(coeffA),
                new MomentMatcher().scale(coeffA)
              ),
              styleUrl = List(styleAUrl),
              magnification = magnification
            ) + new VisualStyleNetwork(
              styleLayers = styleLayers,
              styleModifiers = List(
                // We use the same two operators in the alternate component, which calculates the style B
                new GramMatrixEnhancer().scale(coeffB),
                new MomentMatcher().scale(coeffB)
              ),
              styleUrl = List(styleBUrl),
              magnification = magnification
            ).withContent(
              contentLayers = List(
                VGG16.VGG16_1b2
              ),
              contentModifiers = List(
                new ContentMatcher()
              ))
          }
        }).toList), new BasicOptimizer {
          override val trainingMinutes: Int = 60
          override val trainingIterations: Int = 30
          override val maxRate = 1e9
        }, new GeometricSequence {
          override val min: Double = minResolution
          override val max: Double = maxResolution
          override val steps = StyleTransferSweep.this.steps
        }.toStream.map(_.round.toDouble),
          delay = StyleTransferSweep.this.delay)
        null
      } finally {
        registration.foreach(_.stop()(s3client, ec2client))
      }
    }

Returns:

    <function0>

Input Content

Input Style A

Input Style B

Code from StyleTransferSweep.scala:87 executed in 0.80 seconds (0.000 gc):

    var coeffA = Math.pow(separation, (f.toDouble / frames) - 0.5)
    var coeffB = 1.0 / coeffA
    val mag = coeffA + coeffB
    coeffA = coeffA / mag
    coeffB = coeffB / mag
    f"${coeffA * 100}%.3f - ${coeffB * 100}%.3f" -> {
      val styleLayers = List(
        // We select all the lower-level layers to achieve a good balance between speed and accuracy.
        VGG16.VGG16_0,
        VGG16.VGG16_1a,
        VGG16.VGG16_1b1,
        VGG16.VGG16_1b2,
        VGG16.VGG16_1c1,
        VGG16.VGG16_1c2,
        VGG16.VGG16_1c3
      )
      new VisualStyleNetwork(
        // This primary component accounts for style A
        styleLayers = styleLayers,
        styleModifiers = List(
          // These two operators are a good combination for a vivid yet accurate style
          new GramMatrixEnhancer().scale(coeffA),
          new MomentMatcher().scale(coeffA)
        ),
        styleUrl = List(styleAUrl),
        magnification = magnification
      ) + new VisualStyleNetwork(
        styleLayers = styleLayers,
        styleModifiers = List(
          // We use the same two operators in the alternate component, which calculates the style B
          new GramMatrixEnhancer().scale(coeffB),
          new MomentMatcher().scale(coeffB)
        ),
        styleUrl = List(styleBUrl),
        magnification = magnification
      ).withContent(
        contentLayers = List(
          VGG16.VGG16_1b2
        ),
        contentModifiers = List(
          new ContentMatcher()
        ))
    }

Returns:

    List((9.091 - 90.909,com.simiacryptus.mindseye.art.util.VisualNetwork$$anon$2@7ce85af2), (16.183 - 83.817,com.simiacryptus.mindseye.art.util.VisualNetwork$$anon$2@316acbb5), (27.154 - 72.846,com.simiacryptus.mindseye.art.util.VisualNetwork$$anon$2@56f730b2), (41.850 - 58.150,com.simiacryptus.mindseye.art.util.VisualNetwork$$anon$2@47311277), (58.150 - 41.850,com.simiacryptus.mindseye.art.util.VisualNetwork$$anon$2@7930ffa9), (72.846 - 27.154,com.simiacryptus.mindseye.art.util.VisualNetwork$$anon$2@1e60b459), (83.817 - 16.183,com.simiacryptus.mindseye.art.util.VisualNetwork$$anon$2@717d7587))

Resolution 300.0

9.091 - 90.909

Subreport: Optimization

16.183 - 83.817

Subreport: Optimization

27.154 - 72.846

Subreport: Optimization

41.850 - 58.150

Subreport: Optimization

58.150 - 41.850

Subreport: Optimization

72.846 - 27.154

Subreport: Optimization

83.817 - 16.183

Subreport: Optimization

Resolution 490.0

9.091 - 90.909

Subreport: Optimization

16.183 - 83.817

Subreport: Optimization

27.154 - 72.846

Subreport: Optimization

41.850 - 58.150

Subreport: Optimization

58.150 - 41.850

Subreport: Optimization

72.846 - 27.154

Subreport: Optimization

83.817 - 16.183

Subreport: Optimization

Resolution 800.0

9.091 - 90.909

Subreport: Optimization

16.183 - 83.817

Subreport: Optimization

27.154 - 72.846

Subreport: Optimization

41.850 - 58.150

Subreport: Optimization

58.150 - 41.850

Subreport: Optimization

72.846 - 27.154

Subreport: Optimization

83.817 - 16.183

Subreport: Optimization