Análisis de precios de Polkadot 13 de septiembre

Red neuronal convolucional: implementación de PyTorch en el conjunto de datos CIFAR-10

Nodo de origen: 1866263

Este artículo fue publicado como parte del Blogatón de ciencia de datos

Introducción

Cifar 10 | Redes neuronales convolucionales pytorch
                                    1 imagen

Las redes neuronales convolucionales, también llamadas ConvNets, fueron introducidas por primera vez en la década de 1980 por Yann LeCun, un investigador de ciencias de la computación que trabajaba en segundo plano. LeCun se basó en el trabajo de Kunihiko Fukushima, un científico japonés, una red básica para el reconocimiento de imágenes.

La versión anterior de CNN, llamada LeNet (después de LeCun), puede ver dígitos escritos a mano. CNN ayuda a encontrar códigos PIN de postales. Pero a pesar de su experiencia, ConvNets se mantuvo cerca de la visión por computadora y la inteligencia artificial porque enfrentaron un problema importante: no podían escalar mucho. Las CNN requieren una gran cantidad de datos e integran recursos para funcionar bien con imágenes grandes.

En ese momento, este método solo era aplicable a imágenes de baja resolución. Pytorch es una biblioteca que puede realizar operaciones de aprendizaje profundo. Podemos usar esto para realizar redes neuronales convolucionales. Las redes neuronales convolucionales contienen muchas capas de neuronas artificiales. Las neuronas sintéticas, simulaciones complejas de contrapartes biológicas, son funciones matemáticas que calculan la masa ponderada de múltiples entradas y la activación del valor del producto.

Redes neuronales convolucionales pytorch
2 imagen

La imagen de arriba nos muestra un modelo de CNN que toma una imagen similar a un dígito de 2 y nos da el resultado de qué dígito se mostró en la imagen como un número. Discutiremos en detalle cómo obtenemos esto en este artículo.

CIFAR-10 es un conjunto de datos que tiene una colección de imágenes de 10 clases diferentes. Este conjunto de datos se usa ampliamente con fines de investigación para probar diferentes modelos de aprendizaje automático y especialmente para problemas de visión por computadora. En este artículo, intentaremos construir un modelo de red neuronal usando Pytorch y probarlo en el conjunto de datos CIFAR-10 para verificar qué precisión de predicción se puede obtener.

Importando la biblioteca PyTorch 

importar numpy como np importar pandas como pd
importar antorcha importar torch.nn.functional como F de torchvision importar conjuntos de datos, transformaciones de antorcha importar nn importar matplotlib.pyplot como plt importar numpy como np importar seaborn como sns # de tqdm.notebook importar tqdm de tqdm importar tqdm

En este paso, importamos las bibliotecas necesarias. Podemos ver que usamos NumPy para operaciones numéricas y pandas para operaciones de marco de datos. La biblioteca de antorcha se utiliza para importar Pytorch.

Pytorch tiene un componente nn que se utiliza para la abstracción de operaciones y funciones de aprendizaje automático. Esto se importa como F. ​​La biblioteca de torchvision se usa para que podamos importar el conjunto de datos CIFAR-10. Esta biblioteca tiene muchos conjuntos de datos de imágenes y se usa ampliamente para la investigación. Las transformaciones se pueden importar para que podamos cambiar el tamaño de la imagen al mismo tamaño para todas las imágenes. El tqdm se utiliza para que podamos realizar un seguimiento del progreso durante el entrenamiento y se utiliza para la visualización.

Leer el conjunto de datos requerido

trainData = pd.read_csv ('cifar-10 / trainLabels.csv') trainData.head ()

Una vez que leemos el conjunto de datos, podemos ver varias etiquetas como la rana, el camión, el venado, el automóvil, etc.

Analizando los datos con PyTorch

print ("Número de puntos:", trainData.shape [0]) print ("Número de características:", trainData.shape [1]) print ("Características:", trainData.columns.values) print ("Número de Valores únicos ") para col en trainData: print (col,": ", len (trainData [col] .unique ())) plt.figure (figsize = (12,8))

Salida:

Número de puntos: 50000 Número de características: 2 Características: ['id' 'label'] Número de valores únicos id: 50000 label: 10

En este paso, analizamos el conjunto de datos y vemos que nuestros datos de trenes tienen alrededor de 50000 filas con su identificación y etiqueta asociada. Hay un total de 10 clases como en el nombre CIFAR-10.

Obtener el conjunto de validación usando PyTorch

from torch.utils.data import random_split val_size = 5000 train_size = len (conjunto de datos) - val_size train_ds, val_ds = random_split (conjunto de datos, [train_size, val_size]) len (train_ds), len (val_ds)

Este paso es el mismo que el de entrenamiento, pero queremos dividir los datos en conjuntos de validación y entrenamiento.

(45000, 5000)
from torch.utils.data.dataloader import DataLoader batch_size = 64 train_dl = DataLoader (train_ds, batch_size, shuffle = True, num_workers = 4, pin_memory = True) val_dl = DataLoader (val_ds, batch_size, num_workers = 4, pin_memory = True)

