Implementación y construcción de modelos de convolución y pooling en Pytorch

En el artículo anterior se ha introducido el uso de algunos métodos en la clase Dataset y la clase Transform en Pytorch, a continuación se introducirá la implementación de la convolución y otras operaciones utilizando Pytorch.

1. nn.Clase de módulo

Un nn.Module es el esqueleto básico de una red neuronal y puede verse como un bloque. Si la red neuronal necesita anular el método de inicialización, debe llamar a la función de inicialización de la clase principal.

Todos los módulos contienen dos funciones principales:

Función init: define algunas clases o parámetros requeridos en ella. Incluyendo la capa de red.

función directa: realiza el cálculo final y la salida, y su parámetro formal es la entrada del modelo (bloque).

Ahora simplemente escribamos una clase:

class Test1(nn.Module):
   
def __init__ ( self ) -> Ninguno :
       
super (). __init__ ()

   
def adelante ( auto , entrada):
        salida = entrada+
1
       
retorno salida

La función de esta clase es pasar un número, mostrar el resultado de sumar uno al número y llamar a la clase:

prueba1 = Prueba1() 

x = antorcha.tensor( 1.0 )

Nota: No es necesario hacer referencia a la función al llamar al método de reenvío, porque el método de reenvío en el nn.Module integrado es la implementación del método __call__(), y el objeto invocable llamará al método __call__().

salida = test1(x) 

imprimir (salida)

La salida es la siguiente:

 

dos, convolución

1、conv2d

La integral de convolución se divide en diferentes capas, como con1, con2, etc. Tomando como ejemplo la convolución de dos capas, los parámetros específicos se pueden encontrar en el documento oficial. La operación de convolución se calcula principalmente con el núcleo de convolución (peso ) y los datos originales, además de Otras operaciones, y finalmente obtener una nueva salida. .

Los significados de algunos de estos parámetros importantes son los siguientes:

salida es la salida calculada del modelo de red neuronal convolucional.

input son los datos de entrada, aquí es una matriz bidimensional que representa una imagen.

Kernel representa el kernel de convolución.También es una matriz bidimensional como la forma de entrada, y ambas formas deben tener cuatro indicadores, de lo contrario, se requiere una remodelación.

zancada representa el tamaño del paso.

padding indica cuántas capas se rellenan y el valor predeterminado de padding es 0.

Primero importa el paquete:

importar antorcha 

importar antorcha.nn.funcional como F

Establecer datos de entrada:

input = antorcha.tensor([[ 1 , 2 , 0 , 3 , 1 ] , 

                      [ 0 , 1 , 2 , 3 , 1 ] , 

                      [ 1 , 2 , 1 , 0 , 0 ] , 

                      [ 5 , 2 , 3 , 1 , 1 ] , 

                      [ 2 , 1 , 0 , 1 , 1]])

Establecer el kernel de convolución:

núcleo = antorcha.tensor ([[ 1 , 2 , 1 ] , 

                       [ 0 , 1 , 0 ] , 

                       [ 2 , 1 , 0 ]])

Debido a que los datos establecidos están incompletos, se realiza la remodelación

entrada = antorcha.reforma(entrada , ( 1 , 1 , 5 , 5 )) 

núcleo = antorcha.reforma(núcleo , ( 1 , 1 , 3 , 3 ))

Realice una convolución con un paso de 1:

salida1 = F.conv2d(entrada , núcleo , zancada = 1 ) 

imprimir (salida1)

La salida es la siguiente:

 

Realiza una convolución con un paso de 2:

salida2 = F.conv2d(entrada , núcleo , zancada = 2 ) 

imprimir (salida2)

La salida es la siguiente:

 

Realice una convolución con un tamaño de paso de 1 y una capa de relleno de 1:

salida3 = F.conv2d(entrada , núcleo , zancada = 1 , relleno = 1 ) 

imprimir (salida3)

La salida es la siguiente:

 

2、Conv2d

De hecho, es una encapsulación adicional de nn.function, como nn.Conv2(), los más utilizados son estos cinco parámetros: in_channels, out_channels, kernel_size, stride, padding

Primero importe los paquetes requeridos:

importar torch 

importar torchvision 

de torch importar nn 

de torch.nn importar Conv2d 

de torch.utils.data importar DataLoader 

de torch.utils.tensorboard importar SummaryWriter

Use el conjunto de datos para descargar las muestras de capacitación requeridas y use el cargador de datos para empaquetar:

dataset = torchvision.datasets.CIFAR10( 'dataset' , train = False, transform =torchvision.transforms.ToTensor() , download = True ) 

