기술나눔

Pytorch(참고 8 신경망 nn)

2024-07-12

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

1、nn.모듈

torch.nn은 딥러닝을 위해 특별히 설계된 모듈입니다. torch.nn의 핵심 데이터 구조는 모듈(Module)로, 신경망의 특정 레이어 또는 여러 레이어를 포함하는 신경망을 나타낼 수 있는 추상 개념입니다. 실제 사용에서 가장 일반적인 접근 방식은 nn.Module을 상속하고 자체 네트워크/계층을 작성하는 것입니다. 먼저 nn.Module을 사용하여 완전 연결 계층을 구현하는 방법을 살펴보겠습니다.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
  • 사용자 정의 계층 네트워크는 nn.Module을 상속해야 하며 nn.Module의 생성자는 해당 생성자, 즉 super()에서 호출되어야 합니다.초기화() 또는 nn.모듈.초기화(self), 첫 번째 사용을 권장합니다.
  • 생성자 __init__에서 학습 가능한 매개변수를 직접 정의하고 이를 매개변수로 캡슐화해야 합니다. 예를 들어 이 예에서는 w와 b를 매개변수로 캡슐화합니다. 매개변수는 특수 Tensor이지만 기본적으로 파생 항목이 필요합니다(requires_grad
    = 참)
  • 순방향 함수는 순방향 전파 프로세스를 구현하며 해당 입력은 하나 이상의 Tensor일 수 있습니다.
  • 역전파 함수를 작성할 필요가 없습니다. nn.Module은 autograd를 사용하여 역전파를 자동으로 구현할 수 있으며 이는 Function보다 훨씬 간단합니다.
  • 모듈의 학습 가능한 매개변수는 명명된 매개변수() 또는 매개변수()를 통해 반복자를 반환할 수 있습니다. 전자는 각 매개변수에 이름을 첨부하여 더 쉽게 식별할 수 있도록 합니다.

2. 일반적으로 사용되는 신경망 레이어

2.1 이미지 관련 레이어

이미지 관련 레이어에는 주로 Convolution 레이어(Conv), Pooling 레이어(Pool) 등이 있습니다. 실제 사용에서는 이러한 레이어를 1차원(1D), 2차원(2D), 3차원(3D)으로 나눌 수 있습니다. 풀링 방법도 평균 풀링(AvgPool), 최대 풀링(MaxPool), 적응형 풀링(AdaptiveAvgPool) 등으로 구분됩니다. 일반적으로 사용되는 순방향 컨볼루션 외에도 컨볼루션 계층에는 역 컨볼루션(TransposeConv) 등이 있습니다. 아래에 예가 나와 있습니다.

  • 특징 추출
  • 데이터 공간 구조 유지
  • 비선형 변환 소개 컨볼루션 작업 후 일반적으로 활성화 함수(예: ReLU, Sigmoid 또는 Tanh)가 적용되어 비선형 변환을 도입합니다. 이러한 활성화 함수는 CNN의 표현력을 높이고 더 복잡한 비선형 관계를 학습할 수 있게 해줍니다.
  • 계산 효율성 향상 컨볼루션 작업과 풀링 레이어의 결합을 통해 컨볼루션 레이어는 특징 맵의 공간 차원을 줄여 계산량을 줄이고 모델의 계산 효율성을 향상시킬 수 있습니다. 동시에 풀링 레이어는 특징의 변환 불변성을 향상시켜 입력 데이터의 작은 변화에도 모델을 더욱 강력하게 만들 수 있습니다.

컨볼루션 레이어

딥러닝에서 이미지 처리와 관련된 가장 중요한 네트워크 구조는 Convolutional Layer(Conv)입니다. 컨볼루셔널 신경망의 본질은 컨볼루셔널 레이어, 풀링 레이어, 활성화 레이어 및 기타 레이어의 중첩입니다. 따라서 컨볼루션 레이어의 작동 원리를 이해하는 것이 매우 중요합니다. 컨볼루션 작업.
여기에 이미지 설명을 삽입하세요.

# 导入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

풀링 레이어

