一、神经网络初始化
我喜欢在网络的构造函数中进行。比如
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Sequential(
nn.Conv2d(3, 64, 3, padding = 1),
nn.BatchNorm2d(64),
nn.ReLU(True),
nn.AvgPool2d(2, 2)
)
self.conv21 = nn.Conv2d(64, 64*2, 3, padding = 1 )
self.pool2 = nn.AvgPool2d(2, 2)
self.conv31 = nn.Conv2d(64*2, 10, 1)
self.pool3 = nn.AvgPool2d(8, 8)
self.line = nn.Linear(10,100)
for m in self.modules():
if isinstance(m, nn.Conv2d):
nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
if m.bias is not None:
nn.init.zeros_(m.bias)
elif isinstance(m, nn.BatchNorm2d):
nn.init.normal_(m.weight,1.0,0.02)
nn.init.zeros_(m.bias)
elif isinstance(m, nn.Linear):
nn.init.normal_(m.weight,.0, 0.05)
nn.init.zeros_(m.bias)
def forward(self, x):
x = self.conv1(x)
x = F.relu(self.conv21(x))
x = self.pool2(x)
x = self.conv31(x)
x = self.pool3(x)
x = x.view(-1, 10)
x = self.line(x)
return x
上面代码中的__init__函数中的for m in self.modules(): 循环语句就是对网络结构中的结点进行赋值,那么这段代码是如何进行的呢?它是从外到内依次进行的。
第一次进入循环,m的值会是整个网络,则是
Net(
(conv1): Sequential(
(0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
(3): AvgPool2d(kernel_size=2, stride=2, padding=0)
)
(conv21): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(pool2): AvgPool2d(kernel_size=2, stride=2, padding=0)
(conv31): Conv2d(128, 10, kernel_size=(1, 1), stride=(1, 1))
(pool3): AvgPool2d(kernel_size=8, stride=8, padding=0)
(line): Linear(in_features=10, out_features=100, bias=True)
)
这很明显不会进入任何分支,第二次进入循环,m的值是self.conv1右边的值,即为
Sequential(
(0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU(inplace=True)
(3): AvgPool2d(kernel_size=2, stride=2, padding=0)
)
这也很明显不会进入任何分支,第三次进入循环,m的值是上一次self.conv1的序列内部分的第一个结构,即
Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
这会进入分支中的第一个if语句。接下来的循环m的值为
BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
这会进入elif isinstance(m, nn.BatchNorm2d)

本文详细解析了如何在PyTorch网络中初始化权重,包括Kaiming Normal和Zero初始化,并展示了如何通过实例操作查看和理解bias和weight的初始值与梯度。随后通过反向传播演示了梯度的变化。
最低0.47元/天 解锁文章
9万+

被折叠的 条评论
为什么被折叠?