dataloader = DataLoader(dataset , batch_size = 64 )

Clase de construcción:

class Test1(nn.Module): 

    def __init__ ( self ): 

        super (Test1 , self ).__ init__ () 

        #Debido a que es una imagen en color, in_channels=3, el número de canales de salida=6 

        self .conv1 = Conv2d( in_channels = 3 , out_channels = 6 , kernel_size = 3 , stride = 1 , padding = 0 ) 



    def adelante ( self , x): 

        x = self .conv1(x)

        volver x

En este punto, el tamaño del kernel de convolución establecido es 3x3 y el número de canales de salida es 6.

Llame a la clase, pase la muestra de capacitación a la clase y muéstrela en el navegador:

test1 = Test1 () 

paso = 0 

escritor = SummaryWriter ( 'logs_conv2d' ) 

para datos en el cargador de datos: 

    imgs , objetivos = 

    salida de datos = test1 (imgs)
#Imagen entrante antes de la convolución, torch.Size([64, 3, 32, 32]) 

    escritor.add_images( 'iuput' , imgs , paso) 

    #Imagen entrante después de la convolución, torch.Size([64 , 6, 30, 30 ]) # 


    El número de canales de la imagen después de la convolución 
    es 6 , y la imagen no 
    se puede mostrar . paso) 
    paso = paso + 1 escritor.cerrar()



La salida es la siguiente:

La entrada es la imagen original:

La salida es la imagen convolucionada:

 

3. Máxima agrupación

La función de la capa de agrupación máxima (comúnmente utilizada es maxpool2d):

Una es reducir aún más la dimensionalidad de la información extraída por la capa convolucional y reducir la cantidad de cálculo.

El segundo es fortalecer la invariancia de las características de la imagen, para aumentar la robustez del desplazamiento y la rotación de la imagen.

El tercero es similar a las diferentes resoluciones al ver un video, el efecto real es como mosaicos de una imagen.

1. Realice la agrupación máxima en una matriz bidimensional

Primero importa el paquete:

importar antorcha 

desde antorcha importar nn 

desde antorcha.nn importar MaxPool2d

Defina una matriz binaria similar a un tensor:

input = antorcha.tensor([[ 1 , 2 , 0 , 3 , 1 ] , 

                      [ 0 , 1 , 2 , 3 , 1 ] , 

                      [ 1 , 2 , 1 , 0 , 0 ] , 

                      [ 5 , 2 , 3 , 1 , 1 ] , 

                      [ 2 , 1 , 0 , 1 , 1]] , tipod =antorcha.float32)

Realizar remodelación:

entrada = antorcha.reforma(entrada , (- 1 , 1 , 5 , 5 ))

Defina la clase para la agrupación máxima:

class Test1(nn.Module): 

    def __init__ ( self ): 

        super (Test1 , self ). __init__ () 

        self .maxpool1 = MaxPool2d( kernel_size = 3 , ceil_mode = True ) 



    def adelante ( self , entrada): 

        salida = self .maxpool1(entrada) 

        volver salida

Arriba, cuando el filtro es 3x3 y ceil_mode es True, los píxeles redundantes no se descartan y se agregan ceros a la matriz original que no satisface 3x3.

Clase de llamada:

prueba1 = Prueba1() 

salida = prueba1(entrada) 

imprimir (salida)

La salida es la siguiente:

2. Realice la agrupación máxima en la imagen

Primero importa el paquete:

importar torchvision 

de torch importar nn 

de torch.nn importar MaxPool2d 

de torch.utils.data importar DataLoader 

de torch.utils.tensorboard importar SummaryWriter

Use el conjunto de datos para descargar las muestras de capacitación requeridas y use el cargador de datos para empaquetar:

dataset = torchvision.datasets.CIFAR10( 'dataset' , train = False, transform =torchvision.transforms.ToTensor() , download = True ) 

dataloader = DataLoader(dataset , batch_size = 64 )

Clase de construcción:

class Test1(nn.Module): 

    def __init__ ( self ): 

        super (Test1 , self ). __init__ () 

        self .maxpool1 = MaxPool2d( kernel_size = 3 , ceil_mode = True ) 

    def adelante ( self , entrada): 

        salida = self .maxpool1(entrada) 

        volver salida

Clase de llamada:

test1 = Test1() 

paso = 0 

escritor = SummaryWriter( 'logs_maxpool' ) 

