Pop

Tensorflow.Tutorial Pix2Pix. 4.Construimos el discrimindador

4.Construimos el discriminador

  • En este capítulo vemos como crear nuestro discriminador de imágenes. En nuestro caso el discriminador observará el resultado generado y nos dirá si es cierto o falso , en relación a lo que el considera una imagen correcta. El discriminador en este caso es una PatchGAN: En vez de devolver cierto o falso devuelve una  cuadricula en el que nos dice por si la parte de la imagen corespondiente a cada cuadricula es verdadedo o falso.
  • Código visto en el vídeo:
#Cada bloque en el discriminador es (Conv -> BatchNorm -> Leaky ReLU)
#El discriminador recibira entradas.
#Imagen de entrada y la imagen de destino, que debe clasificar como real.
#Imagen de entrada y la imagen generada (salida del generador), que debe clasificar como #falsa.
#Concatenamos estas 2 entradas juntas en el código (tf.concat ([inp, tar], axis = -1))
def Discriminator():
  initializer = tf.random_normal_initializer(0., 0.02)

  inp = tf.keras.layers.Input(shape=[None, None, 3], name='input_image')#imagen de entrada real
  tar = tf.keras.layers.Input(shape=[None, None, 3], name='target_image')#Imagen del generador

  #concatenamos las dos entradas
  x = tf.keras.layers.concatenate([inp, tar]) # (bs, 256, 256, channels*2)

  #Construimos los distintos bloques
  down1 = downsample(64, 4, False)(x) # (bs, 128, 128, 64)
  down2 = downsample(128, 4)(down1) # (bs, 64, 64, 128)
  down3 = downsample(256, 4)(down2) # (bs, 32, 32, 256)

  zero_pad1 = tf.keras.layers.ZeroPadding2D()(down3) # (bs, 34, 34, 256)
  
  #Añadimos la capa convolucional 
  conv = tf.keras.layers.Conv2D(512, 4, strides=1,
                                kernel_initializer=initializer,
                                use_bias=False)(zero_pad1) # (bs, 31, 31, 512)
  #Añadimos la capa BatchNorm
  batchnorm1 = tf.keras.layers.BatchNormalization()(conv)
  #Añadimos la capa Leaky ReLU
  leaky_relu = tf.keras.layers.LeakyReLU()(batchnorm1)

  zero_pad2 = tf.keras.layers.ZeroPadding2D()(leaky_relu) # (bs, 33, 33, 512)
  #Última capa con único filtro de salida con un canal donde nos dice por cada pixel
  #de la imagen si parece real o no
  last = tf.keras.layers.Conv2D(1, 4, strides=1,
                                kernel_initializer=initializer)(zero_pad2) # (bs, 30, 30, 1)
  #devolvemos el modelo del discriminador
  return tf.keras.Model(inputs=[inp, tar], outputs=last)
  
  #compruebo que todo funciona
discriminator = Discriminator()
#Pasamos dos imagenes y vemos un posible resultado.
#Recordar que todavia no hemos entrenado al modelo
disc_out = discriminator([inp[tf.newaxis,...], gen_output], training=False)
plt.imshow(disc_out[0,...,-1], vmin=-20, vmax=20, cmap='RdBu_r')
plt.colorbar()

#objeto para evaluar el resultado de las imágenes que vayamos obteniendo
loss_object = tf.keras.losses.BinaryCrossentropy(from_logits=True)

#Función para evaluar el comportamiento del discriminador
def discriminator_loss(disc_real_output, disc_generated_output):
  #Diferencia entre la observación de una imagen real y una matriz con todo a unos(representa
  #que la imagen es real) 
  real_loss = loss_object(tf.ones_like(disc_real_output), disc_real_output)
  #Diferencia entre la observación de una imagen generada y una matriz con todo a #ceros(representa que la imagen es fake) 
  generated_loss = loss_object(tf.zeros_like(disc_generated_output), disc_generated_output)
  #La suma evalua el comportamiento del discriminador
  total_disc_loss = real_loss + generated_loss

  return total_disc_loss
  