Torch.utils tiene un cargador de datos que puede ayudarnos a cargar los datos requeridos sin pasar por varios parámetros como el número de trabajador o el tamaño del lote.

Definiendo las funciones requeridas

@ torch.no_grad () def precisión (salidas, etiquetas): _, preds = torch.max (salidas, dim = 1) return torch.tensor (torch.sum (preds == etiquetas) .item () / len (preds )) class ImageClassificationBase (nn.Module): def training_step (self, batch): images, labels = batch out = self (images) # Generar predicciones loss = F.cross_entropy (out, labels) # Calcular la pérdida accu = precisión (out , etiquetas) pérdida de retorno, accu def validation_step (self, batch): imágenes, etiquetas = batch out = self (imágenes) # Generar predicciones loss = F.cross_entropy (out, labels) # Calcular pérdida acc = precisión (out, labels) # Calcular retorno de precisión {'Loss': loss.detach (), 'Accuracy': acc} def validation_epoch_end (self, outputs): batch_losses = [x ['Loss'] para x en salidas] epoch_loss = torch.stack (batch_losses ) .mean () # Combinar pérdidas batch_accs = [x ['Precisión'] para x en salidas] epoch_acc = torch.stack (batch_accs) .mean () # Combinar precisiones return {'Loss': epoch_loss.item (), ' Precisión ': epoch_acc.item ()} def epoch_end (self, epoch, result): pr int ("Epoch:", epoch + 1) print (f'Train Accuracy: {result ["train_accuracy"] * 100: .2f}% Precisión de validación: {result ["Accuracy"] * 100: .2f}% ' ) print (f'Pérdida de tren: {resultado ["pérdida de tren"] :. 4f} Pérdida de validación: {resultado ["Pérdida"] :. 4f} ')

Como podemos ver aquí, hemos utilizado la implementación de clase de ImageClassification y toma un parámetro que es nn.Module. Dentro de esta clase, podemos implementar las diversas funciones o varios pasos como entrenamiento, validación, etc. Las funciones aquí son implementaciones simples de Python.

El paso de formación toma imágenes y etiquetas en lotes. utilizamos la entropía cruzada para la función de pérdida y calculamos la pérdida y devolvemos la pérdida. Esto es similar al paso de validación como podemos ver en la función. Los finales de época combinan pérdidas y precisiones y finalmente imprimimos las precisiones y pérdidas.

Implementación del módulo de red neuronal convolucional

