对PyTorch神经网络初始化Kaiming分布详解
在深度学习中,神经网络的初始化非常重要,它可以影响模型的收敛速度和性能。Kaiming初始化是一种常用的初始化方法,它可以有效地解决梯度消失和梯度爆炸的问题。本文将详细介绍PyTorch中Kaiming初始化的实现方法,并提供两个示例说明。
1. Kaiming初始化方法
Kaiming初始化方法是一种针对ReLU激活函数的初始化方法,它可以使得神经网络的输出具有相同的方差。具体来说,Kaiming初始化方法根据输入和输出的维度计算标准差,并将权重初始化为从均值为0、标准差为$\sqrt{\frac{2}{n_{in}}}$的正态分布中采样得到的值,其中$n_{in}$是输入的维度。
在PyTorch中,可以使用torch.nn.init
模块中的kaiming_normal_
函数或kaiming_uniform_
函数实现Kaiming初始化。以下是一个示例代码:
import torch.nn as nn
import torch.nn.init as init
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1)
self.conv2 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)
self.fc1 = nn.Linear(128 * 8 * 8, 1024)
self.fc2 = nn.Linear(1024, 10)
# 使用kaiming_normal_函数初始化卷积层和全连接层的权重
init.kaiming_normal_(self.conv1.weight, mode='fan_out', nonlinearity='relu')
init.kaiming_normal_(self.conv2.weight, mode='fan_out', nonlinearity='relu')
init.kaiming_normal_(self.fc1.weight, mode='fan_out', nonlinearity='relu')
init.kaiming_normal_(self.fc2.weight, mode='fan_out', nonlinearity='relu')
def forward(self, x):
x = nn.functional.relu(self.conv1(x))
x = nn.functional.max_pool2d(nn.functional.relu(self.conv2(x)), 2)
x = x.view(-1, 128 * 8 * 8)
x = nn.functional.relu(self.fc1(x))
x = self.fc2(x)
return x
在上面的示例代码中,我们定义了一个名为Net
的类,它继承自nn.Module
。在__init__
函数中,我们定义了神经网络的各个层,并使用kaiming_normal_
函数初始化卷积层和全连接层的权重。在forward
函数中,我们定义了模型的前向传播过程。
2. 示例1:使用Kaiming初始化训练神经网络
以下是一个使用Kaiming初始化训练神经网络的示例代码:
import torch.optim as optim
import torchvision.datasets as datasets
import torchvision.transforms as transforms
# 加载数据集
transform = transforms.Compose([
transforms.RandomCrop(32, padding=4),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
trainset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2)
# 定义模型、损失函数和优化器
net = Net()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.01, momentum=0.9, weight_decay=5e-4)
# 训练模型
for epoch in range(100):
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if i % 100 == 99:
print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 100))
running_loss = 0.0
在上面的示例代码中,我们首先加载CIFAR-10数据集,并定义模型、损失函数和优化器。然后,我们训练模型并输出每个epoch的平均损失。
3. 示例2:使用Kaiming初始化进行迁移学习
以下是一个使用Kaiming初始化进行迁移学习的示例代码:
import torch.hub
import torch.optim as optim
import torchvision.datasets as datasets
import torchvision.transforms as transforms
# 加载预训练模型
pretrained_net = torch.hub.load('pytorch/vision:v0.9.0', 'resnet18', pretrained=True)
pretrained_net.fc = nn.Linear(512, 10)
# 使用kaiming_normal_函数初始化全连接层的权重
init.kaiming_normal_(pretrained_net.fc.weight, mode='fan_out', nonlinearity='relu')
# 将模型移动到GPU上
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
pretrained_net = pretrained_net.to(device)
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(pretrained_net.parameters(), lr=0.01, momentum=0.9, weight_decay=5e-4)
# 加载数据集
transform_train = transforms.Compose([
transforms.RandomCrop(32, padding=4),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
trainset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2)
# 训练模型
for epoch in range(100):
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data[0].to(device), data[1].to(device)
optimizer.zero_grad()
outputs = pretrained_net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if i % 100 == 99:
print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 100))
running_loss = 0.0
在上面的示例代码中,我们首先使用torch.hub.load
函数加载预训练的ResNet-18模型,并将其输出层替换为一个新的全连接层。然后,我们使用kaiming_normal_
函数初始化全连接层的权重,并将模型移动到GPU上。接着,我们加载CIFAR-10数据集,并定义损失函数和优化器。最后,我们训练模型并输出每个epoch的平均损失。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:对Pytorch神经网络初始化kaiming分布详解 - Python技术站