Modificación al ejemplo del Perceptron Multicapa (MLP)
Mariano Rivera
agosto 2020
import torch
import torch.nn as nn
import torchvision.transforms as transforms
from torch.autograd import Variable
import torchvision.datasets as datasets
torch.__version__
'1.3.1'
Aqui sólo definimos la clase de la red convolucional para ser usada en vez del Perceptrón Multi-Capa (MLP).
Como alternativa definimos la red neuronal convolucional:
__init__
definimos los componentes de nuestra red convolucional. Los componentes contedrán ahora capas convolucionales, funciones de activación, capas de pooling y una capa Linear
que nos servirá para dar la clasificación de salida.class CONVnet(nn.Module):
def __init__(self, num_filters):
super(CONVnet, self).__init__()
'''
El método __init__ define las capas de las cuales constará el modelo,
aunque no la forma en que se interconectan
'''
self.conv1 = nn.Conv2d(in_channels =1,
out_channels =num_filters[0],
kernel_size =3,
padding =1,)
self.activ1 = nn.ReLU()
self.max1 = nn.MaxPool2d(2)
self.conv2 = nn.Conv2d(in_channels =num_filters[0],
out_channels =num_filters[1],
kernel_size =3,
padding =1,)
self.activ2 = nn.ReLU()
self.max2 = nn.MaxPool2d(2)
self.conv3 = nn.Conv2d(in_channels =num_filters[1],
out_channels =num_filters[2],
kernel_size =3,
padding =1,)
self.activ3 = nn.ReLU()
self.max3 = nn.MaxPool2d(2)
self.fc1 = nn.Linear(num_filters[2]*7*7, 10)
self.num_filters = num_filters
def forward(self, x):
'''
el método forward implementa la arquitecura de la red: define la
interconección de las capas, el orden en que se realiza el procesamiento
'''
x1 = self.conv1 (x)
x1 = self.activ1(x1)
x1 = self.max1 (x1)
x2 = self.conv2 (x1)
x2 = self.activ2(x2)
x1 = self.max2 (x2)
x3 = self.conv3 (x2)
x3 = self.activ3(x3)
x3 = self.max3 (x3)
x4 = x3.view(-1, self.num_filters[2]*7*7) # aqui convertimos la imagen a un vector unidimensional
out = self.fc1(x4)
return out
def name(self):
'''
Regresa el nombre de la Clase de red
'''
return "CONV"
El modelo se construye en este caso con
model = CONVnet(num_filters = [10, 20, 40])
Note que de una capa convolucional a la siguiente se decrementan las dimensiones Alto y Ancho del tensor y se incrementa el número de canales (de acuerdo al número de filtros en la capa que antecede.
print(model)
CONVnet(
(conv1): Conv2d(1, 10, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(activ1): ReLU()
(max1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(conv2): Conv2d(10, 20, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(activ2): ReLU()
(max2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(conv3): Conv2d(20, 40, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(activ3): ReLU()
(max3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(fc1): Linear(in_features=1960, out_features=10, bias=True)
)