PyTorch - Guía rápida

PyTorch se define como una biblioteca de aprendizaje automático de código abierto para Python. Se utiliza para aplicaciones como el procesamiento del lenguaje natural. Inicialmente fue desarrollado por el grupo de investigación de inteligencia artificial de Facebook y el software Pyro de Uber para programación probabilística que se basa en él.

Originalmente, PyTorch fue desarrollado por Hugh Perkins como un contenedor de Python para LusJIT basado en el marco Torch. Hay dos variantes de PyTorch.

PyTorch rediseña e implementa Torch en Python mientras comparte las mismas bibliotecas C centrales para el código backend. Los desarrolladores de PyTorch ajustaron este código de back-end para ejecutar Python de manera eficiente. También mantuvieron la aceleración de hardware basada en GPU, así como las características de extensibilidad que hicieron Torch basado en Lua.

Caracteristicas

Las principales características de PyTorch se mencionan a continuación:

Easy Interface- PyTorch ofrece una API fácil de usar; por lo tanto, se considera que es muy simple de operar y se ejecuta en Python. La ejecución del código en este marco es bastante fácil.

Python usage- Esta biblioteca se considera Pythonic y se integra sin problemas con la pila de ciencia de datos de Python. Por lo tanto, puede aprovechar todos los servicios y funcionalidades que ofrece el entorno Python.

Computational graphs- PyTorch proporciona una plataforma excelente que ofrece gráficos computacionales dinámicos. Por lo tanto, un usuario puede cambiarlos durante el tiempo de ejecución. Esto es muy útil cuando un desarrollador no tiene idea de cuánta memoria se requiere para crear un modelo de red neuronal.

PyTorch es conocido por tener tres niveles de abstracción como se indica a continuación:

  • Tensor: matriz n-dimensional imperativa que se ejecuta en GPU.

  • Variable: nodo en el gráfico computacional. Esto almacena datos y gradiente.

  • Módulo: capa de red neuronal que almacenará estados o pesos aprendibles.

Ventajas de PyTorch

Las siguientes son las ventajas de PyTorch:

  • Es fácil de depurar y comprender el código.

  • Incluye muchas capas como Torch.

  • Incluye muchas funciones de pérdida.

  • Puede considerarse como una extensión de NumPy a las GPU.

  • Permite construir redes cuya estructura depende de la propia computación.

TensorFlow frente a PyTorch

A continuación, veremos las principales diferencias entre TensorFlow y PyTorch:

PyTorch TensorFlow

PyTorch está estrechamente relacionado con el marco Torch basado en lua que se utiliza activamente en Facebook.

TensorFlow es desarrollado por Google Brain y se utiliza activamente en Google.

PyTorch es relativamente nuevo en comparación con otras tecnologías competitivas.

TensorFlow no es nuevo y muchos investigadores y profesionales de la industria lo consideran una herramienta para llevar.

PyTorch incluye todo de manera imperativa y dinámica.

TensorFlow incluye gráficos estáticos y dinámicos como combinación.

El gráfico de cálculo en PyTorch se define durante el tiempo de ejecución.

TensorFlow no incluye ninguna opción de tiempo de ejecución.

PyTorch incluye implementación para marcos móviles e integrados.

TensorFlow funciona mejor para marcos integrados.

PyTorch es un marco de aprendizaje profundo popular. En este tutorial, consideramos "Windows 10" como nuestro sistema operativo. Los pasos para una configuración ambiental exitosa son los siguientes:

Paso 1

El siguiente enlace incluye una lista de paquetes que incluye paquetes adecuados para PyTorch.

https://drive.google.com/drive/folders/0B-X0-FlSGfCYdTNldW02UGl4MXM

Todo lo que necesita hacer es descargar los paquetes respectivos e instalarlos como se muestra en las siguientes capturas de pantalla:

Paso 2

Implica verificar la instalación del marco PyTorch usando Anaconda Framework.

El siguiente comando se usa para verificar lo mismo:

conda list

"Lista de Conda" muestra la lista de marcos que está instalado.

La parte resaltada muestra que PyTorch se ha instalado correctamente en nuestro sistema.

Las matemáticas son vitales en cualquier algoritmo de aprendizaje automático e incluyen varios conceptos básicos de matemáticas para diseñar el algoritmo correcto de una manera específica.

La importancia de los temas de matemáticas para el aprendizaje automático y la ciencia de datos se menciona a continuación:

Ahora, centrémonos en los principales conceptos matemáticos del aprendizaje automático que son importantes desde el punto de vista del procesamiento del lenguaje natural:

Vectores

El vector se considera una matriz de números que es continua o discreta y el espacio que consta de vectores se denomina espacio vectorial. Las dimensiones espaciales de los vectores pueden ser finitas o infinitas, pero se ha observado que los problemas de aprendizaje automático y ciencia de datos tratan con vectores de longitud fija.

La representación vectorial se muestra como se menciona a continuación:

temp = torch.FloatTensor([23,24,24.5,26,27.2,23.0])
temp.size()
Output - torch.Size([6])

En el aprendizaje automático, tratamos con datos multidimensionales. Por lo tanto, los vectores se vuelven muy cruciales y se consideran características de entrada para cualquier enunciado de problema de predicción.

Escalares

Se dice que los escalares tienen dimensiones cero que contienen solo un valor. Cuando se trata de PyTorch, no incluye un tensor especial con dimensiones cero; por lo tanto, la declaración se hará de la siguiente manera:

x = torch.rand(10)
x.size()
Output - torch.Size([10])

Matrices

La mayoría de los datos estructurados generalmente se representan en forma de tablas o una matriz específica. Usaremos un conjunto de datos llamado Boston House Prices, que está disponible en la biblioteca de aprendizaje automático de Python scikit-learn.

