在pytorch模型中如何获得BatchNorm2d层的各个mean和var(平均值和方差)

这个内容是将随便做了一个网络结构,然后简单的训练几次,生成模型,并且存储起来,主要是为了学习获得pytorch中的BatchNorm2d层的各个特征图的平均值和方差。代码如下:

import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision import datasets,transforms
from torch.optim import lr_scheduler
import torch.optim as optim



class VGG(nn.Module):
    def __init__(self):
        super(VGG,self).__init__()

        self.conv1 = nn.Conv2d(3,64,3,padding=(1,1))
        self.bn1 = nn.BatchNorm2d(64)
        self.maxpool1 = nn.MaxPool2d((2,2))

        self.conv2 = nn.Conv2d(64,128,3,padding=(1,1))
        # self.bn2 = nn.BatchNorm2d(128)
        self.maxpool2 = nn.MaxPool2d((2,2))

        self.conv3 = nn.Conv2d(128,256,3,padding=(1,1))
        # self.bn3 = nn.BatchNorm2d(256)
        self.maxpool3 = nn.MaxPool2d((2,2))

        self.fc1 = nn.Linear(256*16*8,4096)
        self.fc2 = nn.Linear(4096,1000)
        self.fc3 = nn.Linear(1000,10)

    def forward(self,x):
        in_size = x.size(0)

        out = self.conv1(x)
        out = self.bn1(out)
        out = F.relu(out)
        out = self.maxpool1(out)

        out = self.conv2(out)
        out = F.relu(out)
        out = self.maxpool2(out)

        out = self.conv3(out)
        out = F.relu(out)
        out = self.maxpool3(out)

        out = out.view(out.size(0),-1)

        out = self.fc1(out)
        out = F.relu(out)

        out = self.fc2(out)
        out = F.relu(out)
        out = self.fc3(out)

        return out

transform_train_list = transforms.Compose([
    transforms.Resize( (256,128),interpolation=3 ),
    transforms.RandomCrop((128,64)),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

train_dataset = datasets.ImageFolder('./train',transform_train_list)
dataloaders = torch.utils.data.DataLoader(train_dataset,batch_size=2,num_workers=0)

dataset_size = len(train_dataset)
class_names = train_dataset.classes

print(dataset_size)
print(class_names)
net=VGG()
optimizer = optim.SGD(net.parameters(),lr=0.001,momentum=0.9)
criterion = nn.CrossEntropyLoss()


for epoch in range(2):#训练模型
    print(epoch)
    net.train(True)

    running_loss = 0.0
    running_corrects = 0.0

    for data in dataloaders:
        inputs,labels = data
        now_batch,c,h,w = inputs.shape

        optimizer.zero_grad()

        outputs = net(inputs)
        # print(outputs)

        _,preds = torch.max(outputs.data,1)
        loss = criterion(outputs,labels)

        loss.backward()
        optimizer.step()

        running_loss = running_loss + loss.item() * now_batch
        running_corrects += float( torch.sum( preds == labels.data ) )

    epoch_loss = running_loss/dataset_size
    epoch_acc = running_corrects/dataset_size
    print(epoch_loss)
    print(epoch_acc)

torch.save(net.cpu().state_dict(),'first.pth')  ##将训练好的模型保存起来

net = VGG()
net.load_state_dict( torch.load('first.pth') )
net.eval()  #产生一个模型并且加载已经训练好的模型的参数


# for data in dataloaders:
#     inputs,labels = data
#     # print(inputs)
#     print(labels)
#     outputs = net(inputs)
#     print(outputs)
#     break

m = VGG()
# m.eval()
m.load_state_dict( torch.load('second.pth') )
print(m.bn1.running_mean.size()) ##获得一共有多少个mean  要是想获得var只要将mean改为var即可
print(m.bn1.running_mean.data[0])
print(m.bn1.running_mean.data[1])
print(m.bn1.running_mean.data[2])

print(m.bn1.running_var.data[0])
print(type(m.bn1.running_mean.data[0]))


m.bn1.running_mean.data[0] = m.bn1.running_mean.data[2]  ##可以对模型参数进行更改,然后保存更改后的模型
m.bn1.running_mean.data[1] = m.bn1.running_mean.data[2]

torch.save(m.cpu().state_dict(),'second.pth')

对于输入到BatchNorm2d层的数据格式为(batch_size,channels_size,h,w),channels_size为多少,就会生成多少个mean和var。

举个例子,如果输入的数据是batch_size=16,channels_size=64,h=32,w=16,则每对mean和var都是 16张某一个特征图中的所有数据的mean和var

发布了36 篇原创文章 · 获赞 11 · 访问量 6551

猜你喜欢

转载自blog.csdn.net/t20134297/article/details/103532999