class Cifar10CnnModel (ImageClassificationBase): def __init __ (self): super () .__ init __ () self.network = nn.Sequential (nn.Conv2d (3, 32, kernel_size = 3, padding = 1), nn.ReLU (), nn.Conv2d (32, 64, kernel_size = 3, stride = 1, padding = 1), nn.ReLU (), nn.MaxPool2d (2, 2), # salida: 64 x 16 x 16 nn.BatchNorm2d (64) , nn.Conv2d (64, 128, kernel_size = 3, stride = 1, padding = 1), nn.ReLU (), nn.Conv2d (128, 128, kernel_size = 3, stride = 1, padding = 1), nn .ReLU (), nn.MaxPool2d (2, 2), # salida: 128 x 8 x 8 nn.BatchNorm2d (128), nn.Conv2d (128, 256, kernel_size = 3, stride = 1, padding = 1), nn.ReLU (), nn.Conv2d (256, 256, kernel_size = 3, stride = 1, padding = 1), nn.ReLU (), nn.MaxPool2d (2, 2), # salida: 256 x 4 x 4 nn.BatchNorm2d (256), nn.Flatten (), nn.Linear (256 * 4 * 4, 1024), nn.ReLU (), nn.Linear (1024, 512), nn.ReLU (), nn.Linear (512, 10)) def forward (self, xb): return self.network (xb)

Esta es la parte más importante de la implementación de una red neuronal. En todo momento, usamos el módulo nn que importamos de antorcha. Como podemos ver en la primera línea, Conv2d es un módulo que ayuda a implementar una red neuronal convolucional. El primer parámetro 3 aquí representa que la imagen está coloreada y en formato RGB. Si fuera una imagen en escala de grises, habríamos optado por 1.

32 es el tamaño del canal de salida inicial y cuando vayamos a la siguiente capa conv2d tendríamos este 32 como canal de entrada y 64 como canal de salida.

El tercer parámetro de la primera línea se llama tamaño de kernel y nos ayuda a cuidar los filtros utilizados. La operación de relleno es el último parámetro.

La operación de convolución está conectada a una capa de activación y Relu aquí. Después de dos capas Conv2d, tenemos una operación de agrupación máxima de tamaño 2 * 2. El valor que surge de esto se normaliza por lotes para la estabilidad y para evitar el cambio de covariables interno. Estas operaciones se repiten con más capas para profundizar la red y reducir el tamaño. Finalmente, aplanamos la capa para que podamos construir una capa lineal para asignar los valores a 10 valores. La probabilidad de cada neurona de estas 10 neuronas determinará a qué clase pertenece una imagen en particular en función de la probabilidad máxima.

Entrenar a la modelo

@ torch.no_grad () def evaluar (modelo, cargador_de_datos): modelo.eval () salidas = [modelo.paso_de_validación (lote) para el lote en cargador_de_datos] devolver modelo.validation_epoch_end (salidas) def ajuste (modelo, cargador_entre, cargador_val, épocas = 10, learning_rate = 0.001): best_valid = None history = [] optimizer = torch.optim.Adam (model.parameters (), learning_rate, weight_decay = 0.0005) para la época en el rango (épocas): # Fase de entrenamiento model.train ( ) train_losses = [] train_accuracy = [] para lote en tqdm (train_loader): pérdida, accu = model.training_step (lote) train_losses.append (loss) train_accuracy.append (accu) loss.backward () optimizer.step () optimizer .zero_grad () # Resultado de la fase de validación = evaluar (modelo, val_loader) resultado ['train_loss'] = torch.stack (train_losses) .mean (). item () result ['train_accuracy'] = torch.stack (train_accuracy). mean (). item () model.epoch_end (época, resultado) if (best_valid == None o best_valid
history = fit (modelo, train_dl, val_dl)

Este es un paso básico para entrenar nuestro modelo para obtener el resultado requerido. la función de ajuste aquí se ajustará a los datos del tren y Val con el modelo que creamos. La función de ajuste toma inicialmente una lista llamada historial que se encarga de los datos de iteración de cada época. Ejecutamos un ciclo for para que podamos iterar sobre cada época. Para cada lote, nos aseguramos de mostrar el progreso usando tqdm. Llamamos al paso de entrenamiento que implementamos antes y calculamos la precisión y la pérdida. Opte por la propagación hacia atrás y ejecute el optimizador que definimos anteriormente. Una vez que hacemos esto, hacemos un seguimiento de nuestra lista y las funciones nos ayudan a imprimir los detalles y el progreso.

La función de evaluación, por otro lado, usa la función de evaluación, y para cada paso, tomamos el lote cargado desde el cargador de datos y se calcula la salida. Luego, el valor se pasa al final de la época de validación que definimos anteriormente y se devuelve el valor respectivo.

Graficar los resultados

En este paso, visualizaremos la precisión frente a cada época. Podemos observar que a medida que aumenta la época, la precisión del sistema sigue aumentando y, de manera similar, la pérdida sigue disminuyendo. La línea roja aquí indica el progreso de los datos de entrenamiento y la azul para la validación. Podemos ver que ha habido una buena cantidad de sobreajuste en nuestros resultados ya que los datos de entrenamiento están superando bastante el resultado de validación y de manera similar en caso de pérdida. Después de 10 épocas, los datos del tren parecen pasar por alto el 90% de precisión, pero tienen una pérdida de alrededor de 0.5. Los datos de las pruebas llegan alrededor del 81% y las pérdidas se acercan a 0.2.

def plot_accuracies (historial): Validation_accuracies = [x ['Accuracy'] for x in history] Training_Accuracies = [x ['train_accuracy'] for x in history] plt.plot (Training_Accuracies, '-rx') plt.plot (Validation_accuracies , '-bx') plt.xlabel ('época') plt.ylabel ('precisión') plt.legend (['Entrenamiento', 'Validación']) plt.title ('Precisión vs. No. de épocas') ; plot_accuracies (historial)
Gráficos de precisión
def plot_losses (historial): train_losses = [x.get ('train_loss') for x in history] val_losses = [x ['Loss'] for x in history] plt.plot (train_losses, '-bx') plt.plot (val_losses, '-rx') plt.xlabel ('época') plt.ylabel ('pérdida') plt.legend (['Entrenamiento', 'Validación']) plt.title ('Pérdida vs. No. de épocas '); plot_losses (historia)

test_dataset = ImageFolder (data_dir + '/ test', transform = ToTensor ()) test_loader = DeviceDataLoader (DataLoader (test_dataset, batch_size), device) result = evaluar (final_model, test_loader) print (f'Precisión de la prueba: {resultado ["Precisión" ] * 100: .2f}% ')
Exactitud de la prueba: 81.07%

Podemos ver que terminamos con una precisión del 81.07%.

Conclusión:

Imagen: https: //unsplash.com/photos/5L0R8ZqPZHk

Acerca de mí: Soy un estudiante de investigación interesado en el campo del aprendizaje profundo y el procesamiento del lenguaje natural y actualmente estoy realizando un posgrado en Inteligencia Artificial.

Fuente de la imagen

  1. Image 1: https://becominghuman.ai/cifar-10-image-classification-fd2ace47c5e8
  2. Imagen 2: https://www.analyticsvidhya.com/blog/2021/05/convolutional-neural-networks-cnn/

No dudes en conectarte conmigo en:

  1.  Linkedin: https://www.linkedin.com/in/siddharth-m-426a9614a/
  2.  Github: https://github.com/Siddharth1698

Los medios que se muestran en este artículo no son propiedad de Analytics Vidhya y se utilizan a discreción del autor.

Fuente: https://www.analyticsvidhya.com/blog/2021/09/convolutional-neural-network-pytorch-implementation-on-cifar10-dataset/

Sello de tiempo:

Mas de Analítica Vidhya