boston_tensor = torch.from_numpy(boston.data)
boston_tensor.size()
Output: torch.Size([506, 13])
boston_tensor[:2]
Output:
Columns 0 to 7
0.0063 18.0000 2.3100 0.0000 0.5380 6.5750 65.2000 4.0900
0.0273 0.0000 7.0700 0.0000 0.4690 6.4210 78.9000 4.9671
Columns 8 to 12
1.0000 296.0000 15.3000 396.9000 4.9800
2.0000 242.0000 17.8000 396.9000 9.1400

El principio fundamental de la red neuronal incluye una colección de elementos básicos, es decir, neurona artificial o perceptrón. Incluye varias entradas básicas como x1, x2… .. xn que produce una salida binaria si la suma es mayor que el potencial de activación.

La representación esquemática de la neurona de muestra se menciona a continuación:

La salida generada se puede considerar como la suma ponderada con potencial de activación o sesgo.

$$ Salida = \ sum_jw_jx_j + Bias $$

La arquitectura de red neuronal típica se describe a continuación:

Las capas entre la entrada y la salida se denominan capas ocultas, y la densidad y el tipo de conexiones entre las capas es la configuración. Por ejemplo, una configuración totalmente conectada tiene todas las neuronas de la capa L conectadas a las de L + 1. Para una localización más pronunciada, podemos conectar solo un vecindario local, digamos nueve neuronas, a la siguiente capa. La figura 1-9 ilustra dos capas ocultas con conexiones densas.

Los diversos tipos de redes neuronales son los siguientes:

Redes neuronales feedforward

Las redes neuronales de retroalimentación incluyen unidades básicas de la familia de redes neuronales. El movimiento de datos en este tipo de red neuronal es desde la capa de entrada a la capa de salida, a través de las capas ocultas presentes. La salida de una capa sirve como capa de entrada con restricciones sobre cualquier tipo de bucle en la arquitectura de red.

Redes neuronales recurrentes

Las redes neuronales recurrentes son cuando el patrón de datos cambia en consecuencia durante un período. En RNN, se aplica la misma capa para aceptar los parámetros de entrada y mostrar los parámetros de salida en la red neuronal especificada.

Las redes neuronales se pueden construir utilizando el paquete torch.nn.

Es una red de alimentación directa simple. Toma la entrada, la alimenta a través de varias capas una tras otra, y finalmente da la salida.

Con la ayuda de PyTorch, podemos utilizar los siguientes pasos para el procedimiento de entrenamiento típico de una red neuronal:

  • Defina la red neuronal que tiene algunos parámetros (o pesos) que se pueden aprender.
  • Iterar sobre un conjunto de datos de entradas.
  • Procesar la entrada a través de la red.
  • Calcule la pérdida (qué tan lejos está la salida de ser correcta).
  • Propagar gradientes de regreso a los parámetros de la red.
  • Actualice los pesos de la red, generalmente usando una actualización simple como se indica a continuación
rule: weight = weight -learning_rate * gradient

La inteligencia artificial es una tendencia en la actualidad en mayor medida. El aprendizaje automático y el aprendizaje profundo constituyen la inteligencia artificial. El diagrama de Venn que se menciona a continuación explica la relación entre el aprendizaje automático y el aprendizaje profundo.

Aprendizaje automático

El aprendizaje automático es el arte de la ciencia que permite que las computadoras actúen según los algoritmos diseñados y programados. Muchos investigadores piensan que el aprendizaje automático es la mejor manera de avanzar hacia la IA a nivel humano. Incluye varios tipos de patrones como:

  • Patrón de aprendizaje supervisado
  • Patrón de aprendizaje no supervisado

Aprendizaje profundo

El aprendizaje profundo es un subcampo del aprendizaje automático en el que los algoritmos en cuestión se inspiran en la estructura y función del cerebro llamadas Redes neuronales artificiales.

El aprendizaje profundo ha ganado mucha importancia a través del aprendizaje supervisado o el aprendizaje a partir de algoritmos y datos etiquetados. Cada algoritmo del aprendizaje profundo pasa por el mismo proceso. Incluye una jerarquía de transformación no lineal de entrada y se utiliza para crear un modelo estadístico como salida.

El proceso de aprendizaje automático se define mediante los siguientes pasos:

  • Identifica conjuntos de datos relevantes y los prepara para su análisis.
  • Elige el tipo de algoritmo a utilizar.
  • Construye un modelo analítico basado en el algoritmo utilizado.
  • Entrena el modelo en conjuntos de datos de prueba y lo revisa según sea necesario.
  • Ejecuta el modelo para generar puntajes de prueba.

En este capítulo, analizaremos la principal diferencia entre los conceptos de aprendizaje automático y profundo.

La cantidad de datos

El aprendizaje automático funciona con diferentes cantidades de datos y se utiliza principalmente para pequeñas cantidades de datos. El aprendizaje profundo, por otro lado, funciona de manera eficiente si la cantidad de datos aumenta rápidamente. El siguiente diagrama muestra el funcionamiento del aprendizaje automático y el aprendizaje profundo con respecto a la cantidad de datos:

Dependencias de hardware

Los algoritmos de aprendizaje profundo están diseñados para depender en gran medida de máquinas de alta gama, al contrario de los algoritmos tradicionales de aprendizaje automático. Los algoritmos de aprendizaje profundo realizan una gran cantidad de operaciones de multiplicación de matrices que requieren un gran soporte de hardware.

Ingeniería de funciones

La ingeniería de características es el proceso de poner el conocimiento del dominio en características específicas para reducir la complejidad de los datos y crear patrones que sean visibles para los algoritmos de aprendizaje.

Por ejemplo, los patrones tradicionales de aprendizaje automático se centran en píxeles y otros atributos necesarios para el proceso de ingeniería de características. Los algoritmos de aprendizaje profundo se enfocan en características de alto nivel a partir de datos. Reduce la tarea de desarrollar un extractor de nuevas funciones para cada nuevo problema.

PyTorch incluye una característica especial de crear e implementar redes neuronales. En este capítulo, crearemos una red neuronal simple con una capa oculta que desarrolla una única unidad de salida.

Usaremos los siguientes pasos para implementar la primera red neuronal usando PyTorch:

Paso 1

