              x = res_block(x, 64)
              x = res_block(x, 64)
              alpha = Conv2D(1, kernel_size=5, padding='same', activation="sigmoid")(x)
              rgb = Conv2D(3, kernel_size=5, padding='same', activation="tanh")(x)
              return Model(inp, [alpha, rgb])
          
          encoder = Encoder(self.img_shape)
          decoder_A = Decoder_ps(self.img_shape)
          decoder_B = Decoder_ps(self.img_shape)    
          x = Input(shape=self.img_shape)
 
</s> remove         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)
 </s> add  </s> remove     def random_warp(self, image, coverage):
 </s> add     def random_warp(self, image, coverage, scale = 5, zoom = 1):
 </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)

            out = concatenate([alpha, rgb])
            return Model(input_, out )

              x = res_block(x, 64)
              x = res_block(x, 64)
              alpha = Conv2D(1, kernel_size=5, padding='same', activation="sigmoid")(x)
              rgb = Conv2D(3, kernel_size=5, padding='same', activation="tanh")(x)
            out = concatenate([alpha, rgb])
            return Model(input_, out )
          
          encoder = Encoder(self.img_shape)
          decoder_A = Decoder_ps(self.img_shape)
          decoder_B = Decoder_ps(self.img_shape)    
          x = Input(shape=self.img_shape)
keep keep keep keep 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