En este tema, exploraremos algunas de las arquitecturas más influyentes y populares de Redes Neuronales Convolucionales (CNN) que han sido desarrolladas y utilizadas en la comunidad de Deep Learning. Estas arquitecturas han demostrado ser altamente efectivas en tareas de reconocimiento de imágenes y han establecido nuevos estándares en competiciones y benchmarks.

  1. LeNet-5

Descripción

LeNet-5, desarrollado por Yann LeCun en 1998, es una de las primeras CNN y fue diseñada para la tarea de reconocimiento de dígitos escritos a mano en el dataset MNIST.

Arquitectura

  • Entrada: Imagen de 32x32 píxeles.
  • Capa Convolucional 1: 6 filtros de 5x5, seguido de una capa de activación tanh.
  • Capa de Pooling 1: Submuestreo (pooling) de 2x2.
  • Capa Convolucional 2: 16 filtros de 5x5, seguido de una capa de activación tanh.
  • Capa de Pooling 2: Submuestreo (pooling) de 2x2.
  • Capa Convolucional 3: 120 filtros de 5x5, seguido de una capa de activación tanh.
  • Capa Fully Connected 1: 84 neuronas, seguido de una capa de activación tanh.
  • Salida: 10 neuronas con activación softmax para clasificación.

Ejemplo de Código en PyTorch

import torch
import torch.nn as nn
import torch.nn.functional as F

class LeNet5(nn.Module):
    def __init__(self):
        super(LeNet5, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, kernel_size=5)
        self.conv2 = nn.Conv2d(6, 16, kernel_size=5)
        self.conv3 = nn.Conv2d(16, 120, kernel_size=5)
        self.fc1 = nn.Linear(120, 84)
        self.fc2 = nn.Linear(84, 10)

    def forward(self, x):
        x = F.tanh(self.conv1(x))
        x = F.avg_pool2d(x, 2)
        x = F.tanh(self.conv2(x))
        x = F.avg_pool2d(x, 2)
        x = F.tanh(self.conv3(x))
        x = x.view(-1, 120)
        x = F.tanh(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)

# Crear una instancia del modelo
model = LeNet5()
print(model)

  1. AlexNet

Descripción

AlexNet, desarrollado por Alex Krizhevsky y su equipo en 2012, ganó la competición ImageNet Large Scale Visual Recognition Challenge (ILSVRC) y marcó un hito en el uso de CNNs para tareas de visión por computadora.

Arquitectura

  • Entrada: Imagen de 224x224 píxeles.
  • Capa Convolucional 1: 96 filtros de 11x11, stride 4, seguido de ReLU y max-pooling de 3x3.
  • Capa Convolucional 2: 256 filtros de 5x5, seguido de ReLU y max-pooling de 3x3.
  • Capa Convolucional 3: 384 filtros de 3x3, seguido de ReLU.
  • Capa Convolucional 4: 384 filtros de 3x3, seguido de ReLU.
  • Capa Convolucional 5: 256 filtros de 3x3, seguido de ReLU y max-pooling de 3x3.
  • Capa Fully Connected 1: 4096 neuronas, seguido de ReLU y dropout.
  • Capa Fully Connected 2: 4096 neuronas, seguido de ReLU y dropout.
  • Salida: 1000 neuronas con activación softmax para clasificación.

Ejemplo de Código en PyTorch

import torch
import torch.nn as nn
import torch.nn.functional as F

