刚开始就全屏:
train_list.txt
train/n01532829/n0153282900000005.jpg 0
train/n01532829/n0153282900000006.jpg 0
train/n01532829/n0153282900000007.jpg 0
train/n01532829/n0153282900000010.jpg 0
train/n01532829/n0153282900000014.jpg 0
train/n01532829/n0153282900000015.jpg 0
train/n01532829/n0153282900000016.jpg 0
val_list.txt
val/n01855672/n0185567200000003.jpg 0
val/n01855672/n0185567200000004.jpg 0
val/n01855672/n0185567200000010.jpg 0
val/n01855672/n0185567200000013.jpg 0
val/n01855672/n0185567200000016.jpg 0
val/n01855672/n0185567200000017.jpg 0
val/n01855672/n0185567200000019.jpg 0
val/n01855672/n0185567200000020.jpg 0
val/n01855672/n0185567200000021.jpg 0
val/n01855672/n0185567200000022.jpg 0
val/n01855672/n0185567200000023.jpg 0
val/n01855672/n0185567200000024.jpg 0
val/n01855672/n0185567200000027.jpg 0
val/n01855672/n0185567200000028.jpg 0
val/n01855672/n0185567200000031.jpg 0
val/n01855672/n0185567200000036.jpg 0
val/n01855672/n0185567200000042.jpg 0
dataset.py
import torch
import torchvision
from torchvision import transforms, utils
import pandas as pd
import os
from skimage import io, transform
from torch.utils.data import Dataset, DataLoader
import numpy as np
from PIL import Image
import random
import json
class NoisyDataset(Dataset):
def __init__(self, root, filename, transform=None, mix=False, plus=False):
self.ids = []
self.targets = []
f = open(filename)
for line in f:
info = line.strip().split(' ')
self.ids.append(info[0])
self.targets.append(np.array(info[1], dtype=np.int32))
self.root_dir = root
self.transform = transform
self.mix = mix
self.plus = plus
def __len__(self):
return len(self.ids)
def __getitem__(self, idx):
if self.mix:
while True:
index1 = random.randint(0, len(self.ids) - 1)
index2 = random.randint(0, len(self.ids) - 1)
label1 = self.targets[index1]
label2 = self.targets[index2]
if label1 != label2:
break
image_name1 = os.path.join(self.root_dir, self.ids[index1])
image_name2 = os.path.join(self.root_dir, self.ids[index2])
image1 = Image.open(image_name1).convert('RGB')
image2 = Image.open(image_name2).convert('RGB')
r = np.array(random.random())
if self.plus:
g1 = np.std(image1)
g2 = np.std(image2)
p = 1.0 / (1 + g1 / g2 * (1-r) / r)
image = ((image1) * p + image2 * (1-p))/ np.sqrt(p ** 2 + (1-p) ** 2).astype(np.float32)
else:
image = (image1 * r + image2 * (1-r)).astype(np.float32)
if self.transform:
image = self.transform(image)
landmarks1 = torch.from_numpy(label1)
landmarks2 = torch.from_numpy(label2)
return image,landmarks1.long(), landmarks2.long(), r
else:
img_name = os.path.join(self.root_dir,self.ids[idx])
image = Image.open(img_name).convert('RGB')
landmarks = torch.from_numpy(self.targets[idx])
if self.transform:
image = self.transform(image)
return image, landmarks.long()
def get_ids(self):
return self.ids
cifar.py
# -*-coding:utf-8-*-
'''
Training script for CIFAR-10/100
Copyright (c) Wei YANG, 2017
'''
from __future__ import print_function
import argparse
import os
import shutil
import time
import random
import torch
import torch.nn as nn
import torch.nn.parallel
import torch.backends.cudnn as cudnn
import torch.optim as optim
import torch.utils.data as data
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import models.cifar as models
from utils import Bar, Logger, AverageMeter, accuracy, mkdir_p, savefig
model_names = sorted(name for name in models.__dict__
if name.islower() and not name.startswith("__")
and callable(models.__dict__[name]))
parser = argparse.ArgumentParser(description='PyTorch CIFAR10/100 Training')
# Datasets
parser.add_argument('-d', '--dataset', default='cifar10', type=str)
parser.add_argument('-j', '--workers', default=4, type=int, metavar='N',
help='number of data loading workers (default: 4)')
# Optimization options
parser.add_argument('--epochs', default=300, type=int, metavar='N',
help='number of total epochs to run')
parser.add_argument('--start-epoch', default=0, type=int, metavar='N',
help='manual epoch number (useful on restarts)')
parser.add_argument('--train-batch', default=128, type=int, metavar='N',
help='train batchsize')
parser.add_argument('--test-batch', default=100, type=int, metavar='N',
help='test batchsize')
parser.add_argument('--lr', '--learning-rate', default=0.1, type=float,
metavar='LR', help='initial learning rate')
parser.add_argument('--drop', '--dropout', default=0, type=float,
metavar='Dropout', help='Dropout ratio')
parser.add_argument('--schedule', type=int, nargs='+', default=[150, 225],
help='Decrease learning rate at these epochs.')
parser.add_argument('--gamma', type=float, default=0.1, help='LR is multiplied by gamma on schedule.')
parser.add_argument('--momentum', default=0.9, type=float, metavar='M',
help='momentum')
parser.add_argument('--weight-decay', '--wd', default=5e-4, type=float,
metavar='W', help='weight decay (default: 1e-4)')
# Checkpoints
parser.add_argument('-c', '--checkpoint', default='checkpoint/cifar', type=str, metavar='PATH',
help='path to save checkpoint (default: checkpoint)')
parser.add_argument('--resume', default='', type=str, metavar='PATH',
help='path to latest checkpoint (default: none)')
# Architecture
parser.add_argument('--arch', '-a', metavar='ARCH', default='resnet_20',
choices=model_names,
help='model architecture: ' +
' | '.join(model_names) +
' (default: resnet18)')
parser.add_argument('--depth', type=int, default=29, help='Model depth.')
parser.add_argument('--block-name', type=str, default='BasicBlock',
help='the building block for Resnet and Preresnet: BasicBlock, Bottleneck (default: Basicblock for cifar10/cifar100)')
parser.add_argument('--cardinality', type=int, default=8, help='Model cardinality (group).')
parser.add_argument('--widen-factor', type=int, default=4, help='Widen factor. 4 -> 64, 8 -> 128, ...')
parser.add_argument('--growthRate', type=int, default=12, help='Growth rate for DenseNet.')
parser.add_argument('--compressionRate', type=int, default=2, help='Compression Rate (theta) for DenseNet.')
# Miscs
parser.add_argument('--manualSeed', type=int, help='manual seed')
parser.add_argument('-e', '--evaluate', dest='evaluate', action='store_true',
help='evaluate model on validation set')
#Device options
parser.add_argument('--gpu-id', default='0', type=str,
help='id(s) for CUDA_VISIBLE_DEVICES')
#show Bar
parser.add_argument('--barflag', type=bool, default=True)
args = parser.parse_args()
state = {k: v for k, v in args._get_kwargs()}
# Validate dataset
assert args.dataset == 'cifar10' or args.dataset == 'cifar100', 'Dataset can only be cifar10 or cifar100.'
# Use CUDA
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id
use_cuda = torch.cuda.is_available()
# Random seed
if args.manualSeed is None:
args.manualSeed = random.randint(1, 10000)
random.seed(args.manualSeed)
torch.manual_seed(args.manualSeed)
if use_cuda:
torch.cuda.manual_seed_all(args.manualSeed)
#num_workers:使用多进程加载的进程数,0代表不使用多进程
#pin_memory:是否将数据保存在pin memory区,pin memory中的数据转到GPU会快一些
#(input, **kwargs)传入
kwargs = {'num_workers': args.workers, 'pin_memory': True} if use_cuda else {}
best_acc = 0 # best test accuracy
def main():
global best_acc
start_epoch = args.start_epoch # start from epoch 0 or last checkpoint epoch
if not os.path.isdir(args.checkpoint):
mkdir_p(args.checkpoint)
# Data
print('==> Preparing dataset %s' % args.dataset)
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)),
])
if args.dataset == 'cifar10':
dataloader = datasets.CIFAR10
num_classes = 10
else:
dataloader = datasets.CIFAR100
num_classes = 100
trainset = dataloader(root='./data', train=True, download=True, transform=transform_train)
trainloader = data.DataLoader(trainset, batch_size=args.train_batch, shuffle=True, **kwargs)
testset = dataloader(root='./data', train=False, download=False, transform=transform_test)
testloader = data.DataLoader(testset, batch_size=args.test_batch, shuffle=False, **kwargs)
# Model
print("==> creating model '{}'".format(args.arch))
if args.arch.startswith('resnext'):
model = models.__dict__[args.arch](
cardinality=args.cardinality,
num_classes=num_classes,
depth=args.depth,
widen_factor=args.widen_factor,
dropRate=args.drop,
)
elif args.arch.startswith('densenet'):
model = models.__dict__[args.arch](
num_classes=num_classes,
depth=args.depth,
growthRate=args.growthRate,
compressionRate=args.compressionRate,
dropRate=args.drop,
)
elif args.arch.startswith('wrn'):
model = models.__dict__[args.arch](
num_classes=num_classes,
depth=args.depth,
widen_factor=args.widen_factor,
dropRate=args.drop,
)
elif args.arch.endswith('resnet'):
model = models.__dict__[args.arch](
num_classes=num_classes,
depth=args.depth,
block_name=args.block_name,
)
else:
model = models.__dict__[args.arch](num_classes=num_classes)
model = torch.nn.DataParallel(model).cuda()
cudnn.benchmark = True
print(' Total params: %.2fM' % (sum(p.numel() for p in model.parameters())/1000000.0))
#=LogSoftMax+NLLLoss
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum, weight_decay=args.weight_decay)
# Resume
title = 'cifar-10-' + args.arch
if args.resume:
# Load checkpoint.
print('==> Resuming from checkpoint..')
assert os.path.isfile(args.resume), 'Error: no checkpoint directory found!'
args.checkpoint = os.path.dirname(args.resume)
checkpoint = torch.load(args.resume)
best_acc = checkpoint['best_acc']
start_epoch = checkpoint['epoch']
model.load_state_dict(checkpoint['state_dict'])
optimizer.load_state_dict(checkpoint['optimizer'])
logger = Logger(os.path.join(args.checkpoint, 'log.txt'), title=title, resume=True)
else:
logger = Logger(os.path.join(args.checkpoint, 'log.txt'), title=title)
logger.set_names(['Learning Rate', 'Train Loss', 'Valid Loss', 'Train Acc.', 'Valid Acc.'])
if args.evaluate:
print('\nEvaluation only')
test_loss, test_acc = test(testloader, model, criterion, start_epoch, use_cuda)
print(' Test Loss: %.8f, Test Acc: %.2f' % (test_loss, test_acc))
return
# Train and val
for epoch in range(start_epoch, args.epochs):
adjust_learning_rate(optimizer, epoch)
print('\nEpoch: [%d | %d] LR: %f' % (epoch + 1, args.epochs, state['lr']))
train_loss, train_acc = train(trainloader, model, criterion, optimizer, epoch, use_cuda)
test_loss, test_acc = test(testloader, model, criterion, epoch, use_cuda)
# append logger file
logger.append([state['lr'], train_loss, test_loss, train_acc, test_acc])
# save model
is_best = test_acc > best_acc
best_acc = max(test_acc, best_acc)
save_checkpoint({
'epoch': epoch + 1,
'state_dict': model.state_dict(),
'acc': test_acc,
'best_acc': best_acc,
'optimizer' : optimizer.state_dict(),
}, is_best, checkpoint=args.checkpoint)
logger.close()
logger.plot()
savefig(os.path.join(args.checkpoint, 'log.eps'))
print('Best acc:')
print(best_acc)
def train(trainloader, model, criterion, optimizer, epoch, use_cuda):
# switch to train mode
model.train()
batch_time = AverageMeter()
data_time = AverageMeter()
losses = AverageMeter()
top1 = AverageMeter()
top5 = AverageMeter()
end = time.time()
if args.barflag:
bar = Bar('Processing', max=len(trainloader))
for batch_idx, (inputs, targets) in enumerate(trainloader):
# measure data loading time
data_time.update(time.time() - end)
if use_cuda:
inputs, targets = inputs.cuda(), targets.cuda(async=True)
###############################
###############################
###############################
###############################
###############################
#inputs, targets = torch.autograd.Variable(inputs), torch.autograd.Variable(targets)
# compute output
outputs = model(inputs)
loss = criterion(outputs, targets)
# measure accuracy and record loss
prec1, prec5 = accuracy(outputs.data, targets.data, topk=(1, 5))
###############################
###############################
###############################
###############################
###############################
#loss.data[0] = loss.item()
#inputs.size(0) = inputs.shape[0]
#prec1[0] = prec1
#prec5[0] = prec5
losses.update(loss.item(), inputs.size(0))
top1.update(prec1, inputs.size(0))
top5.update(prec5, inputs.size(0))
# compute gradient and do SGD step
optimizer.zero_grad()
loss.backward()
optimizer.step()
# measure elapsed time
batch_time.update(time.time() - end)
end = time.time()
# plot progress
if args.barflag:
bar.suffix = '({batch}/{size}) Data: {data:.3f}s | Batch: {bt:.3f}s | Total: {total:} | ETA: {eta:} | Loss: {loss:.4f} | top1: {top1: .4f} | top5: {top5: .4f}'.format(
batch=batch_idx + 1,
size=len(trainloader),
data=data_time.avg,
bt=batch_time.avg,
total=bar.elapsed_td,
eta=bar.eta_td,
loss=losses.avg,
top1=top1.avg,
top5=top5.avg,
)
bar.next()
if args.barflag:
bar.finish()
return (losses.avg, top1.avg)
def test(testloader, model, criterion, epoch, use_cuda):
global best_acc
batch_time = AverageMeter()
data_time = AverageMeter()
losses = AverageMeter()
top1 = AverageMeter()
top5 = AverageMeter()
# switch to evaluate mode
model.eval()
###############################
###############################
###############################
###############################
###############################
with torch.no_grad():
end = time.time()
if args.barflag:
bar = Bar('Processing', max=len(testloader))
for batch_idx, (inputs, targets) in enumerate(testloader):
# measure data loading time
data_time.update(time.time() - end)
if use_cuda:
inputs, targets = inputs.cuda(), targets.cuda()
###############################
###############################
###############################
###############################
###############################
#inputs, targets = torch.autograd.Variable(inputs, volatile=True), torch.autograd.Variable(targets)
# compute output
outputs = model(inputs)
loss = criterion(outputs, targets)
# measure accuracy and record loss
prec1, prec5 = accuracy(outputs.data, targets.data, topk=(1, 5))
###############################
###############################
###############################
###############################
###############################
#loss.data[0] = loss.item()
#prec1[0] = prec1
#prec5[0] = prec5
losses.update(loss.item(), inputs.size(0))
top1.update(prec1, inputs.size(0))
top5.update(prec5, inputs.size(0))
# measure elapsed time
batch_time.update(time.time() - end)
end = time.time()
# plot progress
if args.barflag:
bar.suffix = '({batch}/{size}) Data: {data:.3f}s | Batch: {bt:.3f}s | Total: {total:} | ETA: {eta:} | Loss: {loss:.4f} | top1: {top1: .4f} | top5: {top5: .4f}'.format(
batch=batch_idx + 1,
size=len(testloader),
data=data_time.avg,
bt=batch_time.avg,
total=bar.elapsed_td,
eta=bar.eta_td,
loss=losses.avg,
top1=top1.avg,
top5=top5.avg,
)
bar.next()
if args.barflag:
bar.finish()
return (losses.avg, top1.avg)
def save_checkpoint(state, is_best, checkpoint='checkpoint', filename='checkpoint.pth.tar'):
filepath = os.path.join(checkpoint, filename)
torch.save(state, filepath)
if is_best:
shutil.copyfile(filepath, os.path.join(checkpoint, 'model_best.pth.tar'))
def adjust_learning_rate(optimizer, epoch):
global state
if epoch in args.schedule:
state['lr'] *= args.gamma
for param_group in optimizer.param_groups:
param_group['lr'] = state['lr']
if __name__ == '__main__':
main()
imagenet_datasetsImageFolder.py
# -*-coding:utf-8-*-
'''
Training script for ImageNet
Copyright (c) Wei YANG, 2017
'''
from __future__ import print_function
import argparse
import os
import shutil
import time
import random
import torch
import torch.nn as nn
import torch.nn.parallel
import torch.backends.cudnn as cudnn
import torch.optim as optim
import torch.utils.data as data
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torchvision.models as models
import models.imagenet as customized_models
from utils import Bar, Logger, AverageMeter, accuracy, mkdir_p, savefig
#Python islower() 方法检测字符串是否由小写字母组成
#Python startswith() 方法用于检查字符串是否是以指定子字符串开头,如果是则返回 True,否则返回 False
#callable功能为判断返回对象是否可调用(即某种功能)
#sorted() 函数对所有可迭代的对象进行排序操作。
# Models
testa = models.__dict__
default_model_names = sorted(name for name in models.__dict__
if name.islower() and not name.startswith("__")
and callable(models.__dict__[name]))
customized_models_names = sorted(name for name in customized_models.__dict__
if name.islower() and not name.startswith("__")
and callable(customized_models.__dict__[name]))
for name in customized_models.__dict__:
if name.islower() and not name.startswith("__") and callable(customized_models.__dict__[name]):
models.__dict__[name] = customized_models.__dict__[name]
#保证只能选择model_names内的
model_names = default_model_names + customized_models_names
# Parse arguments
parser = argparse.ArgumentParser(description='PyTorch ImageNet Training')
# Datasets
parser.add_argument('-d', '--data', default='/home/spple/data/mini-imagenet', type=str)
parser.add_argument('-j', '--workers', default=4, type=int, metavar='N',
help='number of data loading workers (default: 4)')
# Optimization options
parser.add_argument('--epochs', default=90, type=int, metavar='N',
help='number of total epochs to run')
parser.add_argument('--start-epoch', default=0, type=int, metavar='N',
help='manual epoch number (useful on restarts)')
parser.add_argument('--train-batch', default=16, type=int, metavar='N',
help='train batchsize (default: 256)')
parser.add_argument('--test-batch', default=16, type=int, metavar='N',
help='test batchsize (default: 200)')
parser.add_argument('--lr', '--learning-rate', default=0.1, type=float,
metavar='LR', help='initial learning rate')
parser.add_argument('--drop', '--dropout', default=0, type=float,
metavar='Dropout', help='Dropout ratio')
parser.add_argument('--schedule', type=int, nargs='+', default=[150, 225],
help='Decrease learning rate at these epochs.')
parser.add_argument('--gamma', type=float, default=0.1, help='LR is multiplied by gamma on schedule.')
parser.add_argument('--momentum', default=0.9, type=float, metavar='M',
help='momentum')
parser.add_argument('--weight-decay', '--wd', default=1e-4, type=float,
metavar='W', help='weight decay (default: 1e-4)')
# Checkpoints
parser.add_argument('-c', '--checkpoint', default='checkpoint', type=str, metavar='PATH',
help='path to save checkpoint (default: checkpoint)')
parser.add_argument('--resume', default='', type=str, metavar='PATH',
help='path to latest checkpoint (default: none)')
# Architecture
parser.add_argument('--arch', '-a', metavar='ARCH', default='resnet18',
choices=model_names,
help='model architecture: ' +
' | '.join(model_names) +
' (default: resnet18)')
parser.add_argument('--depth', type=int, default=29, help='Model depth.')
parser.add_argument('--cardinality', type=int, default=32, help='ResNet cardinality (group).')
parser.add_argument('--base-width', type=int, default=4, help='ResNet base width.')
parser.add_argument('--widen-factor', type=int, default=4, help='Widen factor. 4 -> 64, 8 -> 128, ...')
# Miscs
parser.add_argument('--manualSeed', type=int, help='manual seed')
parser.add_argument('-e', '--evaluate', dest='evaluate', action='store_true',
help='evaluate model on validation set')
parser.add_argument('--pretrained', default=True, dest='pretrained', action='store_true',
help='use pre-trained model')
#Device options
parser.add_argument('--gpu-id', default='0', type=str,
help='id(s) for CUDA_VISIBLE_DEVICES')
args = parser.parse_args()
state = {k: v for k, v in args._get_kwargs()}
# Use CUDA
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id
use_cuda = torch.cuda.is_available()
# Random seed
if args.manualSeed is None:
args.manualSeed = random.randint(1, 10000)
random.seed(args.manualSeed)
torch.manual_seed(args.manualSeed)
if use_cuda:
torch.cuda.manual_seed_all(args.manualSeed)
kwargs = {'num_workers': args.workers, 'pin_memory': True} if use_cuda else {}
best_acc = 0 # best test accuracy
def main():
global best_acc
start_epoch = args.start_epoch # start from epoch 0 or last checkpoint epoch
if not os.path.isdir(args.checkpoint):
mkdir_p(args.checkpoint)
# Data loading code
traindir = os.path.join(args.data, 'train')
valdir = os.path.join(args.data, 'val')
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
train_loader = torch.utils.data.DataLoader(
datasets.ImageFolder(traindir, transforms.Compose([
###############################
###############################
###############################
###############################
###############################
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
normalize,
])),
batch_size=args.train_batch, shuffle=True, **kwargs)
#num_workers=args.workers, pin_memory=True)
val_loader = torch.utils.data.DataLoader(
datasets.ImageFolder(valdir, transforms.Compose([
###############################
###############################
###############################
###############################
###############################
#transforms.Scale(256),
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
normalize,
])),
batch_size=args.test_batch, shuffle=False, **kwargs)
#num_workers=args.workers, pin_memory=True)
# create model
if args.pretrained:
print("=> using pre-trained model '{}'".format(args.arch))
model = models.__dict__[args.arch](pretrained=True)
elif args.arch.startswith('resnext'):
model = models.__dict__[args.arch](
baseWidth=args.base_width,
cardinality=args.cardinality,
)
else:
print("=> creating model '{}'".format(args.arch))
model = models.__dict__[args.arch]()
if args.arch.startswith('alexnet') or args.arch.startswith('vgg'):
model.features = torch.nn.DataParallel(model.features)
model.cuda()
else:
model = torch.nn.DataParallel(model).cuda()
cudnn.benchmark = True
print(' Total params: %.2fM' % (sum(p.numel() for p in model.parameters())/1000000.0))
# define loss function (criterion) and optimizer
criterion = nn.CrossEntropyLoss().cuda()
optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum, weight_decay=args.weight_decay)
# Resume
title = 'ImageNet-' + args.arch
if args.resume:
# Load checkpoint.
print('==> Resuming from checkpoint..')
assert os.path.isfile(args.resume), 'Error: no checkpoint directory found!'
args.checkpoint = os.path.dirname(args.resume)
checkpoint = torch.load(args.resume)
best_acc = checkpoint['best_acc']
start_epoch = checkpoint['epoch']
model.load_state_dict(checkpoint['state_dict'])
optimizer.load_state_dict(checkpoint['optimizer'])
logger = Logger(os.path.join(args.checkpoint, 'log.txt'), title=title, resume=True)
else:
logger = Logger(os.path.join(args.checkpoint, 'log.txt'), title=title)
logger.set_names(['Learning Rate', 'Train Loss', 'Valid Loss', 'Train Acc.', 'Valid Acc.'])
if args.evaluate:
print('\nEvaluation only')
test_loss, test_acc = test(val_loader, model, criterion, start_epoch, use_cuda)
print(' Test Loss: %.8f, Test Acc: %.2f' % (test_loss, test_acc))
return
# Train and val
for epoch in range(start_epoch, args.epochs):
adjust_learning_rate(optimizer, epoch)
print('\nEpoch: [%d | %d] LR: %f' % (epoch + 1, args.epochs, state['lr']))
train_loss, train_acc = train(train_loader, model, criterion, optimizer, epoch, use_cuda)
test_loss, test_acc = test(val_loader, model, criterion, epoch, use_cuda)
# append logger file
logger.append([state['lr'], train_loss, test_loss, train_acc, test_acc])
# save model
is_best = test_acc > best_acc
best_acc = max(test_acc, best_acc)
save_checkpoint({
'epoch': epoch + 1,
'state_dict': model.state_dict(),
'acc': test_acc,
'best_acc': best_acc,
'optimizer' : optimizer.state_dict(),
}, is_best, checkpoint=args.checkpoint)
logger.close()
logger.plot()
savefig(os.path.join(args.checkpoint, 'log.eps'))
print('Best acc:')
print(best_acc)
def train(train_loader, model, criterion, optimizer, epoch, use_cuda):
# switch to train mode
model.train()
batch_time = AverageMeter()
data_time = AverageMeter()
losses = AverageMeter()
top1 = AverageMeter()
top5 = AverageMeter()
end = time.time()
bar = Bar('Processing', max=len(train_loader))
for batch_idx, (inputs, targets) in enumerate(train_loader):
# measure data loading time
data_time.update(time.time() - end)
if use_cuda:
inputs, targets = inputs.cuda(), targets.cuda(async=True)
###############################
###############################
###############################
###############################
###############################
#inputs, targets = torch.autograd.Variable(inputs), torch.autograd.Variable(targets)
# compute output
outputs = model(inputs)
loss = criterion(outputs, targets)
# measure accuracy and record loss
prec1, prec5 = accuracy(outputs.data, targets.data, topk=(1, 5))
###############################
###############################
###############################
###############################
###############################
#loss.data[0] = loss.item()
#inputs.size(0) = inputs.shape[0]
#prec1[0] = prec1
#prec5[0] = prec5
losses.update(loss.item(), inputs.size(0))
top1.update(prec1, inputs.size(0))
top5.update(prec5, inputs.size(0))
# compute gradient and do SGD step
optimizer.zero_grad()
loss.backward()
optimizer.step()
# measure elapsed time
batch_time.update(time.time() - end)
end = time.time()
# plot progress
bar.suffix = '({batch}/{size}) Data: {data:.3f}s | Batch: {bt:.3f}s | Total: {total:} | ETA: {eta:} | Loss: {loss:.4f} | top1: {top1: .4f} | top5: {top5: .4f}'.format(
batch=batch_idx + 1,
size=len(train_loader),
data=data_time.val,
bt=batch_time.val,
total=bar.elapsed_td,
eta=bar.eta_td,
loss=losses.avg,
top1=top1.avg,
top5=top5.avg,
)
bar.next()
bar.finish()
return (losses.avg, top1.avg)
def test(val_loader, model, criterion, epoch, use_cuda):
global best_acc
batch_time = AverageMeter()
data_time = AverageMeter()
losses = AverageMeter()
top1 = AverageMeter()
top5 = AverageMeter()
# switch to evaluate mode
model.eval()
with torch.no_grad():
end = time.time()
bar = Bar('Processing', max=len(val_loader))
for batch_idx, (inputs, targets) in enumerate(val_loader):
# measure data loading time
data_time.update(time.time() - end)
if use_cuda:
inputs, targets = inputs.cuda(), targets.cuda()
###############################
###############################
###############################
###############################
###############################
#inputs, targets = torch.autograd.Variable(inputs, volatile=True), torch.autograd.Variable(targets)
# compute output
outputs = model(inputs)
loss = criterion(outputs, targets)
# measure accuracy and record loss
prec1, prec5 = accuracy(outputs.data, targets.data, topk=(1, 5))
###############################
###############################
###############################
###############################
###############################
#loss.data[0] = loss.item()
#inputs.size(0) = inputs.shape[0]
#prec1[0] = prec1
#prec5[0] = prec5
losses.update(loss.item(), inputs.size(0))
top1.update(prec1, inputs.size(0))
top5.update(prec5, inputs.size(0))
# measure elapsed time
batch_time.update(time.time() - end)
end = time.time()
# plot progress
bar.suffix = '({batch}/{size}) Data: {data:.3f}s | Batch: {bt:.3f}s | Total: {total:} | ETA: {eta:} | Loss: {loss:.4f} | top1: {top1: .4f} | top5: {top5: .4f}'.format(
batch=batch_idx + 1,
size=len(val_loader),
data=data_time.avg,
bt=batch_time.avg,
total=bar.elapsed_td,
eta=bar.eta_td,
loss=losses.avg,
top1=top1.avg,
top5=top5.avg,
)
bar.next()
bar.finish()
return (losses.avg, top1.avg)
def save_checkpoint(state, is_best, checkpoint='checkpoint', filename='checkpoint.pth.tar'):
filepath = os.path.join(checkpoint, filename)
torch.save(state, filepath)
if is_best:
shutil.copyfile(filepath, os.path.join(checkpoint, 'model_best.pth.tar'))
def adjust_learning_rate(optimizer, epoch):
global state
if epoch in args.schedule:
state['lr'] *= args.gamma
for param_group in optimizer.param_groups:
param_group['lr'] = state['lr']
if __name__ == '__main__':
main()
imagenet_datasetsDataLoader.py
# -*-coding:utf-8-*-
'''
Training script for ImageNet
Copyright (c) Wei YANG, 2017
'''
from __future__ import print_function
import argparse
import os
import shutil
import time
import random
import torch
import torch.nn as nn
import torch.nn.parallel
import torch.backends.cudnn as cudnn
import torch.optim as optim
import torch.utils.data as data
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torchvision.models as models
import models.imagenet as customized_models
from utils import Bar, Logger, AverageMeter, accuracy, mkdir_p, savefig
from dataset import NoisyDataset
#Python islower() 方法检测字符串是否由小写字母组成
#Python startswith() 方法用于检查字符串是否是以指定子字符串开头,如果是则返回 True,否则返回 False
#callable功能为判断返回对象是否可调用(即某种功能)
#sorted() 函数对所有可迭代的对象进行排序操作。
# Models
testa = models.__dict__
default_model_names = sorted(name for name in models.__dict__
if name.islower() and not name.startswith("__")
and callable(models.__dict__[name]))
customized_models_names = sorted(name for name in customized_models.__dict__
if name.islower() and not name.startswith("__")
and callable(customized_models.__dict__[name]))
for name in customized_models.__dict__:
if name.islower() and not name.startswith("__") and callable(customized_models.__dict__[name]):
models.__dict__[name] = customized_models.__dict__[name]
#保证只能选择model_names内的
model_names = default_model_names + customized_models_names
# Parse arguments
parser = argparse.ArgumentParser(description='PyTorch ImageNet Training')
# Datasets
parser.add_argument('-d', '--data', default='/home/spple/data/mini-imagenet', type=str)
parser.add_argument('-j', '--workers', default=4, type=int, metavar='N',
help='number of data loading workers (default: 4)')
parser.add_argument('--root', default='/home/spple/data/mini-imagenet', type=str,
help='root dir of training data')
parser.add_argument('--root-val', default='/home/spple/data/mini-imagenet', type=str,
help='root dir of validation data')
parser.add_argument('--train-list', default='/home/spple/data/mini-imagenet/train_list.txt', type=str,
help='training data list file')
parser.add_argument('--val-list', default='/home/spple/data/mini-imagenet/val_list.txt', type=str,
help='validation data list file')
# Optimization options
parser.add_argument('--epochs', default=90, type=int, metavar='N',
help='number of total epochs to run')
parser.add_argument('--start-epoch', default=0, type=int, metavar='N',
help='manual epoch number (useful on restarts)')
parser.add_argument('--train-batch', default=16, type=int, metavar='N',
help='train batchsize (default: 256)')
parser.add_argument('--test-batch', default=16, type=int, metavar='N',
help='test batchsize (default: 200)')
parser.add_argument('--lr', '--learning-rate', default=0.1, type=float,
metavar='LR', help='initial learning rate')
parser.add_argument('--drop', '--dropout', default=0, type=float,
metavar='Dropout', help='Dropout ratio')
#学习率更改--除衰减之外的更改方式,和gamma配合
parser.add_argument('--schedule', type=int, nargs='+', default=[150, 225],
help='Decrease learning rate at these epochs.')
parser.add_argument('--gamma', type=float, default=0.1, help='LR is multiplied by gamma on schedule.')
parser.add_argument('--momentum', default=0.9, type=float, metavar='M',
help='momentum')
parser.add_argument('--weight-decay', '--wd', default=1e-4, type=float,
metavar='W', help='weight decay (default: 1e-4)')
# Checkpoints
parser.add_argument('-c', '--checkpoint', default='checkpoint/imagenet', type=str, metavar='PATH',
help='path to save checkpoint (default: checkpoint)')
parser.add_argument('--resume', default='', type=str, metavar='PATH',
help='path to latest checkpoint (default: none)')
# Architecture
parser.add_argument('--arch', '-a', metavar='ARCH', default='resnet18',
choices=model_names,
help='model architecture: ' +
' | '.join(model_names) +
' (default: resnet18)')
parser.add_argument('--depth', type=int, default=29, help='Model depth.')
parser.add_argument('--cardinality', type=int, default=32, help='ResNet cardinality (group).')
parser.add_argument('--base-width', type=int, default=4, help='ResNet base width.')
parser.add_argument('--widen-factor', type=int, default=4, help='Widen factor. 4 -> 64, 8 -> 128, ...')
# Miscs
parser.add_argument('--manualSeed', type=int, help='manual seed')
parser.add_argument('-e', '--evaluate', dest='evaluate', action='store_true',
help='evaluate model on validation set')
parser.add_argument('--pretrained', default=True, dest='pretrained', action='store_true',
help='use pre-trained model')
#data-augmentation
parser.add_argument('--data-augmentation', dest='data_augmentation', action='store_true',
help='use data augmentation strategy in training')
#Device options
parser.add_argument('--gpu-id', default='0', type=str,
help='id(s) for CUDA_VISIBLE_DEVICES')
args = parser.parse_args()
state = {k: v for k, v in args._get_kwargs()}
# Use CUDA
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id
use_cuda = torch.cuda.is_available()
# Random seed
if args.manualSeed is None:
args.manualSeed = random.randint(1, 10000)
random.seed(args.manualSeed)
torch.manual_seed(args.manualSeed)
if use_cuda:
torch.cuda.manual_seed_all(args.manualSeed)
kwargs = {'num_workers': args.workers, 'pin_memory': True} if use_cuda else {}
best_acc = 0 # best test accuracy
def main():
global best_acc
start_epoch = args.start_epoch # start from epoch 0 or last checkpoint epoch
if not os.path.isdir(args.checkpoint):
mkdir_p(args.checkpoint)
# Data loading code
traindir = os.path.join(args.data, 'train')
valdir = os.path.join(args.data, 'val')
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
if args.data_augmentation:
transform_train = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.RandomVerticalFlip(),
transforms.Scale(256),
transforms.RandomSizedCrop(224),
transforms.ColorJitter(0.5, 0.5, 0.5),
transforms.RandomRotation(30),
transforms.RandomAffine(30),
transforms.ToTensor(),
normalize
])
else:
transform_train = transforms.Compose([
###############################
###############################
###############################
###############################
###############################
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
normalize,
])
transform_test = transforms.Compose([
###############################
###############################
###############################
###############################
###############################
# transforms.Scale(256),
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
normalize,
])
trainset = NoisyDataset(root=args.root, filename=args.train_list, transform=transform_train)
testset = NoisyDataset(root=args.root_val, filename=args.val_list, transform=transform_test)
train_loader = data.DataLoader(dataset = trainset, batch_size=args.train_batch, shuffle=True, **kwargs)
val_loader = data.DataLoader(dataset = testset, batch_size=args.test_batch, shuffle=False, **kwargs)
# create model
if args.pretrained:
print("=> using pre-trained model '{}'".format(args.arch))
model = models.__dict__[args.arch](pretrained=True)
elif args.arch.startswith('resnext'):
model = models.__dict__[args.arch](
baseWidth=args.base_width,
cardinality=args.cardinality,
)
else:
print("=> creating model '{}'".format(args.arch))
model = models.__dict__[args.arch]()
if args.arch.startswith('alexnet') or args.arch.startswith('vgg'):
model.features = torch.nn.DataParallel(model.features)
model.cuda()
else:
model = torch.nn.DataParallel(model).cuda()
cudnn.benchmark = True
print(' Total params: %.2fM' % (sum(p.numel() for p in model.parameters())/1000000.0))
# define loss function (criterion) and optimizer
criterion = nn.CrossEntropyLoss().cuda()
optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum, weight_decay=args.weight_decay)
# Resume
title = 'ImageNet-' + args.arch
if args.resume:
# Load checkpoint.
print('==> Resuming from checkpoint..')
assert os.path.isfile(args.resume), 'Error: no checkpoint directory found!'
args.checkpoint = os.path.dirname(args.resume)
checkpoint = torch.load(args.resume)
best_acc = checkpoint['best_acc']
start_epoch = checkpoint['epoch']
model.load_state_dict(checkpoint['state_dict'])
optimizer.load_state_dict(checkpoint['optimizer'])
logger = Logger(os.path.join(args.checkpoint, 'log.txt'), title=title, resume=True)
else:
logger = Logger(os.path.join(args.checkpoint, 'log.txt'), title=title)
logger.set_names(['Learning Rate', 'Train Loss', 'Valid Loss', 'Train Acc.', 'Valid Acc.'])
if args.evaluate:
print('\nEvaluation only')
test_loss, test_acc = test(val_loader, model, criterion, start_epoch, use_cuda)
print(' Test Loss: %.8f, Test Acc: %.2f' % (test_loss, test_acc))
return
# Train and val
for epoch in range(start_epoch, args.epochs):
#学习率随迭代次数改变,可不开启
adjust_learning_rate(optimizer, epoch)
print('\nEpoch: [%d | %d] LR: %f' % (epoch + 1, args.epochs, state['lr']))
train_loss, train_acc = train(train_loader, model, criterion, optimizer, epoch, use_cuda)
test_loss, test_acc = test(val_loader, model, criterion, epoch, use_cuda)
# append logger file
logger.append([state['lr'], train_loss, test_loss, train_acc, test_acc])
# save model
is_best = test_acc > best_acc
best_acc = max(test_acc, best_acc)
save_checkpoint({
'epoch': epoch + 1,
'state_dict': model.state_dict(),
'acc': test_acc,
'best_acc': best_acc,
'optimizer' : optimizer.state_dict(),
}, is_best, checkpoint=args.checkpoint)
logger.close()
logger.plot()
savefig(os.path.join(args.checkpoint, 'log.eps'))
print('Best acc:')
print(best_acc)
def train(train_loader, model, criterion, optimizer, epoch, use_cuda):
# switch to train mode
model.train()
batch_time = AverageMeter()
data_time = AverageMeter()
losses = AverageMeter()
top1 = AverageMeter()
top5 = AverageMeter()
end = time.time()
bar = Bar('Processing', max=len(train_loader))
for batch_idx, (inputs, targets) in enumerate(train_loader):
# measure data loading time
data_time.update(time.time() - end)
if use_cuda:
inputs, targets = inputs.cuda(), targets.cuda(async=True)
###############################
###############################
###############################
###############################
###############################
#inputs, targets = torch.autograd.Variable(inputs), torch.autograd.Variable(targets)
# compute output
outputs = model(inputs)
#CrossEntropyLoss
#targets = tensor([ 8, 42, 32, 20, 11, 10, 59, 20, 15, 47, 63, 2, 25, 37, 9, 57],device='cuda:0')
#tensor([[ 4],[25],[19],[48],[43],[11]], device='cuda:0') error
loss = criterion(outputs, targets)
# measure accuracy and record loss
prec1, prec5 = accuracy(outputs.data, targets.data, topk=(1, 5))
###############################
###############################
###############################
###############################
###############################
#loss.data[0] = loss.item()
#inputs.size(0) = inputs.shape[0]
#prec1[0] = prec1
#prec5[0] = prec5
losses.update(loss.item(), inputs.size(0))
top1.update(prec1, inputs.size(0))
top5.update(prec5, inputs.size(0))
# compute gradient and do SGD step
optimizer.zero_grad()
loss.backward()
optimizer.step()
# measure elapsed time
batch_time.update(time.time() - end)
end = time.time()
# plot progress
bar.suffix = '({batch}/{size}) Data: {data:.3f}s | Batch: {bt:.3f}s | Total: {total:} | ETA: {eta:} | Loss: {loss:.4f} | top1: {top1: .4f} | top5: {top5: .4f}'.format(
batch=batch_idx + 1,
size=len(train_loader),
data=data_time.val,
bt=batch_time.val,
total=bar.elapsed_td,
eta=bar.eta_td,
loss=losses.avg,
top1=top1.avg,
top5=top5.avg,
)
bar.next()
bar.finish()
return (losses.avg, top1.avg)
def test(val_loader, model, criterion, epoch, use_cuda):
global best_acc
batch_time = AverageMeter()
data_time = AverageMeter()
losses = AverageMeter()
top1 = AverageMeter()
top5 = AverageMeter()
# switch to evaluate mode
model.eval()
with torch.no_grad():
end = time.time()
bar = Bar('Processing', max=len(val_loader))
for batch_idx, (inputs, targets) in enumerate(val_loader):
# measure data loading time
data_time.update(time.time() - end)
if use_cuda:
inputs, targets = inputs.cuda(), targets.cuda()
###############################
###############################
###############################
###############################
###############################
#inputs, targets = torch.autograd.Variable(inputs, volatile=True), torch.autograd.Variable(targets)
# compute output
outputs = model(inputs)
loss = criterion(outputs, targets)
# measure accuracy and record loss
prec1, prec5 = accuracy(outputs.data, targets.data, topk=(1, 5))
###############################
###############################
###############################
###############################
###############################
#loss.data[0] = loss.item()
#inputs.size(0) = inputs.shape[0]
#prec1[0] = prec1
#prec5[0] = prec5
losses.update(loss.item(), inputs.size(0))
top1.update(prec1, inputs.size(0))
top5.update(prec5, inputs.size(0))
# measure elapsed time
batch_time.update(time.time() - end)
end = time.time()
# plot progress
bar.suffix = '({batch}/{size}) Data: {data:.3f}s | Batch: {bt:.3f}s | Total: {total:} | ETA: {eta:} | Loss: {loss:.4f} | top1: {top1: .4f} | top5: {top5: .4f}'.format(
batch=batch_idx + 1,
size=len(val_loader),
data=data_time.avg,
bt=batch_time.avg,
total=bar.elapsed_td,
eta=bar.eta_td,
loss=losses.avg,
top1=top1.avg,
top5=top5.avg,
)
bar.next()
bar.finish()
return (losses.avg, top1.avg)
def save_checkpoint(state, is_best, checkpoint='checkpoint', filename='checkpoint.pth.tar'):
filepath = os.path.join(checkpoint, filename)
torch.save(state, filepath)
if is_best:
shutil.copyfile(filepath, os.path.join(checkpoint, 'model_best.pth.tar'))
def adjust_learning_rate(optimizer, epoch):
global state
if epoch in args.schedule:
state['lr'] *= args.gamma
for param_group in optimizer.param_groups:
param_group['lr'] = state['lr']
if __name__ == '__main__':
main()
vis_datasetsDataLoader.py
# -*-coding:utf-8-*-
'''
Training script for ImageNet
Copyright (c) Wei YANG, 2017
'''
from __future__ import print_function
import argparse
import os
import shutil
import time
import random
import torch
import torch.nn as nn
from dataset import NoisyDataset
import torch.nn.parallel
import torch.backends.cudnn as cudnn
import torch.optim as optim
import torch.utils.data as data
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torchvision.models as models
import models.imagenet as customized_models
from utils import Bar, Logger, AverageMeter, accuracy, mkdir_p, savefig, LabelSmoothLoss, CrossEntropyLoss
import json
import numpy as np
default_model_names = sorted(name for name in models.__dict__
if name.islower() and not name.startswith("__")
and callable(models.__dict__[name]))
customized_models_names = sorted(name for name in customized_models.__dict__
if name.islower() and not name.startswith("__")
and callable(customized_models.__dict__[name]))
for name in customized_models.__dict__:
if name.islower() and not name.startswith("__") and callable(customized_models.__dict__[name]):
models.__dict__[name] = customized_models.__dict__[name]
model_names = default_model_names + customized_models_names
parser = argparse.ArgumentParser(description='PyTorch Imagenet Training')
# Datasets
parser.add_argument('-d', '--data', default='path to dataset', type=str)
parser.add_argument('-j', '--workers', default=4, type=int, metavar='N',
help='number of data loading workers (default: 4)')
parser.add_argument('--root', default='/home/spple/data/mini-imagenet', type=str,
help='root dir of training data')
parser.add_argument('--root-val', default='/home/spple/data/mini-imagenet', type=str,
help='root dir of validation data')
parser.add_argument('--train-list', default='/home/spple/data/mini-imagenet/train_list.txt', type=str,
help='training data list file')
parser.add_argument('--val-list', default='/home/spple/data/mini-imagenet/val_list.txt', type=str,
help='validation data list file')
# Optimization options
parser.add_argument('--epochs', default=90, type=int, metavar='N',
help='number of total epochs to run')
parser.add_argument('--start-epoch', default=0, type=int, metavar='N',
help='manual epoch number (useful on restarts)')
parser.add_argument('--train-epoch', default=16, type=int, metavar='N',
help='train batchsize (default: 16)')
parser.add_argument('--test-epoch', default=16, type=int, metavar='N',
help='test batchsize (default: 16)')
parser.add_argument('--lr', '--learning-rate', default=0.1, type=float,
metavar='LR', help='initial learning rate')
parser.add_argument('--drop', '--dropout', default=0, type=float,
metavar='Dropout', help='Dropout ratio')
parser.add_argument('--schedule', type=int, nargs='+', default=[10, 20],
help='Decrease learning rate at these epochs.')
parser.add_argument('--gamma', type=float, default=0.5, help='LR is multiplied by gamma on schdule.')
parser.add_argument('--momentum', default=0.9, type=float, metavar='M',
help='momentum')
parser.add_argument('--weight-decay', '--wd', default=1e-4, type=float,
metavar='W', help='weight decay (default:1e-4)')
# Checkpoints
parser.add_argument('-c', '--checkpoint', default='checkpoint', type=str, metavar='PATH',
help='path to latest checkpoint (default: none)')
parser.add_argument('--resume', default='checkpoint/checkpoint-1.pth.tar', type=str, metavar='PATH',
help='path to latest checkpoint (default: none)')
# Architecture
parser.add_argument('--arch', '-a', metavar='ARCH', default='resnet18',
choices=model_names,
help='model architecture: ' +
' | '.join(model_names) +
' (default: resnet101)')
parser.add_argument('--depth', type=int, default=29, help='Model depth.')
parser.add_argument('--cardinality', type=int, default=32, help='ResNext cardinality (group).')
parser.add_argument('--base-width', type=int, default=4, help='ResNext base width.')
parser.add_argument('--widen-factor', type=int, default=4, help='Widen factor. 4 -> 64 ...')
# Miscs
parser.add_argument('--manualSeed', type=int, help='manual seed')
parser.add_argument('-e', '--evaluate', dest='evaluate', action='store_true',
help='evaluate model on validation set')
parser.add_argument('--pretrained', default=True, dest='pretrained', action='store_true',
help='use pre-trained model')
parser.add_argument('--gpu-id', default='0', type=str,
help='id(s) for CUDA_VISIBLE_DEVICES')
#47104
parser.add_argument('--num-classes', default=9036, type=int, help='number of classes')
parser.add_argument('--BC-learning', dest='BC_learning', action='store_true',
help='use between class training method')
parser.add_argument('--data-augmentation', dest='data_augmentation', action='store_true',
help='use data augmentation strategy in training')
parser.add_argument('--attention', dest='attention', action='store_true',
help='use spatial attention after last conv layer')
parser.add_argument('--weight-loss', dest='weight_loss', action='store_true',
help='use weighted loss on criterion')
parser.add_argument('--weight-file', default='', type=str,
help='file of weighted ratio on each class')
parser.add_argument('--label-smooth', dest='label_smooth', action='store_true',
help='use label smoothing in training')
parser.add_argument('--label-file', default='', type=str,
help='label smoothing file calculated by coarse model')
args = parser.parse_args()
state = {k: v for k, v in args._get_kwargs()}
# Use CUDA
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id
use_cuda = torch.cuda.is_available()
if args.manualSeed is None:
args.manualSeed = random.randint(1, 10000)
random.seed(args.manualSeed)
torch.manual_seed(args.manualSeed)
if use_cuda:
torch.cuda.manual_seed_all(args.manualSeed)
kwargs = {'num_workers': args.workers, 'pin_memory': True} if use_cuda else {}
best_acc = 0
def main():
global best_acc
start_epoch = args.start_epoch
if not os.path.isdir(args.checkpoint):
mkdir_p(args.checkpoint)
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
if args.data_augmentation:
transform_train = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.RandomVerticalFlip(),
transforms.Scale(256),
transforms.RandomSizedCrop(224),
transforms.ColorJitter(0.5, 0.5, 0.5),
transforms.RandomRotation(30),
transforms.RandomAffine(30),
transforms.ToTensor(),
normalize
])
else:
transform_train = transforms.Compose([
###############################
###############################
###############################
###############################
###############################
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
normalize,
])
transform_test = transforms.Compose([
###############################
###############################
###############################
###############################
###############################
# transforms.Scale(256),
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
normalize,
])
trainset = NoisyDataset(root=args.root, filename=args.train_list, transform=transform_train)
testset = NoisyDataset(root=args.root_val, filename=args.val_list, transform=transform_test)
train_loader = torch.utils.data.DataLoader(trainset, batch_size=args.train_epoch, shuffle=True,
num_workers=args.workers, pin_memory=True)
val_loader = torch.utils.data.DataLoader(testset, batch_size=args.test_epoch, shuffle=False,
num_workers=args.workers, pin_memory=True)
# create model
if args.pretrained:
print("=> using pre-trained model '{}'".format(args.arch))
# check if pretrained model exists
# pretrained_filename = os.path.join('./pretrained', args.arch)
# assert os.path.isfile(pretrained_filename), 'Error: no pretrained checkpoint directory found!'
model = models.__dict__[args.arch](
pretrained=True,
num_classes=args.num_classes)
elif args.arch.startswith('resnext') or args.arch.startswith('se_resnext'):
print("=> creating model '{}'".format(args.arch))
model = models.__dict__[args.arch](
baseWidth=args.base_width,
cardinality=args.cardinality,
num_classes=args.num_classes,
attention=args.attention
)
else:
print("=> creating model '{}'".format(args.arch))
model = models.__dict__[args.arch](
num_classes=args.num_classes
)
if args.arch.startswith('alexnet') or args.arch.startswith('vgg'):
models.features = torch.nn.DataParallel(model.features)
model.cuda()
else:
model = torch.nn.DataParallel(model).cuda()
cudnn.benchmark = True
print(' Total params: %.2fM' % (sum(p.numel() for p in model.parameters()) / 1000000.0))
#针对单目标分类问题, 结合了nn.LogSoftmax()和nn.NLLLoss()来计算loss.
#criterion = nn.CrossEntropyLoss().cuda()
###############################
###############################
###############################
###############################
###############################
if args.weight_loss:
assert os.path.isfile(args.weight_file), 'weight loss training while weight file not found'
weights = json.load(open(args.weight_file))
weight_ = []
for i in range(len(weights.keys())):
weight_.append(weights[str(i)])
weight_ = np.array(weight_, dtype=np.float32)
weight_ = weight_ / sum(weight_) * (args.num_classes + 0.0) * 0.5 + 0.5
print(weight_)
weight_ = torch.from_numpy(weight_)
if args.weight_loss and args.label_smooth:
weight_ = weight_.cuda()
criterion = LabelSmoothLoss(weight=weight_).cuda()
criterion_test = CrossEntropyLoss(weight=weight_).cuda()
elif args.weight_loss:
weight_ = weight_.cuda()
criterion = nn.CrossEntropyLoss(weight=weight_).cuda()
criterion_test = nn.CrossEntropyLoss(weight=weight_).cuda()
elif args.label_smooth:
criterion = LabelSmoothLoss().cuda()
criterion_test = CrossEntropyLoss().cuda()
else:
criterion = nn.CrossEntropyLoss().cuda()
criterion_test = nn.CrossEntropyLoss().cuda()
optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum,
weight_decay=args.weight_decay)
# Resume
title = 'Imagenet-' + args.arch
if args.resume:
print('==> Resuming from checkpoint..')
assert os.path.isfile(args.resume), 'Error: no checkpoint directory found!'
args.checkpoint = os.path.dirname(args.resume)
checkpoint = torch.load(args.resume)
best_acc = checkpoint['best_acc']
start_epoch = checkpoint['epoch']
model.load_state_dict(checkpoint['state_dict'])
optimizer.load_state_dict(checkpoint['optimizer'])
logger = Logger(os.path.join(args.checkpoint, 'log.txt'), title=title, resume=True)
else:
logger = Logger(os.path.join(args.checkpoint, 'log.txt'), title=title)
logger.set_names(['learning Rate', 'Train Loss', 'Valid Loss', 'Train Acc.', 'Valid Acc.'])
if args.evaluate:
print('\nEvaluation only')
test_loss, test_acc = test(val_loader, model, criterion_test, start_epoch, use_cuda)
print(' Test Loss: %.8f, Test Acc: %.2f' % (test_loss, test_acc))
if args.label_smooth:
label_dict = read_label(args.label_file)
else:
label_dict = None
for epoch in range(start_epoch, args.epochs):
adjust_learning_rate(optimizer, epoch)
print('\nEpoch: [%d | %d] LR: %f' % (epoch + 1, args.epochs, state['lr']))
train_loss, train_acc = train(train_loader, model, criterion, optimizer, epoch, use_cuda, label_dict)
#test_loss, test_acc = test(val_loader, model, criterion_test, epoch, use_cuda)
test_loss = 0.0
test_acc = 0.0
# append logger file
logger.append([state['lr'], train_loss, test_loss, train_acc, test_acc])
# save model
is_best = test_acc > best_acc
best_acc = max(test_acc, best_acc)
save_checkpoint(epoch, {
'epoch': epoch + 1,
'state_dict': model.state_dict(),
'acc': test_acc,
'best_acc': best_acc,
'optimizer': optimizer.state_dict(),
}, is_best, checkpoint=args.checkpoint)
logger.close()
logger.plot()
savefig(os.path.join(args.checkpoint, 'log.eps'))
print('Best acc: ')
print(best_acc)
def train(train_loader, model, criterion, optimizer, epoch, use_cuda, label_dict):
# switch to train mode
model.train()
batch_time = AverageMeter()
data_time = AverageMeter()
losses = AverageMeter()
top1 = AverageMeter()
top5 = AverageMeter()
end = time.time()
bar = Bar('Processing', max=len(train_loader))
for batch_idx, (inputs, targets) in enumerate(train_loader):
# measure data loading time
data_time.update(time.time() - end)
prec_targets = targets
if args.label_smooth:
targets = transform_label(targets, label_dict)
if use_cuda:
inputs, targets, prec_targets = inputs.cuda(), targets.cuda(async=True), prec_targets.cuda(async=True)
if not args.label_smooth:
targets = torch.squeeze(targets)
prec_targets = torch.squeeze(prec_targets)
###############################
###############################
###############################
###############################
###############################
#inputs, targets, prec_targets = torch.autograd.Variable(inputs), torch.autograd.Variable(targets), torch.autograd.Variable(prec_targets)
outputs = model(inputs)
loss = criterion(outputs, targets)
prec1, prec5 = accuracy(outputs.data, prec_targets.data, topk=(1, 5))
# if args.label_smooth:
# losses.update(loss, inputs.size(0))
# else:
###############################
###############################
###############################
###############################
###############################
#loss.data[0] = loss.item()
#inputs.size(0) = inputs.shape[0]
#prec1[0] = prec1
#prec5[0] = prec5
losses.update(loss.item(), inputs.size(0))
top1.update(prec1, inputs.size(0))
top5.update(prec5, inputs.size(0))
optimizer.zero_grad()
loss.backward()
optimizer.step()
batch_time.update(time.time() - end)
end = time.time()
# plot progress
bar.suffix = '({batch}/{size}) Data: {data:.3f}s | Batch: {bt:.3f}s | Total: {total:} | ETA: {eta:} | Loss: {loss:.4f} | top1: {top1: .4f} | top5: {top5: .4f}'.format(
batch=batch_idx + 1,
size=len(train_loader),
data=data_time.val,
bt=batch_time.val,
total=bar.elapsed_td,
eta=bar.eta_td,
loss=losses.avg,
top1=top1.avg,
top5=top5.avg,
)
bar.next()
bar.finish()
return (losses.avg, top1.avg)
def test(val_loader, model, criterion, epoch, use_cuda):
global best_acc
batch_time = AverageMeter()
data_time = AverageMeter()
losses = AverageMeter()
top1 = AverageMeter()
top5 = AverageMeter()
# switch to evaluate mode
model.eval()
with torch.no_grad():
end = time.time()
bar = Bar('Processing', max=len(val_loader))
for batch_idx, (inputs, targets) in enumerate(val_loader):
# measure data loading time
data_time.update(time.time() - end)
if use_cuda:
inputs, targets = inputs.cuda(), targets.cuda()
###############################
###############################
###############################
###############################
###############################
#inputs, targets = torch.autograd.Variable(inputs, volatile=True), torch.autograd.Variable(targets)
# compute output
outputs = model(inputs)
loss = criterion(outputs, targets)
# print(torch.max(targets,1)[1].data)
# measure accuracy and record loss
prec1, prec5 = accuracy(outputs.data, targets.data, topk=(1, 5))
###############################
###############################
###############################
###############################
###############################
#loss.data[0] = loss.item()
#inputs.size(0) = inputs.shape[0]
#prec1[0] = prec1
#prec5[0] = prec5
losses.update(loss.item(), inputs.size(0))
top1.update(prec1, inputs.size(0))
top5.update(prec5, inputs.size(0))
# measure elapsed time
batch_time.update(time.time() - end)
end = time.time()
# plot progress
bar.suffix = '({batch}/{size}) Data: {data:.3f}s | Batch: {bt:.3f}s | Total: {total:} | ETA: {eta:} | Loss: {loss:.4f} | top1: {top1: .4f} | top5: {top5: .4f}'.format(
batch=batch_idx + 1,
size=len(val_loader),
data=data_time.avg,
bt=batch_time.avg,
total=bar.elapsed_td,
eta=bar.eta_td,
loss=losses.avg,
top1=top1.avg,
top5=top5.avg,
)
bar.next()
bar.finish()
return (losses.avg, top1.avg)
def save_checkpoint(epoch, state, is_best, checkpoint='checkpoint', filename='checkpoint.pth.tar'):
filename = 'checkpoint-{}.pth.tar'.format(epoch)
filepath = os.path.join(checkpoint, filename)
torch.save(state, filepath)
if is_best:
shutil.copyfile(filepath, os.path.join(checkpoint, 'model_best.pth.tar'))
def adjust_learning_rate(optimizer, epoch):
global state
if epoch in args.schedule:
state['lr'] *= args.gamma
for param_group in optimizer.param_groups:
param_group['lr'] = state['lr']
#对于多分类向量,计算机中往往用[0, 1, 3]等此类离散的、随机的而非有序(连续)的向量表示
#而one-hot vector 对应的向量便可表示为[0, 1, 0],即对于长度为n 的数组,只有一个元素是1,其余都为0
#https://blog.csdn.net/qiu931110/article/details/86684241
#原来的交叉熵softmax 最终在训练网络时,最小化预测概率和标签真实概率的交叉熵,从而得到最优的预测概率分布。
#网络会驱使自身往正确标签和错误标签差值大的方向学习,在训练数据不足以表征所以的样本特征的情况下,这就会导致网络过拟合。
#label smoothing将真实概率分布作如下改变
#其实更新后的分布就相当于往真实分布中加入了噪声,为了便于计算,该噪声服从简单的均匀分布
#https://github.com/dragen1860/DARTS-PyTorch/blob/master/train_imagenet.py
#https://github.com/OpenNMT/OpenNMT-py/blob/e8622eb5c6117269bb3accd8eb6f66282b5e67d9/onmt/utils/loss.py#L186
def read_label(label_file):
print("constructing soft label dict ...")
label_dict = {}
fread = open(label_file, 'r')
value_0 = 0.8
value_1 = 0.1 / 4
value_2 = 0.1 / (args.num_classes - 5)
for line in fread:
info = line.strip().split(':')
key = info[0]
label_value = np.ones((args.num_classes)) * value_2
corr = info[1].split(' ')
for k in range(5):
if corr[k] != key:
label_value[int(corr[k])] = value_1
label_value[int(key)] = value_0
# print(label_value)
label_dict[int(key)] = label_value
return label_dict
def transform_label(targets, label_dict):
value_0 = np.zeros((args.num_classes), dtype=np.float32)
bs = len(targets) #batch tensor([47, 30, 10, 11, 53, 56, 18, 43, 28, 7, 62, 14, 30, 27, 15, 47])
targets_new = []
for i in range(bs):
# print(targets[i].numpy())
targets_new.append(label_dict[targets[i].numpy()[0]])
# print(targets_new[i])
targets_new = np.array(targets_new, dtype=np.float32)
# print(targets_new[0][0])
targets_new = torch.from_numpy(targets_new)
# print(targets_new)
targets_new = targets_new
# print(targets_new[0][0])
return targets_new
if __name__ == '__main__':
main()
labelSmoothing_vis_datasetsDataLoader.py
# -*-coding:utf-8-*-
'''
Training script for ImageNet
Copyright (c) Wei YANG, 2017
'''
from __future__ import print_function
import argparse
import os
import shutil
import time
import random
import torch
import torch.nn as nn
from dataset import NoisyDataset
import torch.nn.parallel
import torch.backends.cudnn as cudnn
import torch.optim as optim
import torch.utils.data as data
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torchvision.models as models
import models.imagenet as customized_models
from utils import Bar, Logger, AverageMeter, accuracy, mkdir_p, savefig, LabelSmoothLoss, CrossEntropyLoss
import json
import numpy as np
default_model_names = sorted(name for name in models.__dict__
if name.islower() and not name.startswith("__")
and callable(models.__dict__[name]))
customized_models_names = sorted(name for name in customized_models.__dict__
if name.islower() and not name.startswith("__")
and callable(customized_models.__dict__[name]))
for name in customized_models.__dict__:
if name.islower() and not name.startswith("__") and callable(customized_models.__dict__[name]):
models.__dict__[name] = customized_models.__dict__[name]
model_names = default_model_names + customized_models_names
parser = argparse.ArgumentParser(description='PyTorch Imagenet Training')
# Datasets
parser.add_argument('-d', '--data', default='path to dataset', type=str)
parser.add_argument('-j', '--workers', default=4, type=int, metavar='N',
help='number of data loading workers (default: 4)')
parser.add_argument('--root', default='/home/spple/data/mini-imagenet', type=str,
help='root dir of training data')
parser.add_argument('--root-val', default='/home/spple/data/mini-imagenet', type=str,
help='root dir of validation data')
parser.add_argument('--train-list', default='/home/spple/data/mini-imagenet/train_list.txt', type=str,
help='training data list file')
parser.add_argument('--val-list', default='/home/spple/data/mini-imagenet/val_list.txt', type=str,
help='validation data list file')
# Optimization options
parser.add_argument('--epochs', default=90, type=int, metavar='N',
help='number of total epochs to run')
parser.add_argument('--start-epoch', default=0, type=int, metavar='N',
help='manual epoch number (useful on restarts)')
parser.add_argument('--train-epoch', default=16, type=int, metavar='N',
help='train batchsize (default: 16)')
parser.add_argument('--test-epoch', default=16, type=int, metavar='N',
help='test batchsize (default: 16)')
parser.add_argument('--lr', '--learning-rate', default=0.1, type=float,
metavar='LR', help='initial learning rate')
parser.add_argument('--drop', '--dropout', default=0, type=float,
metavar='Dropout', help='Dropout ratio')
parser.add_argument('--schedule', type=int, nargs='+', default=[10, 20],
help='Decrease learning rate at these epochs.')
parser.add_argument('--gamma', type=float, default=0.5, help='LR is multiplied by gamma on schdule.')
parser.add_argument('--momentum', default=0.9, type=float, metavar='M',
help='momentum')
parser.add_argument('--weight-decay', '--wd', default=1e-4, type=float,
metavar='W', help='weight decay (default:1e-4)')
# Checkpoints
parser.add_argument('-c', '--checkpoint', default='checkpoint', type=str, metavar='PATH',
help='path to latest checkpoint (default: none)')
parser.add_argument('--resume', default='checkpoint/checkpoint-1.pth.tar', type=str, metavar='PATH',
help='path to latest checkpoint (default: none)')
# Architecture
parser.add_argument('--arch', '-a', metavar='ARCH', default='resnet18',
choices=model_names,
help='model architecture: ' +
' | '.join(model_names) +
' (default: resnet101)')
parser.add_argument('--depth', type=int, default=29, help='Model depth.')
parser.add_argument('--cardinality', type=int, default=32, help='ResNext cardinality (group).')
parser.add_argument('--base-width', type=int, default=4, help='ResNext base width.')
parser.add_argument('--widen-factor', type=int, default=4, help='Widen factor. 4 -> 64 ...')
# Miscs
parser.add_argument('--manualSeed', type=int, help='manual seed')
parser.add_argument('-e', '--evaluate', dest='evaluate', action='store_true',
help='evaluate model on validation set')
parser.add_argument('--pretrained', default=True, dest='pretrained', action='store_true',
help='use pre-trained model')
parser.add_argument('--gpu-id', default='0', type=str,
help='id(s) for CUDA_VISIBLE_DEVICES')
#47104
parser.add_argument('--num-classes', default=9036, type=int, help='number of classes')
parser.add_argument('--BC-learning', dest='BC_learning', action='store_true',
help='use between class training method')
parser.add_argument('--data-augmentation', dest='data_augmentation', action='store_true',
help='use data augmentation strategy in training')
parser.add_argument('--attention', dest='attention', action='store_true',
help='use spatial attention after last conv layer')
parser.add_argument('--weight-loss', dest='weight_loss', action='store_true',
help='use weighted loss on criterion')
parser.add_argument('--weight-file', default='', type=str,
help='file of weighted ratio on each class')
parser.add_argument('--label-smooth', default=True, dest='label_smooth', action='store_true',
help='use label smoothing in training')
parser.add_argument('--label_smooth_epsilon', type=float, default=0.1, help='label smoothing')
parser.add_argument('--label-file', default='', type=str,
help='label smoothing file calculated by coarse model')
args = parser.parse_args()
state = {k: v for k, v in args._get_kwargs()}
# Use CUDA
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id
use_cuda = torch.cuda.is_available()
if args.manualSeed is None:
args.manualSeed = random.randint(1, 10000)
random.seed(args.manualSeed)
torch.manual_seed(args.manualSeed)
if use_cuda:
torch.cuda.manual_seed_all(args.manualSeed)
kwargs = {'num_workers': args.workers, 'pin_memory': True} if use_cuda else {}
best_acc = 0
class CrossEntropyLabelSmooth(nn.Module):
def __init__(self, num_classes, epsilon=0.1):
super(CrossEntropyLabelSmooth, self).__init__()
self.num_classes = num_classes
self.epsilon = epsilon
self.logsoftmax = nn.LogSoftmax(dim=1)
def forward(self, inputs, targets):
log_probs = self.logsoftmax(inputs)
targets = torch.zeros_like(log_probs).scatter_(1, targets.unsqueeze(1), 1)
targets = (1 - self.epsilon) * targets + self.epsilon / self.num_classes
loss = (-targets * log_probs).mean(0).sum()
return loss
def main():
global best_acc
start_epoch = args.start_epoch
if not os.path.isdir(args.checkpoint):
mkdir_p(args.checkpoint)
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
if args.data_augmentation:
transform_train = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.RandomVerticalFlip(),
transforms.Scale(256),
transforms.RandomSizedCrop(224),
transforms.ColorJitter(0.5, 0.5, 0.5),
transforms.RandomRotation(30),
transforms.RandomAffine(30),
transforms.ToTensor(),
normalize
])
else:
transform_train = transforms.Compose([
###############################
###############################
###############################
###############################
###############################
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
normalize,
])
transform_test = transforms.Compose([
###############################
###############################
###############################
###############################
###############################
# transforms.Scale(256),
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
normalize,
])
trainset = NoisyDataset(root=args.root, filename=args.train_list, transform=transform_train)
testset = NoisyDataset(root=args.root_val, filename=args.val_list, transform=transform_test)
train_loader = torch.utils.data.DataLoader(trainset, batch_size=args.train_epoch, shuffle=True,
num_workers=args.workers, pin_memory=True)
val_loader = torch.utils.data.DataLoader(testset, batch_size=args.test_epoch, shuffle=False,
num_workers=args.workers, pin_memory=True)
# create model
if args.pretrained:
print("=> using pre-trained model '{}'".format(args.arch))
# check if pretrained model exists
# pretrained_filename = os.path.join('./pretrained', args.arch)
# assert os.path.isfile(pretrained_filename), 'Error: no pretrained checkpoint directory found!'
model = models.__dict__[args.arch](
pretrained=True,
num_classes=args.num_classes)
elif args.arch.startswith('resnext') or args.arch.startswith('se_resnext'):
print("=> creating model '{}'".format(args.arch))
model = models.__dict__[args.arch](
baseWidth=args.base_width,
cardinality=args.cardinality,
num_classes=args.num_classes,
attention=args.attention
)
else:
print("=> creating model '{}'".format(args.arch))
model = models.__dict__[args.arch](
num_classes=args.num_classes
)
if args.arch.startswith('alexnet') or args.arch.startswith('vgg'):
models.features = torch.nn.DataParallel(model.features)
model.cuda()
else:
model = torch.nn.DataParallel(model).cuda()
cudnn.benchmark = True
print(' Total params: %.2fM' % (sum(p.numel() for p in model.parameters()) / 1000000.0))
#针对单目标分类问题, 结合了nn.LogSoftmax()和nn.NLLLoss()来计算loss.
#criterion = nn.CrossEntropyLoss().cuda()
###############################
###############################
###############################
###############################
###############################
#参数 weight是1D Tensor,分别对应每个类别class的权重.对于类别不平衡的训练数据集比较有用.
if args.weight_loss:
assert os.path.isfile(args.weight_file), 'weight loss training while weight file not found'
weights = json.load(open(args.weight_file))
weight_ = []
for i in range(len(weights.keys())):
weight_.append(weights[str(i)])
weight_ = np.array(weight_, dtype=np.float32)
weight_ = weight_ / sum(weight_) * (args.num_classes + 0.0) * 0.5 + 0.5
print(weight_)
weight_ = torch.from_numpy(weight_)
if args.weight_loss and args.label_smooth:
weight_ = weight_.cuda()
criterion = CrossEntropyLabelSmooth(args.num_classes, args.label_smooth_epsilon).cuda()
criterion_test = CrossEntropyLoss(weight=weight_).cuda()
elif args.weight_loss:
weight_ = weight_.cuda()
criterion = nn.CrossEntropyLoss(weight=weight_).cuda()
criterion_test = nn.CrossEntropyLoss(weight=weight_).cuda()
elif args.label_smooth:
criterion = CrossEntropyLabelSmooth(args.num_classes, args.label_smooth_epsilon).cuda()
criterion_test = CrossEntropyLoss().cuda()
else:
criterion = nn.CrossEntropyLoss().cuda()
criterion_test = nn.CrossEntropyLoss().cuda()
#权重衰减(weight decay)与学习率衰减(learning rate decay)
#https://blog.csdn.net/program_developer/article/details/80867468
#在不使用L2正则化时,求导结果中w前系数为1,现在w前面系数为1-ηλ/n,因为η、λ、n都是正的,所以1-ηλ/n小于1,它的效果是减小w,
#这也就是权重衰减(weight decay)的由来。当然考虑到后面的导数项,w最终的值可能增大也可能减小。
optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum,
weight_decay=args.weight_decay)
# Resume
title = 'Imagenet-' + args.arch
if args.resume:
print('==> Resuming from checkpoint..')
assert os.path.isfile(args.resume), 'Error: no checkpoint directory found!'
args.checkpoint = os.path.dirname(args.resume)
checkpoint = torch.load(args.resume)
best_acc = checkpoint['best_acc']
start_epoch = checkpoint['epoch']
model.load_state_dict(checkpoint['state_dict'])
optimizer.load_state_dict(checkpoint['optimizer'])
logger = Logger(os.path.join(args.checkpoint, 'log.txt'), title=title, resume=True)
else:
logger = Logger(os.path.join(args.checkpoint, 'log.txt'), title=title)
logger.set_names(['learning Rate', 'Train Loss', 'Valid Loss', 'Train Acc.', 'Valid Acc.'])
if args.evaluate:
print('\nEvaluation only')
test_loss, test_acc = test(val_loader, model, criterion_test, start_epoch, use_cuda)
print(' Test Loss: %.8f, Test Acc: %.2f' % (test_loss, test_acc))
#参考pytorch学习(十三)—学习率调整策略
#https://www.jianshu.com/p/a20d5a7ed6f3
# lr_scheduler.StepLR()
# Assuming optimizer uses lr = 0.05 for all groups
# lr = 0.05 if epoch < 30
# lr = 0.005 if 30 <= epoch < 60
# lr = 0.0005 if 60 <= epoch < 90
#按指定步长衰减的另一种写法
#scheduler = torch.optim.lr_scheduler.StepLR(optimizer, args.schedule, gamma=args.gamma)
#scheduler.step()
for epoch in range(start_epoch, args.epochs):
adjust_learning_rate(optimizer, epoch)
print('\nEpoch: [%d | %d] LR: %f' % (epoch + 1, args.epochs, state['lr']))
train_loss, train_acc = train(train_loader, model, criterion, optimizer, epoch, use_cuda)
#test_loss, test_acc = test(val_loader, model, criterion_test, epoch, use_cuda)
test_loss = 0.0
test_acc = 0.0
# append logger file
logger.append([state['lr'], train_loss, test_loss, train_acc, test_acc])
# save model
is_best = test_acc > best_acc
best_acc = max(test_acc, best_acc)
save_checkpoint(epoch, {
'epoch': epoch + 1,
'state_dict': model.state_dict(),
'acc': test_acc,
'best_acc': best_acc,
'optimizer': optimizer.state_dict(),
}, is_best, checkpoint=args.checkpoint)
logger.close()
logger.plot()
savefig(os.path.join(args.checkpoint, 'log.eps'))
print('Best acc: ')
print(best_acc)
def train(train_loader, model, criterion, optimizer, epoch, use_cuda):
# switch to train mode
model.train()
batch_time = AverageMeter()
data_time = AverageMeter()
losses = AverageMeter()
top1 = AverageMeter()
top5 = AverageMeter()
end = time.time()
bar = Bar('Processing', max=len(train_loader))
for batch_idx, (inputs, targets) in enumerate(train_loader):
# measure data loading time
data_time.update(time.time() - end)
prec_targets = targets
if use_cuda:
inputs, targets, prec_targets = inputs.cuda(), targets.cuda(async=True), prec_targets.cuda(async=True)
if not args.label_smooth:
targets = torch.squeeze(targets)
prec_targets = torch.squeeze(prec_targets)
###############################
###############################
###############################
###############################
###############################
#inputs, targets, prec_targets = torch.autograd.Variable(inputs), torch.autograd.Variable(targets), torch.autograd.Variable(prec_targets)
outputs = model(inputs)
loss = criterion(outputs, targets)
prec1, prec5 = accuracy(outputs.data, prec_targets.data, topk=(1, 5))
# if args.label_smooth:
# losses.update(loss, inputs.size(0))
# else:
###############################
###############################
###############################
###############################
###############################
#loss.data[0] = loss.item()
#inputs.size(0) = inputs.shape[0]
#prec1[0] = prec1
#prec5[0] = prec5
losses.update(loss.item(), inputs.size(0))
top1.update(prec1, inputs.size(0))
top5.update(prec5, inputs.size(0))
optimizer.zero_grad()
loss.backward()
optimizer.step()
batch_time.update(time.time() - end)
end = time.time()
# plot progress
bar.suffix = '({batch}/{size}) Data: {data:.3f}s | Batch: {bt:.3f}s | Total: {total:} | ETA: {eta:} | Loss: {loss:.4f} | top1: {top1: .4f} | top5: {top5: .4f}'.format(
batch=batch_idx + 1,
size=len(train_loader),
data=data_time.val,
bt=batch_time.val,
total=bar.elapsed_td,
eta=bar.eta_td,
loss=losses.avg,
top1=top1.avg,
top5=top5.avg,
)
bar.next()
bar.finish()
return (losses.avg, top1.avg)
def test(val_loader, model, criterion, epoch, use_cuda):
global best_acc
batch_time = AverageMeter()
data_time = AverageMeter()
losses = AverageMeter()
top1 = AverageMeter()
top5 = AverageMeter()
# switch to evaluate mode
model.eval()
with torch.no_grad():
end = time.time()
bar = Bar('Processing', max=len(val_loader))
for batch_idx, (inputs, targets) in enumerate(val_loader):
# measure data loading time
data_time.update(time.time() - end)
if use_cuda:
inputs, targets = inputs.cuda(), targets.cuda()
###############################
###############################
###############################
###############################
###############################
#inputs, targets = torch.autograd.Variable(inputs, volatile=True), torch.autograd.Variable(targets)
# compute output
outputs = model(inputs)
loss = criterion(outputs, targets)
# print(torch.max(targets,1)[1].data)
# measure accuracy and record loss
prec1, prec5 = accuracy(outputs.data, targets.data, topk=(1, 5))
###############################
###############################
###############################
###############################
###############################
#loss.data[0] = loss.item()
#inputs.size(0) = inputs.shape[0]
#prec1[0] = prec1
#prec5[0] = prec5
losses.update(loss.item(), inputs.size(0))
top1.update(prec1, inputs.size(0))
top5.update(prec5, inputs.size(0))
# measure elapsed time
batch_time.update(time.time() - end)
end = time.time()
# plot progress
bar.suffix = '({batch}/{size}) Data: {data:.3f}s | Batch: {bt:.3f}s | Total: {total:} | ETA: {eta:} | Loss: {loss:.4f} | top1: {top1: .4f} | top5: {top5: .4f}'.format(
batch=batch_idx + 1,
size=len(val_loader),
data=data_time.avg,
bt=batch_time.avg,
total=bar.elapsed_td,
eta=bar.eta_td,
loss=losses.avg,
top1=top1.avg,
top5=top5.avg,
)
bar.next()
bar.finish()
return (losses.avg, top1.avg)
def save_checkpoint(epoch, state, is_best, checkpoint='checkpoint', filename='checkpoint.pth.tar'):
filename = 'checkpoint-{}.pth.tar'.format(epoch)
filepath = os.path.join(checkpoint, filename)
torch.save(state, filepath)
if is_best:
shutil.copyfile(filepath, os.path.join(checkpoint, 'model_best.pth.tar'))
def adjust_learning_rate(optimizer, epoch):
global state
if epoch in args.schedule:
state['lr'] *= args.gamma
for param_group in optimizer.param_groups:
param_group['lr'] = state['lr']
if __name__ == '__main__':
main()