Primero, necesitamos importar la biblioteca PyTorch usando el siguiente comando:

import torch 
import torch.nn as nn

Paso 2

Defina todas las capas y el tamaño del lote para comenzar a ejecutar la red neuronal como se muestra a continuación:

# Defining input size, hidden layer size, output size and batch size respectively
n_in, n_h, n_out, batch_size = 10, 5, 1, 10

Paso 3

Como la red neuronal incluye una combinación de datos de entrada para obtener los datos de salida respectivos, seguiremos el mismo procedimiento que se indica a continuación:

# Create dummy input and target tensors (data)
x = torch.randn(batch_size, n_in)
y = torch.tensor([[1.0], [0.0], [0.0], 
[1.0], [1.0], [1.0], [0.0], [0.0], [1.0], [1.0]])

Etapa 4

Cree un modelo secuencial con la ayuda de funciones integradas. Con las siguientes líneas de código, cree un modelo secuencial:

# Create a model
model = nn.Sequential(nn.Linear(n_in, n_h),
   nn.ReLU(),
   nn.Linear(n_h, n_out),
   nn.Sigmoid())

Paso 5

Construya la función de pérdida con la ayuda del optimizador Gradient Descent como se muestra a continuación:

Construct the loss function
criterion = torch.nn.MSELoss()
# Construct the optimizer (Stochastic Gradient Descent in this case)
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01)

Paso 6

Implemente el modelo de descenso de gradiente con el bucle iterativo con las líneas de código dadas:

# Gradient Descent
for epoch in range(50):
   # Forward pass: Compute predicted y by passing x to the model
   y_pred = model(x)

   # Compute and print loss
   loss = criterion(y_pred, y)
   print('epoch: ', epoch,' loss: ', loss.item())

   # Zero gradients, perform a backward pass, and update the weights.
   optimizer.zero_grad()

   # perform a backward pass (backpropagation)
   loss.backward()

   # Update the parameters
   optimizer.step()

Paso 7

La salida generada es la siguiente:

epoch: 0 loss: 0.2545787990093231
epoch: 1 loss: 0.2545052170753479
epoch: 2 loss: 0.254431813955307
epoch: 3 loss: 0.25435858964920044
epoch: 4 loss: 0.2542854845523834
epoch: 5 loss: 0.25421255826950073
epoch: 6 loss: 0.25413978099823
epoch: 7 loss: 0.25406715273857117
epoch: 8 loss: 0.2539947032928467
epoch: 9 loss: 0.25392240285873413
epoch: 10 loss: 0.25385022163391113
epoch: 11 loss: 0.25377824902534485
epoch: 12 loss: 0.2537063956260681
epoch: 13 loss: 0.2536346912384033
epoch: 14 loss: 0.25356316566467285
epoch: 15 loss: 0.25349172949790955
epoch: 16 loss: 0.25342053174972534
epoch: 17 loss: 0.2533493936061859
epoch: 18 loss: 0.2532784342765808
epoch: 19 loss: 0.25320762395858765
epoch: 20 loss: 0.2531369626522064
epoch: 21 loss: 0.25306645035743713
epoch: 22 loss: 0.252996027469635
epoch: 23 loss: 0.2529257833957672
epoch: 24 loss: 0.25285571813583374
epoch: 25 loss: 0.25278574228286743
epoch: 26 loss: 0.25271597504615784
epoch: 27 loss: 0.25264623761177063
epoch: 28 loss: 0.25257670879364014
epoch: 29 loss: 0.2525072991847992
epoch: 30 loss: 0.2524380087852478
epoch: 31 loss: 0.2523689270019531
epoch: 32 loss: 0.25229987502098083
epoch: 33 loss: 0.25223103165626526
epoch: 34 loss: 0.25216227769851685
epoch: 35 loss: 0.252093642950058
epoch: 36 loss: 0.25202515721321106
epoch: 37 loss: 0.2519568204879761
epoch: 38 loss: 0.251888632774353
epoch: 39 loss: 0.25182053446769714
epoch: 40 loss: 0.2517525553703308
epoch: 41 loss: 0.2516847252845764
epoch: 42 loss: 0.2516169846057892
epoch: 43 loss: 0.2515493929386139
epoch: 44 loss: 0.25148195028305054
epoch: 45 loss: 0.25141456723213196
epoch: 46 loss: 0.2513473629951477
epoch: 47 loss: 0.2512802183628082
epoch: 48 loss: 0.2512132525444031
epoch: 49 loss: 0.2511464059352875

El entrenamiento de un algoritmo de aprendizaje profundo implica los siguientes pasos:

  • Construyendo una canalización de datos
  • Construyendo una arquitectura de red
  • Evaluación de la arquitectura mediante una función de pérdida
  • Optimización de los pesos de la arquitectura de red mediante un algoritmo de optimización

El entrenamiento de un algoritmo de aprendizaje profundo específico es el requisito exacto de convertir una red neuronal en bloques funcionales como se muestra a continuación:

Con respecto al diagrama anterior, cualquier algoritmo de aprendizaje profundo implica obtener los datos de entrada, construir la arquitectura respectiva que incluye un montón de capas incrustadas en ellos.

Si observa el diagrama anterior, la precisión se evalúa utilizando una función de pérdida con respecto a la optimización de los pesos de la red neuronal.

En este capítulo, discutiremos algunos de los términos más utilizados en PyTorch.

PyTorch NumPy

Un tensor de PyTorch es idéntico a una matriz NumPy. Un tensor es una matriz n-dimensional y con respecto a PyTorch, proporciona muchas funciones para operar en estos tensores.

Los tensores PyTorch suelen utilizar GPU para acelerar sus cálculos numéricos. Estos tensores que se crean en PyTorch se pueden usar para ajustar una red de dos capas a datos aleatorios. El usuario puede implementar manualmente las pasadas hacia adelante y hacia atrás a través de la red.

Variables y autogrado

