- Código visto en el vídeo:
#cargamos las imagenes de entrenamiento en un dataset
train_dataset = tf.data.Dataset.list_files(PATH+'train/*.jpg')
#data.experimental.AUTOTUNE -->Permite que sea el propio
#TS el que ajuste el número de hilos en paralelo
train_dataset = train_dataset.map(load_image_train,
num_parallel_calls=tf.data.experimental.AUTOTUNE)
train_dataset = train_dataset.cache().shuffle(BUFFER_SIZE)
train_dataset = train_dataset.batch(1)
#for im1,img2 in train_dataset.take(3):
#plt.imshow(((im1[0,...])+1)/2)
#plt.imshow(((img2[0,...])+1)/2)
#plt.show()
#cargamos las imagenes de test en otro dataset
test_dataset = tf.data.Dataset.list_files(PATH+'test/*.jpg')
test_dataset = test_dataset.map(load_image_test)
test_dataset = test_dataset.batch(1)
#for im1,img2 in test_dataset.take(3):
#plt.imshow(((im1[0,...])+1)/2)
#plt.imshow(((img2[0,...])+1)/2)
#plt.show()
OUTPUT_CHANNELS = 3
# Cada bloque en el codificador es (Conv -> Batchnorm -> ReLU)
# (Covoulución-->Normalizacion-->Activación)
#Función para generar los bloques de nuestro codificador:
def downsample(filters, size, apply_batchnorm=True):
initializer = tf.random_normal_initializer(0., 0.02)
result = tf.keras.Sequential()
#añadimos la capa convolucional
result.add(
tf.keras.layers.Conv2D(filters, size, strides=2, padding='same',
kernel_initializer=initializer, use_bias=False))
#añadimos capa normalización
if apply_batchnorm:
result.add(tf.keras.layers.BatchNormalization())
#añadimos capa activación
result.add(tf.keras.layers.LeakyReLU())
return result
down_model = downsample(3, 4)
down_result = down_model(tf.expand_dims(inp, 0))
print (down_result.shape)
# Cada bloque en nuestro decodificador es (Transposed Conv -> Batchnorm -> Dropout -> #ReLU)
def upsample(filters, size, apply_dropout=False):
initializer = tf.random_normal_initializer(0., 0.02)
result = tf.keras.Sequential()
#añadimos la capa convolucional inversa
result.add(
tf.keras.layers.Conv2DTranspose(filters, size, strides=2,
padding='same',
kernel_initializer=initializer,
use_bias=False))
#añadimos capa normalización
result.add(tf.keras.layers.BatchNormalization())
#añadimos capa dropout
if apply_dropout:
result.add(tf.keras.layers.Dropout(0.5))
#añadimos capa activación
result.add(tf.keras.layers.ReLU())
return result
up_model = upsample(3, 4)
up_result = up_model(down_result)
print (up_result.shape)
#Empezamos a construir el generador:
# El generador es una U-Net modificada.
def Generator():
#Construimos los distintos bloques utilizando las funciones definidas anteriormente
down_stack = [
downsample(64, 4, apply_batchnorm=False), # (bs, 128, 128, 64)
downsample(128, 4), # (bs, 64, 64, 128)
downsample(256, 4), # (bs, 32, 32, 256)
downsample(512, 4), # (bs, 16, 16, 512)
downsample(512, 4), # (bs, 8, 8, 512)
downsample(512, 4), # (bs, 4, 4, 512)
downsample(512, 4), # (bs, 2, 2, 512)
downsample(512, 4), # (bs, 1, 1, 512)
]
#Construimos los distintos bloques utilizando las funciones definidas anteriormente
up_stack = [
upsample(512, 4, apply_dropout=True), # (bs, 2, 2, 1024)
upsample(512, 4, apply_dropout=True), # (bs, 4, 4, 1024)
upsample(512, 4, apply_dropout=True), # (bs, 8, 8, 1024)
upsample(512, 4), # (bs, 16, 16, 1024)
upsample(256, 4), # (bs, 32, 32, 512)
upsample(128, 4), # (bs, 64, 64, 256)
upsample(64, 4), # (bs, 128, 128, 128)
]
initializer = tf.random_normal_initializer(0., 0.02)
#Capa convolucional para la imgen que queremos generar
#Les especificamos OUTPUT_CHANNELS(tres canales de color)
# El tipo de activación debe ser el parecido a la normalización[-1,1] que definimos
# utilizamos una capa de activación que cumpla esto (tanh)
last = tf.keras.layers.Conv2DTranspose(OUTPUT_CHANNELS, 4,
strides=2,
padding='same',
kernel_initializer=initializer,
activation='tanh') # (bs, 256, 256, 3)
concat = tf.keras.layers.Concatenate()
inputs = tf.keras.layers.Input(shape=[None,None,3])
x = inputs
# Conectamos las capas del codificador
skips = []
#Guardamos los diferentes elementos en un array para las skip connections
#que son conexiones que se saltan el procesamiento de algunas capas
for down in down_stack:
x = down(x)
skips.append(x)#alamcenamos en array los elementos
#La ultima capa de debe ser la primera en el decodificador
skips = reversed(skips[:-1])
# Conectamos las capas del decodificador
for up, skip in zip(up_stack, skips):
x = up(x)
x = concat([x, skip])
#Gracias a keras podemos concatenae el resultado de dos capas
x = last(x)
#devolvemos un modelo compuesto por todas las capas creadas previamente
return tf.keras.Model(inputs=inputs, outputs=x)
generator = Generator()
gen_output = generator(inp[tf.newaxis,...], training=False)
plt.imshow(gen_output[0,...])