BN和Dropout在训练和测试时的差别

Batch Normalization

BN,Batch Normalization,就是在深度神经网络训练过程中使得每一层神经网络的输入保持相近的分布。

BN训练和测试时的参数是一样的嘛?

对于BN,在训练时,是对每一批的训练数据进行归一化,也即用每一批数据的均值和方差。

而在测试时,比如进行一个样本的预测,就并没有batch的概念,因此,这个时候用的均值和方差是全量训练数据的均值和方差,这个可以通过移动平均法求得。

对于BN,当一个模型训练完成之后,它的所有参数都确定了,包括均值和方差,gamma和bata。

BN训练时为什么不用全量训练集的均值和方差呢?

因为用全量训练集的均值和方差容易过拟合,对于BN,其实就是对每一批数据进行归一化到一个相同的分布,而每一批数据的均值和方差会有一定的差别,而不是用固定的值,这个差别实际上能够增加模型的鲁棒性,也会在一定程度上减少过拟合。

也正是因此,BN一般要求将训练集完全打乱,并用一个较大的batch值,否则,一个batch的数据无法较好得代表训练集的分布,会影响模型训练的效果。

Dropout

Dropout 是在训练过程中以一定的概率的使神经元失活,即输出为0,以提高模型的泛化能力,减少过拟合。

Dropout 在训练和测试时都需要嘛?

Dropout 在训练时采用,

  • 32
    点赞
  • 107
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
好的,下面我以PyTorch框架为例,演示如何使用该框架完成Tiny-ImageNet的训练和分类预测。 首先,需要下载Tiny-ImageNet数据集,可以从官网上下载并解压。接下来,我们可以使用PyTorch提供的Dataset和DataLoader类来加载数据集。代码如下: ```python import torch import torchvision.transforms as transforms from torchvision.datasets import ImageFolder from torch.utils.data import DataLoader # 定义数据预处理的转换 transform_train = transforms.Compose([ transforms.RandomCrop(64, padding=4), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) transform_test = transforms.Compose([ transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) # 加载训练集和验证集 train_set = ImageFolder('tiny-imagenet-200/train', transform=transform_train) train_loader = DataLoader(train_set, batch_size=64, shuffle=True, num_workers=4) val_set = ImageFolder('tiny-imagenet-200/val', transform=transform_test) val_loader = DataLoader(val_set, batch_size=64, shuffle=False, num_workers=4) # 加载类别标签 with open('tiny-imagenet-200/wnids.txt', 'r') as f: class_names = sorted([line.strip() for line in f.readlines()]) ``` 接下来,我们可以定义一个卷积神经网络模型,并使用SGD算法进行优化。代码如下: ```python import torch.nn as nn import torch.optim as optim # 定义卷积神经网络模型 class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1) self.bn1 = nn.BatchNorm2d(32) self.relu1 = nn.ReLU(inplace=True) self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2) self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1) self.bn2 = nn.BatchNorm2d(64) self.relu2 = nn.ReLU(inplace=True) self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2) self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) self.bn3 = nn.BatchNorm2d(128) self.relu3 = nn.ReLU(inplace=True) self.pool3 = nn.MaxPool2d(kernel_size=2, stride=2) self.fc1 = nn.Linear(128 * 8 * 8, 1024) self.relu4 = nn.ReLU(inplace=True) self.drop1 = nn.Dropout(p=0.5) self.fc2 = nn.Linear(1024, 200) def forward(self, x): x = self.conv1(x) x = self.bn1(x) x = self.relu1(x) x = self.pool1(x) x = self.conv2(x) x = self.bn2(x) x = self.relu2(x) x = self.pool2(x) x = self.conv3(x) x = self.bn3(x) x = self.relu3(x) x = self.pool3(x) x = x.view(-1, 128 * 8 * 8) x = self.fc1(x) x = self.relu4(x) x = self.drop1(x) x = self.fc2(x) return x # 定义损失函数和优化器 criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4) ``` 在模型训练过程中,我们可以使用训练集对模型进行训练,并使用验证集来评估模型性能。代码如下: ```python # 定义模型训练函数 def train(net, train_loader, criterion, optimizer, epoch): net.train() train_loss = 0 correct = 0 total = 0 for batch_idx, (inputs, targets) in enumerate(train_loader): inputs, targets = inputs.cuda(), targets.cuda() optimizer.zero_grad() outputs = net(inputs) loss = criterion(outputs, targets) loss.backward() optimizer.step() train_loss += loss.item() _, predicted = outputs.max(1) total += targets.size(0) correct += predicted.eq(targets).sum().item() print('Epoch: %d, Train Loss: %.3f, Train Acc: %.3f%% (%d/%d)' % (epoch, train_loss / len(train_loader), 100. * correct / total, correct, total)) # 定义模型验证函数 def validate(net, val_loader, criterion): net.eval() val_loss = 0 correct = 0 total = 0 with torch.no_grad(): for batch_idx, (inputs, targets) in enumerate(val_loader): inputs, targets = inputs.cuda(), targets.cuda() outputs = net(inputs) loss = criterion(outputs, targets) val_loss += loss.item() _, predicted = outputs.max(1) total += targets.size(0) correct += predicted.eq(targets).sum().item() print('Val Loss: %.3f, Val Acc: %.3f%% (%d/%d)' % (val_loss / len(val_loader), 100. * correct / total, correct, total)) # 开始模型训练 net.cuda() for epoch in range(100): train(net, train_loader, criterion, optimizer, epoch) validate(net, val_loader, criterion) ``` 最后,我们可以使用训练好的模型对测试集进行分类预测,并输出预测结果。代码如下: ```python # 加载测试集 test_set = ImageFolder('tiny-imagenet-200/test', transform=transform_test) test_loader = DataLoader(test_set, batch_size=64, shuffle=False, num_workers=4) # 对测试集进行分类预测 net.eval() test_preds = [] with torch.no_grad(): for batch_idx, (inputs, targets) in enumerate(test_loader): inputs = inputs.cuda() outputs = net(inputs) _, predicted = outputs.max(1) test_preds.extend(predicted.cpu().numpy()) # 输出预测结果 with open('tiny-imagenet-200/val/val_annotations.txt', 'r') as f: lines = f.readlines() class_to_idx = {class_names[i]: i for i in range(len(class_names))} idx_to_class = {i: class_names[i] for i in range(len(class_names))} test_filenames = [line.split()[0] for line in lines] test_labels = [class_to_idx[line.split()[1]] for line in lines] test_acc = sum([1 if pred == true_label else 0 for pred, true_label in zip(test_preds, test_labels)]) / len(test_labels) print('Test Acc: %.3f%% (%d/%d)' % (100. * test_acc, sum([1 if pred == true_label else 0 for pred, true_label in zip(test_preds, test_labels)]), len(test_labels))) ``` 以上就是使用PyTorch框架完成Tiny-ImageNet的训练和分类预测的完整代码。注意,由于数据集较大,训练和预测可能需要较长间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海晨威

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值