풀링 레이어는 주로 다운샘플링에 사용되는 특수 컨볼루션 레이어로 간주할 수 있으며, 풀링 레이어를 추가하면 주요 특징을 유지하면서 매개변수 수를 줄일 수 있으므로 어느 정도 과적합을 방지할 수 있습니다. 풀링 레이어에는 학습 가능한 매개변수가 없으며 가중치는 고정되어 있습니다. torch.nn 툴박스에는 다양한 풀링 레이어가 포함되어 있습니다. 일반적인 레이어로는 Max Pooling(MaxPool)과 Average Pooling(AvgPool)이 있습니다. 풀링 레이어는 CNN(Convolutional Neural Network)에서 매우 중요한 역할을 합니다. 주요 용도는 다음과 같이 요약할 수 있습니다.

  • 차원 축소(계산량 감소): 풀링 레이어는 데이터의 공간적 크기(즉, 높이와 너비)를 줄여 계산량과 후속 레이어의 매개변수 수를 줄입니다. 이는 과적합을 방지하고 계산 속도를 높이는 데 매우 유용합니다.
  • 특징 불변성: 풀링 레이어를 사용하면 모델이 보다 강력한 특징 표현, 즉 입력 데이터의 작은 변화(예: 변환, 회전 등)에 변하지 않는 것을 학습할 수 있습니다. 이는 Max Pooling, Average Pooling 등의 Pooling 연산이 특정 위치 정보에 의존하기보다는 해당 영역 내의 대표적인 특징을 선택하기 때문입니다.
  • 주요 특징 추출: 풀링 작업을 통해 중요하지 않은 세부 사항을 무시하고 이미지에서 가장 중요한 특징을 추출할 수 있습니다. 이는 후속 컨벌루션 레이어에서 상위 수준 기능을 추가로 추출하는 데 도움이 됩니다.
  • 수용 필드 확장: 네트워크 계층의 수가 증가함에 따라 풀링 계층은 후속 계층의 각 뉴런에 해당하는 입력 영역(즉, 수용 필드)을 점차 확장할 수 있습니다. 이는 네트워크가 더 많은 전역 기능 정보를 학습하는 데 도움이 됩니다.
  • 과적합 감소: 풀링 레이어는 데이터의 공간 차원을 줄여 매개변수 수를 줄이므로 모델의 복잡성을 어느 정도 줄일 수 있어 과적합을 방지하는 데 도움이 됩니다.

일반적인 풀링 작업은 다음과 같습니다.

  • Max Pooling: 풀링 창 내 최대값을 출력으로 선택합니다. 이 접근 방식은 이미지의 가장자리와 텍스처 정보를 보존하는 데 도움이 됩니다.
  • 평균 풀링: 풀링 창 내의 모든 값의 평균을 출력으로 계산합니다. 이 접근 방식은 이미지의 배경 정보를 보존하는 데 도움이 됩니다.
  • 확률적 풀링(Stochastic Pooling): 풀링 창의 각 요소 값을 기반으로 확률에 따라 요소가 출력으로 무작위로 선택됩니다. 이 방법은 최대 풀링과 평균 풀링의 장점을 결합하지만 계산 복잡도가 더 높습니다.

즉, 풀링 레이어는 컨볼루셔널 신경망에서 없어서는 안 될 부분으로, 데이터의 공간적 차원을 줄이고, 주요 특징을 추출하며, 수용 영역을 확장하고, 과적합을 방지함으로써 전체 네트워크의 학습 능력과 성능을 제공합니다. 지원하다.

# 导入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

다른 레이어

컨벌루션 레이어 및 풀링 레이어 외에도 다음 레이어도 딥러닝에 일반적으로 사용됩니다.

  • 선형: 완전히 연결된 레이어;
  • BatchNorm: 배치 정규화 계층으로 1D, 2D, 3D로 구분됩니다. 표준 BatchNorm 외에도 스타일 마이그레이션에 일반적으로 사용되는 InstanceNorm 레이어도 있습니다.
  • Dropout : Overfitting을 방지하기 위해 사용되는 Dropout 레이어도 1D, 2D, 3D로 구분됩니다.

3. 초기화 전략

딥러닝에서는 매개변수 초기화가 매우 중요합니다. 초기화를 잘하면 모델이 더 빠르게 수렴되고 더 높은 수준에 도달할 수 있지만, 초기화가 잘못되면 모델이 빨리 붕괴될 수 있습니다. PyTorch의 nn.Module 모듈 매개변수는 보다 합리적인 초기화 전략을 채택하므로 일반적으로 이를 고려할 필요가 없습니다. 물론 사용자 정의 초기화를 사용하여 시스템의 기본 초기화를 대체할 수도 있습니다. Parameter를 사용할 때 사용자 정의 초기화가 특히 중요합니다. 이는 torch.Tensor()가 메모리에 난수를 반환하는데, 이는 최대값을 가질 가능성이 높기 때문에 실제 훈련 네트워크에서 오버플로나 오버플로가 발생할 수 있기 때문입니다. . PyTorch의 nn.init 모듈은 초기화를 위해 특별히 설계된 모듈로, 일반적으로 사용되는 초기화 전략을 구현합니다. 특정 초기화 전략 nn.init가 제공되지 않는 경우 사용자가 직접 초기화할 수도 있습니다.

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