pytorch学习day4

一、卷积层(Convolution Layers)

卷积层是卷积神经网络(CNN)中的核心组件,用于提取输入数据的特征。它们通过应用卷积运算来捕捉局部的空间特征,非常适合处理图像和视频等具有空间结构的数据。

1. 卷积层的基本概念

卷积层通过在输入图像上滑动一个小的卷积核(也称为滤波器),计算每个位置的加权和来生成特征图。卷积核的权重是可以学习的参数,通过训练数据进行优化。

主要参数:

  • 输入通道数(in_channels):输入数据的通道数。例如,RGB图像的通道数为3。
  • 输出通道数(out_channels):卷积层输出的通道数,即卷积核的数量。
  • 卷积核大小(kernel_size):卷积核的空间尺寸,通常是一个整数(例如3表示3x3的卷积核)或一个元组(例如(3, 3))。
  • 步幅(stride):卷积核在输入上滑动的步长。默认值为1。
  • 填充(padding):在输入的边缘补充零,使卷积核可以在边缘处理。默认值为0。

2. PyTorch中的二维卷积层(nn.Conv2d)

代码示例:

import torch
import torch.nn as nn# 定义一个二维卷积层
conv_layer = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, stride=1, padding=1)# 创建一个输入张量,形状为(批量大小, 通道数, 高度, 宽度)
input_tensor = torch.randn(1, 3, 32, 32)# 通过卷积层处理输入张量
output_tensor = conv_layer(input_tensor)print(output_tensor.shape)# 提取第一个通道的特征图
feature_map = outputimg[0, 0, :, :].detach().numpy()# 可视化特征图
plt.imshow(feature_map, cmap='gray')
plt.colorbar()
plt.title('Feature Map')
plt.show()

在这个示例中,我们定义了一个卷积层,输入通道数为3,输出通道数为16,卷积核大小为3x3,步幅为1,填充为1。输入张量为一个随机生成的32x32的RGB图像。卷积层处理输入张量后,输出张量的形状为(1, 16, 32, 32)。

详细解释:

  • 输入通道数(in_channels):卷积层接收输入数据的深度。例如,对于RGB图像,深度为3。
  • 输出通道数(out_channels):卷积层生成的特征图的深度。每个卷积核会产生一个特征图。
  • 卷积核大小(kernel_size):定义卷积核的高度和宽度。例如,3x3卷积核会考虑3x3区域内的像素。
  • 步幅(stride):决定卷积核在输入图像上滑动的步长。步幅越大,输出特征图的尺寸越小。
  • 填充(padding):在输入图像的边缘添加额外的像素,以便卷积核能够处理图像边缘。填充越多,输出特征图的尺寸越大。

3. nn.Conv2d对数据进行读取和卷积

import torch
import torch.nn as  nn
import matplotlib.pyplot as plt
import os
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from PIL import Image
from torchvision import transformsdef transform_invert(img_tensor, transform):"""反转图像的预处理操作:param img_tensor: 经过预处理的图像张量:param transform: 预处理操作:return: 反转预处理操作后的图像"""if 'Normalize' in str(transform):mean = torch.tensor(transform.transforms[1].mean)std = torch.tensor(transform.transforms[1].std)img_tensor = img_tensor * std[:, None, None] + mean[:, None, None]img_tensor = img_tensor.squeeze()  # 移除批量维度img = transforms.ToPILImage()(img_tensor)  # 转换为PIL图像return img# ================================= load img ==================================
# 定义图像预处理变换
transform = transforms.Compose([# transforms.Resize((128, 128)),  # 调整图像大小# transforms.RandomHorizontalFlip(),  # 随机水平翻转# transforms.RandomRotation(10),  # 随机旋转10度# transforms.ColorJitter(brightness=0.5),  # 随机改变亮度transforms.ToTensor(),  # 转换为张量并归一化到[0, 1]transforms.Normalize((0.5,), (0.5,))  # 用均值0.5和标准差0.5归一化
])# 加载图像
image = Image.open("taylorpicture.jpg").convert("RGB")# 应用预处理变换
transformed_image = transform(image)# 检查变换后的图像
print(transformed_image.size())
# image.show()# 转换为张量
img_transform = transforms.Compose([transforms.ToTensor()])
img_tensor = img_transform(image)# 添加 batch 维度
img_tensor.unsqueeze_(dim=0)# =============== create convolution layer ==================# 定义一个二维卷积层
input_convd = nn.Conv2d(in_channels=3, out_channels=1, kernel_size=3)nn.init.xavier_normal_(input_convd.weight.data)# 通过卷积层处理输入张量
img_conv = input_convd(img_tensor)print(img_conv.shape)# ================================= visualization ==================================
print("卷积前尺寸:{}\n卷积后尺寸:{}".format(img_tensor.shape, img_conv.shape))
img_conv = transform_invert(img_conv[0, 0:1, ...], img_transform)
img_raw = transform_invert(img_tensor.squeeze(), img_transform)
plt.subplot(122).imshow(img_conv, cmap='gray')
plt.subplot(121).imshow(img_raw)
plt.show()