LAMBDA = 100
#Función para evaluar el comportamiento del generador.
#Le pasamos como parametros el mapa generado por el dicriminador, la imagen generada, 
#y la imagen real  
def generator_loss(disc_generated_output, gen_output, target):
  #Lo contrario al discminador
  gan_loss = loss_object(tf.ones_like(disc_generated_output), disc_generated_output)

  #error absoluto medio
  l1_loss = tf.reduce_mean(tf.abs(target - gen_output))
  #Para la suma además utilizamos el hiperparametro LAMBDA con valor 100
  total_gen_loss = gan_loss + (LAMBDA * l1_loss)

  return total_gen_loss
  
 #Definimos los optimizadores
generator_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)
discriminator_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)

#guardamos checkpoints para permitir reanudar el entrenamiento donde nos quedamos
checkpoint_dir = './training_checkpoints'
checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt")
checkpoint = tf.train.Checkpoint(generator_optimizer=generator_optimizer,
                                 discriminator_optimizer=discriminator_optimizer,
                                 generator=generator,
                                 discriminator=discriminator)

Curso diseño de bases de datos 6.Ejemplo diagrama entidad relación.Torneo de ajedrez

6.  Ejemplo diagrama entidad relación.Torneo de ajedrez

  • Hola a todos. En esta serie de vídeos pretendo diseñar una base de datos partiendo de unas especificaciones iniciales proporcionadas por un cliente. En este cuarto vídeo creamos nuestro diseño de base de datos con gestor  el de base de datos SQL SERVER.
  • En este capítulo haremos el diseño del modelo entidad relación del siguiente enunciado:
Un club de ajedrez es encargado de organizar un campeonato.Por este motivo, desea llevar a una base de datos toda la gestión relativa a participantes, alojamientos y partidas. 
Teniendo en cuenta que:

-En el campeonato participan jugadores y árbitros, de ambos se requiere conocer el número de asociado, nombre, dirección y teléfono de contacto. 
De los jugadores se precisa además el nivel de juego en una escala de 1 a 10.
- Ningún árbitro puede participar como jugador.
- Los países envían al campeonato un conjunto de jugadores y árbitros, aunque no todos los países envían participantes. Todo jugador y árbitro es enviado por un único país.
Un país puede ser representado por otro país.
-Cada país se identifica por un número correlativo según su orden alfabético e interesa conocer además su nombre y el número de clubes de ajedrez existentes en el mismo.
-Cada partida se identifica por un número correlativo (CódigoPartida), la juegan dos jugadores y la arbitra un árbitro. Interesa registrar las partidas que juega cada jugador 
y el color (blancas o negras) con el que juega. Ha de tenerse en cuenta que un árbitro no puede arbitrar a jugadores enviados por el mismo país que ha enviado él.
-Todo participante participa en al menos una partida.
Tanto jugadores como árbitros se alojan en uno de los hoteles en los que se desarrollan las partidas, se desea conocer en qué hotel y en qué fechas se ha alojado 
cada uno de los participantes.De cada hotel, se desea conocer el nombre, la dirección y el número de teléfono.
-El campeonato se desarrolla a lo largo de una serie de jornadas (año, mes, día) y cada partida tiene lugar en una de las jornadas aunque no tengan lugar partidas todas las jornadas.
-Cada partida se celebra en una de las salas de las que pueden disponer los hoteles, se desea conocer el número de entradas vendidas en la sala para cada partida. 
De cada sala, se desea conocer la capacidad y medios de que dispone (radio, televisión, vídeo,…) para facilitar la retransmisión de los encuentros. 
Una sala puede disponer de varios medios distintos.
-De cada partida se pretende registrar todos los movimientos que la componen, la identificación de movimiento se establece en base a un número de orden 
dentro de cada partida, para cada movimiento se guardan la jugada (5 posiciones) y un breve comentario realizado por un experto.

  • En el vídeo iremos comentando como hacer el diseño:



Curso .NET Core en C# - 25.Creamos vista de usuario con Tags Helpers

