赞
踩
import torch.nn as nn import torch.utils.model_zoo as model_zoo import urllib3 from tqdm import tqdm from torchvision.models.resnet import model_urls, resnet18 __all__ = ['ResNet18', 'resnet18', 'BasicBlock'] url = 'https://download.pytorch.org/models/resnet18-5c106cde.pth' http = urllib3.PoolManager() response = http.request('GET', url, preload_content=False) total_size = int(response.headers.get('content-length', 0)) block_size = 1024 with tqdm(total=total_size, unit='iB', unit_scale=True) as progress_bar: with open('resnet18-5c106cde.pth', 'wb') as f: for data in response.stream(block_size): progress_bar.update(len(data)) f.write(data) class BasicBlock(nn.Module): expansion = 1 def __init__(self, inplanes, planes, stride=1, downsample=None): super(BasicBlock, self).__init__() self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=3, stride=stride, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(planes) self.relu = nn.ReLU(inplace=True) self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False) self.bn2 = nn.BatchNorm2d(planes) self.downsample = downsample self.stride = stride self.fc = nn.Linear(512 * self.expansion, 128) self.fc2 = nn.Linear(512 * self.expansion, 20) # 添加dropout层 self.dropout = nn.Dropout(p=0.5) def forward(self, x): identity = x out = self.conv1(x) out = self.bn1(out) out = self.relu(out) out = self.conv2(out) out = self.bn2(out) # 添加dropout层 out = self.dropout(out) if self.downsample is not None: identity = self.downsample(x) out += identity out = self.relu(out) return out class ResNet18(nn.Module): def __init__(self, block=BasicBlock, layers=[2, 2, 2, 2], num_classes=10): super(ResNet18, self).__init__() self.inplanes = 64 self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False) self.bn1 = nn.BatchNorm2d(64) self.relu = nn.ReLU(inplace=True) self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) self.layer1 = self._make_layer(block, 64, layers[0]) self.layer2 = self._make_layer(block, 128, layers[1], stride=2) self.layer3 = self._make_layer(block, 256, layers[2], stride=2) self.layer4 = self._make_layer(block, 512, layers[3], stride=2) self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) self.fc = nn.Linear(512 * block.expansion, num_classes) # 将输出维度修改为10 self.softmax = nn.Softmax(dim=1) for m in self.modules(): if isinstance(m, nn.Conv2d): nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') elif isinstance(m, nn.BatchNorm2d): nn.init.constant_(m.weight, 1) nn.init.constant_(m.bias, 0) def _make_layer(self, block, planes, blocks, stride=1): downsample = None if stride != 1 or self.inplanes != planes * block.expansion: downsample = nn.Sequential( nn.Conv2d(self.inplanes, planes * block.expansion, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(planes * block.expansion), ) layers = [block(self.inplanes, planes, stride, downsample)] self.inplanes = planes * block.expansion for i in range(1, blocks): layers.append(block(self.inplanes, planes)) return nn.Sequential(*layers) def forward(self, x): x = self.conv1(x) x = self.bn1(x) x = self.relu(x) x = self.maxpool(x) x = self.layer1(x) x = self.layer2(x) x = self.layer3(x) x = self.layer4(x) x = self.avgpool(x) x = x.view(x.size(0), -1) x = self.fc(x) x = self.softmax(x) # 使用softmax函数对输出结果进行归一化 return x def resnet18(pretrained=True, progress=True, **kwargs): model = ResNet18(BasicBlock, [2, 2, 2, 2], **kwargs) if pretrained: state_dict = model_zoo.load_url(model_urls['resnet18'], progress=progress) model.load_state_dict(state_dict) return model
这是resnet18网络搭建的代码
import torch import random from torch.utils.data import DataLoader from torchvision import transforms from torchvision.datasets import ImageFolder from net import resnet18 import matplotlib.pyplot as plt from typing import Any # 定义超参数 batch_size = 16 learning_rate_backbone = 0.0001 learning_rate_fc = 0.002 num_epochs = 100 # 定义数据增强 train_transforms_list = [ transforms.Compose([ transforms.Resize((64, 64)), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]), transforms.Compose([ transforms.Resize((64, 64)), transforms.RandomRotation(degrees=15), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]), transforms.Compose([ transforms.Resize((64, 64)), transforms.RandomCrop(size=64, padding=4), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]), ] test_transform = transforms.Compose([ transforms.Resize((64, 64)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) # 加载数据集 train_datasets_list = [ ImageFolder('train', transform=train_transforms_list[0]), ImageFolder('train', transform=train_transforms_list[1]), ImageFolder('train', transform=train_transforms_list[2]) ] test_dataset = ImageFolder('test', transform=test_transform) train_loaders_list = [ DataLoader(train_datasets_list[0], batch_size=batch_size, shuffle=True), DataLoader(train_datasets_list[1], batch_size=batch_size, shuffle=True), DataLoader(train_datasets_list[2], batch_size=batch_size, shuffle=True) ] test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False) # 定义模型 model = resnet18(pretrained=False) num_ftrs = model.fc.in_features model.fc = torch.nn.Sequential( torch.nn.Linear(num_ftrs, 128), torch.nn.ReLU(), torch.nn.Linear(128, 10) ) criterion = torch.nn.CrossEntropyLoss() backbone_params = list(model.parameters()) fc_params = list(model.fc.parameters()) weight_decay = 1e-4 optimizer = torch.optim.Adam([ {'params': model.fc.parameters(), 'lr': learning_rate_fc}, {'params': model.layer4.parameters()}, {'params': model.layer3.parameters()}, {'params': model.layer2.parameters()}, {'params': model.layer1.parameters()}, {'params': model.conv1.parameters()}, ], lr=learning_rate_backbone, weight_decay=weight_decay) # 添加学习率调度器 step_size = 10 gamma = 0.1 scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=step_size, gamma=gamma) # 定义四个列表分别存储4个指标的值 train_losses = [] train_accs = [] test_losses = [] test_accs = [] # 训练模型 device = torch.device('cpu') model = model.to(device) for epoch in range(num_epochs): train_transform = random.choice(train_transforms_list) train_dataset = ImageFolder('train', transform=train_transform) train_loader: DataLoader[Any] = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) model.train() train_loss = 0.0 train_acc = 0.0 for i, (inputs, labels) in enumerate(train_loader): inputs = inputs.to(device) labels = labels.to(device) optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() train_loss += loss.item() * inputs.size(0) _, preds = torch.max(outputs, 1) train_acc += torch.sum(preds == labels.data) train_loss = train_loss / len(train_dataset) train_acc = train_acc / len(train_dataset) print('Epoch: [{}/{}], Train Loss: {:.4f}, Train Acc: {:.4f}, Train Transform: {}'.format(epoch + 1, num_epochs, train_loss, train_acc, train_transform)) model.eval() test_loss = 0.0 test_acc = 0.0 for i, (inputs, labels) in enumerate(test_loader): inputs = inputs.to(device) labels = labels.to(device) outputs = model(inputs) loss = criterion(outputs, labels) test_loss += loss.item() * inputs.size(0) _, preds = torch.max(outputs, 1) test_acc += torch.sum(preds == labels.data) test_loss = test_loss / len(test_dataset) test_acc = test_acc / len(test_dataset) print('Epoch: [{}/{}], Test Loss: {:.4f}, Test Acc: {:.4f}'.format(epoch + 1, num_epochs, test_loss, test_acc)) # 更新学习率 scheduler.step() # 将得到的指标添加到对应列表 train_losses.append(train_loss) train_accs.append(train_acc) test_losses.append(test_loss) test_accs.append(test_acc) # 绘制精度曲线loss曲线 plt.figure(figsize=(10, 3)) plt.subplot(1, 2, 1) plt.title('Loss') plt.plot(train_losses, label='Train Loss') plt.plot(test_losses, label='Test Loss') plt.legend() plt.subplot(1, 2, 2) plt.title('Accuracy') plt.plot(train_accs, label='Train Acc') plt.plot(test_accs, label='Test Acc') plt.legend() plt.show() # 保存模型 torch.save(model.state_dict(), 'resnet18_model.pth')
这是调用resnet18网络,训练自己10个人每个人100个样本一共1000个时频图样本的数据集,为什么生成的loss曲线和精确度曲线振荡呢?
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。