Compartir tecnología

Pytorch (notas 8 red neuronal nn)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1、nn.Módulo

torch.nn es un módulo especialmente diseñado para el aprendizaje profundo. La estructura de datos central de torch.nn es Módulo, que es un concepto abstracto que puede representar una determinada capa en una red neuronal o una red neuronal que contiene muchas capas. En el uso real, el método más común es heredar nn.Module y escribir su propia red/capa. Primero echemos un vistazo a cómo usar nn.Module para implementar su propia capa completamente conectada.Y=AX+B

import torch as t
import torch.nn as nn

class network(nn.Module):
    def __init__(self, input, output):
        super().__init__()
        # 定义权重矩阵a,它是一个可训练的参数,形状为(input, output)
        self.a = nn.Parameter(t.randn(input, output))
        # 定义偏置向量b,它也是一个可训练的参数,形状为(output,)
        # 注意:偏置向量的长度应与输出特征的维度相匹配
        self.b = nn.Parameter(t.randn(output))

    def forward(self, x):
        """
        定义前向传播过程

        参数:
            x (torch.Tensor): 输入数据,形状应为(batch_size, input)

        返回:
            torch.Tensor: 输出数据,形状为(batch_size, output)
        """
        # 首先,使用权重矩阵a对输入x进行线性变换
        # [email protected]执行矩阵乘法,x的每一行与a相乘,结果形状为(batch_size, output)
        x = x @ self.a
        # 然后,将偏置向量b扩展(通过broadcasting)到与x相同的形状,并加到x上
        # self.b.expand_as(x)将b的形状从(output,)扩展到(batch_size, output)
        # x + self.b.expand_as(x)将偏置加到每个样本的输出上
        x = x + self.b.expand_as(x)
        # 返回变换后的输出
        return x


a = network(4, 3)
# 创建输入数据,形状为(6, 4),表示有6个样本,每个样本有4个特征
input = t.rand(6, 4)
# 通过网络前向传播得到输出
output = a(input)
# 打印输出,形状应为(6, 3),表示有6个样本,每个样本的输出特征维度为3
print(output)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • La red de capa personalizada debe heredar nn.Module, y el constructor de nn.Module debe llamarse en su constructor, es decir, super ().en eso() o nn.Módulo.en eso(auto), se recomienda el primer uso;
  • En el constructor __init__, usted mismo debe definir los parámetros que se pueden aprender y encapsularlos en Parámetros. Por ejemplo, en este ejemplo, encapsulamos w y b en Parámetros. El parámetro es un tensor especial, pero requiere derivadas de forma predeterminada (requires_grad
    = Verdadero)
  • La función directa implementa el proceso de propagación hacia adelante y su entrada puede ser uno o más tensores;
  • No es necesario escribir una función de retropropagación nn.Module puede usar autograd para implementar automáticamente la retropropagación, que es mucho más simple que Function;
  • Los parámetros que se pueden aprender en el Módulo pueden devolver un iterador a través de nombrados_parametros() o parámetros(). El primero adjuntará un nombre a cada parámetro para hacerlo más identificable.

2. Capas de redes neuronales de uso común

2.1 Capa relacionada con la imagen

Las capas relacionadas con imágenes incluyen principalmente capas de convolución (Conv), capas de agrupación (Pool), etc. En el uso real, estas capas se pueden dividir en unidimensionales (1D), bidimensionales (2D) y tridimensionales (3D). El método de agrupación también se divide en agrupación promedio (AvgPool), agrupación máxima (MaxPool), agrupación adaptativa (AdaptiveAvgPool), etc. Además de la convolución directa comúnmente utilizada, la capa convolucional también tiene convolución inversa (TransposeConv), etc. A continuación se dará un ejemplo.

  • Extracción de características
  • Mantener la estructura del espacio de datos.
  • Introducción de la transformación no lineal Después de la operación de convolución, generalmente se aplica una función de activación (como ReLU, Sigmoid o Tanh) para introducir la transformación no lineal. Estas funciones de activación pueden aumentar el poder expresivo de CNN y permitirle aprender relaciones no lineales más complejas.
  • Mejorar la eficiencia computacional Mediante el uso combinado de operaciones convolucionales y capas de agrupación, la capa convolucional puede reducir la dimensión espacial del mapa de características, reduciendo así la cantidad de cálculo y mejorando la eficiencia computacional del modelo. Al mismo tiempo, la capa de agrupación también puede mejorar la invariancia de traducción de las características, haciendo que el modelo sea más robusto ante pequeños cambios en los datos de entrada.

capa de convolución

En el aprendizaje profundo, la estructura de red más importante relacionada con el procesamiento de imágenes es la capa convolucional (Conv). La esencia de una red neuronal convolucional es la superposición de capas convolucionales, capas de agrupación, capas de activación y otras capas. Por lo tanto, es extremadamente importante comprender el principio de funcionamiento de la capa convolucional. El siguiente es un ejemplo del proceso específico. operación de convolución.
Insertar descripción de la imagen aquí