25.Creamos vista de usuario con Tags Helpers

  • Hola a todos. En este curso, analizaremos todos los conceptos básicos, intermedios y avanzados de ASP.NET Core que nos ayudan a crear aplicaciones web basadas en datos.Al final de este curso, podremos realizar todas las operaciones de un CRUD, es decir, crear, leer, actualizar y eliminar datos  utilizando SQL Server como nuestra base de datos. 
  • En este vídeo vamos a crear el mecanismo necesario para crear una vista donde poder añadir nuevos amigos.Vamos a utilizar tags helpers.Utilizamos los siguientes a tags helpers para crear un formulario en ASP.NET Core:
    • Form Tag Helper
    • Label Tag Helper
    • Input Tag Helper
    • Select Tag Helper
  • En el siguiente vídeo lo podemos ver con más detalles:
  • Parte del código visto en el vídeo:
    • Vista Create.cshtml:
    <form asp-controller="Home" asp-action="Create" method="Post" class="m-2">

        <div class="form-group row">
            <label asp-for="Nombre" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                <input asp-for="Nombre" class="form-control" placeholder="Nombre" />
            </div>
        </div>
        <div class="form-group row">
            <label asp-for="Email" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                <input asp-for="Email" class="form-control" placeholder="E-mail" />
            </div>
        </div>
        <div class="form-group row">
            <label asp-for="Ciudad" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                <select asp-for="Ciudad" class="custom-select mr-sm-2" asp-items="Html.GetEnumSelectList<Provincia>()"></select>
            </div>
        </div>

        <div class="form-group row">
            <div class="col-sm-10">
                <button type="submit" class="btn btn-primary">Nuevo</button>
            </div>
        </div>
    • Código de la clase Provincia:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Ejemplo1.Models
{
    public enum Provincia
    {
        Ninguna, Albacete, Alicante, Almería, Álava, Asturias, Ávila, Badajoz, Baleares, Barcelona, Bizkaia,
        Burgos, Cáceres, Cádiz, Cantabria, Castellón, CiudadReal, Córdoba, Coruña, Cuenca, Guipuzcoa,
        Girona, Granada, Guadalajara, Huelva, Huesca, Jaén, León, Lleida, Lugo, Madrid, Málaga, Murcia,
        Navarra, Ourense, Palencia, Palmas, Pontevedra, Rioja, Salamanca, Tenerife, Segovia, Sevilla,
        Soria, Tarragona, Teruel, Toledo, Valencia, Valladolid, Zamora, Zaragoza, Ceuta, Melilla

    }
}

Curso .NET Core en C# - 24.Creamos un menú con BootStrap.

24.Creamos un menú con BootStrap

  • Hola a todos. En este curso, analizaremos todos los conceptos básicos, intermedios y avanzados de ASP.NET Core que nos ayudan a crear aplicaciones web basadas en datos.Al final de este curso, podremos realizar todas las operaciones de un CRUD, es decir, crear, leer, actualizar y eliminar datos  utilizando SQL Server como nuestra base de datos. 

  • En este vídeo veremos como configurar nuestra aplicación para que coja nuestro fichero de bootstrap de un lugar u otro. Para facilitar la depuración, en nuestra máquina de desarrollo local (es decir, en el entorno de desarrollo) queremos que la aplicación cargue el archivo css de nuestra ruta local. En los entornos de producción o staging queremos que la aplicación cargue el archivo de arranque de CSS (bootstrap.min.css) desde un CDN (Red de distribución de contenidos) para un mejor rendimiento.Sin embargo, si el CDN está caído o por alguna razón, nuestra aplicación no puede llegar al CDN, queremos que nuestra aplicación se repliegue y cargue el archivo de arranque desde nuestro propio servidor web de aplicaciones.
  • Además creamos un menú aplicando bootstrap.En el siguiente vídeo lo podemos ver con más detalles:

  • Os dejo parte del código visto en el vídeo:

   <environment exclude="Development">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
              integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
              crossorigin="anonymous"

        href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
        asp-fallback-href="~/lib/twitter-bootstrap/css/bootstrap.css"
        asp-fallback-test-class="sr-only" 
        asp-fallback-test-property="position"
        asp-fallback-test-value="absolute"
        asp-suppress-fallback-integrity="true" />


    <div class="container">
        <nav class="navbar navbar-expand-sm bg-dark navbar-dark">
            <a class="navbar-brand" asp-controller="home" asp-action="index">
                <img src="~/images/Amigos.png" width="30" height="30">
            </a>
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="collapsibleNavbar">
                <ul class="navbar-nav">
                    <li class="nav-item">
                        <a class="nav-link" asp-controller="home" asp-action="index">Listado</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" asp-controller="home" asp-action="create">Crear</a>
                    </li>
                </ul>
            </div>
        </nav>

        <div>
            @RenderBody()
        </div>

            @RenderSection("Scripts", required: false)
      
    </div>