para datos en el cargador de datos: 

    imgs , targets = salida de datos 

    = test1(imgs) 

    escritor.add_images( 'iuput' , imgs , paso) 

    escritor.add_images( 'salida ' , salida , paso) 

    paso = paso + 1 


escritor.cerrar()

La salida es la siguiente:

La imagen original es la siguiente:

 

La imagen después de la agrupación máxima es la siguiente:

 

4. Activación no lineal

El objetivo principal de la transformación no lineal es agregar algunas características no lineales a la red. Cuanto más no lineales, más se puede entrenar el modelo para cumplir con varias características. Activaciones no lineales comunes:

ReLU: es principalmente para truncar lo que es menor que 0 (convertir lo que es menor que 0 en 0), y el efecto de la transformación de la imagen no es obvio. El parámetro principal está en su lugar:

Cuando inplace es verdadero, asigna el resultado procesado al parámetro original; cuando es falso, el valor original no cambiará.

Sigmoide: Procesamiento normalizado. El efecto no es tan bueno como ReLU, pero por el problema de hasta dónde clasificar, se debe usar sigmoid.

Tome el método ReLU como ejemplo:

Primero importa el paquete

importar antorcha 

desde antorcha importar nn 

desde antorcha.nn importar ReLU

Establecer parámetros entrantes:

entrada = antorcha.tensor([[ 1 , - 0.5 ] , 

                      [- 1 , 3 ]]) 

entrada = antorcha.reforma(entrada , (- 1 , 1 , 2 , 2 ))

Clase de construcción:

class Test1(nn.Module): 

    def __init__ ( self ): 

        super (Test1 , self ). __init__ () 

        self .relu1 = ReLU() 

    def adelante ( self , entrada): 

        salida = self .relu1(entrada) 

        volver salida

Clase de llamada:

prueba1 = Prueba1() 

salida = prueba1(entrada) 

imprimir (salida)

La salida es la siguiente:

 

5. Capa lineal

La capa lineal también se denomina capa totalmente conectada, en la que cada neurona está conectada a todas las neuronas de la capa anterior.

La función lineal es: torch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None), y los tres parámetros importantes in_features, out_features y bias se describen a continuación:

in_features: el tamaño de las características para cada muestra de entrada (x)

out_features: el tamaño de las características para cada muestra de salida (y)

sesgo: si se establece en Falso, la capa no aprenderá sesgo adicional. El valor predeterminado es Verdadero, lo que significa aumentar el sesgo de aprendizaje.

    En la figura anterior, in_features=d, out_features=L.

El efecto puede ser reducir la longitud de los datos unidimensionales.

  • Uso de secuencial (torch.nn.Sequential)

Todas las operaciones requeridas se pueden escribir en una función. Es principalmente para facilitar la escritura del código y hacerlo más conciso.

Por ejemplo, implemente el modelo que se muestra en la siguiente figura:

 

Primero importa el paquete:

importar antorcha 

de antorcha importar nn 

de torch.nn importar Conv2d , MaxPool2d , Flatten , Linear , Sequential 

de torch.utils.tensorboard importar SummaryWriter

Clase de construcción:

class Test(nn.Module): 

    def __init__ ( self ): 

        super (Test , self ). __init__ () 

        self .model1 = Sequential( 

            Conv2d( in_channels = 3 , out_channels = 32 , kernel_size = 5 , stride = 1 , padding = 2 ) , 

            MaxPool2d( 2 ) , 

            Conv2d( in_channels = 32 , out_channels= 32 , kernel_size = 5 , padding = 2 , stride = 1 ) , 

            MaxPool2d( 2 ) , 

            Conv2d( in_channels = 32 , out_channels = 64 , kernel_size = 5 , padding = 2 , stride = 1 ) , 

            MaxPool2d( 2 ) , 

            Flatten () , 

            Lineal ( en_características = 1024, out_features = 64 ) , 

            Linear( in_features = 64 , out_features = 10 ) 

        ) 



    def adelante ( self , x): 

        x = self .model1(x) 

        return x

Clase de llamada:

prueba1 = Prueba() 

print (prueba1) 

entrada = torch.ones(( 64 , 3 , 32 , 32 )) 

salida = prueba1(entrada) 

print (salida.forma) 



escritor = SummaryWriter( 'logs_seq1' ) 

escritor.add_graph(prueba1 , entrada) 

escritor.cerrar()

La salida es la siguiente:

 Puede ver el contexto de este modelo de red neuronal.

Supongo que te gusta

Origin blog.csdn.net/m0_51864191/article/details/127678277
Recomendado
Clasificación