          self.netDB.compile(loss='mse', optimizer=optimizer, metrics=['accuracy'])
  
          # Build and compile the generator
          self.netGA, self.netGB = self.build_generator()
          self.netGA.compile(loss=['mae', 'mse'], optimizer=optimizer)
          self.netGB.compile(loss=['mae', 'mse'], optimizer=optimizer)
  
          img = Input(shape=self.img_shape)
          alphaA, reconstructed_imgA = self.netGA(img)
          alphaB, reconstructed_imgB = self.netGB(img)
  
          def one_minus(x): return 1 - x
          # masked_img = alpha * reconstructed_img + (1 - alpha) * img
          masked_imgA = add([multiply([alphaA, reconstructed_imgA]), multiply([Lambda(one_minus)(alphaA), img])])
          masked_imgB = add([multiply([alphaB, reconstructed_imgB]), multiply([Lambda(one_minus)(alphaB), img])])
          out_discriminatorA = self.netDA(concatenate([masked_imgA, img], axis=-1))
          out_discriminatorB = self.netDB(concatenate([masked_imgB, img], axis=-1))
  
          # The adversarial_autoencoder model  (stacked generator and discriminator) takes
          # img as input => generates encoded represenation and reconstructed image => determines validity 
          self.adversarial_autoencoderA = Model(img, [reconstructed_imgA, out_discriminatorA])
          self.adversarial_autoencoderB = Model(img, [reconstructed_imgB, out_discriminatorB])
          self.adversarial_autoencoderA.compile(loss=['mae', 'mse'],
                                                loss_weights=[1, 0.5],
                                                optimizer=optimizer)
          self.adversarial_autoencoderB.compile(loss=['mae', 'mse'],
                                                loss_weights=[1, 0.5],
                                                optimizer=optimizer)
  
      def converter(self, swap):
          predictor = self.netGB if not swap else self.netGA
          return lambda img: predictor.predict(img)
  
 
</s> remove         epoch, warped_A, target_A = next(self.train_batchA) 
        epoch, warped_B, target_B = next(self.train_batchB) 

        # Generate a half batch of new images
        gen_alphasA, gen_imgsA = self.model.netGA.predict(warped_A)
        gen_alphasB, gen_imgsB = self.model.netGB.predict(warped_B)
        #gen_masked_imgsA = gen_alphasA * gen_imgsA + (1 - gen_alphasA) * warped_A
        #gen_masked_imgsB = gen_alphasB * gen_imgsB + (1 - gen_alphasB) * warped_B
        gen_masked_imgsA = np.array([gen_alphasA[i] * gen_imgsA[i] + (1 - gen_alphasA[i]) * warped_A[i] 
                                     for i in range(self.batch_size)])
        gen_masked_imgsB = np.array([gen_alphasB[i] * gen_imgsB[i] + (1 - gen_alphasB[i]) * warped_B[i]
                                     for i in range (self.batch_size)])

        valid = np.ones((self.batch_size, ) + self.model.netDA.output_shape[1:])
        fake = np.zeros((self.batch_size, ) + self.model.netDA.output_shape[1:])

        concat_real_inputA = np.array([np.concatenate([target_A[i], warped_A[i]], axis=-1) 
                                       for i in range(self.batch_size)])
        concat_real_inputB = np.array([np.concatenate([target_B[i], warped_B[i]], axis=-1) 
                                       for i in range(self.batch_size)])
        concat_fake_inputA = np.array([np.concatenate([gen_masked_imgsA[i], warped_A[i]], axis=-1) 
                                       for i in range(self.batch_size)])
        concat_fake_inputB = np.array([np.concatenate([gen_masked_imgsB[i], warped_B[i]], axis=-1) 
                                       for i in range(self.batch_size)])
        if self.use_mixup:
            lam = np.random.beta(self.mixup_alpha, self.mixup_alpha)
            mixup_A = lam * concat_real_inputA + (1 - lam) * concat_fake_inputA
            mixup_B = lam * concat_real_inputB + (1 - lam) * concat_fake_inputB
 </s> add         epoch, warped_A, target_A = next(self.train_batchA)
        epoch, warped_B, target_B = next(self.train_batchB)
 </s> remove             return Model(inp, [alpha, rgb])
 </s> add             out = concatenate([alpha, rgb])
            return Model(input_, out )
 </s> remove     def random_warp(self, image, coverage):
 </s> add     def random_warp(self, image, coverage, scale = 5, zoom = 1):

          self.netDB.compile(loss='mse', optimizer=optimizer, metrics=['accuracy'])
  
          # Build and compile the generator
          self.netGA, self.netGB = self.build_generator()
























  
      def converter(self, swap):
          predictor = self.netGB if not swap else self.netGA
          return lambda img: predictor.predict(img)
  
keep keep keep keep replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace keep keep keep keep keep
 Update GAN64 to v2 (#217)

* Clearer requirements for each platform

* Refactoring of old plugins (Model_Original + Extract_Align) + Cleanups

* Adding GAN128

* Update GAN to v2

* Create instance_normalization.py

* Fix decoder output

* Revert "Fix decoder output"

This reverts commit 3a8ecb8957fe65e66282197455d775eb88455a77.

* Fix convert

* Enable all options except perceptual_loss by default

* Disable instance norm

* Update Model.py

* Update Trainer.py

* Match GAN128 to shaoanlu's latest v2

* Add first_order to GAN128

* Disable `use_perceptual_loss`

* Fix call to `self.first_order`

* Switch to average loss in output

* Constrain average to last 100 iterations

* Fix math, constrain average to intervals of 100

* Fix math averaging again

* Remove math and simplify this damn averagin

* Add gan128 conversion

* Update convert.py

* Use non-warped images in masked preview

* Add K.set_learning_phase(1) to gan64

* Add K.set_learning_phase(1) to gan128

* Add missing keras import

* Use non-warped images in masked preview for gan128

* Exclude deleted faces from conversion

* --input-aligned-dir defaults to "{input_dir}/aligned"

* Simplify map operation

* port 'face_alignment' from PyTorch to Keras. It works x2 faster, but initialization takes 20secs.

2DFAN-4.h5 and mmod_human_face_detector.dat included in lib\FaceLandmarksExtractor

fixed dlib vs tensorflow conflict: dlib must do op first, then load keras model, otherwise CUDA OOM error

if face location not found by CNN, its try to find by HOG.

removed this:
-        if face.landmarks == None:
-            print("Warning! landmarks not found. Switching to crop!")
-            return cv2.resize(face.image, (size, size))
because DetectedFace always has landmarks

* Enabled masked converter for GAN models

* Histogram matching, cli option for perceptual loss

* Fix init() positional args error

* Add backwards compatibility for aligned filenames

* Fix masked converter

* Remove GAN converters 
plugins/Model_GAN/Model.py