# 导入PyTorch库  
import torch  
import torch.nn as nn  
  
# 从torchvision.transforms导入ToTensor和ToPILImage,用于图像张量和PIL图像之间的转换  
from torchvision.transforms import ToTensor, ToPILImage  
  
# 从PIL(Python Imaging Library,Pillow是其一个分支)导入Image模块,用于处理图像文件  
from PIL import Image  
  
# 使用PIL的Image.open函数打开指定路径的图片文件,并通过.convert("L")将其转换为灰度图像(单通道)  
img = Image.open("H:\PYTHON_Proj\handlearnpytorch\OIP-C.jpg").convert("L")  
  
# 实例化ToTensor转换对象,用于将PIL图像转换为PyTorch张量  
to_tensor = ToTensor()  
  
# 实例化ToPILImage转换对象,用于将PyTorch张量转换回PIL图像  
to_PIL = ToPILImage()  
  
# 使用to_tensor将PIL图像转换为PyTorch张量,并通过.unsqueeze(0)在批次大小维度上增加一个维度,使其形状变为(1, 1, H, W)  
img = to_tensor(img).unsqueeze(0)  
  
# 创建一个3x3的卷积核(滤波器),初始时所有元素都被设置为-1/9,然后将中心元素设置为1  
kernel = torch.ones(3, 3) / (-9.0)  
kernel[1][1] = 1  
  
# 创建一个Conv2d层,指定输入通道数为1(因为是灰度图像),输出通道数也为1,卷积核大小为3x3,步长为1,填充为1(保持输出尺寸与输入相同),且不使用偏置项  
conv = nn.Conv2d(1, 1, 3, 1, 1, bias=False)  
  
# 将之前定义的卷积核赋值给Conv2d层的权重,注意要调整形状以匹配Conv2d层的期望(out_channels, in_channels, kernel_size[0], kernel_size[1])  
conv.weight.data = kernel.reshape(1, 1, 3, 3)  
  
# 对图像应用卷积操作,此时img是一个四维张量,Conv2d层会处理它并返回一个新的四维张量  
img = conv(img)  
  
# 使用to_PIL将卷积后的PyTorch张量转换回PIL图像,并通过.squeeze(0)移除批次大小维度  
img = to_PIL(img.squeeze(0))  
  
# 使用PIL的.show()方法显示图像  
img.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

capa de agrupación

La capa de agrupación puede considerarse como una capa de convolución especial, que se utiliza principalmente para reducir la resolución. Agregar una capa de agrupación puede reducir la cantidad de parámetros y al mismo tiempo conservar las características principales, evitando así el sobreajuste hasta cierto punto. La capa de agrupación no tiene parámetros que se puedan aprender y su peso es fijo. Varias capas de agrupación están empaquetadas en la caja de herramientas de torch.nn. Las más comunes incluyen Max Pooling (MaxPool) y Average Pooling (AvgPool). La capa de agrupación juega un papel muy importante en la red neuronal convolucional. Sus principales usos se pueden resumir en los siguientes:

  • Reducción de dimensionalidad (reducción de la cantidad de cálculo): la capa de agrupación reduce la cantidad de cálculo y la cantidad de parámetros de las capas posteriores al reducir el tamaño espacial de los datos (es decir, la altura y el ancho). Esto es muy beneficioso para evitar el sobreajuste y acelerar los cálculos.
  • Invariancia de características: la capa de agrupación puede permitir que el modelo aprenda una representación de características más sólida, es decir, invariante a pequeños cambios en los datos de entrada (como traslación, rotación, etc.). Esto se debe a que las operaciones de agrupación (como agrupación máxima, agrupación promedio, etc.) seleccionan características representativas dentro del área en lugar de depender de información de ubicación específica.
  • Extraer características principales: mediante la operación de agrupación, se pueden extraer las características más importantes de la imagen ignorando algunos detalles sin importancia. Esto es útil para que las capas convolucionales posteriores extraigan aún más características de alto nivel.
  • Ampliar el campo receptivo: a medida que aumenta el número de capas de red, la capa de agrupación puede expandir gradualmente el área de entrada (es decir, el campo receptivo) correspondiente a cada neurona en las capas posteriores. Esto ayuda a la red a obtener más información sobre funciones globales.
  • Reducir el sobreajuste: dado que la capa de agrupación reduce la cantidad de parámetros al reducir la dimensión espacial de los datos, esto puede reducir la complejidad del modelo hasta cierto punto, lo que ayuda a prevenir el sobreajuste.