class AlexNet(nn.Module):
    def __init__(self, num_classes=1000):
        super(AlexNet, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 96, kernel_size=11, stride=4, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(96, 256, kernel_size=5, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(256, 384, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(384, 384, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(384, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
        )
        self.classifier = nn.Sequential(
            nn.Dropout(),
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, num_classes),
        )

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), 256 * 6 * 6)
        x = self.classifier(x)
        return x

# Crear una instancia del modelo
model = AlexNet()
print(model)

  1. VGGNet

Descripción

VGGNet, desarrollado por el Visual Geometry Group de la Universidad de Oxford, es conocido por su simplicidad y profundidad. VGGNet utiliza solo capas convolucionales de 3x3 y max-pooling de 2x2.

Arquitectura

  • Entrada: Imagen de 224x224 píxeles.
  • Bloque Convolucional 1: 2 capas de 64 filtros de 3x3, seguido de max-pooling de 2x2.
  • Bloque Convolucional 2: 2 capas de 128 filtros de 3x3, seguido de max-pooling de 2x2.
  • Bloque Convolucional 3: 3 capas de 256 filtros de 3x3, seguido de max-pooling de 2x2.
  • Bloque Convolucional 4: 3 capas de 512 filtros de 3x3, seguido de max-pooling de 2x2.
  • Bloque Convolucional 5: 3 capas de 512 filtros de 3x3, seguido de max-pooling de 2x2.
  • Capa Fully Connected 1: 4096 neuronas, seguido de ReLU y dropout.
  • Capa Fully Connected 2: 4096 neuronas, seguido de ReLU y dropout.
  • Salida: 1000 neuronas con activación softmax para clasificación.

Ejemplo de Código en PyTorch

import torch
import torch.nn as nn
import torch.nn.functional as F

class VGGNet(nn.Module):
    def __init__(self, num_classes=1000):
        super(VGGNet, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(64, 128, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(128, 128, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(128, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(256, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
        )
        self.classifier = nn.Sequential(
            nn.Dropout(),
            nn.Linear(512 * 7 * 7, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, num_classes),
        )

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), 512 * 7 * 7)
        x = self.classifier(x)
        return x

# Crear una instancia del modelo
model = VGGNet()
print(model)

  1. ResNet

Descripción

ResNet, desarrollado por Kaiming He y su equipo en 2015, introdujo la idea de "residual learning" para abordar el problema de la degradación en redes muy profundas. ResNet ganó el ILSVRC 2015 con una arquitectura de 152 capas.

Arquitectura

  • Entrada: Imagen de 224x224 píxeles.
  • Bloque Residual: Cada bloque consiste en capas convolucionales de 3x3 con conexiones de salto (skip connections) que permiten que la entrada se sume a la salida del bloque.
  • Variantes: ResNet-18, ResNet-34, ResNet-50, ResNet-101, ResNet-152, donde el número indica la cantidad de capas.

Ejemplo de Código en PyTorch

import torch
import torch.nn as nn
import torch.nn.functional as F

class BasicBlock(nn.Module):
    def __init__(self, in_channels, out_channels, stride=1):
        super(BasicBlock, self).__init__()
        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1)
        self.bn1 = nn.BatchNorm2d(out_channels)
        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1)
        self.bn2 = nn.BatchNorm2d(out_channels)
        self.shortcut = nn.Sequential()
        if stride != 1 or in_channels != out_channels:
            self.shortcut = nn.Sequential(
                nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride),
                nn.BatchNorm2d(out_channels)
            )

    def forward(self, x):
        out = F.relu(self.bn1(self.conv1(x)))
        out = self.bn2(self.conv2(out))
        out += self.shortcut(x)
        out = F.relu(out)
        return out

class ResNet(nn.Module):
    def __init__(self, block, num_blocks, num_classes=1000):
        super(ResNet, self).__init__()
        self.in_channels = 64
        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3)
        self.bn1 = nn.BatchNorm2d(64)
        self.layer1 = self._make_layer(block, 64, num_blocks[0], stride=1)
        self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)
        self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)
        self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)
        self.fc = nn.Linear(512, num_classes)

    def _make_layer(self, block, out_channels, num_blocks, stride):
        layers = []
        layers.append(block(self.in_channels, out_channels, stride))
        self.in_channels = out_channels
        for _ in range(1, num_blocks):
            layers.append(block(self.in_channels, out_channels))
        return nn.Sequential(*layers)

    def forward(self, x):
        x = F.relu(self.bn1(self.conv1(x)))
        x = F.max_pool2d(x, kernel_size=3, stride=2, padding=1)
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)
        x = F.avg_pool2d(x, 4)
        x = x.view(x.size(0), -1)
        x = self.fc(x)
        return x

def ResNet18():
    return ResNet(BasicBlock, [2, 2, 2, 2])

# Crear una instancia del modelo
model = ResNet18()
print(model)

Conclusión

En esta sección, hemos explorado algunas de las arquitecturas más populares de CNN, incluyendo LeNet-5, AlexNet, VGGNet y ResNet. Cada una de estas arquitecturas ha contribuido significativamente al avance del campo de Deep Learning y ha establecido nuevos estándares en tareas de reconocimiento de imágenes. Entender estas arquitecturas y sus componentes es crucial para cualquier profesional que desee profundizar en el diseño y la implementación de redes neuronales convolucionales.

En el siguiente tema, exploraremos las aplicaciones de CNN en el reconocimiento de imágenes, donde veremos cómo estas arquitecturas se utilizan en la práctica para resolver problemas del mundo real.

© Copyright 2024. Todos los derechos reservados