140 lines
5.7 KiB
Python
140 lines
5.7 KiB
Python
|
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||
|
|
import tensorflow as tf
|
||
|
|
from tensorflow.keras import layers
|
||
|
|
import numpy as np
|
||
|
|
import os
|
||
|
|
import cv2
|
||
|
|
import time
|
||
|
|
import math
|
||
|
|
import re
|
||
|
|
|
||
|
|
taille_batch=128
|
||
|
|
nbr_entrainement=10000
|
||
|
|
bruit_dim=100
|
||
|
|
nbr_exemples=36
|
||
|
|
dir_faces='faces/'
|
||
|
|
|
||
|
|
def generateur_model():
|
||
|
|
model=tf.keras.Sequential()
|
||
|
|
|
||
|
|
model.add(layers.Dense(4*4*1024, use_bias=False, input_shape=(bruit_dim,)))
|
||
|
|
model.add(layers.BatchNormalization())
|
||
|
|
model.add(layers.LeakyReLU())
|
||
|
|
model.add(layers.Reshape((4, 4, 1024)))
|
||
|
|
|
||
|
|
model.add(layers.Conv2DTranspose(512, (5, 5), strides=(2, 2), padding='same', use_bias=False))
|
||
|
|
model.add(layers.BatchNormalization())
|
||
|
|
model.add(layers.LeakyReLU())
|
||
|
|
|
||
|
|
model.add(layers.Conv2DTranspose(256, (5, 5), strides=(2, 2), padding='same', use_bias=False))
|
||
|
|
model.add(layers.BatchNormalization())
|
||
|
|
model.add(layers.LeakyReLU())
|
||
|
|
|
||
|
|
model.add(layers.Conv2DTranspose(128, (5, 5), strides=(2, 2), padding='same', use_bias=False))
|
||
|
|
model.add(layers.BatchNormalization())
|
||
|
|
|
||
|
|
model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))
|
||
|
|
model.add(layers.BatchNormalization())
|
||
|
|
|
||
|
|
model.add(layers.Conv2DTranspose(3, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='sigmoid'))
|
||
|
|
|
||
|
|
return model
|
||
|
|
|
||
|
|
def discriminateur_model():
|
||
|
|
model=tf.keras.Sequential()
|
||
|
|
|
||
|
|
model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same', input_shape=[128, 128, 3]))
|
||
|
|
model.add(layers.LeakyReLU())
|
||
|
|
model.add(layers.BatchNormalization())
|
||
|
|
|
||
|
|
model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))
|
||
|
|
model.add(layers.LeakyReLU())
|
||
|
|
model.add(layers.BatchNormalization())
|
||
|
|
|
||
|
|
model.add(layers.Conv2D(256, (3, 3), strides=(2, 2), padding='same'))
|
||
|
|
model.add(layers.LeakyReLU())
|
||
|
|
model.add(layers.BatchNormalization())
|
||
|
|
model.add(layers.Dropout(0.2))
|
||
|
|
|
||
|
|
model.add(layers.Conv2D(512, (3, 3), strides=(2, 2), padding='same'))
|
||
|
|
model.add(layers.LeakyReLU())
|
||
|
|
model.add(layers.BatchNormalization())
|
||
|
|
model.add(layers.Dropout(0.3))
|
||
|
|
|
||
|
|
model.add(layers.Conv2D(512, (3, 3), strides=(2, 2), padding='same'))
|
||
|
|
model.add(layers.LeakyReLU())
|
||
|
|
model.add(layers.BatchNormalization())
|
||
|
|
model.add(layers.Dropout(0.3))
|
||
|
|
|
||
|
|
model.add(layers.Flatten())
|
||
|
|
model.add(layers.Dense(1024, activation=tf.nn.relu))
|
||
|
|
model.add(layers.Dense(1))
|
||
|
|
|
||
|
|
return model
|
||
|
|
|
||
|
|
@tf.function
|
||
|
|
def train_step(vrais_visages):
|
||
|
|
bruit=tf.random.normal([taille_batch, bruit_dim])
|
||
|
|
with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
|
||
|
|
faux_visages=generateur(bruit, training=True)
|
||
|
|
|
||
|
|
prediction_vrais_visages=discriminateur(vrais_visages, training=True)
|
||
|
|
prediction_faux_visages =discriminateur(faux_visages , training=True)
|
||
|
|
|
||
|
|
generateur_loss =cross_entropy(tf.ones_like (prediction_faux_visages ), prediction_faux_visages)
|
||
|
|
discriminateur_loss=cross_entropy(tf.ones_like (prediction_vrais_visages), prediction_vrais_visages)+\
|
||
|
|
cross_entropy(tf.zeros_like(prediction_faux_visages ), prediction_faux_visages )
|
||
|
|
|
||
|
|
gradients_generateur =gen_tape.gradient(generateur_loss , generateur.trainable_variables)
|
||
|
|
gradients_discriminateur=disc_tape.gradient(discriminateur_loss, discriminateur.trainable_variables)
|
||
|
|
|
||
|
|
generateur_optimizer.apply_gradients (zip(gradients_generateur , generateur.trainable_variables))
|
||
|
|
discriminateur_optimizer.apply_gradients(zip(gradients_discriminateur, discriminateur.trainable_variables))
|
||
|
|
|
||
|
|
def train(dataset, nbr_entrainement, bruit_pour_exemple=None):
|
||
|
|
m=0
|
||
|
|
for file in sorted(os.listdir('.')):
|
||
|
|
f=re.search('img_(.+?).png', file)
|
||
|
|
if f:
|
||
|
|
m=int(f.group(1))
|
||
|
|
checkpoint.restore(tf.train.latest_checkpoint("./training_checkpoints/"))
|
||
|
|
for entrainement in range(m, nbr_entrainement):
|
||
|
|
start=time.time()
|
||
|
|
for image_batch in dataset:
|
||
|
|
train_step(image_batch)
|
||
|
|
if bruit_pour_exemple is not None:
|
||
|
|
generatation_exemples(generateur, entrainement+1, bruit_pour_exemple)
|
||
|
|
if (entrainement+1)%100==0:
|
||
|
|
checkpoint.save(file_prefix="./training_checkpoints/ckpt")
|
||
|
|
print ('Entrainement {}: temps {} secondes'.format(entrainement+1, time.time()-start))
|
||
|
|
|
||
|
|
def generatation_exemples(model, entrainement, bruit_pour_exemple):
|
||
|
|
test_images=model(bruit_pour_exemple, training=False)
|
||
|
|
n=int(math.sqrt(len(bruit_pour_exemple)))
|
||
|
|
tab_img_test=np.zeros(shape=(128*n, 128*n, 3), dtype=np.float32)
|
||
|
|
for i in range(n):
|
||
|
|
for j in range(n):
|
||
|
|
tab_img_test[i*128:(i+1)*128, j*128:(j+1)*128, :]=test_images[i*n+j]
|
||
|
|
cv2.imwrite('img_{:05d}.png'.format(entrainement), tab_img_test*255)
|
||
|
|
|
||
|
|
train_images=[]
|
||
|
|
for file in os.listdir(dir_faces):
|
||
|
|
if file.endswith("jpg"):
|
||
|
|
img=cv2.imread(dir_faces+file, cv2.IMREAD_COLOR)
|
||
|
|
if img is not None:
|
||
|
|
train_images.append(cv2.resize(img, (128, 128)))
|
||
|
|
train_images=np.array(train_images, dtype=np.float32)/255
|
||
|
|
|
||
|
|
generateur=generateur_model()
|
||
|
|
discriminateur=discriminateur_model()
|
||
|
|
cross_entropy=tf.keras.losses.BinaryCrossentropy(from_logits=True)
|
||
|
|
generateur_optimizer=tf.keras.optimizers.Adam(1e-4)
|
||
|
|
discriminateur_optimizer=tf.keras.optimizers.Adam(1e-4)
|
||
|
|
checkpoint=tf.train.Checkpoint(generateur_optimizer=generateur_optimizer,
|
||
|
|
discriminateur_optimizer=discriminateur_optimizer,
|
||
|
|
generateur=generateur,
|
||
|
|
discriminateur=discriminateur)
|
||
|
|
bruit_pour_exemple=tf.random.normal([nbr_exemples, bruit_dim])
|
||
|
|
train_dataset=tf.data.Dataset.from_tensor_slices(train_images).batch(taille_batch)
|
||
|
|
train(train_dataset ,nbr_entrainement, bruit_pour_exemple)
|