Las operaciones de agrupación comunes incluyen:

  • Agrupación máxima: seleccione el valor máximo dentro de la ventana de agrupación como salida. Este enfoque ayuda a preservar la información de bordes y texturas de la imagen.
  • Agrupación promedio: calcula el promedio de todos los valores dentro de la ventana de agrupación como salida. Este enfoque ayuda a preservar la información de fondo de la imagen.
  • Agrupación estocástica: según el valor de cada elemento en la ventana de agrupación, los elementos se seleccionan aleatoriamente como salida de acuerdo con la probabilidad. Este método combina las ventajas de la agrupación máxima y la agrupación promedio, pero tiene una mayor complejidad computacional.

En resumen, la capa de agrupación es una parte indispensable de la red neuronal convolucional. Proporciona la capacidad de aprendizaje y el rendimiento de toda la red al reducir la dimensión espacial de los datos, extraer las características principales, expandir el campo receptivo y evitar el sobreajuste. apoyo.

# 导入PyTorch库  
import torch  
  
# 导入PyTorch的神经网络模块,用于构建和训练神经网络  
import torch.nn as nn  
  
# 从torchvision.transforms模块导入ToTensor和ToPILImage,这两个转换工具用于图像数据的预处理和后处理  
from torchvision.transforms import ToTensor, ToPILImage  
  
# 从PIL库导入Image模块,用于图像的打开、显示等操作  
from PIL import Image  
  
# 创建一个ToTensor的实例,用于将PIL图像或numpy.ndarray转换为FloatTensor,并归一化到[0.0, 1.0]  
to_tensor = ToTensor()  
  
# 创建一个ToPILImage的实例,用于将Tensor或ndarray转换为PIL图像  
to_pil = ToPILImage()  
  
# 使用PIL的Image.open方法打开指定路径的图像文件,并将其转换为灰度图像('L'模式)  
img = Image.open("H:\PYTHON_Proj\handlearnpytorch\OIP-C.jpg").convert('L')  
  
# 使用PIL的show方法显示图像  
img.show()  
  
# 使用ToTensor转换将PIL图像转换为Tensor,并增加一个维度使其成为[1, H, W]形状,即增加一个批次维度  
img = to_tensor(img).unsqueeze(0)  
  
# 创建一个平均池化层实例,使用2x2的窗口大小和步长为2进行池化  
pool = nn.AvgPool2d(2, 2)  
  
# 对图像Tensor应用平均池化层,然后移除批次维度(squeeze(0)),使其变回[H', W']形状  
img = pool(img).squeeze(0)  
  
# 将Tensor转换回PIL图像以便显示  
img = to_pil(img)  
  
# 再次使用PIL的show方法显示经过池化处理的图像  
img.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

otras capas

Además de las capas convolucionales y las capas de agrupación, las siguientes capas también se usan comúnmente en el aprendizaje profundo:

  • Lineal: capa completamente conectada;
  • BatchNorm: capa de normalización por lotes, dividida en 1D, 2D y 3D. Además del BatchNorm estándar, también existe la capa InstanceNorm que se usa comúnmente en la migración de estilos;
  • Abandono: la capa de abandono, utilizada para evitar el sobreajuste, también se divide en 1D, 2D y 3D.

3. Estrategia de inicialización

La inicialización de parámetros es muy importante en el aprendizaje profundo. Una buena inicialización puede hacer que el modelo converja más rápido y alcance un nivel superior, mientras que una inicialización deficiente puede hacer que el modelo colapse rápidamente. Los parámetros del módulo de nn.Module en PyTorch adoptan una estrategia de inicialización más razonable, por lo que generalmente no es necesario considerarlo. Por supuesto, también podemos utilizar la inicialización personalizada para reemplazar la inicialización predeterminada del sistema. Cuando usamos parámetros, la inicialización personalizada es particularmente importante, porque torch.Tensor () devuelve un número aleatorio en la memoria, que probablemente tenga un valor máximo, lo que provocará un desbordamiento o un desbordamiento en la red de entrenamiento real. . El módulo nn.init en PyTorch es un módulo especialmente diseñado para la inicialización e implementa estrategias de inicialización de uso común. Si nn.init no proporciona una determinada estrategia de inicialización, los usuarios también pueden inicializarla directamente ellos mismos.

import torch  
from torch.nn import init  
from torch import nn  
  
# 创建一个线性层,其权重和偏置会被随机初始化(与torch.manual_seed无关,因为这是在调用torch.manual_seed之前发生的)  
linear = nn.Linear(3, 4)  
  
# 打印层创建时默认初始化的权重  
print("默认初始化的权重:")  
print(linear.weight)  
  
# 设置随机数生成的种子,以确保接下来的随机数生成是可重复的  
torch.manual_seed(2021)  
  
# 使用Xavier正态分布重新初始化权重  
# 这个初始化是受torch.manual_seed(2021)影响的  
init.xavier_normal_(linear.weight)  
  
# 打印重新初始化后的权重  
print("Xavier正态分布初始化后的权重:")  
print(linear.weight)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21