Al usar autograd, el pase directo de su red definirá un computational graph - los nodos en el gráfico serán Tensores y los bordes serán funciones que producen Tensores de salida a partir de Tensores de entrada.

Los tensores de PyTorch se pueden crear como objetos variables donde una variable representa un nodo en un gráfico computacional.

Gráficos dinámicos

Los gráficos estáticos son agradables porque el usuario puede optimizar el gráfico desde el principio. Si los programadores están reutilizando el mismo gráfico una y otra vez, esta optimización inicial potencialmente costosa se puede mantener mientras se vuelve a ejecutar el mismo gráfico una y otra vez.

La principal diferencia entre ellos es que los gráficos computacionales de Tensor Flow son estáticos y PyTorch usa gráficos computacionales dinámicos.

Paquete Optim

El paquete optim en PyTorch abstrae la idea de un algoritmo de optimización que se implementa de muchas formas y proporciona ilustraciones de los algoritmos de optimización de uso común. Esto se puede llamar dentro de la declaración de importación.

Multiprocesamiento

El multiprocesamiento admite las mismas operaciones, por lo que todos los tensores funcionan en varios procesadores. Los datos de la cola se moverán a la memoria compartida y solo enviará un identificador a otro proceso.

PyTorch incluye un paquete llamado torchvision que se usa para cargar y preparar el conjunto de datos. Incluye dos funciones básicas, a saber, Dataset y DataLoader, que ayudan en la transformación y carga del conjunto de datos.

Conjunto de datos

El conjunto de datos se usa para leer y transformar un punto de datos del conjunto de datos dado. La sintaxis básica para implementar se menciona a continuación:

trainset = torchvision.datasets.CIFAR10(root = './data', train = True,
   download = True, transform = transform)

DataLoader se utiliza para mezclar y procesar datos por lotes. Se puede utilizar para cargar los datos en paralelo con los trabajadores de multiprocesamiento.

trainloader = torch.utils.data.DataLoader(trainset, batch_size = 4,
   shuffle = True, num_workers = 2)

Ejemplo: carga de archivo CSV

Usamos el paquete Python Panda para cargar el archivo csv. El archivo original tiene el siguiente formato: (nombre de la imagen, 68 puntos de referencia; cada punto de referencia tiene coordenadas ax, y).

landmarks_frame = pd.read_csv('faces/face_landmarks.csv')

n = 65
img_name = landmarks_frame.iloc[n, 0]
landmarks = landmarks_frame.iloc[n, 1:].as_matrix()
landmarks = landmarks.astype('float').reshape(-1, 2)

En este capítulo, nos centraremos en un ejemplo básico de implementación de regresión lineal con TensorFlow. La regresión logística o regresión lineal es un enfoque de aprendizaje automático supervisado para la clasificación de categorías discretas de orden. Nuestro objetivo en este capítulo es construir un modelo mediante el cual un usuario pueda predecir la relación entre las variables predictoras y una o más variables independientes.

La relación entre estas dos variables se considera lineal, es decir, si y es la variable dependiente y x se considera la variable independiente, entonces la relación de regresión lineal de dos variables se verá como la ecuación que se menciona a continuación:

Y = Ax+b

A continuación, diseñaremos un algoritmo de regresión lineal que nos permita comprender dos conceptos importantes que se dan a continuación:

  • Función de costo
  • Algoritmos de descenso de gradiente

La representación esquemática de la regresión lineal se menciona a continuación.

Interpretando el resultado

$$ Y = ax + b $$

  • El valor de a es la pendiente.

  • El valor de b es el y − intercept.

  • r es el correlation coefficient.

  • r2 es el correlation coefficient.

La vista gráfica de la ecuación de regresión lineal se menciona a continuación:

Los siguientes pasos se utilizan para implementar la regresión lineal usando PyTorch:

Paso 1

Importe los paquetes necesarios para crear una regresión lineal en PyTorch usando el siguiente código:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import seaborn as sns
import pandas as pd
%matplotlib inline

sns.set_style(style = 'whitegrid')
plt.rcParams["patch.force_edgecolor"] = True

Paso 2

Cree un único conjunto de entrenamiento con el conjunto de datos disponible como se muestra a continuación:

m = 2 # slope
c = 3 # interceptm = 2 # slope
c = 3 # intercept
x = np.random.rand(256)

noise = np.random.randn(256) / 4

y = x * m + c + noise

df = pd.DataFrame()
df['x'] = x
df['y'] = y

sns.lmplot(x ='x', y ='y', data = df)

Paso 3

Implemente la regresión lineal con las bibliotecas de PyTorch como se menciona a continuación:

import torch
import torch.nn as nn
from torch.autograd import Variable
x_train = x.reshape(-1, 1).astype('float32')
y_train = y.reshape(-1, 1).astype('float32')

class LinearRegressionModel(nn.Module):
   def __init__(self, input_dim, output_dim):
      super(LinearRegressionModel, self).__init__()
      self.linear = nn.Linear(input_dim, output_dim)

   def forward(self, x):
      out = self.linear(x)
      return out
input_dim = x_train.shape[1]
output_dim = y_train.shape[1]
input_dim, output_dim(1, 1)
model = LinearRegressionModel(input_dim, output_dim)
criterion = nn.MSELoss()
[w, b] = model.parameters()

def get_param_values():
   return w.data[0][0], b.data[0]

def plot_current_fit(title = ""):
plt.figure(figsize = (12,4))
plt.title(title)
plt.scatter(x, y, s = 8)
w1 = w.data[0][0]
b1 = b.data[0]
x1 = np.array([0., 1.])
y1 = x1 * w1 + b1
plt.plot(x1, y1, 'r', label = 'Current Fit ({:.3f}, {:.3f})'.format(w1, b1))
plt.xlabel('x (input)')
plt.ylabel('y (target)')
plt.legend()
plt.show()
plot_current_fit('Before training')

La trama generada es la siguiente:

El aprendizaje profundo es una división del aprendizaje automático y se considera un paso crucial dado por los investigadores en las últimas décadas. Los ejemplos de implementación de aprendizaje profundo incluyen aplicaciones como reconocimiento de imágenes y reconocimiento de voz.

