anchor.diff:          let kl = -0.5 * dsharp.sum(1. + logVar - mu.pow(2.) - logVar.exp())
           bce + kl
   
  -    member m.loss(x) =
  +    member m.loss(x, ?normalize:bool) =
  +        let normalize = defaultArg normalize true
           let xRecon, mu, logVar = m.encodeDecode x
  -        VAE.loss(xRecon, x, mu, logVar)
  +        let loss = VAE.loss(xRecon, x, mu, logVar)
  +        if normalize then loss / x.shape.[0] else loss
   
       member _.sample(?numSamples:int) = 
           let numSamples = defaultArg numSamples 1
  
positive.code:         let logVar = enc.[enc.Length-1].forward(x)
          mu, logVar
  
      let latent mu (logVar:Tensor) =
          let std = dsharp.exp(0.5*logVar)
          let eps = dsharp.randnLike(std)
          eps.mul(std).add(mu)
  
negative.code:         let l = model.loss(x)
          l.reverse()
          optimizer.step()
          printfn "Epoch: %A/%A minibatch: %A/%A loss: %A" epoch epochs i trainLoader.length (float(l))
  
          if i % validInterval = 0 then
              let mutable validLoss = dsharp.zero()
              for _, x, _ in validLoader.epoch() do
                  validLoss <- validLoss + model.loss(x, normalize=false)
              validLoss <- validLoss / validSet.length
              printfn "Validation loss: %A" (float validLoss)
              let fileName = sprintf "samples_epoch_%A_minibatch_%A.png" epoch i
              printfn "Saving %A samples to %A" numSamples fileName
              let samples = model.sample(numSamples).view([-1; 1; 28; 28])
              samples.saveImage(fileName)
  
  