-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Zhang Yuan
committed
Oct 10, 2017
1 parent
5d80b90
commit 813cc47
Showing
28 changed files
with
3,085 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
'''Train CIFAR10 with PyTorch.''' | ||
from __future__ import print_function | ||
|
||
import torch | ||
import torch.nn as nn | ||
import torch.optim as optim | ||
import torch.nn.functional as F | ||
#import torch.backends.cudnn as cudnn | ||
|
||
import torchvision | ||
import torchvision.transforms as transforms | ||
|
||
import os | ||
import argparse | ||
|
||
from models import * | ||
from utils import progress_bar | ||
from torch.autograd import Variable | ||
|
||
|
||
parser = argparse.ArgumentParser(description='PyTorch CIFAR10 Training') | ||
parser.add_argument('--lr', default=0.1, type=float, help='learning rate') | ||
parser.add_argument('--resume', '-r', action='store_true', help='resume from checkpoint') | ||
args = parser.parse_args() | ||
|
||
use_cuda = torch.cuda.is_available() | ||
best_acc = 0 # best test accuracy | ||
start_epoch = 0 # start from epoch 0 or last checkpoint epoch | ||
|
||
# Data | ||
print('==> Preparing data..') | ||
transform = 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)), | ||
]) | ||
|
||
trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=False, transform=transform) | ||
trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2) | ||
|
||
testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=False, transform=transform) | ||
testloader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=False, num_workers=2) | ||
|
||
classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck') | ||
|
||
# Model | ||
if args.resume: | ||
# Load checkpoint. | ||
print('==> Resuming from checkpoint..') | ||
assert os.path.isdir('checkpoint'), 'Error: no checkpoint directory found!' | ||
checkpoint = torch.load('./checkpoint/ckpt.t7') | ||
net = checkpoint['net'] | ||
best_acc = checkpoint['acc'] | ||
start_epoch = checkpoint['epoch'] | ||
else: | ||
print('==> Building model..') | ||
net = VGG('VGG19') | ||
# net = ResNet18() | ||
# net = GoogLeNet() | ||
# net = DenseNet121() | ||
# net = ResNeXt29_2x64d() | ||
# net = LeNet() | ||
|
||
if use_cuda: | ||
net.cuda() | ||
#net = torch.nn.DataParallel(net, device_ids=[0,1,2,3]) | ||
#cudnn.benchmark = True | ||
|
||
criterion = nn.CrossEntropyLoss() | ||
optimizer = optim.SGD(net.parameters(), lr=args.lr, momentum=0.9, weight_decay=5e-4) | ||
|
||
# Training | ||
def train(epoch): | ||
|
||
print('\nEpoch: %d' % epoch) | ||
net.train() | ||
train_loss = 0 | ||
correct = 0 | ||
total = 0 | ||
for batch_idx, (inputs, targets) in enumerate(trainloader): | ||
if use_cuda: | ||
inputs, targets = inputs.cuda(), targets.cuda() | ||
optimizer.zero_grad() | ||
inputs, targets = Variable(inputs), Variable(targets) | ||
outputs = net(inputs) | ||
loss = criterion(outputs, targets) | ||
loss.backward() | ||
optimizer.step() | ||
|
||
train_loss += loss.data[0] | ||
_, predicted = torch.max(outputs.data, 1) | ||
total += targets.size(0) | ||
correct += predicted.eq(targets.data).cpu().sum() | ||
|
||
progress_bar(batch_idx, len(trainloader), 'Loss: %.3f | Acc: %.3f%% (%d/%d)' | ||
% (train_loss/(batch_idx+1), 100.*correct/total, correct, total)) | ||
|
||
def test(epoch): | ||
|
||
global best_acc | ||
net.eval() | ||
test_loss = 0 | ||
correct = 0 | ||
total = 0 | ||
for batch_idx, (inputs, targets) in enumerate(testloader): | ||
if use_cuda: | ||
inputs, targets = inputs.cuda(), targets.cuda() | ||
inputs, targets = Variable(inputs, volatile=True), Variable(targets) | ||
outputs = net(inputs) | ||
loss = criterion(outputs, targets) | ||
|
||
test_loss += loss.data[0] | ||
_, predicted = torch.max(outputs.data, 1) | ||
total += targets.size(0) | ||
correct += predicted.eq(targets.data).cpu().sum() | ||
|
||
progress_bar(batch_idx, len(testloader), 'Loss: %.3f | Acc: %.3f%% (%d/%d)' | ||
% (test_loss/(batch_idx+1), 100.*correct/total, correct, total)) | ||
|
||
# Save checkpoint. | ||
acc = 100.*correct/total | ||
if acc > best_acc: | ||
print('Saving..') | ||
state = { | ||
#'net': net.module if use_cuda else net, | ||
'net': net, | ||
'acc': acc, | ||
'epoch': epoch, | ||
} | ||
if not os.path.isdir('checkpoint'): | ||
os.mkdir('checkpoint') | ||
torch.save(state, './checkpoint/ckpt.t7') | ||
best_acc = acc | ||
|
||
|
||
for epoch in range(start_epoch, start_epoch+200): | ||
train(epoch) | ||
test(epoch) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from .vgg import * | ||
from .lenet import * | ||
from .resnet import * | ||
from .resnext import * | ||
from .densenet import * | ||
from .googlenet import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
'''DenseNet in PyTorch.''' | ||
import math | ||
|
||
import torch | ||
import torch.nn as nn | ||
import torch.nn.functional as F | ||
|
||
from torch.autograd import Variable | ||
|
||
|
||
class Bottleneck(nn.Module): | ||
def __init__(self, in_planes, growth_rate): | ||
super(Bottleneck, self).__init__() | ||
self.bn1 = nn.BatchNorm2d(in_planes) | ||
self.conv1 = nn.Conv2d(in_planes, 4*growth_rate, kernel_size=1, bias=False) | ||
self.bn2 = nn.BatchNorm2d(4*growth_rate) | ||
self.conv2 = nn.Conv2d(4*growth_rate, growth_rate, kernel_size=3, padding=1, bias=False) | ||
|
||
def forward(self, x): | ||
out = self.conv1(F.relu(self.bn1(x))) | ||
out = self.conv2(F.relu(self.bn2(out))) | ||
out = torch.cat([out,x], 1) | ||
return out | ||
|
||
|
||
class Transition(nn.Module): | ||
def __init__(self, in_planes, out_planes): | ||
super(Transition, self).__init__() | ||
self.bn = nn.BatchNorm2d(in_planes) | ||
self.conv = nn.Conv2d(in_planes, out_planes, kernel_size=1, bias=False) | ||
|
||
def forward(self, x): | ||
out = self.conv(F.relu(self.bn(x))) | ||
out = F.avg_pool2d(out, 2) | ||
return out | ||
|
||
|
||
class DenseNet(nn.Module): | ||
def __init__(self, block, nblocks, growth_rate=12, reduction=0.5, num_classes=10): | ||
super(DenseNet, self).__init__() | ||
self.growth_rate = growth_rate | ||
|
||
num_planes = 2*growth_rate | ||
self.conv1 = nn.Conv2d(3, num_planes, kernel_size=3, padding=1, bias=False) | ||
|
||
self.dense1 = self._make_dense_layers(block, num_planes, nblocks[0]) | ||
num_planes += nblocks[0]*growth_rate | ||
out_planes = int(math.floor(num_planes*reduction)) | ||
self.trans1 = Transition(num_planes, out_planes) | ||
num_planes = out_planes | ||
|
||
self.dense2 = self._make_dense_layers(block, num_planes, nblocks[1]) | ||
num_planes += nblocks[1]*growth_rate | ||
out_planes = int(math.floor(num_planes*reduction)) | ||
self.trans2 = Transition(num_planes, out_planes) | ||
num_planes = out_planes | ||
|
||
self.dense3 = self._make_dense_layers(block, num_planes, nblocks[2]) | ||
num_planes += nblocks[2]*growth_rate | ||
out_planes = int(math.floor(num_planes*reduction)) | ||
self.trans3 = Transition(num_planes, out_planes) | ||
num_planes = out_planes | ||
|
||
self.dense4 = self._make_dense_layers(block, num_planes, nblocks[3]) | ||
num_planes += nblocks[3]*growth_rate | ||
|
||
self.bn = nn.BatchNorm2d(num_planes) | ||
self.linear = nn.Linear(num_planes, num_classes) | ||
|
||
def _make_dense_layers(self, block, in_planes, nblock): | ||
layers = [] | ||
for i in range(nblock): | ||
layers.append(block(in_planes, self.growth_rate)) | ||
in_planes += self.growth_rate | ||
return nn.Sequential(*layers) | ||
|
||
def forward(self, x): | ||
out = self.conv1(x) | ||
out = self.trans1(self.dense1(out)) | ||
out = self.trans2(self.dense2(out)) | ||
out = self.trans3(self.dense3(out)) | ||
out = self.dense4(out) | ||
out = F.avg_pool2d(F.relu(self.bn(out)), 4) | ||
out = out.view(out.size(0), -1) | ||
out = self.linear(out) | ||
return out | ||
|
||
def DenseNet121(): | ||
return DenseNet(Bottleneck, [6,12,24,16], growth_rate=32) | ||
|
||
def DenseNet169(): | ||
return DenseNet(Bottleneck, [6,12,32,32], growth_rate=32) | ||
|
||
def DenseNet201(): | ||
return DenseNet(Bottleneck, [6,12,48,32], growth_rate=32) | ||
|
||
def DenseNet161(): | ||
return DenseNet(Bottleneck, [6,12,36,24], growth_rate=48) | ||
|
||
def densenet_cifar(): | ||
return DenseNet(Bottleneck, [6,12,24,16], growth_rate=12) | ||
|
||
def test_densenet(): | ||
net = densenet_cifar() | ||
x = torch.randn(1,3,32,32) | ||
y = net(Variable(x)) | ||
print(y) | ||
|
||
# test_densenet() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
'''GoogLeNet with PyTorch.''' | ||
import torch | ||
import torch.nn as nn | ||
import torch.nn.functional as F | ||
|
||
from torch.autograd import Variable | ||
|
||
|
||
class Inception(nn.Module): | ||
def __init__(self, in_planes, n1x1, n3x3red, n3x3, n5x5red, n5x5, pool_planes): | ||
super(Inception, self).__init__() | ||
# 1x1 conv branch | ||
self.b1 = nn.Sequential( | ||
nn.Conv2d(in_planes, n1x1, kernel_size=1), | ||
nn.BatchNorm2d(n1x1), | ||
nn.ReLU(True), | ||
) | ||
|
||
# 1x1 conv -> 3x3 conv branch | ||
self.b2 = nn.Sequential( | ||
nn.Conv2d(in_planes, n3x3red, kernel_size=1), | ||
nn.BatchNorm2d(n3x3red), | ||
nn.ReLU(True), | ||
nn.Conv2d(n3x3red, n3x3, kernel_size=3, padding=1), | ||
nn.BatchNorm2d(n3x3), | ||
nn.ReLU(True), | ||
) | ||
|
||
# 1x1 conv -> 5x5 conv branch | ||
self.b3 = nn.Sequential( | ||
nn.Conv2d(in_planes, n5x5red, kernel_size=1), | ||
nn.BatchNorm2d(n5x5red), | ||
nn.ReLU(True), | ||
nn.Conv2d(n5x5red, n5x5, kernel_size=3, padding=1), | ||
nn.BatchNorm2d(n5x5), | ||
nn.ReLU(True), | ||
nn.Conv2d(n5x5, n5x5, kernel_size=3, padding=1), | ||
nn.BatchNorm2d(n5x5), | ||
nn.ReLU(True), | ||
) | ||
|
||
# 3x3 pool -> 1x1 conv branch | ||
self.b4 = nn.Sequential( | ||
nn.MaxPool2d(3, stride=1, padding=1), | ||
nn.Conv2d(in_planes, pool_planes, kernel_size=1), | ||
nn.BatchNorm2d(pool_planes), | ||
nn.ReLU(True), | ||
) | ||
|
||
def forward(self, x): | ||
y1 = self.b1(x) | ||
y2 = self.b2(x) | ||
y3 = self.b3(x) | ||
y4 = self.b4(x) | ||
return torch.cat([y1,y2,y3,y4], 1) | ||
|
||
|
||
class GoogLeNet(nn.Module): | ||
def __init__(self): | ||
super(GoogLeNet, self).__init__() | ||
self.pre_layers = nn.Sequential( | ||
nn.Conv2d(3, 192, kernel_size=3, padding=1), | ||
nn.BatchNorm2d(192), | ||
nn.ReLU(True), | ||
) | ||
|
||
self.a3 = Inception(192, 64, 96, 128, 16, 32, 32) | ||
self.b3 = Inception(256, 128, 128, 192, 32, 96, 64) | ||
|
||
self.maxpool = nn.MaxPool2d(3, stride=2, padding=1) | ||
|
||
self.a4 = Inception(480, 192, 96, 208, 16, 48, 64) | ||
self.b4 = Inception(512, 160, 112, 224, 24, 64, 64) | ||
self.c4 = Inception(512, 128, 128, 256, 24, 64, 64) | ||
self.d4 = Inception(512, 112, 144, 288, 32, 64, 64) | ||
self.e4 = Inception(528, 256, 160, 320, 32, 128, 128) | ||
|
||
self.a5 = Inception(832, 256, 160, 320, 32, 128, 128) | ||
self.b5 = Inception(832, 384, 192, 384, 48, 128, 128) | ||
|
||
self.avgpool = nn.AvgPool2d(8, stride=1) | ||
self.linear = nn.Linear(1024, 10) | ||
|
||
def forward(self, x): | ||
out = self.pre_layers(x) | ||
out = self.a3(out) | ||
out = self.b3(out) | ||
out = self.maxpool(out) | ||
out = self.a4(out) | ||
out = self.b4(out) | ||
out = self.c4(out) | ||
out = self.d4(out) | ||
out = self.e4(out) | ||
out = self.maxpool(out) | ||
out = self.a5(out) | ||
out = self.b5(out) | ||
out = self.avgpool(out) | ||
out = out.view(out.size(0), -1) | ||
out = self.linear(out) | ||
return out | ||
|
||
# net = GoogLeNet() | ||
# x = torch.randn(1,3,32,32) | ||
# y = net(Variable(x)) | ||
# print(y.size()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
'''LeNet in PyTorch.''' | ||
import torch.nn as nn | ||
import torch.nn.functional as F | ||
|
||
class LeNet(nn.Module): | ||
def __init__(self): | ||
super(LeNet, self).__init__() | ||
self.conv1 = nn.Conv2d(3, 6, 5) | ||
self.conv2 = nn.Conv2d(6, 16, 5) | ||
self.fc1 = nn.Linear(16*5*5, 120) | ||
self.fc2 = nn.Linear(120, 84) | ||
self.fc3 = nn.Linear(84, 10) | ||
|
||
def forward(self, x): | ||
out = F.relu(self.conv1(x)) | ||
out = F.max_pool2d(out, 2) | ||
out = F.relu(self.conv2(out)) | ||
out = F.max_pool2d(out, 2) | ||
out = out.view(out.size(0), -1) | ||
out = F.relu(self.fc1(out)) | ||
out = F.relu(self.fc2(out)) | ||
out = self.fc3(out) | ||
return out |
Oops, something went wrong.