Los dos tipos importantes de redes neuronales profundas se dan a continuación:

  • Redes neuronales convolucionales
  • Redes neuronales recurrentes.

En este capítulo, nos centraremos en el primer tipo, es decir, redes neuronales convolucionales (CNN).

Redes neuronales convolucionales

Las redes neuronales convolucionales están diseñadas para procesar datos a través de múltiples capas de arreglos. Este tipo de redes neuronales se utilizan en aplicaciones como el reconocimiento de imágenes o el reconocimiento facial.

La principal diferencia entre CNN y cualquier otra red neuronal ordinaria es que CNN toma la entrada como una matriz bidimensional y opera directamente en las imágenes en lugar de enfocarse en la extracción de características en las que se enfocan otras redes neuronales.

El enfoque dominante de CNN incluye soluciones para problemas de reconocimiento. Las principales empresas como Google y Facebook han invertido en proyectos de investigación y desarrollo de proyectos de reconocimiento para realizar las actividades con mayor rapidez.

Cada red neuronal convolucional incluye tres ideas básicas:

  • Campos respectivos locales
  • Convolution
  • Pooling

Entendamos cada una de estas terminologías en detalle.

Campos respectivos locales

CNN utiliza correlaciones espaciales que existen dentro de los datos de entrada. Cada una de las capas concurrentes de redes neuronales conecta algunas neuronas de entrada. Esta región específica se llama campo receptivo local. Solo se enfoca en neuronas ocultas. La neurona oculta procesará los datos de entrada dentro del campo mencionado sin darse cuenta de los cambios fuera del límite específico.

La representación del diagrama de la generación de campos respectivos locales se menciona a continuación:

Circunvolución

En la figura anterior, observamos que cada conexión aprende un peso de neurona oculta con una conexión asociada con el movimiento de una capa a otra. Aquí, las neuronas individuales realizan un cambio de vez en cuando. Este proceso se llama "convolución".

El mapeo de conexiones desde la capa de entrada al mapa de características ocultas se define como "pesos compartidos" y el sesgo incluido se denomina "sesgo compartido".

Agrupación

Las redes neuronales convolucionales utilizan capas de agrupación que se colocan inmediatamente después de la declaración de CNN. Toma la entrada del usuario como un mapa de características que genera redes convolucionales y prepara un mapa de características condensado. La agrupación de capas ayuda a crear capas con neuronas de capas anteriores.

Implementación de PyTorch

Los siguientes pasos se utilizan para crear una red neuronal convolucional utilizando PyTorch.

Paso 1

Importe los paquetes necesarios para crear una red neuronal simple.

from torch.autograd import Variable
import torch.nn.functional as F

Paso 2

Cree una clase con representación por lotes de una red neuronal convolucional. Nuestra forma de lote para la entrada x tiene una dimensión de (3, 32, 32).

class SimpleCNN(torch.nn.Module):
   def __init__(self):
      super(SimpleCNN, self).__init__()
      #Input channels = 3, output channels = 18
      self.conv1 = torch.nn.Conv2d(3, 18, kernel_size = 3, stride = 1, padding = 1)
      self.pool = torch.nn.MaxPool2d(kernel_size = 2, stride = 2, padding = 0)
      #4608 input features, 64 output features (see sizing flow below)
      self.fc1 = torch.nn.Linear(18 * 16 * 16, 64)
      #64 input features, 10 output features for our 10 defined classes
      self.fc2 = torch.nn.Linear(64, 10)

Paso 3

Calcule la activación de los primeros cambios de tamaño de convolución de (3, 32, 32) a (18, 32, 32).

El tamaño de la dimensión cambia de (18, 32, 32) a (18, 16, 16). Reformar la dimensión de datos de la capa de entrada de la red neuronal debido a que el tamaño cambia de (18, 16, 16) a (1, 4608).

Recuerde que -1 infiere esta dimensión de la otra dimensión dada.

def forward(self, x):
   x = F.relu(self.conv1(x))
   x = self.pool(x)
   x = x.view(-1, 18 * 16 *16)
   x = F.relu(self.fc1(x))
   #Computes the second fully connected layer (activation applied later)
   #Size changes from (1, 64) to (1, 10)
   x = self.fc2(x)
   return(x)

Las redes neuronales recurrentes son un tipo de algoritmo orientado al aprendizaje profundo que sigue un enfoque secuencial. En las redes neuronales, siempre asumimos que cada entrada y salida es independiente de todas las demás capas. Este tipo de redes neuronales se denominan recurrentes porque realizan cálculos matemáticos de manera secuencial completando una tarea tras otra.

El siguiente diagrama especifica el enfoque completo y el funcionamiento de las redes neuronales recurrentes:

En la figura anterior, c1, c2, c3 y x1 se consideran entradas que incluyen algunos valores de entrada ocultos, a saber, h1, h2 y h3 entregando la salida respectiva de o1. Ahora nos centraremos en implementar PyTorch para crear una onda sinusoidal con la ayuda de redes neuronales recurrentes.

Durante el entrenamiento, seguiremos un enfoque de entrenamiento para nuestro modelo con un punto de datos a la vez. La secuencia de entrada x consta de 20 puntos de datos y se considera que la secuencia objetivo es la misma que la secuencia de entrada.

Paso 1

Importe los paquetes necesarios para implementar redes neuronales recurrentes utilizando el siguiente código:

import torch
from torch.autograd import Variable
import numpy as np
import pylab as pl
import torch.nn.init as init

Paso 2

Estableceremos los hiperparámetros del modelo con el tamaño de la capa de entrada establecido en 7. Habrá 6 neuronas de contexto y 1 neurona de entrada para crear la secuencia objetivo.

dtype = torch.FloatTensor
input_size, hidden_size, output_size = 7, 6, 1
epochs = 300
seq_length = 20
lr = 0.1
data_time_steps = np.linspace(2, 10, seq_length + 1)
data = np.sin(data_time_steps)
data.resize((seq_length + 1, 1))