卷积前,图像尺寸是464×580, 卷积后, 图像尺寸是462×578。我们这里的卷积核设置, 输入通道3, 卷积核个数1, 卷积核大小3, 无padding,步长是1, 那么我们根据上面的公式, 输出尺寸:(464−3)/1+1=462   (580−3)/1+1=578

torch.Size([3, 464, 580])
torch.Size([1, 1, 462, 578])
卷积前尺寸:torch.Size([1, 3, 464, 580])
卷积后尺寸:torch.Size([1, 1, 462, 578])

 3.1 增加 batch 维度

img_tensor.unsqueeze_(dim=0) 

这行代码使用unsqueeze_方法在张量的第0维添加一个新的维度。unsqueeze_方法是原地操作,会直接修改img_tensor而不是返回一个新的张量。

在此之前,img_tensor只有通道、高度和宽度。为了让这个张量能够作为输入传递给卷积神经网络模型,我们通常需要一个包含批量大小的维度(batch size)。卷积神经网络的输入通常是四维张量,形状为 [batch_size, channels, height, width]。通过在第0维添加一个维度,这里的1表示批量大小,即一次处理一个图像。

3.2 增加卷积权值初始化

在这段代码中,nn.init.xavier_normal_ 使用了Xavier正态分布来初始化卷积层的权重。这种初始化方法使得每个卷积核中的权重值根据一个正态分布随机生成,分布的标准差根据输入和输出的通道数进行计算,确保每一层输出的方差稳定。

总结:通过这些操作,可以确保图像正确加载为张量,并以适合卷积神经网络输入的格式传递。

4. nn.ConvTranspose 转置卷积

转置卷积(Transposed Convolution)也称为反卷积(Deconvolution),是一种用于上采样(Upsampling)的操作,通常用于生成对原始输入分辨率更高的特征图。转置卷积最常用于生成对抗网络(GANs)和语义分割等需要将低分辨率特征图恢复到高分辨率的任务中。

转置卷积的作用

  1. 上采样:转置卷积可以将特征图的分辨率放大,从而恢复到原始输入的尺寸。这对于图像生成和分割任务非常重要。
  2. 特征重建:它可以帮助重建原始图像的细节,通过将低分辨率特征图恢复到高分辨率。
  3. 反向传播有效性:转置卷积允许有效的梯度反向传播,从而使得网络能够学习到有效的特征。

PyTorch 中的 nn.ConvTranspose2d

PyTorch 提供了 nn.ConvTranspose2d 类,用于实现二维转置卷积。其参数与普通卷积类似,包括输入通道数、输出通道数、卷积核大小等。

参数介绍

  • in_channels:输入特征图的通道数。
  • out_channels:输出特征图的通道数。
  • kernel_size:卷积核的大小,可以是单个整数或者元组。
  • stride:卷积核的步幅,决定了上采样的倍数。
  • padding:在输入图像四周填充的像素数。
  • output_padding:输出图像额外的填充,控制输出尺寸。
  • bias:是否使用偏置,默认为True。

示例代码

以下示例展示了如何定义和使用二维转置卷积层:

import torch
import torch.nn as  nn
import matplotlib.pyplot as plt
import os
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from PIL import Image
from torchvision import transformsdef transform_invert(img_tensor, transform):"""反转图像的预处理操作:param img_tensor: 经过预处理的图像张量:param transform: 预处理操作:return: 反转预处理操作后的图像"""if 'Normalize' in str(transform):mean = torch.tensor(transform.transforms[1].mean)std = torch.tensor(transform.transforms[1].std)img_tensor = img_tensor * std[:, None, None] + mean[:, None, None]img_tensor = img_tensor.squeeze()  # 移除批量维度img = transforms.ToPILImage()(img_tensor)  # 转换为PIL图像return img# ================================= load img ==================================
# 定义图像预处理变换
transform = transforms.Compose([# transforms.Resize((128, 128)),  # 调整图像大小# transforms.RandomHorizontalFlip(),  # 随机水平翻转# transforms.RandomRotation(10),  # 随机旋转10度# transforms.ColorJitter(brightness=0.5),  # 随机改变亮度transforms.ToTensor(),  # 转换为张量并归一化到[0, 1]transforms.Normalize((0.5,), (0.5,))  # 用均值0.5和标准差0.5归一化
])# 加载图像
image = Image.open("taylorpicture.jpg").convert("RGB")# 应用预处理变换
transformed_image = transform(image)# 检查变换后的图像
print(transformed_image.size())
# image.show()# 转换为张量
img_transform = transforms.Compose([transforms.ToTensor()])
img_tensor = img_transform(image)# 添加 batch 维度
img_tensor.unsqueeze_(dim=0)# =============== create convolution layer ==================# 定义一个二维卷积层
input_convd = nn.ConvTranspose2d(in_channels=3, out_channels=1, kernel_size=3,stride=1)nn.init.xavier_normal_(input_convd.weight.data)# 通过卷积层处理输入张量
img_conv = input_convd(img_tensor)print(img_conv.shape)# ================================= visualization ==================================
print("卷积前尺寸:{}\n卷积后尺寸:{}".format(img_tensor.shape, img_conv.shape))
img_conv = transform_invert(img_conv[0, 0:1, ...], img_transform)
img_raw = transform_invert(img_tensor.squeeze(), img_transform)
plt.subplot(122).imshow(img_conv, cmap='gray')
plt.subplot(121).imshow(img_raw)
plt.show()

输出解释

  1. 当然,以下是可以直接复制的转置卷积输出尺寸计算公式:

    Hout​=(Hin​−1)×stride+kernel_size−2×padding+output_padding

    Wout​=(Win​−1)×stride+kernel_size−2×padding+output_padding

    在这段代码中,

  2. 应用公式计算输出尺寸:

    Hout​=(464−1)×1+3−2×0+0=464+2=466

    Wout​=(580−1)×1+3−2×0+0=580+2=582

    因此,输入尺寸为 torch.Size([1, 3, 464, 580]) 的图像通过转置卷积层后,输出尺寸变为 torch.Size([1, 1, 466, 582])

转置卷积的数学原理

转置卷积可以理解为将卷积操作反转。普通卷积是通过卷积核在输入上滑动并计算加权和,转置卷积则是将输入的每个元素反向传播到输出,通过插值(通常是零填充)来扩展尺寸。具体实现中,转置卷积可以通过对输入进行零填充并进行标准卷积实现。

5. 卷积层的优点

参数共享

卷积层中的卷积核在整个输入图像上共享相同的权重参数,这大大减少了需要训练的参数数量,从而减轻了过拟合的风险,并提高了计算效率。

局部感受野

卷积核只处理输入图像的局部区域,这使得卷积层能够有效捕捉局部特征,如边缘、纹理和角点等。

平移不变性

由于卷积运算在整个图像上进行滑动,卷积层具有一定的平移不变性,能够识别图像中同一特征的不同位置。

二、池化层(Convolution Layers)

1.池化层介绍

池化层(Pooling Layer)是卷积神经网络(CNN)中的一种常见操作,通常用于减少数据的空间维度(即宽度和高度),从而减少参数数量和计算量,同时保留重要的特征信息。

主要类型的池化层

  1. 最大池化(Max Pooling)

    • 在池化窗口内取最大值,主要用于提取最显著的特征。
    • 公式: [ Y(i, j) = \max(X_{i:i+f, j:j+f}) ] 其中 X 是输入特征图,f 是池化窗口大小,Y 是输出特征图。
  2. 平均池化(Average Pooling)

    • 在池化窗口内取平均值,用于平滑特征图。
    • 公式: [ Y(i, j) = \frac{1}{f^2} \sum_{m=0}^{f-1} \sum_{n=0}^{f-1} X(i+m, j+n) ] 其中 X 是输入特征图,f 是池化窗口大小,Y 是输出特征图。

池化层参数

池化层的主要参数包括:

  • 池化窗口大小(Kernel Size or Pool Size):通常为 2×2 或 3×3。
  • 步幅(Stride):决定池化窗口在输入特征图上滑动的步长,通常与池化窗口大小相同。
  • 填充(Padding):决定是否在输入特征图周围添加零填充,通常池化层不使用填充。

池化层效果展示

上图展示了池化层(Pooling Layer)的操作:

  • 左侧:输入图像,尺寸为 4×4,每个格子中的数字代表像素值。
  • 右侧:经过最大池化(Max Pooling)后的输出图像,尺寸为 2×2。在每个 2×2 的池化窗口内,取最大值作为输出。

输入图像中的数值经过最大池化后,每个池化窗口内的最大值被提取出来,形成一个更小的输出图像。这种操作减少了图像的空间尺寸,同时保留了重要的特征信息。

2.池化层函数nn.MaxPool2d

nn.MaxPool2d 详细解释:

nn.MaxPool2d 是 PyTorch 中用于实现二维最大池化操作的函数。

参数
  • kernel_size: 池化窗口的大小,可以是一个整数或一个整数元组。例如,kernel_size=2 或 kernel_size=(2, 2)
  • stride: 步幅,窗口在输入张量上滑动的步长。默认为 kernel_size 的大小。如果步幅和池化窗口的大小相同,则不会重叠。如果步幅小于窗口大小,则会有重叠。
  • padding: 填充,在输入张量的边缘补零的数量。默认为0,即不填充。
  • dilation: 空洞池化中的扩张率,默认为1。
  • return_indices: 如果设为 True,会返回最大值的索引。通常用于最大池化的反向操作(如 nn.MaxUnpool2d)。
  • ceil_mode: 如果设为 True,则在计算输出大小时使用上取整,而不是默认的下取整。
import torch
import torch.nn as  nn
import matplotlib.pyplot as plt
import os
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from PIL import Image
from torchvision import transformsdef transform_invert(img_tensor, transform):"""反转图像的预处理操作:param img_tensor: 经过预处理的图像张量:param transform: 预处理操作:return: 反转预处理操作后的图像"""if 'Normalize' in str(transform):mean = torch.tensor(transform.transforms[1].mean)std = torch.tensor(transform.transforms[1].std)img_tensor = img_tensor * std[:, None, None] + mean[:, None, None]img_tensor = img_tensor.squeeze()  # 移除批量维度img = transforms.ToPILImage()(img_tensor)  # 转换为PIL图像return img# ================================= load img ==================================
# 定义图像预处理变换
transform = transforms.Compose([# transforms.Resize((128, 128)),  # 调整图像大小# transforms.RandomHorizontalFlip(),  # 随机水平翻转# transforms.RandomRotation(10),  # 随机旋转10度# transforms.ColorJitter(brightness=0.5),  # 随机改变亮度transforms.ToTensor(),  # 转换为张量并归一化到[0, 1]transforms.Normalize((0.5,), (0.5,))  # 用均值0.5和标准差0.5归一化
])# 加载图像
image = Image.open("taylorpicture.jpg").convert("RGB")# 应用预处理变换
transformed_image = transform(image)# 检查变换后的图像
print(transformed_image.size())
# image.show()# 转换为张量
img_transform = transforms.Compose([transforms.ToTensor()])
img_tensor = img_transform(image)# 添加 batch 维度
img_tensor.unsqueeze_(dim=0)# =============== create convolution layer ==================# 定义一个二维卷积层
maxpool_layer = nn.MaxPool2d((2, 2), stride=(2, 2))# 通过卷积层处理输入张量
img_conv = maxpool_layer(img_tensor)print(img_conv.shape)# ================================= visualization ==================================
print("卷积前尺寸:{}\n卷积后尺寸:{}".format(img_tensor.shape, img_conv.shape))
img_conv = transform_invert(img_conv[0, 0:1, ...], img_transform)
img_raw = transform_invert(img_tensor.squeeze(), img_transform)
plt.subplot(122).imshow(img_conv, cmap='gray')
plt.subplot(121).imshow(img_raw)
plt.show()
torch.Size([3, 464, 580])
torch.Size([1, 3, 232, 290])
卷积前尺寸:torch.Size([1, 3, 464, 580])
卷积后尺寸:torch.Size([1, 3, 232, 290])

从输入尺寸和输出尺寸的变化,我们可以推测池化层的参数:

假设使用最大池化层 nn.MaxPool2d 进行操作,且池化窗口大小为 2x2,那么可以计算步幅和池化窗口的参数。

计算步幅和池化窗口大小

假设我们使用 kernel_size=2stride=2,即池化窗口为2x2,步幅为2,则可以通过以下公式计算输出尺寸:

Hout​=⌊strideHin​−kernel_size​⌋/stride+1

Wout​=⌊strideWin​−kernel_size​⌋/stride+1

应用公式计算实例

假设输入张量的高度和宽度分别为 464 和 580,使用 kernel_size=2stride=2 的最大池化层:

计算高度(Height):

Hout​=⌊464−2​⌋/2+1=⌊231⌋+1=232

计算宽度(Width):

Wout​=⌊580−2​⌋/2+1=⌊289⌋+1=290

3.池化层函数nn.AvgPool2d

nn.AvgPool2d 详细解释

nn.AvgPool2d 是 PyTorch 中用于实现二维平均池化操作的函数。

参数
  • kernel_size: 池化窗口的大小,可以是一个整数或一个整数元组。例如,kernel_size=2 或 kernel_size=(2, 2)
  • stride: 步幅,窗口在输入张量上滑动的步长。默认为 kernel_size 的大小。如果步幅和池化窗口的大小相同,则不会重叠。如果步幅小于窗口大小,则会有重叠。
  • padding: 填充,在输入张量的边缘补零的数量。默认为0,即不填充。
  • ceil_mode: 如果设为 True,则在计算输出大小时使用上取整,而不是默认的下取整。
  • count_include_pad: 如果设为 True,将计算填充在内,否则不计算填充。
import torch
import torch.nn as  nn
import matplotlib.pyplot as plt
import os
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from PIL import Image
from torchvision import transformsdef transform_invert(img_tensor, transform):"""反转图像的预处理操作:param img_tensor: 经过预处理的图像张量:param transform: 预处理操作:return: 反转预处理操作后的图像"""if 'Normalize' in str(transform):mean = torch.tensor(transform.transforms[1].mean)std = torch.tensor(transform.transforms[1].std)img_tensor = img_tensor * std[:, None, None] + mean[:, None, None]img_tensor = img_tensor.squeeze()  # 移除批量维度img = transforms.ToPILImage()(img_tensor)  # 转换为PIL图像return img# ================================= load img ==================================
# 定义图像预处理变换
transform = transforms.Compose([# transforms.Resize((128, 128)),  # 调整图像大小# transforms.RandomHorizontalFlip(),  # 随机水平翻转# transforms.RandomRotation(10),  # 随机旋转10度# transforms.ColorJitter(brightness=0.5),  # 随机改变亮度transforms.ToTensor(),  # 转换为张量并归一化到[0, 1]transforms.Normalize((0.5,), (0.5,))  # 用均值0.5和标准差0.5归一化
])# 加载图像
image = Image.open("taylorpicture.jpg").convert("RGB")# 应用预处理变换
transformed_image = transform(image)# 检查变换后的图像
print(transformed_image.size())
# image.show()# 转换为张量
img_transform = transforms.Compose([transforms.ToTensor()])
img_tensor = img_transform(image)# 添加 batch 维度
img_tensor.unsqueeze_(dim=0)# =============== create convolution layer ==================# 定义一个二维卷积层
AvgPool_layer = nn.AvgPool2d((2, 2), stride=(2, 2))# 通过卷积层处理输入张量
img_conv = AvgPool_layer(img_tensor)print(img_conv.shape)# ================================= visualization ==================================
print("卷积前尺寸:{}\n卷积后尺寸:{}".format(img_tensor.shape, img_conv.shape))
img_conv = transform_invert(img_conv[0, 0:1, ...], img_transform)
img_raw = transform_invert(img_tensor.squeeze(), img_transform)
plt.subplot(122).imshow(img_conv, cmap='gray')
plt.subplot(121).imshow(img_raw)
plt.show()
torch.Size([3, 464, 580])
torch.Size([1, 3, 232, 290])
卷积前尺寸:torch.Size([1, 3, 464, 580])
卷积后尺寸:torch.Size([1, 3, 232, 290])

4.池化层函数nn.MaxUnpool2d

nn.MaxUnpool2d 详细解释

nn.MaxUnpool2d 是 PyTorch 中用于实现二维最大池化的反操作(反池化)的函数。反池化用于将池化后的特征图恢复到池化前的尺寸,通常与 nn.MaxPool2d 一起使用,以便在一些网络结构(如自编码器或生成对抗网络)中进行上采样操作。

参数
  • kernel_size: 反池化窗口的大小,可以是一个整数或一个整数元组。例如,kernel_size=2 或 kernel_size=(2, 2)
  • stride: 步幅,窗口在输入张量上滑动的步长。默认为 kernel_size 的大小。
  • padding: 填充,在输入张量的边缘补零的数量。默认为0,即不填充。
import torch
import torch.nn as nn# 定义输入张量
input_tensor = torch.tensor([[[[1, 2, 3, 4],[5, 6, 7, 8],[9, 10, 11, 12],[13, 14, 15, 16]]]], dtype=torch.float32)# 定义最大池化层
max_pool = nn.MaxPool2d(kernel_size=2, stride=2, return_indices=True)# 应用最大池化层
output_max_pool, indices = max_pool(input_tensor)print("Max pooling output:")
print(output_max_pool)
print("Indices of max values:")
print(indices)# 定义最大池化反操作层
max_unpool = nn.MaxUnpool2d(kernel_size=2, stride=2)# 应用最大池化反操作层
output_unpool = max_unpool(output_max_pool, indices, output_size=input_tensor.shape)print("Unpooled output (after MaxUnpool2d):")
print(output_unpool)
tensor([[[[ 6.,  8.],[14., 16.]]]])
Indices of max values:
tensor([[[[ 5,  7],[13, 15]]]])
Unpooled output (after MaxUnpool2d):
tensor([[[[ 0.,  0.,  0.,  0.],[ 0.,  6.,  0.,  8.],[ 0.,  0.,  0.,  0.],[ 0., 14.,  0., 16.]]]])

这里的参数与池化层是类似的。唯一的不同就是前向传播的时候我们需要传进一个indices, 我们的索引值,要不然不知道把输入的元素放在输出的哪个位置上。

三、线性层—Linear Layer

线性层(Linear Layer)是神经网络中的基本层之一,通常用于全连接网络或密集层。在 PyTorch 中,线性层由 nn.Linear 类实现。线性层执行的是线性变换,它将输入向量乘以一个权重矩阵,并加上一个偏置向量。

线性层的定义和操作

线性层的操作可以用以下数学公式表示:

y = 𝒙𝑾𝑻 + 𝒃𝒊𝒂𝒔 

其中:

  • x 是输入向量或输入张量。
  • W 是权重矩阵。
  • b 是偏置向量。
  • y 是输出向量或输出张量。

nn.Linear 详细解释

参数
  • in_features: 输入特征的数量。
  • out_features: 输出特征的数量。
  • bias: 如果设置为 False,层将不会学习偏置。默认值为 True。

示例代码

以下示例代码展示了如何使用 nn.Linear 定义和应用线性层:

import torch
import torch.nn as nn# 定义输入张量
input_tensor = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], dtype=torch.float32)# 打印输入张量形状
print(f"Input tensor shape: {input_tensor.shape}")# 定义线性层
linear_layer = nn.Linear(in_features=3, out_features=2)# 打印线性层权重和偏置
print("Initial weights:")
print(linear_layer.weight)
print("Initial bias:")
print(linear_layer.bias)# 应用线性层
output_tensor = linear_layer(input_tensor)# 打印输出张量形状
print(f"Output tensor shape: {output_tensor.shape}")# 打印输出张量
print(f"Output tensor: \n{output_tensor}")

解释

  1. 输入张量:形状为 (2, 3),表示有两个样本,每个样本有3个特征。
  2. 线性层:定义一个线性层,将3个输入特征映射到2个输出特征。
  3. 权重和偏置:线性层包含一个权重矩阵和一个偏置向量。权重矩阵的形状为 (2, 3),偏置向量的形状为 (2,)
  4. 输出张量:形状为 (2, 2),表示经过线性层后的输出,每个样本有2个输出特征。

详细代码解释

  • 输入张量

    input_tensor = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], dtype=torch.float32)

    输入张量的形状为 (2, 3),表示有两个样本,每个样本有3个特征。

  • 定义线性层

    linear_layer = nn.Linear(in_features=3, out_features=2)

    定义一个线性层,将3个输入特征映射到2个输出特征。

  • 打印线性层权重和偏置

    print("Initial weights:")
    print(linear_layer.weight)
    print("Initial bias:")
    print(linear_layer.bias)

  • 应用线性层

    output_tensor = linear_layer(input_tensor)

  • 打印输出张量

    print(f"Output tensor: \n{output_tensor}")

    运行结果

    Input tensor shape: torch.Size([2, 3])
    Initial weights:
    Parameter containing:
    tensor([[-0.5265, -0.2825,  0.4228],[ 0.0674, -0.0214,  0.0749]], requires_grad=True)
    Initial bias:
    Parameter containing:
    tensor([-0.4118, -0.1031], requires_grad=True)
    Output tensor shape: torch.Size([2, 2])
    Output tensor: 
    tensor([[-0.2350,  0.1464],[-1.3938,  0.5094]], grad_fn=<AddmmBackward0>)Process finished with exit code 0
    

总结

线性层是神经网络中的基本构建块,通常用于将输入特征映射到输出特征。通过定义输入和输出特征的数量,可以使用 nn.Linear 创建线性层,并将其应用到输入张量上,执行线性变换。这个过程在神经网络的训练和推理中非常常见,是许多复杂网络结构的基础。

 四、激活函数层—Activate Layer

激活函数层(Activation Layer)是神经网络中的关键组件,用于引入非线性特性,使网络能够学习和表示复杂的函数。常见的激活函数包括 ReLU、Sigmoid、Tanh 等。在 PyTorch 中,激活函数可以通过 torch.nn.functionaltorch.nn 模块来使用。

常见激活函数

  1. ReLU(Rectified Linear Unit)
  2. Sigmoid
  3. Tanh(Hyperbolic Tangent)
  4. Leaky ReLU
  5. Softmax

1. ReLU(Rectified Linear Unit)

ReLU 是一种简单且常用的激活函数,它将输入中的负值置为零,正值保持不变。

示例代码:

import torch
import torch.nn.functional as F# 定义输入张量
input_tensor = torch.tensor([[-1.0, 2.0, -3.0], [4.0, -5.0, 6.0]])# 应用 ReLU 激活函数
output_tensor = F.relu(input_tensor)print("ReLU activation output:")
print(output_tensor)

2. Sigmoid

Sigmoid 函数将输入映射到 (0, 1) 的区间内,常用于二分类问题。

示例代码:

# 应用 Sigmoid 激活函数
output_tensor = torch.sigmoid(input_tensor)print("Sigmoid activation output:")
print(output_tensor)

3. Tanh(Hyperbolic Tangent)

Tanh 函数将输入映射到 (-1, 1) 的区间内。

示例代码:

# 应用 Tanh 激活函数
output_tensor = torch.tanh(input_tensor)print("Tanh activation output:")
print(output_tensor)

4. Leaky ReLU

Leaky ReLU 是 ReLU 的一种变体,它允许负值有一个小的斜率,以解决 ReLU 的“神经元死亡”问题。

示例代码:

# 应用 Leaky ReLU 激活函数
leaky_relu = torch.nn.LeakyReLU(0.01)
output_tensor = leaky_relu(input_tensor)print("Leaky ReLU activation output:")
print(output_tensor)

5. Softmax

Softmax 函数通常用于多分类问题的最后一层,它将输入转换为概率分布。

示例代码:

# 应用 Softmax 激活函数
output_tensor = F.softmax(input_tensor, dim=1)print("Softmax activation output:")
print(output_tensor)

详细代码解释

以下是一个综合示例,展示如何在一个简单的神经网络中使用这些激活函数:

import torch
import torch.nn as nn
import torch.nn.functional as Fclass SimpleNN(nn.Module):def __init__(self):super(SimpleNN, self).__init__()self.fc1 = nn.Linear(3, 5)self.fc2 = nn.Linear(5, 2)def forward(self, x):x = self.fc1(x)x = F.relu(x)  # 使用 ReLU 激活函数x = self.fc2(x)x = torch.sigmoid(x)  # 使用 Sigmoid 激活函数return x# 定义输入张量
input_tensor = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], dtype=torch.float32)# 创建简单神经网络实例
model = SimpleNN()# 前向传播
output_tensor = model(input_tensor)print("Output tensor:")
print(output_tensor)

6. PReLU

nn.PReLU 详细解释

nn.PReLU 是 PyTorch 中的 Parametric Rectified Linear Unit(参数化线性修正单元)层。Parametric ReLU 是 Leaky ReLU 的一种扩展,它允许神经网络学习激活函数中的负斜率,而不是固定地设置为一个小的常数。这意味着神经网络可以根据数据动态地学习激活函数的形状。

参数
  • num_parameters: 定义 PReLU 中需要学习的负斜率的数量,通常设置为1以学习一个共享的负斜率。

示例代码

import torch
import torch.nn as nn# 定义输入张量
input_tensor = torch.tensor([-1.0, 2.0, -3.0], dtype=torch.float32)# 定义 Parametric ReLU 层
prelu = nn.PReLU(num_parameters=1)# 应用 Parametric ReLU
output_tensor = prelu(input_tensor)# 打印输出张量
print("Parametric ReLU output:")
print(output_tensor)

在这个示例中,nn.PReLU 层被用来应用 Parametric ReLU 激活函数到输入张量上。这允许神经网络按照数据的需求学习负斜率。

总结

激活函数层在神经网络中起到引入非线性特性的作用,使得网络能够学习复杂的模式和函数。PyTorch 提供了多种激活函数,可以根据具体任务选择合适的激活函数来构建和训练神经网络。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/21768.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

创建模拟器

修改模拟器默认路径 由于模拟器文件比较大&#xff0c;默认路径在C:\Users\用户名.android\avd&#xff0c;可修改默认路径 创建修改后的路径文件 D:\A-software\Android\AVD添加系统变量ANDROID_SDK_HOME&#xff1a;D:\A-software\Android\AVD重启Android Studio 创建模拟…

【机器学习】机器学习与大模型在人工智能领域的融合应用与性能优化新探索

文章目录 引言机器学习与大模型的基本概念机器学习概述监督学习无监督学习强化学习 大模型概述GPT-3BERTResNetTransformer 机器学习与大模型的融合应用自然语言处理文本生成文本分类机器翻译 图像识别自动驾驶医学影像分析 语音识别智能助手语音转文字 大模型性能优化的新探索…

【android 9】【input】【7.发送按键事件1——InputReader线程】

系列文章目录 本人系列文章-CSDN博客 目录 系列文章目录 1.简介 1.1发送流程介绍 1.2 时序图 2.普通按键消息发送部分源码分析 2.1 设备的监听 2.2 inputreader线程阻塞等待事件发生 2.3 按键事件的产生 2.4 EventHub::getEvents 2.5 InputReader::loopOnce 2.6 process…

丢失的数字 ---- 位运算

题目链接 题目: 分析: 解法一: 哈希表解法二: 高斯求和解法三:位运算 异或运算根据运算的性质, 相同的两个a异或 0 以示例一为例: 数组中有0,1,3, 缺失的数字是2, 那么只要我们将数组与0,1,2,3 异或, 就会得到2 代码: class Solution {public int missingNumber(int[] num…

【Redis】 Java操作客户端命令——集合操作与有序集合操作

文章目录 &#x1f343;前言&#x1f333;集合操作&#x1f6a9;sadd 和 smembers&#x1f6a9;srem 和 sismember&#x1f6a9;scard&#x1f6a9;sinter&#x1f6a9;sunion&#x1f6a9;sdiff &#x1f332;有序集合操作&#x1f6a9;zadd 和 zrange&#x1f6a9;zrem 和 zc…

拖拽tableView

拖拽tableView&#xff0c;随手指移动&#xff0c;插入。demo地址github

JAVAEE之网络初识_协议、TCP/IP网络模型、封装、分用

前言 在这一节我们简单介绍一下网络的发展 一、通信网络基础 网络互连的目的是进行网络通信&#xff0c;也即是网络数据传输&#xff0c;更具体一点&#xff0c;是网络主机中的不同进程间&#xff0c;基于网络传输数据。那么&#xff0c;在组建的网络中&#xff0c;如何判断到…

迪丽热巴与大姐的璀璨友情

迪丽热巴与“大姐”的璀璨友情&#xff1a;星光熠熠&#xff0c;友谊长存在娱乐圈的繁华舞台上&#xff0c;有两位耀眼的女星&#xff0c;她们如同夜空中亮的两颗星&#xff0c;交相辉映&#xff0c;共同谱写着一段段动人的佳话。她们&#xff0c;一个是被亲切称为“迪迪”的迪…

HarmonyOS-9(stage模式)

配置文件 {"module": {"requestPermissions": [ //权限{"name": "ohos.permission.EXECUTE_INSIGHT_INTENT"}],"name": "entry", //模块的名称"type": "entry", //模块类型 :ability类型和…

AWR设置工程仿真频率、原理图仿真频率、默认单位

AWR设置工程仿真频率、原理图仿真频率、默认单位 生活不易&#xff0c;喵喵叹气。马上就要上班了&#xff0c;公司的ADS的版权紧缺&#xff0c;主要用的软件都是NI 的AWR&#xff0c;只能趁着现在没事做先学习一下子了&#xff0c;希望不要裁我。 最近稍微学习了一下AWR这个软…

UMG绝对坐标与局部空间

在 Unreal Engine 的 UMG&#xff08;Unreal Motion Graphics&#xff09;中&#xff0c;“绝对坐标”和“局部空间”是两个常见的概念&#xff0c;主要用于描述 UI 元素的位置和大小。 概念与区别 绝对坐标&#xff08;Absolute Coordinates&#xff09;&#xff1a;这是指相…

list~模拟实现

目录 list的介绍及使用 list的底层结构 节点类的实现 list的实现 构造函数 拷贝构造 方法一&#xff1a;方法二&#xff1a; 析构函数 赋值重载 insert / erase push_/pop_(尾插/尾删/头插/头删) begin和end&#xff08;在已建立迭代器的基础上&#xff09; 迭代…

kafka命令--简单粗暴有效

zookeeper bin目录下执行 启动&#xff1a;./zkServer.sh start 停止&#xff1a;./zkServer.sh stop 重启&#xff1a;./zkServer.sh restart 状态&#xff1a;./zkServer.sh status kafka bin目录下执行 启动&#xff1a;./kafka-server-start.sh -daemon …/config/server.…

直播预告|手把手教你玩转 Milvus Lite !

Milvus Lite&#xff08;https://milvus.io/docs/milvus_lite.md&#xff09;是一个轻量级向量数据库&#xff0c;支持本地运行&#xff0c;可用于搭建 Python 应用&#xff0c;由 Zilliz 基于全球最受欢迎的开源向量数据库 Milvus&#xff08;https://milvus.io/intro&#xf…

使用python优雅的将PDF转为Word

使用python优雅的将PDF转为Word 先装这个优雅的库 pip install pdf2docx然后运行下面优雅的代码&#xff0c;将pdf路径和docx路径修改 from pdf2docx import Converter # path pdf_file C:\\Users\\phl\\Desktop\\软件工程期末\\软件工程模拟试题5.pdf docx_file C:\\User…

【iOS】UI学习——导航控制器、分栏控制器

UI学习&#xff08;三&#xff09; 导航控制器导航控制器基础导航控制器切换导航栏和工具栏 分栏控制器分栏控制器基础分栏控制器高级 导航控制器 导航控制器负责控制导航栏&#xff08;navigationBar&#xff09;&#xff0c;导航栏上的按钮叫UINavigationItem&#xff08;导航…

【STL源码剖析】deque 的使用

别院深深夏席清&#xff0c;石榴开遍透帘明。 树阴满地日当午&#xff0c;梦觉流莺时一声。 目录 deque 的结构 deque 的迭代器剖析 deque 的使用 ​编辑 deque 的初始化 deque 的容量操作 deque 的访问操作 在 pos 位置插入另一个向量的 [forst&#xff0c;last] 间的数据​编…

【人工智能Ⅱ】实验9:强化学习Q-Learning算法

实验9&#xff1a;强化学习Q-Learning算法 一&#xff1a;实验目的 1&#xff1a;了解强化学习的基本概念。 2&#xff1a;学习强化学习经典算法——Q-Learing算法。 3&#xff1a;通过Q-Learing算法解决问题。 二&#xff1a;实验内容 2.1 强化学习 强化学习&#xff08;…

iOS18新功能大爆料,打破常规,全面升级,这些变化不容错过!

众所周知&#xff0c;苹果 iOS 操作系统近年来都没有发生重大变化&#xff0c;主要是添加小部件、锁屏编辑和手机屏幕编辑等功能&#xff0c;再加上bug偏多&#xff0c;以至于越来越多iPhone用户不愿意再升级系统了。这一点&#xff0c;从 iOS 17 明显降低的安装率中就能看出一…

对人脸图像进行性别和年龄的判断

判断性别和年龄 导入必要的库加载预训练的人脸检测模型加载预训练的性别和年龄识别模型定义性别和年龄的标签列表创建Tkinter窗口&#xff1a;定义选择图片的函数&#xff1a;创建一个按钮&#xff0c;用于打开文件选择对话框定义显示图片的函数创建预测性别和年龄的函数创建预…