文章目录
- 1.主干权重和模型权重
- 2.超参数
- 2.1 ReLU(inplace=True)
- 2.2 交叉熵损失CrossEntropyLoss
- 3.反向传播
- 4.优化器
- 4.1 optimizer.zero_grad()
- 5.卷积
- 6.Batch Normalization
- 7.U-Net结构
这章节比较枯燥,都是大段文字
1.主干权重和模型权重
- 主干权重(Backbone Weights):在深度学习中,特别是在目标检测、图像分类等任务中,主干网络(Backbone Network)指的是用来提取输入数据特征的基础网络结构。主干网络通常由一系列的卷积层组成,它负责从原始数据中提取高层次的特征表示,以供后续的任务处理。主干权重则是指这些主干网络中各个层次的权重参数。这些权重参数通常是通过在大规模数据集上进行训练而得到的,例如在ImageNet上进行的预训练。
- 模型权重(Model Weights):模型权重则是指整个模型中所有层次的权重参数,包括主干网络以及其他附加的层次(例如分类头或其他自定义层次)。在深度学习任务中,训练过程旨在调整这些权重参数,使得模型能够对输入数据进行有效的学习和预测。模型权重包括了主干权重以及所有其他层次的权重,它们一起定义了整个模型的状态。总的来说,主干权重是指主干网络中的权重参数,而模型权重是指整个模型中所有层次的权重参数,包括主干网络以及其他自定义层次的权重。
2.超参数
超参数(Hyperparameters)是机器学习和深度学习模型训练过程中的配置参数,它们不是通过训练数据学习得到的,而是在训练模型之前需要手动设置。这些参数用于控制模型的训练过程和结构,以确保模型能够有效地学习并产生良好的性能。与模型的权重和偏差不同,超参数通常不是通过梯度下降等优化算法进行调整的,而是由数据科学家或研究人员手动选择和调整的。
一些常见的超参数包括:
- 学习率(Learning Rate):学习率控制了模型参数在每次迭代中的更新幅度。较小的学习率可能
导致训练收敛缓慢,而较大的学习率可能导致不稳定的训练过程。选择合适的学习率对于训练成功
至关重要。 - 迭代次数(Epochs):迭代次数确定了模型在整个训练数据集上训练的次数。过多的迭代可能导
致过拟合,而过少的迭代可能导致模型欠拟合。需要根据任务和数据集选择适当的迭代次数。 - 批量大小(Batch Size):批量大小定义了每次迭代中使用的样本数量。较大的批量大小可以提高
训练速度,但可能需要更多内存。较小的批量大小通常会导致更稳定的训练。 - 模型层数和节点数:神经网络的结构由层数和每层的节点数决定。这些是模型的架构超参数,需要
根据任务选择适当的结构。 - 正则化参数:正则化参数(如L1正则化和L2正则化)用于控制模型的复杂性,防止过拟合。需要根
据数据和模型选择适当的正则化参数。 - 优化器:选择用于更新模型参数的优化算法,如随机梯度下降(SGD)、Adam等。
- 激活函数:选择适当的激活函数,如ReLU、Sigmoid、Tanh等。
- 丢弃率(Dropout Rate):丢弃率用于控制在训练中应用的丢弃(Dropout)层的保留节点的比例。
这些超参数的选择可以直接影响模型的性能和训练过程。通常,数据科学家和研究人员需要通过实验和
调整来找到最佳的超参数组合,以获得最佳的模型性能。超参数调整通常是一项重要的任务,被称为超
参数优化或调参。
2.1 ReLU(inplace=True)
ReLU(inplace=True) 是指在使用ReLU(Rectified Linear Unit)激活函数时的一种设置。ReLU是一种常用的非线性激活函数,通常用于神经网络的隐藏层,它的定义为 f(x) = max(0, x) 。在这里,我将解释 inplace 参数的含义:
- Inplace 操作:如果将 inplace 参数设置为 True ,那么ReLU操作将被就地执行,即在原地修改输入,而不创建新的张量。这意味着,如果输入的值大于0,它将保持不变,但如果小于0,它将被设置为0,而不是创建一个新的张量来存储结果。
- 默认值:在PyTorch中, inplace 参数的默认值通常是 False ,这意味着ReLU操作将创建一个新的张量来存储结果,而不会改变原始输入。这是出于安全和梯度计算的考虑,因为修改原始张量可能会导致梯度计算出错。
- 使用场景:在实际应用中,通常不需要设置 inplace 为 True ,除非你非常明确地知道自己在做什么,因为原地操作可能会导致难以追踪的错误。 inplace 通常用于内存优化,以减少内存消耗,但要小心使用。
在大多数情况下,你可以安全地使用默认的 inplace=False 设置,这将创建一个新的张量来存储ReLU
的输出,而不会影响原始输入。这有助于避免潜在的错误和梯度问题。
2.2 交叉熵损失CrossEntropyLoss
交叉熵损失(Cross-Entropy Loss)是用于衡量两个概率分布之间的差异的损失函数。在深度学习中,
它经常用于分类问题,特别是多类别分类问题。让我们尝试以通俗的方式理解它:
想象你正在做一个多类别分类任务,例如将图像分为猫、狗和鸟。对于每个图像,你的模型会为每个类
别分配一个概率,表示该图像属于该类别的可能性。交叉熵损失的目标是衡量你的模型的概率分布与实
际情况之间的差异。
在通俗的术语中,你可以将交叉熵损失视为以下情况的度量标准:
- 如果你的模型对正确答案的概率分配得非常高,交叉熵损失将非常低。这意味着模型非常自信且准确,因此损失很小。这是你想要的情况,因为模型准确地预测了图像的真实类别。
- 如果你的模型对正确答案的概率分配得不高,交叉熵损失将相对较高。这意味着模型不太确定或错误地预测了图像的类别,因此损失较高。这通常是模型需要学习的情况,以提高准确性。
在PyTorch框架中,你可以使用 torch.nn.CrossEntropyLoss 来定义和计算交叉熵损失。这个函数接
受两个参数,分别是模型的输出和真实的目标标签,具体写法如下:
import torch
import torch.nn as nn
num_classes = 10
# 模型的输出(预测值)通常是一个张量
predicted = torch.randn(1, num_classes) # 这里的num_classes表示类别的数量
# 真实目标标签(target)通常是一个包含类别索引的张量
target = torch.randint(0, num_classes, (1,))
# 定义交叉熵损失函数
criterion = nn.CrossEntropyLoss()
# 计算交叉熵损失
loss = criterion(predicted, target)
print('loss = ', loss)
在上面的代码中, predicted 是模型的输出,它是一个张量,通常具有形状 (batch_size,num_classes) ,其中 num_classes 是类别的数量。 target 是真实的目标标签,它是一个包含类别索引的张量,形状为 (batch_size,) 。
然后,你可以使用 nn.CrossEntropyLoss() 来定义交叉熵损失函数,最后计算损失值通过传递predicted 和 target 到这个损失函数中。损失值即为模型的预测值与真实标签之间的交叉熵损失
3.反向传播
反向传播(Backpropagation)是深度学习中用于训练神经网络的关键算法。它是一种基于梯度下降的
优化算法,用于调整神经网络的权重和参数,以最小化损失函数,从而使网络能够学习并提高其性能。
以下是反向传播的主要概念:
- 前向传播:首先,输入数据经过神经网络的前向传播。这意味着数据从输入层经过各个隐藏层,最
终到达输出层。在每个层中,数据被传递给激活函数,并且权重和偏置会调整数据的转换。前向传
播计算模型的预测输出。 - 计算损失:在前向传播后,计算损失函数(通常是均方误差、交叉熵等)来度量模型的预测与实际
目标之间的差距。损失函数提供了一个单一的标量值,表示了模型的性能。 - 反向传播:反向传播是通过计算损失对于网络参数的梯度,从输出层向后传递梯度。这个过程利用
了链式法则(链式求导法则),它允许计算每个层的梯度,并将梯度传递回神经网络的每一层。 - 参数更新:一旦计算了各层的梯度,使用梯度下降或其变种来更新神经网络的权重和偏置。梯度下
降的目标是通过反复迭代来减小损失,从而使网络的预测逐渐接近真实值。 - 重复迭代:整个反向传播的过程通常需要多次迭代,每次迭代都会更新权重和参数。在每次迭代
中,前向传播、损失计算、反向传播和参数更新都会执行。
通过多次迭代反向传播,神经网络逐渐学习到如何更好地拟合训练数据,以减小损失。这使网络能够自
动调整其内部参数,以改进其性能,并在处理新数据时进行更准确的预测。反向传播是深度学习的核心
技术之一,使神经网络能够进行有效的训练和学习。
4.优化器
优化器(Optimizer)是深度学习中的一种算法,用于自动调整神经网络的权重和参数,以最小化损失函
数。它是训练神经网络的关键组件之一,帮助网络逐渐学习数据的模式,以提高性能。以下是关于优化
器的主要概念:
- 梯度下降:绝大多数优化器基于梯度下降算法。梯度下降的目标是找到损失函数的最小值。它通过
计算损失函数对于模型参数的梯度(梯度是损失函数相对于参数的变化率),然后按照梯度的反方
向来更新参数,从而逐渐减小损失函数的值。 - 学习率:学习率是优化器的一个重要超参数,控制了参数更新的步长。较小的学习率会导致参数更
新缓慢,但通常更稳定。较大的学习率可能会导致快速参数更新,但可能不稳定。 - 梯度下降的变种:除了标准梯度下降,还有一些变种优化器,如随机梯度下降(SGD)、Adam、
RMSProp等。每种优化器都有其自己的优势和适用场景,可以根据任务的性质来选择合适的优化
器。 - 参数更新规则:不同的优化器使用不同的规则来更新模型参数。例如,Adam优化器使用了动量和
适应性学习率的概念,以加速收敛并处理不同尺度的参数。 - 收敛性和稳定性:选择适当的优化器可以影响训练的收敛速度和稳定性。某些优化器在特定任务上
表现更好,而某些优化器对于处理梯度爆炸或梯度消失问题具有一定的鲁棒性。 - 超参数调整:学习率和其他优化器相关的超参数通常需要进行调整,以使模型训练达到最佳性能。
总之,优化器是深度学习中的一个关键组件,它负责根据损失函数的梯度来更新神经网络的权重和参
数,以最小化损失函数。选择适当的优化器对于成功训练和提高模型性能至关重要。
4.1 optimizer.zero_grad()
optimizer.zero_grad()
是用于在每个训练迭代中将模型的梯度归零的操作。理解这个操作的重要性
和作用如下:
- 梯度积累:在深度学习中,每个参数都有一个梯度,用于告诉优化器如何更新该参数以减小损失。
这些梯度在每个训练迭代中都会被计算。如果不在每个迭代开始时将梯度归零,那么梯度将在迭代
之间积累,导致不正确的参数更新。 - 多次反向传播:在某些情况下,你可能需要多次反向传播。例如,当使用一批数据进行多个前向传
播和反向传播以计算梯度时,梯度在这些传播之间会累积。因此,在每次开始新的传播之前,必须
清零梯度,以确保每个传播都以干净的梯度状态开始。 - 循环和迭代:在循环中训练模型时,如在 PyTorch 中的训练循环中,通常会在每个训练迭代的开头
调用 optimizer.zero_grad() 以清除上一个迭代中的梯度。这有助于保持参数更新的独立性,
确保每个迭代都是基于当前迭代的梯度计算的。
示例使用方式如下:(仅示例,非可执行代码)
import torch
import torch.optim as optim
# 创建一个优化器
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 在每个训练迭代开始时清零梯度
optimizer.zero_grad()
# 进行前向传播、损失计算和反向传播
# ...
# 更新参数
optimizer.step()
在这个示例中, optimizer.zero_grad() 用于清零模型参数的梯度,以确保每个迭代都从零开始累积
新的梯度。这是深度学习训练中的常见操作,以确保梯度计算的正确性。
5.卷积
CNN的基本结构
卷积神经网络(Convolutional Neural Network, CNN)是深度学习中的一种强大的网络架构,广泛应
用于图像和视频识别、图像分类、物体检测以及许多其他领域。CNN的基本结构通常包括以下几种类型
的层:
- 卷积层(Convolutional Layer):这是CNN的核心,负责进行特征提取。通过滤波器(或称为卷积核)在输入图像上滑动并进行卷积操作,输出称为特征图(featuremaps)。
卷积操作有助于捕获输入数据的局部相关性。 - 激活层(Activation Layer):激活层通常紧随卷积层之后。最常用的激活函数是ReLU(Rectified Linear Unit),它为网络引入非线性,帮助网络学习复杂的模式。
- 池化层(Pooling Layer):也称为下采样层,用于减少特征图的维度,提高计算效率,同时保留重要信息。常见的池化操作有最大池化(Max Pooling)和平均池化(Average Pooling)。
- 全连接层(Fully Connected Layer):在多个卷积和池化层之后,网络会包括一个或多个全连接层,其目的是将前面学到的特征表示
映射到最终的输出,如分类标签。在进行全连接层之前,通常会有一个扁平化(Flatten)操作,将二维特征图转换为一维特征向量。 - Dropout层(Dropout Layer):Dropout是一种正则化技术,用于防止网络过拟合。它通过在训练过程中随机“丢弃”一些神经元的输出,来减少模型对于某些特定的神经元的依赖。
- 批归一化层(Batch Normalization Layer):批归一化是为了加快训练速度、提高性能,通过对小批量数据进行归一化处理,保持激活分布的稳定。这些层可以按照不同的方式组合,构建起适应各种任务需求的网络架构。在深度学习的实践中,设计网络时通常会根据具体的数据集和任务进行调整,可能会引入或省略某些层,或者调整层的参数,如滤波器的大小、数量、步长(stride)以及填充(padding)等。
在典型的卷积神经网络(Convolutional Neural Network,CNN)中,通常会按照以下顺序排列卷积层、池化层和全连接层,这是CNN的基本结构:
- 卷积层(Convolutional Layers):卷积层通常是CNN的第一层。它用于从原始输入数据中提取特征。每个卷积层包含多个卷积核(也称为滤波器),这些卷积核对输入数据进行卷积操作,以生成特征映射(feature maps)。卷积操作帮助网络识别图像中的局部特征,例如边缘、纹理等。通常,卷积层之间可以通过激活函数(如ReLU)引入非线性。
- 池化层(Pooling Layers):池化层紧随卷积层。它用于减小特征映射的空间尺寸,同时保留最重要的信息。池化操作通常使用最大池化(Max Pooling)或平均池化(Average Pooling),通过在局部区域内取最大值或平均值来减小特征映射的维度。这有助于减少计算量和参数数量,同时保持特征的不变性和位置不变性。
- 全连接层(Fully Connected Layers):全连接层通常位于CNN的末尾。它们将前面卷积和池化层提取的特征映射转换成与任务相关的输出。全连接层中的每个神经元与前一层的所有神经元相连接,因此全连接层引入了全局关联性。最后一个全连接层通常用于分类任务,其输出数量等于类别数,经过softmax激活以获得类别概率分布。所以,典型的CNN结构是卷积层 -> 池化层(可重复多次) -> 全连接层。然而,网络的具体架构和层数可以根据任务和数据集的要求而变化。例如,深度的CNN可以包含多个卷积和池化层,而浅层网络可能
只有少数几层。此外,一些CNN架构还可能包括其他层类型,如批归一化层(Batch Normalization)或残差连接(Residual onnections),以提高性能和训练稳定性。在卷积神经网络(CNN)中,将图像从3个通道转换成64个通道是通过应用一组卷积滤波器(也称为卷
积核或卷积层)实现的。每个滤波器都是一个小的权重矩阵,它在输入图像上滑动(或“卷积”),通过逐个像素点乘加权重来计算新的特征图(feature map)。在输入层,你的图像通常有3个通道,对应于RGB(红、绿、蓝)颜色空间的三种颜色。当你应用卷积层时,你不是只用一个滤波器,而是使用了多个。每个滤波器都会在输入图像的所有通道上进行操作,并生成一个新的二维特征图。如果你使用了64个不同的滤波器,那么就会得到64个这样的特征图,每个特征图都可以看作是输入图像的一个“特征表示”。这些特征图中的每一个都可能会捕捉到输入数据的不同方面,例如边缘、角点、纹理等。不同的卷积滤波器可以学习到图像中不同层次的抽象特征。例如,第一层的卷积核可能会识别简单的边缘和角点,而更深层的卷积核可能会识别更复杂的图案和对象部分。在卷积网络的训练过程中,这些滤波器的权重是通过反向传播算法根据任务(如图像分类、目标检测等)进行优化的。网络的目标是学习那些对完成特定任务有用的特征表示。总的来说,虽然原始的输入图像只有3个通道,通过使用多个卷积滤波器,网络可以将其转换成一个更深的、具有多个通道的特征空间,这些新的通道不再代表原始的颜色信息,而是代表了图像中更加抽象和复杂的特征。这就是为什么可以从3个通道变成64个通道(或者更多)。每个新的通道都是输入图像的一个新的、不同的特征表示。
下面是使用PyTorch框架的Python代码,演示了一个简单的卷积神经网络(CNN)模型的定义,这个模
型可以用于图像的分类任务。为了简单起见,假设我们处理的是一个多类别的图像分类问题,比如
CIFAR-10,其中图像大小为32x32像素,有3个颜色通道(红、绿、蓝):
import torch
import torch.nn as nn
import torch.nn.functional as F
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
# 卷积层1,输入通道数为3(RGB图像),输出通道数为32,卷积核大小为3x3,填充为1
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
# 添加批量归一化层
self.bn1 = nn.BatchNorm2d(32)
# 卷积层2,输入通道数为32,输出通道数为64,卷积核大小为3x3,填充为1
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
# 添加批量归一化层
self.bn2 = nn.BatchNorm2d(64)
# 最大池化层,池化窗口为2x2
self.max_pool1 = nn.MaxPool2d(kernel_size=2)
self.max_pool2 = nn.MaxPool2d(kernel_size=2)
# Dropout层,概率为0.25
self.dropout1 = nn.Dropout(0.25)
# 全连接层1,输入特征数为64 * 8 * 8(因为前面有1次池化,所以大小减半了一次),输出特征数为512
self.fc1 = nn.Linear(64 * 8 * 8, 512)
# Dropout层,概率为0.5
self.dropout2 = nn.Dropout(0.5)
# 全连接层2,输入特征数为512,输出特征数为10(假设有10个类别)
self.fc2 = nn.Linear(512, 10)
def forward(self, x):
print(x.shape) # 打印输入张量的形状 torch.Size([4, 3, 32, 32])
# 通过第一个卷积层后使用批量归一化层和ReLU激活函数
x = F.relu(self.bn1(self.conv1(x)))
# 这段代码定义了一个简单的卷积神经网络(CNN)模型,并对模型的前向传播过程进行了详细注释和打
# 印输出,以便理解数据张量的形状变化。以下是代码的简要解释:
# 1. SimpleCNN 类继承自 nn.Module ,表示这是一个PyTorch模型。
# 2. 在 __init__ 方法中定义了模型的各个层:两个卷积层、两个批量归一化层、两个最大池化层、
# 两个Dropout层和两个全连接层。
# 3. 在 forward 方法中定义了模型的前向传播过程,包括卷积、批量归一化、ReLU激活、最大池化、
# Dropout、展平、全连接和softmax激活等操作。
# 4. 在 __main__ 部分,首先创建了一个 SimpleCNN 模型的实例 model 。
# 5. 然后创建了一个形状为 (4, 3, 32, 32) 的随机输入张量 dummy_input ,表示一个大小为32x32
# 的RGB图像批次,批大小为4。
print(x.shape) # 打印第一个卷积层输出张量的形状 torch.Size([4, 32, 32, 32])
x = self.max_pool1(x) # 使用最大池化层
print(x.shape) # 打印第一个池化层输出张量的形状 torch.Size([4, 32, 16, 16])
# 通过第二个卷积层后使用批量归一化层和ReLU激活函数
print(x.shape) # 打印第二个池化层输出张量的形状 torch.Size([4, 32, 16, 16])
x = F.relu(self.bn2(self.conv2(x)))
# 通过最大池化层
print(x.shape) # 打印第二个卷积层输出张量的形状 torch.Size([4, 64, 16, 16])
x = self.max_pool2(x) # 使用最大池化层
# 应用Dropout
print(x.shape) # 打印第二个池化层输出张量的形状 torch.Size([4, 64, 8, 8])
x = self.dropout1(x) # 使用Dropout
print(x.shape) # 打印Dropout后张量的形状 torch.Size([4, 64, 8, 8])
# 展平特征张量
x = torch.flatten(x, 1) # 在第1维度(批次维度)之后展平
# 通过第一个全连接层后使用ReLU激活函数
print(x.shape) # 打印展平后张量的形状 torch.Size([4, 4096])
x = F.relu(self.fc1(x))
# 应用Dropout
print(x.shape) # 打印第一个全连接层输出张量的形状 torch.Size([4, 512])
x = self.dropout2(x) # 使用Dropout
# 通过第二个全连接层
print(x.shape) # 打印第二个全连接层输出张量的形状 torch.Size([4, 512])
x = self.fc2(x)
# 应用softmax激活函数,最后一个全连接层(self.fc2)的输出经过softmax激活函数处理,
# 沿着第二维度(即dim=1)进行分类,以获得每个样本对10个类别的概率分布
x = F.softmax(x, dim=1)
print(x.shape) # 打印经过softmax处理后张量的形状 torch.Size([4, 10])
return x
if __name__ == '__main__':
# 创建CNN模型的实例
model = SimpleCNN()
# 假设我们有一批大小为32x32的图像
# 这些图像有3个通道,batch大小为4
dummy_input = torch.randn(4, 3, 32, 32)
# 计算模型的输出
output = model(dummy_input)
print(output.shape)
6.Batch Normalization
归一化层,特别是在深度学习中常见的Batch Normalization (BN),是一种用于提高网络训练速度和稳
定性的技术。理解Batch Normalization可以从以下几个方面入手:
- 内部协变量偏移(Internal Covariate Shift)(不好的现象):
这是一个现象,指的是训练神经网络时,每层输入数据的分布随着前一层参数的更新而改变。
这使得每层都需要不断适应新的数据分布,这会减慢训练速度并降低训练稳定性。
Batch Normalization通过规范化每一层的输入来减少内部协变量偏移,使得网络的每一层学
习到的特征更加稳定。 - 规范化(Normalization):
在Batch Normalization中,对于每个特征,算法会在一个mini-batch的范围内计算均值和方
差。
然后,它使用这些统计数据将每个特征标准化,使其均值接近0,方差接近1。 - 可学习的参数:
Batch Normalization引入了两个可学习的参数,γ(gamma)和β(beta),用于每个特
征。这些参数分别对应于缩放和平移操作,允许模型恢复特征可能需要的任何原始的、非标准
化的形式。
这意味着模型可以学习到,在特征规范化之后,对于最优性能而言,是否需要恢复特征的原始
分布。 - 效果:
通过使用Batch Normalization,神经网络可以使用更高的学习率而不会那么容易发生梯度消
失或梯度爆炸的问题。
它还可以作为一种正则化的形式,某种程度上减少(但不替代)对Dropout的需求。 - 操作步骤:
步骤1:计算mini-batch的均值和方差。
步骤2:使用均值和方差来标准化mini-batch中的每个输入值。
步餐3:使用可学习参数γ和β进行缩放和平移操作。 - 使用场景:
Batch Normalization通常在全连接层或卷积层之后、激活函数之前使用。 - 批量依赖性:
由于Batch Normalization依赖于每个mini-batch的统计数据,它可能对batch的大小和内容
敏感,这在某些场景如小batch大小或序列数据中可能是一个问题。 - 变种和改进:
由于Batch Normalization的某些限制,已经提出了其他的归一化方法,如Layer
Normalization、Instance Normalization和Group Normalization,它们试图解决BN的批量
依赖问题,并且更适用于不同的数据类型和网络结构。
理解Batch Normalization的关键是认识到它通过规范化神经网络各层的输入来减少内部协变量偏移,从
而加快训练速度、提高模型性能和稳定性。
让我们以一个简单的神经网络中使用Batch Normalization的例子来说明这个过程:
假设你有一个简单的全连接神经网络,用于图像分类任务。网络有三层,每层之后你想使用BatchNormalization来加速训练并改善性能。以下是将Batch Normalization应用于第一层后的详细步骤:
-
前向传播(对于一个mini-batch):
第一层的输出:假设你的mini-batch大小为32,输入层接收到这32个图像数据,并通过第一
层的权重和偏置进行转换,得到第一层的输出。 -
计算均值和方差:
对于第一层的输出,你计算这个mini-batch中每个神经元输出的均值和方差。
均值(μ):对于每个神经元,计算32个输出值的平均值。
方差(σ²):接着计算每个神经元输出值与其均值差的平方的平均值。 -
标准化:
使用计算出的均值和方差,对每个神经元的输出进行标准化。对于每个输出值,减去均值并除以方差的平方根(加上一个很小的数ε以避免除以零),得到标准化后的值。 -
缩放和平移:
然后对每个标准化后的神经元输出值进行缩放和平移操作:γ(缩放因子)和β(平移因子)是通过训练学习得到的参数。
标准化的值乘以γ并加上β,得到最终的Batch Normalization输出。 -
激活函数:
Batch Normalization的输出可以直接输入到激活函数(如ReLU)中,得到第一层最终的激活输出。 -
反向传播:
在训练的反向传播阶段,Batch Normalization层不仅会根据梯度更新权重,还会更新γ和β这两个参数。
通过以上步骤,你的网络可以更快地进行训练,因为每层的输入更加稳定,不再需要小心翼翼地选择学
习率。同时,模型也可能因为这种内部的正则化效果而有更好的泛化能力。
7.U-Net结构
上图是U-net的一个经典架构图,通常用于深度学习中的图像分割任务。U-net是一种卷积神经网络,它
由两部分组成:收缩路径(左侧)和扩张路径(右侧)。下面是对这个架构的详细解读:
收缩路径(左侧)
- 输入图像块:图像分割通常在小块图像上进行,以减少计算资源的需求。在这个例子中,输入图像
的尺寸是 ( 572 * 572 ) 像素。 - 卷积层(蓝色箭头):使用 ( 3 * 3 ) 的卷积核进行特征提取,每次卷积后都会使用ReLU激活函数。
在这些层之后,特征图的尺寸稍微减小。 - 池化层(红色箭头):使用 ( 2 * 2 ) 的最大池化操作减少特征图的尺寸,同时增加了网络的抽象能
力。每次池化操作后,图像尺寸减半。 - 通道数:随着网络深入,每个卷积层后的通道数会增加(64,128,256,512,1024),这是为
了捕获更复杂的特征。
扩张路径(右侧)
- 上采样层(绿色箭头):使用 ( 2 * 2 ) 的上卷积操作增加特征图的尺寸。这是为了逐渐恢复图像的
尺寸以进行精确的定位。 - 剪裁与复制(灰色箭头):从收缩路径复制的特征图会与上采样后的特征图结合。由于复制的特征
图可能会比上采样的特征图大,所以需要进行剪裁。 - 卷积层(蓝色箭头):和收缩路径类似,继续使用 ( 3 * 3 ) 的卷积核进行特征提取。
最终输出 - 输出分割图:网络的最终输出是一个分割图,它将输入图像的每个像素分类到不同的类别。在这个
例子中,输出的分割图大小为 ( 388 * 388 ) 像素,这比原始输入图像小了,因为边缘的像素在卷积
过程中被“吃掉”了。
U-Net主要分为两个部分:编码器(Encoder)和解码器(Decoder)。
- 编码器(Encoder):
- 编码器负责将输入图像逐渐减小分辨率,提取图像中的特征。
- 通常使用卷积层(Convolutional Layers)和池化层(Pooling Layers)交替堆叠以逐渐缩小特征图的尺寸。
- 在每个编码器步骤中,特征图的通道数量(即特征的维度)逐渐增加,以捕获更丰富的特征信
息。 - 编码器的最后一层通常是一个普通的卷积层,将特征图的通道数量调整为模型所需的输出类别
数。
- 解码器(Decoder):
- 解码器的任务是将编码器提取的特征映射还原为原始输入图像的分割掩码(Mask)。
- 解码器使用转置卷积层(Transpose Convolutional Layers,也称为反卷积层)来逐渐增加特征图的尺寸。
- 在解码器的每个步骤中,与编码器对应的特征图会连接(Concatenate)起来,以保留更多的上下文信息
- 解码器的最后一层通常使用一个卷积层,其输出通道数量等于模型的目标类别数,并通过softmax激活来生成最终的分割掩码
U-Net是一个用于图像分割任务的深度卷积神经网络,其详细结构如下:
- 编码器部分(下采样部分):
- 输入层:接受原始图像作为输入。
- 一系列卷积层(通常包括卷积核大小为3x3,激活函数为ReLU):用于提取低级别特征。
- 池化层(通常使用最大池化或平均池化):用于降低特征图的分辨率。
- 在每个卷积层后添加批量归一化(Batch Normalization)可以有助于训练稳定性。
- 中间层:
- 一系列卷积层:这些层用于进一步提取高级别的语义特征,有助于特征的融合和转换。
- 解码器部分(上采样部分):
- 上采样层(或转置卷积层):将特征图的尺寸还原到接近原始图像的大小。通常采用转置卷积
操作,其卷积核通常为3x3或更大,以逐渐增加分辨率。 - 跳跃连接:将相应编码器层的特征图与解码器层的特征图连接起来。
- 一系列卷积层:用于进一步处理特征,使其更适合分割任务。
- 输出层:通常是一个卷积层,使用Sigmoid激活函数来生成分割掩码。分割掩码表示每个像素
的属于前景或背景的概率。
这就是U-Net的基本结构,但实际的U-Net架构可以根据具体任务和数据集的需求进行调整和扩展。例
如,你可以增加或减少编码器和解码器部分的卷积层以控制模型的深度,或者在中间层中添加额外的卷
积层以提取更高级别的特征。
U-Net的关键特点包括跳跃连接和上采样操作,它们允许模型同时利用来自不同分辨率的特征,从而提
高分割性能。跳跃连接有助于保留细节和局部信息,而上采样操作有助于还原图像的分辨率,使分割结
果更准确。