x = Variable(torch.Tensor(data[:-1]).type(dtype), requires_grad=False)
y = Variable(torch.Tensor(data[1:]).type(dtype), requires_grad=False)

Generaremos datos de entrenamiento, donde x es la secuencia de datos de entrada e y es la secuencia objetivo requerida.

Paso 3

Los pesos se inicializan en la red neuronal recurrente utilizando una distribución normal con media cero. W1 representará la aceptación de las variables de entrada y w2 representará la salida que se genera como se muestra a continuación:

w1 = torch.FloatTensor(input_size, 
hidden_size).type(dtype)
init.normal(w1, 0.0, 0.4)
w1 = Variable(w1, requires_grad = True)
w2 = torch.FloatTensor(hidden_size, output_size).type(dtype)
init.normal(w2, 0.0, 0.3)
w2 = Variable(w2, requires_grad = True)

Etapa 4

Ahora, es importante crear una función para la retroalimentación que defina de manera única la red neuronal.

def forward(input, context_state, w1, w2):
   xh = torch.cat((input, context_state), 1)
   context_state = torch.tanh(xh.mm(w1))
   out = context_state.mm(w2)
   return (out, context_state)

Paso 5

El siguiente paso es iniciar el procedimiento de entrenamiento de la implementación de la onda sinusoidal de la red neuronal recurrente. El ciclo externo itera sobre cada ciclo y el ciclo interno itera a través del elemento de secuencia. Aquí, también calcularemos el error cuadrático medio (MSE) que ayuda en la predicción de variables continuas.

for i in range(epochs):
   total_loss = 0
   context_state = Variable(torch.zeros((1, hidden_size)).type(dtype), requires_grad = True)
   for j in range(x.size(0)):
      input = x[j:(j+1)]
      target = y[j:(j+1)]
      (pred, context_state) = forward(input, context_state, w1, w2)
      loss = (pred - target).pow(2).sum()/2
      total_loss += loss
      loss.backward()
      w1.data -= lr * w1.grad.data
      w2.data -= lr * w2.grad.data
      w1.grad.data.zero_()
      w2.grad.data.zero_()
      context_state = Variable(context_state.data)
   if i % 10 == 0:
      print("Epoch: {} loss {}".format(i, total_loss.data[0]))

context_state = Variable(torch.zeros((1, hidden_size)).type(dtype), requires_grad = False)
predictions = []

for i in range(x.size(0)):
   input = x[i:i+1]
   (pred, context_state) = forward(input, context_state, w1, w2)
   context_state = context_state
   predictions.append(pred.data.numpy().ravel()[0])

Paso 6

Ahora es el momento de graficar la onda sinusoidal como se necesita.

pl.scatter(data_time_steps[:-1], x.data.numpy(), s = 90, label = "Actual")
pl.scatter(data_time_steps[1:], predictions, label = "Predicted")
pl.legend()
pl.show()

Salida

El resultado del proceso anterior es el siguiente:

En este capítulo, nos centraremos más en torchvision.datasetsy sus diversos tipos. PyTorch incluye los siguientes cargadores de conjuntos de datos:

  • MNIST
  • COCO (subtítulos y detección)

El conjunto de datos incluye la mayoría de los dos tipos de funciones que se indican a continuación:

  • Transform- una función que toma una imagen y devuelve una versión modificada de cosas estándar. Estos se pueden componer junto con transformaciones.

  • Target_transform- una función que toma el objetivo y lo transforma. Por ejemplo, toma la cadena de subtítulos y devuelve un tensor de índices mundiales.

MNIST

El siguiente es el código de muestra para el conjunto de datos MNIST:

dset.MNIST(root, train = TRUE, transform = NONE, 
target_transform = None, download = FALSE)

Los parámetros son los siguientes:

  • root - directorio raíz del conjunto de datos donde existen los datos procesados.

  • train - Verdadero = Conjunto de entrenamiento, Falso = Conjunto de prueba

  • download - Verdadero = descarga el conjunto de datos de Internet y lo coloca en la raíz.

COCO

Esto requiere que se instale la API de COCO. El siguiente ejemplo se utiliza para demostrar la implementación de COCO del conjunto de datos utilizando PyTorch:

import torchvision.dataset as dset
import torchvision.transforms as transforms
cap = dset.CocoCaptions(root = ‘ dir where images are’, 
annFile = ’json annotation file’,
transform = transforms.ToTensor())
print(‘Number of samples: ‘, len(cap))
print(target)

El resultado obtenido es el siguiente:

Number of samples: 82783
Image Size: (3L, 427L, 640L)

Convents se trata de construir el modelo de CNN desde cero. La arquitectura de red contendrá una combinación de los siguientes pasos:

  • Conv2d
  • MaxPool2d
  • Unidad lineal rectificada
  • View
  • Capa lineal

Entrenando el modelo

El entrenamiento del modelo es el mismo proceso que los problemas de clasificación de imágenes. El siguiente fragmento de código completa el procedimiento de un modelo de entrenamiento en el conjunto de datos proporcionado:

def fit(epoch,model,data_loader,phase 
= 'training',volatile = False):
   if phase == 'training':
      model.train()
   if phase == 'training':
      model.train()
   if phase == 'validation':
      model.eval()
   volatile=True
   running_loss = 0.0
   running_correct = 0
   for batch_idx , (data,target) in enumerate(data_loader):
      if is_cuda:
         data,target = data.cuda(),target.cuda()
         data , target = Variable(data,volatile),Variable(target)
      if phase == 'training':
         optimizer.zero_grad()
         output = model(data)
         loss = F.nll_loss(output,target)
         running_loss + = 
         F.nll_loss(output,target,size_average = 
         False).data[0]
         preds = output.data.max(dim = 1,keepdim = True)[1]
         running_correct + = 
         preds.eq(target.data.view_as(preds)).cpu().sum()
         if phase == 'training':
            loss.backward()
            optimizer.step()
   loss = running_loss/len(data_loader.dataset)
   accuracy = 100. * running_correct/len(data_loader.dataset)
   print(f'{phase} loss is {loss:{5}.{2}} and {phase} accuracy is {running_correct}/{len(data_loader.dataset)}{accuracy:{return loss,accuracy}})

El método incluye una lógica diferente para el entrenamiento y la validación. Hay dos razones principales para usar diferentes modos:

  • En el modo de tren, la deserción elimina un porcentaje de los valores, lo que no debería ocurrir en la fase de validación o prueba.

  • Para el modo de entrenamiento, calculamos gradientes y cambiamos el valor de los parámetros del modelo, pero la propagación hacia atrás no es necesaria durante las fases de prueba o validación.

En este capítulo, nos centraremos en crear un convento desde cero. Esto se infiere en la creación del respectivo convento o muestra de red neuronal con antorcha.

Paso 1

Cree una clase necesaria con los parámetros respectivos. Los parámetros incluyen pesos con valor aleatorio.

class Neural_Network(nn.Module):
   def __init__(self, ):
      super(Neural_Network, self).__init__()
      self.inputSize = 2
      self.outputSize = 1
      self.hiddenSize = 3
      # weights
      self.W1 = torch.randn(self.inputSize, 
      self.hiddenSize) # 3 X 2 tensor
      self.W2 = torch.randn(self.hiddenSize, self.outputSize) # 3 X 1 tensor

Paso 2

Cree un patrón de función de retroalimentación con funciones sigmoideas.

def forward(self, X):
   self.z = torch.matmul(X, self.W1) # 3 X 3 ".dot" 
   does not broadcast in PyTorch
   self.z2 = self.sigmoid(self.z) # activation function
   self.z3 = torch.matmul(self.z2, self.W2)
   o = self.sigmoid(self.z3) # final activation 
   function
   return o
   def sigmoid(self, s):
      return 1 / (1 + torch.exp(-s))
   def sigmoidPrime(self, s):
      # derivative of sigmoid
      return s * (1 - s)
   def backward(self, X, y, o):
      self.o_error = y - o # error in output
      self.o_delta = self.o_error * self.sigmoidPrime(o) # derivative of sig to error
      self.z2_error = torch.matmul(self.o_delta, torch.t(self.W2))
      self.z2_delta = self.z2_error * self.sigmoidPrime(self.z2)
      self.W1 + = torch.matmul(torch.t(X), self.z2_delta)
      self.W2 + = torch.matmul(torch.t(self.z2), self.o_delta)

Paso 3

Cree un modelo de entrenamiento y predicción como se menciona a continuación:

def train(self, X, y):
   # forward + backward pass for training
   o = self.forward(X)
   self.backward(X, y, o)
def saveWeights(self, model):
   # Implement PyTorch internal storage functions
   torch.save(model, "NN")
   # you can reload model with all the weights and so forth with:
   # torch.load("NN")
def predict(self):
   print ("Predicted data based on trained weights: ")
   print ("Input (scaled): \n" + str(xPredicted))
   print ("Output: \n" + str(self.forward(xPredicted)))

Las redes neuronales convolucionales incluyen una característica principal, extraction. Los siguientes pasos se utilizan para implementar la extracción de características de la red neuronal convolucional.

Paso 1

Importe los modelos respectivos para crear el modelo de extracción de características con "PyTorch".

import torch
import torch.nn as nn
from torchvision import models

Paso 2

Cree una clase de extractor de características que se pueda llamar cuando sea necesario.

class Feature_extractor(nn.module):
   def forward(self, input):
      self.feature = input.clone()
      return input
new_net = nn.Sequential().cuda() # the new network
target_layers = [conv_1, conv_2, conv_4] # layers you want to extract`
i = 1
for layer in list(cnn):
   if isinstance(layer,nn.Conv2d):
      name = "conv_"+str(i)
      art_net.add_module(name,layer)
      if name in target_layers:
         new_net.add_module("extractor_"+str(i),Feature_extractor())
      i+=1
   if isinstance(layer,nn.ReLU):
      name = "relu_"+str(i)
      new_net.add_module(name,layer)
   if isinstance(layer,nn.MaxPool2d):
      name = "pool_"+str(i)
      new_net.add_module(name,layer)
new_net.forward(your_image)
print (new_net.extractor_3.feature)

En este capítulo, nos centraremos en el modelo de visualización de datos con la ayuda de conventos. Se requieren los siguientes pasos para obtener una imagen perfecta de visualización con una red neuronal convencional.

Paso 1

Importa los módulos necesarios, lo cual es importante para la visualización de redes neuronales convencionales.

import os
import numpy as np
import pandas as pd
from scipy.misc import imread
from sklearn.metrics import accuracy_score

import keras
from keras.models import Sequential, Model
from keras.layers import Dense, Dropout, Flatten, Activation, Input
from keras.layers import Conv2D, MaxPooling2D
import torch

Paso 2

Para detener la aleatoriedad potencial con datos de entrenamiento y prueba, llame al conjunto de datos respectivo como se indica en el código a continuación:

seed = 128
rng = np.random.RandomState(seed)
data_dir = "../../datasets/MNIST"
train = pd.read_csv('../../datasets/MNIST/train.csv')
test = pd.read_csv('../../datasets/MNIST/Test_fCbTej3.csv')
img_name = rng.choice(train.filename)
filepath = os.path.join(data_dir, 'train', img_name)
img = imread(filepath, flatten=True)

Paso 3

Trace las imágenes necesarias para obtener los datos de entrenamiento y prueba definidos de manera perfecta utilizando el siguiente código:

pylab.imshow(img, cmap ='gray')
pylab.axis('off')
pylab.show()

La salida se muestra a continuación:

En este capítulo, proponemos un enfoque alternativo que, en cambio, se basa en una única red neuronal convolucional 2D en ambas secuencias. Cada capa de nuestra red vuelve a codificar los tokens de origen sobre la base de la secuencia de salida producida hasta ahora. Por lo tanto, las propiedades similares a la atención son omnipresentes en toda la red.

Aquí, nos centraremos en creating the sequential network with specific pooling from the values included in dataset. Este proceso también se aplica mejor en el "Módulo de reconocimiento de imágenes".

Los siguientes pasos se utilizan para crear un modelo de procesamiento de secuencia con conventos usando PyTorch:

Paso 1

Importe los módulos necesarios para la ejecución del procesamiento de secuencias utilizando conventos.

import keras 
from keras.datasets import mnist 
from keras.models import Sequential 
from keras.layers import Dense, Dropout, Flatten 
from keras.layers import Conv2D, MaxPooling2D 
import numpy as np

Paso 2

Realice las operaciones necesarias para crear un patrón en la secuencia respectiva utilizando el siguiente código:

batch_size = 128 
num_classes = 10 
epochs = 12
# input image dimensions 
img_rows, img_cols = 28, 28
# the data, split between train and test sets 
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(60000,28,28,1) 
x_test = x_test.reshape(10000,28,28,1)
print('x_train shape:', x_train.shape) 
print(x_train.shape[0], 'train samples') 
print(x_test.shape[0], 'test samples')
y_train = keras.utils.to_categorical(y_train, num_classes) 
y_test = keras.utils.to_categorical(y_test, num_classes)

Paso 3

Compile el modelo y ajuste el patrón en el modelo de red neuronal convencional mencionado como se muestra a continuación:

model.compile(loss = 
keras.losses.categorical_crossentropy, 
optimizer = keras.optimizers.Adadelta(), metrics = 
['accuracy'])
model.fit(x_train, y_train, 
batch_size = batch_size, epochs = epochs, 
verbose = 1, validation_data = (x_test, y_test)) 
score = model.evaluate(x_test, y_test, verbose = 0) 
print('Test loss:', score[0]) 
print('Test accuracy:', score[1])

La salida generada es la siguiente:

En este capítulo, entenderemos el famoso modelo de inserción de palabras: word2vec. El modelo Word2vec se utiliza para producir incrustaciones de palabras con la ayuda de un grupo de modelos relacionados. El modelo de Word2vec se implementa con código C puro y el gradiente se calcula manualmente.

La implementación del modelo word2vec en PyTorch se explica en los siguientes pasos:

Paso 1

Implemente las bibliotecas en la incrustación de palabras como se menciona a continuación:

import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F

Paso 2

Implemente el modelo Skip Gram de incrustación de palabras con la clase llamada word2vec. Incluyeemb_size, emb_dimension, u_embedding, v_embedding tipo de atributos.

class SkipGramModel(nn.Module):
   def __init__(self, emb_size, emb_dimension):
      super(SkipGramModel, self).__init__()
      self.emb_size = emb_size
      self.emb_dimension = emb_dimension
      self.u_embeddings = nn.Embedding(emb_size, emb_dimension, sparse=True)
      self.v_embeddings = nn.Embedding(emb_size, emb_dimension, sparse = True)
      self.init_emb()
   def init_emb(self):
      initrange = 0.5 / self.emb_dimension
      self.u_embeddings.weight.data.uniform_(-initrange, initrange)
      self.v_embeddings.weight.data.uniform_(-0, 0)
   def forward(self, pos_u, pos_v, neg_v):
      emb_u = self.u_embeddings(pos_u)
      emb_v = self.v_embeddings(pos_v)
      score = torch.mul(emb_u, emb_v).squeeze()
      score = torch.sum(score, dim = 1)
      score = F.logsigmoid(score)
      neg_emb_v = self.v_embeddings(neg_v)
      neg_score = torch.bmm(neg_emb_v, emb_u.unsqueeze(2)).squeeze()
      neg_score = F.logsigmoid(-1 * neg_score)
      return -1 * (torch.sum(score)+torch.sum(neg_score))
   def save_embedding(self, id2word, file_name, use_cuda):
      if use_cuda:
         embedding = self.u_embeddings.weight.cpu().data.numpy()
      else:
         embedding = self.u_embeddings.weight.data.numpy()
      fout = open(file_name, 'w')
      fout.write('%d %d\n' % (len(id2word), self.emb_dimension))
      for wid, w in id2word.items():
         e = embedding[wid]
         e = ' '.join(map(lambda x: str(x), e))
         fout.write('%s %s\n' % (w, e))
def test():
   model = SkipGramModel(100, 100)
   id2word = dict()
   for i in range(100):
      id2word[i] = str(i)
   model.save_embedding(id2word)

Paso 3

Implemente el método principal para que el modelo de incrustación de palabras se muestre correctamente.

if __name__  ==  '__main__':
   test()

Las redes neuronales profundas tienen una característica exclusiva para permitir avances en el aprendizaje automático que comprenden el proceso del lenguaje natural. Se observa que la mayoría de estos modelos tratan el lenguaje como una secuencia plana de palabras o caracteres, y utilizan una especie de modelo que se denomina red neuronal recurrente o RNN.

Muchos investigadores llegan a la conclusión de que el lenguaje se comprende mejor con respecto al árbol jerárquico de frases. Este tipo se incluye en redes neuronales recursivas que tienen en cuenta una estructura específica.

PyTorch tiene una característica específica que ayuda a hacer que estos complejos modelos de procesamiento del lenguaje natural sean mucho más fáciles. Es un marco con todas las funciones para todo tipo de aprendizaje profundo con un fuerte soporte para la visión por computadora.

Características de la red neuronal recursiva

  • Una red neuronal recursiva se crea de tal manera que incluye la aplicación del mismo conjunto de pesos con diferentes estructuras gráficas.

  • Los nodos se atraviesan en orden topológico.

  • Este tipo de red se entrena mediante el modo inverso de diferenciación automática.

  • El procesamiento del lenguaje natural incluye un caso especial de redes neuronales recursivas.

  • Esta red de tensor neuronal recursiva incluye varios nodos funcionales de composición en el árbol.

El ejemplo de red neuronal recursiva se muestra a continuación: