Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

train.py #22

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 161 additions & 0 deletions train.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import argparse

import torch
from torch import nn
from torch import optim
from torch.autograd import Variable
from torchvision import datasets, transforms, models
from torchvision.datasets import ImageFolder
import torch.nn.functional as F

from PIL import Image

from collections import OrderedDict

import time

import numpy as np
import matplotlib.pyplot as plt

from run_utils import save_checkpoint, load_checkpoint

def parse_args():
parser = argparse.ArgumentParser(description="Training")
parser.add_argument('--data_dir', action='store')
parser.add_argument('--arch', dest='arch', default='vgg19', choices=['vgg19', 'vgg13'])
parser.add_argument('--learning_rate', dest='learning_rate', default='0.001')
parser.add_argument('--hidden_units', dest='hidden_units', default='512')
parser.add_argument('--epochs', dest='epochs', default='3')
parser.add_argument('--gpu', action='store', default='gpu')
parser.add_argument('--save_dir', dest="save_dir", action="store", default="checkpoint.pth")
return parser.parse_args()

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print('Training is starting')
def train(model, criterion, optimizer, dataloaders, epochs, gpu):
steps = 0
running_loss = 0
print_every = 10

for epoch in range(epochs):
model.to(device)
for inputs, labels in dataloaders['trainloader']:
steps += 1
# Move input and label tensors to the default device

inputs, labels = inputs.to(device), labels.to(device)

optimizer.zero_grad()
logps = model.forward(inputs)
loss = criterion(logps, labels)
loss.backward()
optimizer.step()

running_loss += loss.item()

if steps % print_every == 0:
valid_loss = 0
accuracy = 0
model.eval()

with torch.no_grad():
for inputs2, label in dataloaders['validloader']:
inputs, labels = inputs.to(device), labels.to(device)
logps = model.forward(inputs)
batch_loss = criterion(logps, labels)

valid_loss += batch_loss.item()

# Calculate accuracy
ps = torch.exp(logps)
top_p, top_class = ps.topk(1, dim=1)
equals = top_class == labels.view(*top_class.shape)
accuracy += torch.mean(equals.type(torch.FloatTensor)).item()

print(f"Epoch {epoch+1}/{epochs}.. "
f"Train loss: {running_loss/print_every:.3f}.. "
f"valid loss: {valid_loss/len(dataloaders['validloader']):.3f}.. "
f"valid accuracy: {accuracy/len(dataloaders['validloader']):.3f}")
running_loss = 0
def main():
args = parse_args()
data_dir = 'flowers'
train_dir = data_dir + '/train'
valid_dir = data_dir + '/valid'
test_dir = data_dir + '/test'

data_transforms = {

'train': transforms.Compose([transforms.RandomRotation(30),
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406],
[0.229, 0.224, 0.225])]),
'valid': transforms.Compose([transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406],
[0.229, 0.224, 0.225])]),
'test': transforms.Compose([transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406],
[0.229, 0.224, 0.225])])

}

# TODO: Load the datasets with ImageFolder
image_datasets = {
'train_data' : datasets.ImageFolder(train_dir, data_transforms['train']),
'valid_data' : datasets.ImageFolder(valid_dir, data_transforms['valid']),
'test_data' : datasets.ImageFolder(test_dir, data_transforms['test'])
}

# TODO: Using the image datasets and the trainforms, define the dataloaders
dataloaders = {
'trainloader' : torch.utils.data.DataLoader(image_datasets['train_data'], batch_size=64, shuffle=True),
'validloader' : torch.utils.data.DataLoader(image_datasets['valid_data'], batch_size=64, shuffle=True),
'testloader' : torch.utils.data.DataLoader(image_datasets['test_data'], batch_size=64, shuffle=True)
}

model = getattr(models, args.arch)(pretrained=True)

for param in model.parameters():
param.requires_grad = False



if args.arch == "vgg19":
feature_num = model.classifier[0].in_features


model.classifier = nn.Sequential(nn.Linear(25088, 256),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(256, 102),
nn.LogSoftmax(dim=1))
elif args.arch == "vgg13":
model.classifier = nn.Sequential(nn.Linear(25088, 256),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(256, 102),
nn.LogSoftmax(dim=1))



criterion = nn.NLLLoss()

# Only train the classifier parameters, feature parameters are frozen
optimizer = optim.Adam(model.classifier.parameters(), lr=float(args.learning_rate))
epochs = int(args.epochs)
class_index = image_datasets['train_data'].class_to_idx
gpu = args.gpu
train(model, criterion, optimizer, dataloaders, epochs, gpu)
model.class_to_idx = class_index
path = args.save_dir
save_checkpoint(path, model, optimizer, args, model.classifier)


if __name__ == "__main__":
main()