时间20210502
作者:知道许多的橘子
实现:ResNet34对CIFAR-10数据集的分类
测试集准确度:95.89%
实现框架pytorch
数据增强方法:Normalize+Fix等
训练次数:200
阶段学习率[0-200]:smooth_step(10,40,100,150,epoch_s)
优化器optimizer = torch.optim.SGD(model.parameters(),lr=smooth_step(10,40,100,150,epoch_s), momentum=0.9,weight_decay=1e-5)
如果感觉算力不够用了,或者心疼自己电脑了!
可以用我实验室的算力,试试呢!
害,谁叫我的算力都用不完呢!
支持所有框架!实际上框架都配置好了!
傻瓜式云计算!
Tesla v100 1卡,2卡,4卡,8卡
内存16-128G
cpu:8-24核
想要?加个微信:15615634293
欢迎打扰!
import os
import torch
import torch.nn as nn
import torchvision
from torchvision import datasets,transforms
import time
from torch.nn import functional as F
from math import floor, ceil
import math
import numpy as np
import sys
sys.path.append(r'/home/megstudio/workspace/')
from FMIX.fmix import sample_and_apply, sample_mask
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(device)
import random
num_epochs = 200
batch_size = 100
tbatch_size = 5000
test_name = '/_R34_SJGB3_BLIN_S_C10'
transform_train = transforms.Compose([
transforms.RandomCrop(32, padding=4),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])
transform_test = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])
cifar10_train = torchvision.datasets.CIFAR10(root='/home/megstudio/dataset', train=True, download=False, transform=transform_train)
cifar10_test = torchvision.datasets.CIFAR10(root='/home/megstudio/dataset', train=False, download=False, transform=transform_test)
train_loader = torch.utils.data.DataLoader(cifar10_train, batch_size=batch_size, shuffle=True, num_workers=2)
test_loader = torch.utils.data.DataLoader(cifar10_test, batch_size=tbatch_size, shuffle=False, num_workers=2)
class BasicBlock(nn.Module):
expansion = 1
def __init__(self, in_planes, planes, stride=1):
super(BasicBlock, self).__init__()
self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3,
stride=stride, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(planes)
self.conv2 = nn.Conv2d(planes, planes, kernel_size=3,
stride=1, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(planes)
self.shortcut = nn.Sequential()
if stride != 1 or in_planes != self.expansion*planes:
self.shortcut = nn.Sequential(
nn.Conv2d(in_planes, self.expansion*planes,
kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(self.expansion*planes)
)
def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
out += self.shortcut(x)
out = F.relu(out)
return out
class Bottleneck(nn.Module):
expansion = 4
def __init__(self, in_planes, planes, stride=1):
super(Bottleneck, self).__init__()
self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=1, bias=False)
self.bn1 = nn.BatchNorm2d(planes)
self.conv2 = nn.Conv2d(planes, planes, kernel_size=3,
stride=stride, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(planes)
self.conv3 = nn.Conv2d(planes, self.expansion*planes,
kernel_size=1, bias=False)
self.bn3 = nn.BatchNorm2d(self.expansion*planes)
self.shortcut = nn.Sequential()
if stride != 1 or in_planes != self.expansion*planes:
self.shortcut = nn.Sequential(
nn.Conv2d(in_planes, self.expansion*planes,
kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(self.expansion*planes)
)
def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = F.relu(self.bn2(self.conv2(out)))
out = self.bn3(self.conv3(out))
out += self.shortcut(x)
out = F.relu(out)
return out
class ResNet(nn.Module):
def __init__(self, block, num_blocks, num_classes=10):
super(ResNet, self).__init__()
self.in_planes = 64
self.conv1 = nn.Conv2d(3, 64, kernel_size=3,
stride=1, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(64)
self.layer1 = self._make_layer(block, 64, num_blocks[0], stride=1)
self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)
self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)
self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)
self.linear = nn.Linear(512*block.expansion, num_classes)
def _make_layer(self, block, planes, num_blocks, stride):
strides = [stride] + [1]*(num_blocks-1)
layers = []
for stride in strides:
layers.append(block(self.in_planes, planes, stride))
self.in_planes = planes * block.expansion
return nn.Sequential(*layers)
def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.layer1(out)
out = self.layer2(out)
out = self.layer3(out)
out = self.layer4(out)
out = F.avg_pool2d(out, 4)
out = out.view(out.size(0), -1)
out = self.linear(out)
return out
def ResNet18():
return ResNet(BasicBlock, [2,2,2,2])
def ResNet34():
return ResNet(BasicBlock, [3,4,6,3])
def ResNet50():
return ResNet(Bottleneck, [3,4,6,3])
def ResNet101():
return ResNet(Bottleneck, [3,4,23,3])
def ResNet152():
return ResNet(Bottleneck, [3,8,36,3])
def smooth_step(a,b,c,d,x):
level_s=0.01
level_m=0.1
level_n=0.01
level_r=0.005
if x<=a:
return level_s
if a<x<=b:
return (((x-a)/(b-a))*(level_m-level_s)+level_s)
if b<x<=c:
return level_m
if c<x<=d:
return level_n
if d<x:
return level_r
def update_lr(optimizer, lr):
for param_group in optimizer.param_groups:
param_group['lr'] = lr
def test(model,test_loader):
model.eval()
with torch.no_grad():
correct = 0
total = 0
for images, labels in test_loader:
images = images.to(device)
labels = labels.to(device)
outputs= model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
acc=100 * correct / total
print('Accuracy of the model on the test images: {} %'.format(acc))
return acc
def mkdir(path):
folder = os.path.exists(path)
if not folder:
os.makedirs(path)
print("--- new folder... ---")
print("--- OK ---")
else:
print("--- There is this folder! ---")
path = os.getcwd()
path = path+test_name
print(path)
mkdir(path)
try:
model = torch.load(path+'/model.pkl').to(device)
epoch_s = np.load(path+'/learning_rate.npy')
print(epoch_s)
train_loss = np.load(path+'/test_acc.npy').tolist()
test_acc = np.load(path+'/test_acc.npy').tolist()
print("--- There is a model in the folder... ---")
except:
print("--- Create a new model... ---")
epoch_s = 0
model = ResNet34().to(device)
train_loss=[]
test_acc=[]
def saveModel(model,epoch,test_acc,train_loss):
torch.save(model, path+'/model.pkl')
epoch_save=np.array(epoch)
np.save(path+'/learning_rate.npy',epoch_save)
test_acc=np.array(test_acc)
np.save(path+'/test_acc.npy',test_acc)
train_loss=np.array(train_loss)
np.save(path+'/train_loss.npy',train_loss)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(),lr=smooth_step(10,40,100,150,epoch_s), momentum=0.9,weight_decay=1e-5)
total_step = len(train_loader)
for epoch in range(epoch_s, num_epochs):
in_epoch = time.time()
for i, (images, labels) in enumerate(train_loader):
images, index, lam = sample_and_apply(images, alpha=1, decay_power=3, shape=(32,32))
images = images.type(torch.FloatTensor)
shuffled_label = labels[index].to(device)
images = images.to(device)
labels = labels.to(device)
outputs = model(images)
loss = lam*criterion(outputs, labels) + (1-lam)*criterion(outputs, shuffled_label)
optimizer.zero_grad()
loss.backward(retain_graph=False)
optimizer.step()
if (i + 1) % 100 == 0:
print("Epoch [{}/{}], Step [{}/{}] Loss: {:.4f}"
.format(epoch + 1, num_epochs, i + 1, total_step, loss.item()))
train_loss.append(loss.item())
acctemp = test(model, test_loader)
test_acc.append(acctemp)
curr_lr = smooth_step(10, 40, 100, 150, epoch)
update_lr(optimizer, curr_lr)
saveModel(model, epoch, test_acc, train_loss)
out_epoch = time.time()
print(f"use {(out_epoch-in_epoch)//60}min{(out_epoch-in_epoch)%60}s")
test(model, train_loader)