WOT

Thursday, March 30, 2017

Aprendizaje profundo para principiantes (Parte2)

Nota: Este artículo es una traducción del original que aparece en HACKERNOON: Deep Learning for Noobs [Part 2]

Muchas gracias al autor Debarko De por permitir su publicación en español.


Aprendizaje profundo para principiantes (Parte 2)
¿Cómo podemos configurar nuestra propia red neuronal convolucional? En esta exposición vamos a tratar de responder a esta pregunta. Trabajaremos sobre el problema de segmentación de imágenes que discutimos en la primera parte de esta serie.
Hay muchas bibliotecas disponibles para crear una red neuronal convolucional. Elegimos Keras y Tensorflow. La primera pregunta que viene a la mente es:
¿Por qué estos dos en concreto? ¿Por qué no sólo Tensorflow?
En lo que sería la biblioteca general de aprendizaje automático hay muchas bibliotecas. Tensorflow, Theano, PyTorch, Caffe y Torch son algunas de los más importantes. Desde aquí quiero expresar el profundo reconocimiento a PyTorch gracias a Soumith Chintala y a su equipo, que han creado una biblioteca impresionante. Esperemos que se puedan hacer cargo del mundo (** sonrisa maliciosa **).

PyTorch planea hacerse con el mundo: P Andrej Karpathy tiene grandes esperanzas en Tensorflow
Todas ellas son bibliotecas de bajo nivel. Lo que implica tener que acelerar los procesos mediante GPU o CPU y optimizar cálculos matriciales. Por lo tanto, construir redes que utilicen estas bibliotecas podría convertirse en un importante reto. Keras es una biblioteca de alto nivel. Ayuda a crear capas neuronales  y simplifica las complejidades de las operaciones de cálculo. Keras trabaja con Theano o Tensorflow como respaldo. He elegido Tensorflow como respaldo porque tiene un mejor apoyo de la comunidad.
KEras & TEnsorflow (KETE) es la combinación perfecta.
Instalación
Vamos a decidir los componentes que hay que instalar. Y lo vamos a ir haciendo según avanzamos. Los sistemas tradicionales se eternizarían entrenando conjuntos de datos. Así que vamos a conseguir un servidor AWS. Si disponemos de un equipo para videojuegos podemos programarlo en local. Utilizaremos el sistema g2.2xLarge de AWS. Tiene 26 núcleos de GPU y cuesta 0,65 dólares / hora. ¿Por qué lo elegimos? Nos decidimos por él porque es el sistema de GPU más barato disponible en la nube, y funcionará mejor que la mayor parte del hardware que tengamos en casa. Lo siguiente es decidir el sistema operativo que vamos a emplear. Definitivamente tiene sentido utilizar Ubuntu 16.04 LTS pero ¡un momento! Vamos a utilizar una AMI pre-horneado que tiene un montón de herramientas incorporadas. De esta manera podemos dejar acabada la mayor parte de la configuración. Busquemos Deep Learning AMI de AWS. Hay otras buenas AMIs en aprendizaje automático que se pueden encontrar en la red. Necesitamos que Python 2.7 y Tensorflow estén instalados al menos en la AMI.



   Instancia GPU y aprendizaje profundo AMI en AWS