Tensorflow.Tutorial Pix2Pix. 3.Construimos el generador

3.Construimos el generador

  • En este capítulo vemos como crear nuestro generador de imágenes. En el siguiente vídeo tenemos la explicación y más abajo os dejo el código visto en el vídeo:

  • 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,...])

Curso .NET Core en C# - 23.Tag Helpers

23.Tag Helpers

  • Hola a todos. En este curso, analizaremos todos los conceptos básicos, intermedios y avanzados de ASP.NET Core que nos ayudan a crear aplicaciones web basadas en datos.Al final de este curso, podremos realizar todas las operaciones de un CRUD, es decir, crear, leer, actualizar y eliminar datos  utilizando SQL Server como nuestra base de datos. 

    • Los  Tag Helpers son nuevos en ASP.NET Core. Comprendamos qué son los Tag Helpers y su uso con un ejemplo. Los Tag Helpers son componentes del lado del servidor. Se procesan en el servidor para crear y representar elementos HTML en archivos Razor. Si tienes alguna experiencia con la versión anterior de ASP.NET MVC, puede estar familiarizado con los tag helper para  HTML.  Los Tag Helpers son similares a los HTML helpers.
    • En el siguiente vídeo explico como empezar a trabajar con ellos mediante un ejemplo:

    Tensorflow.Tutorial Pix2Pix. 2.Elegimos nuestro dataset

    2.Elegimos nuestro dataset y empezamos con el código

    • Antes de comenzar con la implementación de nuestro código es necesario tener claro  el problema que queremos solucionar en nuestro caso queremos generar fachadas  a partir de bocetos. Hemos utilizado el dataset que google nos proporciona. En el siguiente vídeo lo explicamos mejor:
    • Vamos a empezar a con el código.
    #importamos las librerias necesarias.
    from __future__ import absolute_import, division, print_function, unicode_literals
    import os
    import time
    import matplotlib.pyplot as plt
    from IPython.display import clear_output
    import tensorflow as tf #IMPORTANTE TENER VERSIÓN 2.0
    print(tf.__version__ )

    #En esta porción de código descargamos el dataset de imagenes

    _URL = 'https://people.eecs.berkeley.edu/~tinghuiz/projects/pix2pix/datasets/facades.tar.gz'
    #Ruta local donde descomprimosmos el fichero zip con el dataset de imágenes
    path_to_zip = tf.keras.utils.get_file('facades.tar.gz',origin=_URL,extract=True)
    PATH = os.path.join(os.path.dirname(path_to_zip), 'facades/')
    print(PATH)

    #definimos algunas constantes que utilizaremos posteriormente

    BUFFER_SIZE = 400
    BATCH_SIZE = 1
    IMG_WIDTH = 256  #Ancho de las imagenes
    IMG_HEIGHT = 256 #Alto de las imagenes

    #función que carga las imágenes y las devuelve
    def load(image_file):
        image = tf.io.read_file(image_file) #carga la imagen de disco
        image = tf.image.decode_jpeg(image) # la decodificamos a jpg

        w = tf.shape(image)[1]

        w = w // 2
        real_image = image[:, :w, :]
        input_image = image[:, w:, :]

        input_image = tf.cast(input_image, tf.float32) #cast para pasarlas a float para los calculos 
        real_image = tf.cast(real_image, tf.float32)

        return input_image, real_image
    #cargamos imagen de entrenamiento
    inp, re = load(PATH+'train/2.jpg')
    plt.figure()
    plt.imshow(inp/255.0)
    plt.figure()
    plt.imshow(re/255.0)

    #Función para redimensionar las imágenes.
    #Se le pasan como paramteros las imágenes y sus tamaños.Llamamos
    #al método de TS resize y las devuelve.

    def resize(input_image, real_image, height, width):
      input_image = tf.image.resize(input_image, [height, width],
                                    method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)
      real_image = tf.image.resize(real_image, [height, width],
                                   method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)

      return input_image, real_image
      
      #función que coge una parte de la imágenes pasadas como parámetros
    def random_crop(input_image, real_image):
      stacked_image = tf.stack([input_image, real_image], axis=0)
      cropped_image = tf.image.random_crop(
          stacked_image, size=[2, IMG_HEIGHT, IMG_WIDTH, 3])

      return cropped_image[0], cropped_image[1]
     # Normalizamos.Queremos que las imágenes estén en el rango de 
    #[-1,1].Como las imágenes son de de tamaño 256 dividimos entre 127.5 y 
    #restamos 1
    def normalize(input_image, real_image):
      input_image = (input_image / 127.5) - 1
      real_image = (real_image / 127.5) - 1

      return input_image, real_image
      
     #Funcíon que se utiliza para aumentación de datos.Aplicancdo está función se
    #generan virtualmente más imágenes a base de ampliar las imagenes y desplazarlas.
    @tf.function()
    def random_jitter(input_image, real_image):
      # aumentamos el tamaño 286 x 286 x 3 (canales de color)
      input_image, real_image = resize(input_image, real_image, 286, 286)

      # cogemos una parte de la imagen (256 x 256 x 3) anteriormente ampliada a 286 x 286 x 3  
      input_image, real_image = random_crop(input_image, real_image)

      if tf.random.uniform(()) > 0.5:
        # Volteamos la imagen horizontalmente
        input_image = tf.image.flip_left_right(input_image)
        real_image = tf.image.flip_left_right(real_image)

      return input_image, real_image
      
      # Probamos las funciones
    # 1. Cambiar el tamaño de una imagen a mayor altura y ancho
    # 2. Recorte aleatoriamente al tamaño original
    # 3. Voltear aleatoriamente la imagen horizontalmente

    plt.figure(figsize=(6, 6))
    for i in range(4):
      rj_inp, rj_re = random_jitter(inp, re)
      plt.subplot(2, 2, i+1)
      plt.imshow(rj_inp/255.0)
      plt.axis('off')
    plt.show()

    #función para cargar imágenes de entrenamiento
    def load_image_train(image_file):
      input_image, real_image = load(image_file)
      input_image, real_image = random_jitter(input_image, real_image)
      input_image, real_image = normalize(input_image, real_image)

      return input_image, real_image
      
      #función para cargar imagen de test.En la función de test NO aplicamos
    #el aumento de datos (función random_jitter)
    def load_image_test(image_file):
      input_image, real_image = load(image_file)
      input_image, real_image = resize(input_image, real_image,
                                       IMG_HEIGHT, IMG_WIDTH)
      input_image, real_image = normalize(input_image, real_image)

      return input_image, real_image

    Tensorflow.Tutorial Pix2Pix. 1.Introducción

    1.Introducción

    • En pix2pix la red se compone de dos piezas principales: el Generador y el Discriminador. El generador aplica alguna transformación a la imagen de entrada para obtener la imagen de salida. El Discriminador compara la imagen de entrada con una imagen desconocida , ya sea una imagen objetivo del conjunto de datos o una imagen de salida del generador e intenta adivinar si fue producida por el generador. 
    • Concepto GAN: Una GAN es un modelo generativo en el que dos redes compiten en un escenario de teoría de juegos. La primera red es el generador, genera una muestra (por ejemplo, una imagen), mientras que su adversario, el discriminador,  intenta detectar si una muestra es real o si es el resultado del generador. En pocas palabras, GAN significa que dos redes funcionan una contra la otra. Primero se alimenta con datos en bruto que se descompone. A partir de estos, trata de crear una imagen. Luego lo envía a otra red que,  solo tiene fotos o imágenes reales en su base de datos. Esta segunda red hará un juicio de la imagen e informará a la primera.Si la imagen no se parece al resultado esperado, el primer algoritmo reanuda el proceso. Si hay una coincidencia, se le informa que está en el camino correcto y  termina por entender qué es una buena imagen.
    • En el siguiente vídeo podéis verlo con más detalles:






    Curso .NET Core en C# - 22.Cómo instalar y usar Bootstrap.

    22.Cómo instalar y usar Bootstrap.

    • Hola a todos. En este curso, analizaremos todos los conceptos básicos, intermedios y avanzados de ASP.NET Core que nos ayudan a crear aplicaciones web basadas en datos.Al final de este curso, podremos realizar todas las operaciones de un CRUD, es decir, crear, leer, actualizar y eliminar datos  utilizando SQL Server como nuestra base de datos. 

    • En este vídeo discutiremos cómo instalar y usar Bootstrap en ASP.NET Core.. Bootstrap es una biblioteca multiplataforma o conjunto de herramientas de código abierto para diseño de sitios y aplicaciones web. Contiene plantillas de diseño con tipografía, formularios, botones, cuadros, menús de navegación y otros elementos de diseño basado en HTML y  CSS, así como extensiones de JavaScript adicionales.

    • Para instalar el paquete de  Bootstrap utilizaremos Library Manager (LibMan para abreviar). Library Manager es una herramienta ligera de adquisición de bibliotecas del lado del cliente. Para poder usar LibMan, debe tener Visual Studio 2017 versión 15.8 o posterior.
    • En el siguiente vídeo podemos ver como instalarlo:

    • Os dejo parte del código visto en el vídeo:
    libman.json
    {
      "version": "1.0",
      "defaultProvider": "cdnjs",
      "libraries": [
        {
          "library": "twitter-bootstrap@4.3.1",
          "destination": "wwwroot/lib/twitter-bootstrap/"
        }
      ]
    }

    _Layout.cshtml

    <!DOCTYPE html>

    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <link href="~/css/sitio.css" rel="stylesheet" />
        <link href="~/lib/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" />
      
        <title>@ViewBag.Title</title>
    </head>
    <body>
        <div>
            @RenderBody()
        </div>


        @RenderSection("Scripts",required:false)
    </body>
    </html>


    Index.cshtml
    @model List<Amigo>

    @{


        ViewBag.Title = "Amigos indice";

    }



    <div class="card-deck">
        @foreach (var amigo in Model)
        {
            <div class="card m-3">
                <div class="card-header">
                    <h3>@amigo.Nombre</h3>
                </div>
                <img class="card-img-top" src="~/images/ChicaCodigo.jpg" />
                <div class="card-footer text-center">
                    <a href="#" class="btn btn-primary">Ver</a>
                    <a href="#" class="btn btn-primary">Editar</a>
                    <a href="#" class="btn btn-danger">Borrar</a>
                </div>
            </div>
        }
    </div>

    DetallesView.cshtml

    @model DetallesView

    @{
    ViewBag.Title = "Amigos Detalles";
    }

        <div class="row justify-content-center m-3">
            <div class="col-sm-8">
                <div class="card">
                    <div class="card-header">
                        <h1>@Model.amigo.Nombre</h1>
                    </div>

                    <div class="card-body text-center">
                        <img class="card-img-top" src="~/images/ChicaCodigo.jpg" />

                        <h4>Amigo ID : @Model.amigo.Id</h4>
                        <h4>Email:  @Model.amigo.Email</h4>
                        <h4>Ciudad: @Model.amigo.Ciudad</h4>

                    </div>
                    <div class="card-footer text-center">
                        <a href="#" class="btn btn-primary">Volver</a>
                        <a href="#" class="btn btn-primary">Editar</a>
                        <a href="#" class="btn btn-danger">Borrar</a>
                    </div>
                </div>
            </div>
        </div>


    @section  Scripts
    {
        <script src="~/js/MiScript.js"></script>
    }


    Curso diseño de bases de datos 5.Nuevo ejemplo completo

    5.  Nuevo ejemplo completo

    • Hola a todos. En esta serie de vídeos pretendo diseñar una base de datos partiendo de unas especificaciones iniciales proporcionadas por un cliente. En este cuarto vídeo creamos nuestro diseño de base de datos con gestor  el de base de datos SQL SERVER.
    • En este capítulo resolvemos al completo el siguiente problema. Desde el diseño del modelo entidad/relación al diseño de las tablas de nuestra base de datos:
    Se desea informatizar la gestión de una tienda informática. La tienda dispone de una serie
    de productos que se pueden vender a los clientes.

    “De cada producto informático se desea guardar el código, descripción, precio y número
    de existencias. De cada cliente se desea guardar el código, nombre, apellidos, dirección y
    número de teléfono.
    Un cliente puede comprar varios productos en la tienda y un mismo producto puede ser
    comprado por varios clientes. Cada vez que se compre un artículo quedará registrada la
    compra en la base de datos junto con la fecha en la que se ha comprado el artículo.
    La tienda tiene contactos con varios proveedores que son los que suministran los
    productos. Un mismo producto puede ser suministrado por varios proveedores. De cada
    proveedor se desea guardar el código, nombre, apellidos, dirección, provincia y número
    de teléfono”.

    • Os dejo el vídeo con la solución de este problema:

    Curso .NET Core en C# - 21.Enrutamiento en MVC

    21. Enrutamiento en MVC

    • Hola a todos. En este curso, analizaremos todos los conceptos básicos, intermedios y avanzados de ASP.NET Core que nos ayudan a crear aplicaciones web basadas en datos.Al final de este curso, podremos realizar todas las operaciones de un CRUD, es decir, crear, leer, actualizar y eliminar datos  utilizando SQL Server como nuestra base de datos. 
    • En este vídeo, analizaremos el enrutamiento en ASP.NET Core MVC. Hay 2 técnicas de enrutamiento. Enrutamiento convencional y enrutamiento de atributos. Cuando una solicitud del navegador llega a nuestra aplicación, es el controlador en el patrón de diseño MVC, el que maneja la solicitud HTTP entrante   responde a la acción del usuario.
    • En el vídeo veremos las diferentes maneras de gestionar las rutas en MVC:

    • Con el enrutamiento de atributos, las rutas se colocan al lado de los métodos de acción que realmente las usarán. Las rutas de atributos ofrecen un poco más de  flexibilidad que las rutas convencionales. Sin embargo, en general, las rutas convencionales se utilizan para controladores que sirven páginas HTML  y rutas de atributos para controladores que sirven API REST. 
    • Os dejo parte del código visto en el vídeo:
      • Clase HomeController:

    Enrutamiento con Atributos:
    using Ejemplo1.Models;
    using Ejemplo1.ViewModels;
    using Microsoft.AspNetCore.Mvc;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;

    namespace Ejemplo1.Controllers
    {
        public class HomeController:Controller
        {
            private IAmigoAlmacen amigoAlmacen;

            public HomeController(IAmigoAlmacen AmigoAlmacen)
            {
                amigoAlmacen = AmigoAlmacen;
            }

            //public string Index()
            //{
            //    return amigoAlmacen.dameDatosAmigo(3).Email;
            //}

            //public JsonResult Details()
            //{
            //    Amigo modelo = amigoAlmacen.dameDatosAmigo(1);
            //    return Json(modelo);
            //}
            [Route("")]
            [Route("Home")]
            [Route("Home/Index")]
            public ViewResult Index(int id)
            {
                var modelo = amigoAlmacen.DameTodosLosAMigos();
                return View(modelo);
            }
            [Route("Home/Details/{id?}")]
            public ViewResult Details(int? id)
            {
            
                DetallesView detalles = new DetallesView();
                //Si es nulo forzamo a qque busque los detalles del amigo uno
                detalles.amigo= amigoAlmacen.dameDatosAmigo(id?? 1);
                detalles.Titulo = "LISTA AMIGOS VIEW MODELS";
                detalles.SubTitulo = "XXXXXXXXXXXX";

                return View(detalles);
            }
    }
    }
      • Clase Startup:
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;

    namespace Ejemplo1
    {
        public class Startup
        {

            private IConfiguration _configuration;

            public Startup(IConfiguration configuration)
            {
                _configuration = configuration;
            }

            // This method gets called by the runtime. Use this method to add services to the container.
            // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddMvc();
                services.AddSingleton<IAmigoAlmacen, MockAmigoRepositorio>();
             

            }

            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env )
            {

                if (env.IsDevelopment())
                {
                    DeveloperExceptionPageOptions d = new DeveloperExceptionPageOptions
                    {
                        SourceCodeLineCount = 2
                    };
                    app.UseDeveloperExceptionPage(d);
                }
                else if (env.IsProduction() || env.IsStaging())
                {
                    app.UseExceptionHandler("/Error");
                }

                app.UseStaticFiles();
                //app.UseMvcWithDefaultRoute();

                app.UseMvc();
                //app.UseMvc(routes =>
                //{
                //    routes.MapRoute("default", "{controller=Home}/{action=Index}/{id}");
                //});

            }
        }
    }

    Curso .NET Core en C# - 34.Creamos nuestro propio log

    34.Creamos nuestro propio log Hola a todos. En este curso, analizaremos todos los conceptos básicos, intermedios y avanzados de  ASP.NET...