1. AnimatedStyleTransfer
  2. Resolution 300.0
    1. 1
    2. 3
    3. 5
    4. 4
    5. 2
  3. Resolution 490.0
    1. 1
    2. 3
    3. 5
    4. 4
    5. 2
  4. Resolution 800.0
    1. 1
    2. 3
    3. 5
    4. 4
    5. 2

AnimatedStyleTransfer

Paints a series of images, each to match the content of one while in the style of another using:
  1. Random noise initialization
  2. Standard VGG16 layers
  3. Operators to match content and constrain and enhance style
  4. Progressive resolution increase
The parameters for each frame are fixed, but due to the random initialization and loose constraints we can achive a dynamic effect.

Code from AnimatedStyleTransfer.scala:67 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, styleUrl, (maxResolution * Math.sqrt(magnification)).toInt), "Input Style"))
      log.p(log.jpg(ImageArtUtil.load(log, contentUrl, maxResolution), "Input Content"))
      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()))
      try {
        paintEveryOther(contentUrl, initUrl, canvases, (1 to frames).map(f => f.toString -> {
          new VisualStyleContentNetwork(
            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
            ),
            styleModifiers = List(
              // These two operators are a good combination for a vivid yet accurate style
              new GramMatrixEnhancer(),
              new MomentMatcher()
            ),
            styleUrl = List(styleUrl),
            contentLayers = List(
              VGG16.VGG16_1b2
            ),
            contentModifiers = List(
              new ContentMatcher()
            ),
            magnification = magnification
          )
        }).toList, new BasicOptimizer {
          override val trainingMinutes: Int = 60
          override val trainingIterations: Int = 30
          override val maxRate = 1e9
        }, x => new PipelineNetwork(1), new GeometricSequence {
          override val min: Double = minResolution
          override val max: Double = maxResolution
          override val steps = AnimatedStyleTransfer.this.steps
        }.toStream.map(_.round.toDouble): _*)
        null
      } finally {
        registration.foreach(_.stop()(s3client, ec2client))
      }
    }

Returns:

    <function0>

Input Style

Input Content

Resolution 300.0

1

Subreport: Optimization

3

Subreport: Optimization

5

Subreport: Optimization

4

Subreport: Optimization

2

Subreport: Optimization

Resolution 490.0

1

Subreport: Optimization

3

Subreport: Optimization

5

Subreport: Optimization

4

Subreport: Optimization

2

Subreport: Optimization

Resolution 800.0

1

Subreport: Optimization

3

Subreport: Optimization

5

Subreport: Optimization

4

Subreport: Optimization

2

Subreport: Optimization