Después de seleccionar el tipo de instancia (máquina virtual de Amazon) y la AMI hay que crear una clave. Puede utilizar cualquier clave que ya tenga preparada. Pero para este caso crearemos una. Vamos a utilizar una clave con el siguiente nombre: deepkey.pem. Descargue la clave y guárdela en un lugar seguro. Inicie la instancia. Para crearla se necesitan entre 5 y 10 minutos. Mientras tanto, hay que cambiar el permiso de la clave a 400. De lo contrario ssh no le permitirá iniciar sesión.
Chmod 400 ~ / deepkey.pem
A continuación, hay que ir a la lista de instancias de EC2. Desde allí, seleccionar la instancia que se ha creado. Hay que copiar la DNS pública de la instancia de AWS. Se parecerá a esto: ec2-52-24-183-62.us-west-2.compute.amazonaws.com
# A continuación entramos en el sistema
Ssh ec2-user@ec2-52-24-183-62.us-west-2.compute.amazonaws.com -i ~ / deepkey.pem
# La AMI podría estar desafasada por lo que siempre es mejor ponerla al día
Sudo yum update
# Instalamos pip para obtener Keras
sudo yum install python-pip
# Actualizamos el pip master instalado
sudo /usr/local/bin/pip install — upgrade pip
# Instalamos Keras
sudo /usr/local/bin/pip install keras
Por defecto, la configuración básica Keras se instala con Theano. Vamos a usar Tensorflow. Así que vamos a cambiarlo. Abrir ~ / .keras / keras.conf y actualizarlo como se muestra a continuación. El archivo se debe ver como se muestra en la sección siguiente.
{
“image_dim_ordering”: “tf”,
“epsilon”: 1e-07,
“floatx”: “float32”,
“backend”: “tensorflow”
}
Espero que todos los pasos se hayan seguido sin cometer errores. Vamos ahora a probar nuestra instalación. Abrimos python y luego importamos keras para probarlo. La salida debe tener un aspecto como el que se muestra a continuación.


    Prueba de instalación Keras
Así que ahora tenemos Python, Tensorflow y Keras instalados. La AMI también proporciona Theano y otros recursos pre instalados, pero no los vamos a utilizar. No es necesario desinstalarlos ya que no interfieren en el funcionamiento. Terminada la instalación, vayamos con el código.

No hay que perder el tiempo en la instalación, sino que hay que aprovecharlo en  aprender y en realizar la implementación.
Vamos a entrenar una red que podamos usar para clasificar imágenes de perros y gatos de Kaggle. Antes de esto comenzaremos a escribir un modelo sencillo. Esto ayudará a entender cómo funciona Keras. Comenzaré con el código. Si lo observamos, hay comentarios antes de cada línea de código. Estos comentarios explican en cierta medida lo que sucede en esa línea particular de código. Para ejecutar el código, se puede utilizar cualquier base de datos conteniendo imágenes de perros y gatos, o podemos descargar los datos de la muestra de Kaggle. Para poder descargar los datos de la muestra es necesario registrarse en Kaggle. Aquí está el enlace de Kaggle.
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense


# tamaño esperado de la imagen
img_width, img_height = 150, 150
# carpeta que contiene las imágenes sobre
# las que se entrenará la red. La carpeta de entrenamiento
# tiene dos subcarpetas, perros y gatos.
train_data_dir = 'data/train'
# carpeta que contiene las muestras de validación
# la estructura de la carpeta es la misma que la de la carpeta de entrenamiento
validation_data_dir = 'data/validation'
# número de imágenes que se consideran para el entrenamiento
train_samples = 2000
# número de imágenes se utilizan en la validación
validation_samples = 800
# número de veces que se ejecutará la red # sobre el conjunto de entrenamiento antes
# de empezar con la validación
epoch = 50
# ** Inicio del modelo **
model = Sequential()
model.add(Convolution2D(32, 3, 3, input_shape=(3, img_width, img_height)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
# ** Fin del modelo **
model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

# esta es la mejora de la configuración que utilizaremos para el entrenamiento
# en el que generamos un gran número de imágenes transformadas de manera que el
# modelo puede tratar con una gran variedad de escenarios del mundo real
train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

# esta es la mejora de la configuración que utilizaremospara la prueba:
# sólo para reajuste
test_datagen = ImageDataGenerator(rescale=1./255)
# esta sección toma imágenes de la carpeta
# y las pasa al ImageGenerator que crea entonces
# un gran número de versiones transformadas
train_generator = train_datagen.flow_from_directory(
        train_data_dir,
        target_size=(img_width, img_height),
        batch_size=32,
        class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
        validation_data_dir,
        target_size=(img_width, img_height),
        batch_size=32,
        class_mode='binary')
# aquí es donde se produce el proceso real
# y llevará algún tiempo ejecutar este paso.
model.fit_generator(
        train_generator,
        samples_per_epoch=train_samples,
        nb_epoch=epoch,
        validation_data=validation_generator,
        nb_val_samples=validation_samples)

model.save_weights('trial.h5')
El código es autoexplicativo. Se puede reemplazar la sección entre 'Inicio del modelo' y 'Final del modelo' para usar otros modelos. Tendremos nuestro propio código clasificador, y yo serviré de guía en el código.
Primero importamos algunas dependencias de Keras. A continuación, definimos las dimensiones de la imagen que pasará a la red. Después de eso informamos el código donde están los conjuntos de imágenes: el conjunto de datos de entrenamiento y el conjunto de datos de validación. Después se construye el modelo desde el principio hasta el final. No voy a entrar en profundidad en el modelo, ya que es una implementación VGGNet estándar. Los detalles sobre la arquitectura de red se pueden encontrar en el siguiente documento arXiv:
Very Deep Convolutional Networks for Large-Scale Image Recognition
K. Simonyan, A. Zisserman
arXiv:1409.1556
A continuación, el código genera transformaciones en los datos. Aquí se puede acortar, estirar, inclinar el conjunto de datos para que la red no entre en sobre entrenamiento. Creamos generadores para que el código pueda leer imágenes de las carpetas especificadas. Después se inicia el procesamiento. El sistema realiza el entrenamiento y la validación el número veces que se mencionan en 'epoch'. Finalmente almacenamos estos pesos para  usarlos en el futuro y evitar que la red tenga que entrenarse de nuevo. Si tiene  dudas, por favor, decídase y  formule las preguntas que considere. Intentaré contestarlas según mi leal saber y entender.
El modelo anterior es sencillo y sólo existe por una explicación más sencilla aún. La clasificación de gatos y perros podría no tener tanto éxito debido a la cantidad de datos que tenemos. Así que tenemos que acudir al aprendizaje de transferencia. En el aprendizaje de transferencia trabajamos en modelos que entrenamos para resolver cuestiones similares. Tomamos los pesos de entrenamiento y los reutilizamos para resolver cuestiones completamente diferentes. Entrenamos modelos que pre-entrenamos sobre imágenes para clasificar diferentes cosas. ¿Por qué funciona esto? Es porque el modelo que vamos a utilizar fue entrenado para hacer la clasificación de imágenes. Las capas más profundas siempre serán capaces de clasificar de forma genérica, y trabajarán en el nivel de detección de bordes y curvas. De ahí el término transferencia de aprendizaje, ya que se transfiere el aprendizaje del planteamiento de un problema al de otro problema distinto. Esto podría funcionar bien en nuestro caso. Pero podemos hacer que funcione mejor. A continuación entrenamos las capas superiores. Estas capas realmente se preocupan por los elementos reales que se clasifican. Las entrenamos con nuestro conjunto de datos de entrenamiento. Podemos llamar a este conjunto de datos dominio específico. Esto le permite a la red comprender que es exactamente lo que queremos clasificar. Así que el código es el siguiente:
import os
import h5py
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D, ZeroPadding2D
from keras.layers import Activation, Dropout, Flatten, Dense

# ruta a los archivos de pesos del modelo.
weights_path = 'vgg16_weights.h5'
top_model_weights_path = 'fc_model.h5'
# dimensiones de las imágenes.
img_width, img_height = 150, 150

train_data_dir = 'data/train'
validation_data_dir = 'data/validation'
nb_train_samples = 2000
nb_validation_samples = 800
nb_epoch = 50

# creación de la red VGG16
model = Sequential()
model.add(ZeroPadding2D((1, 1), input_shape=(3, img_width, img_height)))

model.add(Convolution2D(64, 3, 3, activation='relu', name='conv1_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(64, 3, 3, activation='relu', name='conv1_2'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))

model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(128, 3, 3, activation='relu', name='conv2_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(128, 3, 3, activation='relu', name='conv2_2'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))

model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(256, 3, 3, activation='relu', name='conv3_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(256, 3, 3, activation='relu', name='conv3_2'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(256, 3, 3, activation='relu', name='conv3_3'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))

model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv4_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv4_2'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv4_3'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))

model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_2'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_3'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))

# cargar los pesos de las redes VGG16 networks
# (entrenadas sobre ImageNet, ganaron la competición ILSVRC en 2014)
# nota: cuando hay una correspondencia completa entre la definición del modelo
# y el archivo de pesos, se puede llamar a model.load_weights(filename)
imponer os.path.exists(weights_path), 'Los pesos del modelo no se encuentran (ver la variable "weights_path" en el script).'
f = h5py.File(weights_path)
for k in range(f.attrs['nb_layers']):
    if k >= len(model.layers):
        # no miramos las últimas capas (completamente conectadas) del archivo
        break
    g = f['layer_{}'.format(k)]
    weights = [g['param_{}'.format(p)] for p in range(g.attrs['nb_params'])]
    model.layers[k].set_weights(weights)
f.close()
print('Model loaded.')

# creación de un modelo clasificador para situarlo encima del modelo convolucional top_model = Sequential()
top_model.add(Flatten(input_shape=model.output_shape[1:]))
top_model.add(Dense(256, activation='relu'))
top_model.add(Dropout(0.5))
top_model.add(Dense(1, activation='sigmoid'))

# hay que notar que es necesario empezar con un clasificador
# completamente entrenado, incluyendo el clasificador situado arriba,
# para realizar con éxito un ajuste fino
top_model.load_weights(top_model_weights_path)

# añadir el modelo en la parte superior de la base convolucional
model.add(top_model)

# establecer las primeras 25 capas (hasta el último bloque de convolución)
# a las no entrenables (los pesos no se actualizarán)
for layer in model.layers[:25]:
    layer.trainable = False

# compilar el modelo con un SDG/ momento optimizador
# y a una tasa de aprendizaje muy baja.
model.compile(loss='binary_crossentropy',
              optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
              metrics=['accuracy'])

# preparación de los datos de mejora de la configuración
train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
        train_data_dir,
        target_size=(img_height, img_width),
        batch_size=32,
        class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
        validation_data_dir,
        target_size=(img_height, img_width),
        batch_size=32,
        class_mode='binary')

# ajuste fino del modelo
model.fit_generator(
        train_generator,
        samples_per_epoch=nb_train_samples,
        nb_epoch=nb_epoch,
        validation_data=validation_generator,
        nb_val_samples=nb_validation_samples)
Los pesos para VGG16 se pueden conseguir en mi Github. También se puede conseguir el archivo de pesos del fc_model ejecutando este programa sobre el conjunto de datos dataset. Se puede utilizar el mismo conjunto de pesos del enlace compartido VGG16. Se puede ajustar el número de epoch para conseguir un mejor aprendizaje, pero tener cuidado porque esto podría llevar a la sobrealimentación. Yo he utilizado esta técnica en una gran cantidad de casos prácticos en mi trabajo. Un caso práctico es distinguir entre prescripciones y no prescripciones. Utilizamos exactamente el mismo modelo entrenado en los datos de ImageNet de gatos y perros para clasificar las recetas. Espero que lo puedan usar en casos prácticos en el mundo real. Comuníquenos cualquier caso interesante que haya resuelto utilizando este método.
Gran parte del contenido de este artículo está extraído de una entrada de blog de Keras.
Puede seguirme en twitter y también puede registrarse en una pequeña lista de correo mailing list. Si le ha gustado este artículo, pulse el botón ❤ para recomendarlo. Esto ayudará a otros usuarios de Medium a encontrarlo.
  

Sunday, March 12, 2017

EL ROBOT CASSIE DE AGILITY ROBOTICS

Agility Robotics surgida de una labor de investigación de la Oregon State University (OSU), tiene como objetivo revolucionar la movilidad de los robots

Por David Stauth, 541-737-0787

Contacto de la OSU: Jonathan Hurst, 541-737-7010 o jonathan.hurst@oregonstate.edu
Contacto de Agility Robotics: Damion Shelton, 541-738-8888 x7001 o damion.shelton@agilityrobotics.com

Al final de este artículo se proporcionan enlaces a una foto y a varios archivos de audio y video.
Este artículo está disponible online en: http://bit.ly/2kr8yPo

CORVALLIS, Oregón. La rápida expansión del programa de robótica de la Escuela de Ingeniería de la Oregon State University ha dado lugar a una de sus primeras empresas, una empresa centrada en la locomotora con patas que puede revolucionar la movilidad de los robots al permitirles acceder a cualquier sitio como lo hacen las personas.



La firma, Agility Robotics, tiene sedes en Albany (Oregón), y Pittsburgh, (Pensilvania) y ya cuenta con sus primeros clientes; licitará algunas tecnologías desarrolladas por primera vez en la OSU, y planea emplear estos fundamentos científicos en la investigación y desarrollo de sus productos.

Afirman los responsables de la empresa que una de las aplicaciones más importantes para este tipo de movilidad es la entrega de paquetes. A largo plazo, la movilidad avanzada permitirá el envío de forma  automatizada y tan barato que su coste será irrelevante, abriendo nuevas y vastas posibilidades en el comercio minorista, al tiempo que reducirá los costes de fabricación y producción.

'Esta tecnología explotará en algún momento, cuando produzcamos vehículos tan automatizados y robots tan eficientes que las entregas y envíos sean prácticamente gratuitos', dijo Jonathan Hurst, profesor asociado de robótica en la Escuela de Ingeniería de la OSU, director de tecnología de Agility Robótics y líder internacional en el desarrollo de la locomoción con patas.

'Es muy sencillo, los robots con patas pueden acceder a muchos lugares a los que los robots con ruedas no pueden hacerlo. Esta será la clave para las que las entregas se puedan realizar las 24 horas del día, los 365 días del año, por una flota de furgonetas autónomas que lleguen hasta la acera, y un robot que sale de su interior haga la entrega en la puerta del cliente'.



'Esta capacidad de los robots liberará a las personas de las compras de fin de semana, reducirá el consumo de energía y los consumidores dispondrán de más tiempo para hacer lo que deseen. Esto dará lugar al desarrollo de una logística automatizada eficiente entre los almacenes provistos de los últimos adelantos y el resto del mundo'.

Esta visión a largo plazo supondrá tener que dar muchos pasos, dijeron los responsables de la empresa.

Algunas de las primeras ventas de Agility Robotics se realizarán a otras instituciones académicas y de investigación, para hacer crecer la comunidad investigadora y educar a una nueva generación de ingenieros en esta área, dijeron responsables de la empresa. Lo que actualmente ofrece la firma es un robot bípedo llamado “Cassie' – similar a la versión del prototipo exhibido el 8 de febrero en el discurso sobre el estado de la Universidad de la OSU en Portland, Oregón, por el Presidente Edward J. Ray.

El robot Cassie puede permanecer de pie, se puede orientar, y sufrir caídas sin romperse. Comparado con los robots desarrollados anteriormente en la OSU, tiene la mitad de peso y una capacidad mucho mayor.

'El anterior robot, ATRIAS, tenía motores que funcionaban uno en oposición al otro, lo que hacía que tuviera un funcionamiento ineficiente', dijo Hurst. 'Con Cassie, hemos solucionado este problema y además de estar dotado de la capacidad de orientación, le incorporamos pies y lo protegimos con un sistema sellado, lo que le permite funcionar al aire libre, bajo lluvia y nieve al tiempo que seguimos con las pruebas del controlador'.

La cuestión concreta de los motores que trabajan en oposición dio lugar a una amplia investigación teórica para crear los marcos matemáticos necesarios que ayudaran a resolver el problema. La configuración final de las extremidades de Cassie se parece mucho a la de las patas de un avestruz o a las de otras aves preparadas para correr.

'No estábamos tratando de reproducir la apariencia de un animal, sino de aplicar sus técnicas para que pudiera ser ágil, eficiente y robusto en su movimiento', dijo Hurst.

'No nos importaba su apariencia y lo que queríamos era averiguar porqué la madre naturaleza hizo las cosas de cierta manera. Pero a pesar de que no estábamos tratando de imitar la forma, lo que apareció al final de nuestra investigación se parecía mucho a las patas de un animal'.

La creación de Cassie ha supuesto 16 meses de trabajo, una subvención de 1 millón de dólares de la Advanced Research Projects Agency del  Department of Defense de Estados Unidos, y ya es una de las innovaciones líderes en el mundo de los robots con patas.



Responsables de la empresa han declarado que tienen planeado que la producción inicial se lleve a cabo en Oregón y enfocarán su negocio a aplicaciones comerciales de robots con patas. La contratación está prevista para las actividades de investigación, producción y desarrollo.

'La revolución de la robótica traerá consigo enormes cambios, tal vez antes de lo que muchos se den cuenta', dijo Hurst. 'Esperamos que Agility Robotics sea una parte importante de esa revolución. Queremos cambiar y mejorar la vida de las personas'.

Responsables de la empresa indicaron que el acceso a la base investigadora y a la formación de los estudiantes de la OSU ayudará a su crecimiento, proporcionando la experiencia necesaria y mano de obra capacitada. Grad School Hub ha nominado a la OSU como la mejor institución de la zona oeste de Estados Unidos y ha considerado qeu su programa ocupe el cuarto puesto entre los programas líderes a nivel nacional en investigación y educación en robótica.

El mes pasado, los responsables de la OSU anunciaron también que la Universidad será un socio académico fundador del nuevo Manufacturing USA Institute, el Advance Robotics Manufacturing Innovation Hub. Este amplio programa con 14 institutos es una iniciativa federal y de una empresa privada con un coste de 3 millones de dólares diseñada para mejorar la competitividad de Estados Unidos en fabricación avanzada.

-30-

Nota del editor: Para ilustrar el artículo están disponibles una foto, y grabaciones de audio y video.
·         Foto del robot Cassie: https://flic.kr/p/RYRAuR
·         Vídeo de YouTube para las redes sociales: http://bit.ly/2kwD5xV
·         Vídeo adicional, entrevista de audio y vídeo de fondo B-roll: http://bit.ly/2lsVSrg

La Escuela de Ingeniería de la OSU: El programa de la Escuela de Ingeniería de la OSU se encuentra entre los programas de ingeniería más extensos y productivos del país. Desde 1999, la Universidad ha más que triplicado sus gastos en investigación hasta llegar a 37,2 millones de dólares, haciendo incapié en la investigación y la innovación, con un alto grado de colaboración, que aportn soluciones a problemas globales. Es líder en áreas de investigación de marcas, entre las que se incluyen la salud de precisión, energía limpia, infraestructuras resistentes y fabricación avanzada, y áreas estratégicas específicas, incluyendo robótica, investigación de materiales y agua no contaminada.


Agility Robotics: Fundada a finales de 2015, Agility Robotics está trabajando para establecer la locomoción con patas como una alternativa real a la locomoción con ruedas y bandas de rodadura de los robots móviles tradicionales. Agility Robotics, como licenciatario comercial exclusivo de la tecnología robótica bípeda patentada de la OSU, y con un experimentado equipo de científicos e ingenieros, está en una posición única para convertirse en uno de los líderes en robótica móvil.

Friday, March 3, 2017

Aprendizaje profundo para principiantes

Nota: Este artículo es una traducción del original que aparece en HACKERNOON: https://hackernoon.com/supervised-deep-learning-in-image-classification-for-noobs-part-1-9f831b6d430d#.rbtjt4bkd

Muchas gracias al autor Debarko De por permitir su publicación en español. 

Aprendizaje profundo para principiantes (Parte I)
Hace tiempo que el software de aprendizaje profundo va ganando terreno, y su aplicación se ha extendido a múltiples campos.
En estas entradas aprenderá a resolver el problema elemental de detectar un objeto (como puede ser un gato o un perro) en una imagen. A medida que avance en la solución, podrá aprender sobre un tipo concreto de aprendizaje profundo. También podrá codificar en Keras y Tensorflow, dos de las famosas bibliotecas de esta tecnología. 
No nos vamos a ocupar de las matemáticas que hay detrás del aprendizaje profundo.
La serie tiene dos partes. La primera parte trata de los fundamentos y trucos del aprendizaje profundo. En la segunda parte, vamos a investigar la forma de crear sus propios modelos en Keras.
Pero antes de entrar en materia me gustaría presentarme. Soy ingeniero informático y actualmente trabajo en @ Practo. Con anterioridad he trabajado en el desarrollo de juegos en la plataforma de Facebook (cuando se trataba de una sola tarea) y más tarde en juegos para móviles.
Para empezar, ¿qué es aprendizaje profundo? ¿Por qué se le llama profundo? ¿Es un sistema que realmente aprende?
Comencemos con un poco de historia. El aprendizaje profundo es el último grito en el campo de las redes neuronales, aunque en realidad éstas surgieron en los años 60 del pasado siglo. Si no sabe lo que es una red neural, no se preocupe porque lo explicaré al final de esta entrada. En 2006 un genio llamado Geoffrey Hinton y sus colaboradores publicaron un artículo. El artículo contenía una interesante descripción de un tipo de red neuronal. En 2012, dos de los estudiantes colaboradores de Hinton ganaron una competición (ILSVRC) por un margen que duplicaba al de sus competidores más cercanos. Esto demostró a todo el mundo que el trabajo de Hinton puede llegar a solucionar problemas muy interesantes.
Vamos a tratar de resolver el problema de Clasificación de imágenes. Con la operación de clasificación lo que estamos tratando de hacer es intentar entender cuál es el contenido de una imagen. Las posibilidades actuales limitan la solución, ya que tratan imágenes que sólo tienen un tipo de objeto. La imagen será la de un gato o un perro. Para hacerlo más sencillo, no vamos a clasificar por ejemplo las imágenes que tienen un perro sentado en un coche.
En una red neuronal, hay un número n de neuronas que se interconectan entre ellas de una manera lineal. Se presenta una imagen  en la entrada de la red y ésta decide a qué clase de salida pertenece. Entrenar una red significa presentar en la entrada una gran cantidad de imágenes de varias clases. Cada una de estas imágenes ya tiene la etiqueta de pertenencia a una de las clases.


Figura básica que representa la sección transversal de una red neuronal convolucional

La red neuronal es una sencilla fórmula matemática que se parece a algo así:
x * w = y
Supongamos que la x es la imagen de entrada y  la y es una salida, que es la clase que define la red. x es constante porque sólo hay un conjunto fijo de imágenes. La red proporciona la y como salida. Sólo podemos cambiar la w. Llamamos w al peso de una capa neuronal. El proceso de entrenamiento consta de dos partes: el paso hacia adelante y la propagación hacia atrás. En el paso hacia adelante proporcionamos imágenes a la entrada de la red (x) y la red genera algún tipo de salida y'. La proximidad de y' a y es el error de la red.
En la propagación hacia atrás, la red intenta disminuir el error ajustando el peso w. En la jerga se conoce a w como hiper parámetro, kernel, o filtro. El problema con las redes neuronales es que  todos los datos pasan de una capa a la otra. Para resolver esto vamos a utilizar las redes neuronales convolucionales. ¿Y qué es la convolución? Lo veremos a continuación.
Capa de convolución


Capa de convolución
Las redes neuronales están totalmente conectadas, lo que significa que una capa de neuronas pasaría todo el conjunto de datos a la siguiente capa. La siguiente capa procesaría todos los datos  y así sucesivamente. Esto funciona para imágenes simples como son las de 8x8 o incluso de 36x36. Pero las imágenes prácticas son de un tamaño de 1024x768, lo que supone una enorme tarea de cálculo. Las imágenes son fijas por naturaleza. Esto significa que los datos estadísticos de una parte de la imagen son los mismos que los de cualquier otra parte. Por lo tanto, una característica aprendida en una zona puede presentar coincidencias de patrones similares en otra zona. En una imagen grande, tomamos una sección pequeña y la pasamos a través de todos los puntos de la imagen grande. Al pasar por cualquier punto realizamos la convolución de los mismos en una única posición. Trate de imaginar que una gran caja de datos se convierte en una pequeña caja de datos para la siguiente capa de neurona. Ese es el resultado de la convolución. Esto ayuda a realizar un cálculo más rápido sin perder precisión en los datos. Cada pequeña sección de la imagen que pasa sobre la imagen grande realiza las funciones de filtro. Los filtros se configuran más tarde basándose en los datos de la propagación hacia atrás (llegaremos a eso en un bit).
Capa de agrupación
El paso siguiente es la agrupación. La agrupación no es otra cosa que el muestreo de una imagen con una frecuencia inferior a la normal. De nuevo ayuda al procesador a procesar los datos más rápido. Hay muchas técnicas de agrupación. Una de ellas es la agrupación máxima en la que tomamos el mayor de los valores de los píxeles de un segmento. También existe la llamada agrupación media. En lugar de elegir el píxel con mayor valor, calculamos la media. La agrupación hace que la red sea invariante a las traducciones de la forma, tamaño y escala. El agrupamiento máximo es generalmente el predominante.

Un sencillo ejemplo de agrupación máxima, en la que elegimos el pixel de mayor valor en cada cuadrado de color.
Capa de activación
Una neurona se comporta como un clasificador lineal. Una neurona tiene la capacidad de encenderse o apagarse dependiendo de ciertas secciones consecutivas de datos de entrada. A esta propiedad de la neurona la llamamos activación. Las funciones de activación son funciones matemáticas que se comportan como válvulas. Suponga que hay una válvula que se abre cuando hay una buena cantidad de presión como en el caso de una olla a presión. Los datos que hacen que una función de activación se vuelva verdadera marca la neurona como activa. Clasificamos una imagen basándonos en las neuronas que se activaron de entre todas ellas. Hay muchas funciones de activación, pero ReLu es las más famosa. El porqué de elegir ReLu es una cuestión que está fuera del alcance de este documento. Pronto escribiré otro artículo que habla sobre diferentes funciones de Activación.
Propagación hacia atrás
La propagación hacia atrás es el proceso en el que intentamos reducir el error. Por error, me refiero a la diferencia entre y e y'. Esto ayudará a ajustar el conjunto de datos que le dimos a la red. Realizamos la propagación hacia atrás utilizando el proceso de descenso de gradiente. Este proceso intenta aproximar el valor de error a cero.
¿Que sigue?
Ya hemos tenido suficiente literatura para empezar a trabajar en las aplicaciones de redes neuronales convolucionales ó # CNNs. Para cómo y cuándo usted se quede atrapado en la fase de implementación, puede leer más sobre ese tema en particular. Si formula preguntas en la sección de comentarios, trataré de contestarlas personalmente. Esto nos lleva al final de esta parte de la serie. Actualmente estoy trabajando en la segunda parte. Hablaré de la implementación de redes neuronales convolucionales mediante código. La publicaré la próxima semana.
En este espacio se insertará el enlace al siguiente artículo. Sígame en twitter y también puede registrarse en una pequeña lista de correo mailing list. Si le ha gustado este artículo, pulse el botón ❤ para recomendarlo. Esto ayudará a otros usuarios de Medium a encontrarlo.