import torch
|
|
import numpy as np
|
|
import cv2, os, sys
|
|
import pandas as pd
|
|
from torch.utils.data import Dataset
|
|
from matplotlib import pyplot as plt
|
|
from torch.utils.data import ConcatDataset, DataLoader, Subset
|
|
import torch.nn as nn
|
|
import torchvision.transforms as transforms
|
|
from torchvision.datasets import DatasetFolder
|
|
from PIL import Image
|
|
import torchvision.models as models
|
|
batch_size = 32
|
|
num_epoch = 1
|
|
|
|
torch.cuda.set_device(1)
|
|
train_tfm = transforms.Compose([
|
|
transforms.Grayscale(),
|
|
transforms.RandomHorizontalFlip(),
|
|
transforms.RandomResizedCrop((68,68)),
|
|
transforms.ToTensor(),
|
|
#transforms.RandomResizedCrop((40,30)),
|
|
#transforms.TenCrop((40,30)),
|
|
#transforms.Normalize(0.5,0.5),
|
|
])
|
|
|
|
test_tfm = transforms.Compose([
|
|
transforms.Grayscale(),
|
|
transforms.ToTensor()
|
|
])
|
|
'''
|
|
class Classifier(nn.Module):
|
|
def __init__(self):
|
|
super(Classifier, self).__init__()
|
|
|
|
self.cnn_layers = nn.Sequential(
|
|
#input_size(1,30,40)
|
|
nn.Conv2d(1, 16, 3, 1), #output_size(16,28,38)
|
|
nn.BatchNorm2d(16),
|
|
nn.ReLU(),
|
|
nn.Dropout(0.2),
|
|
nn.MaxPool2d(kernel_size = 2), #output_size(16,14,19)
|
|
|
|
nn.Conv2d(16, 24, 3, 1), #output_size(24,12,17)
|
|
nn.BatchNorm2d(24),
|
|
nn.ReLU(),
|
|
nn.Dropout(0.2),
|
|
nn.MaxPool2d(kernel_size = 2), #output_size(24,6,8)
|
|
|
|
nn.Conv2d(24, 32, 3, 1), #output_size(32,4,6)
|
|
nn.BatchNorm2d(32),
|
|
nn.ReLU(),
|
|
nn.Dropout(0.2),
|
|
nn.MaxPool2d(kernel_size = 2) #ouput_size(32,2,3)
|
|
|
|
|
|
)
|
|
self.fc_layers = nn.Sequential(
|
|
nn.Linear(32 * 2 * 3, 32),
|
|
nn.ReLU(),
|
|
nn.Dropout(0.2),
|
|
|
|
|
|
nn.Linear(32,8)
|
|
)
|
|
|
|
def forward(self, x):
|
|
x = self.cnn_layers(x)
|
|
|
|
x = x.flatten(1)
|
|
|
|
x = self.fc_layers(x)
|
|
|
|
return x
|
|
'''
|
|
def main():
|
|
train_set = DatasetFolder("pose_data2/train", loader=lambda x: Image.open(x), extensions="bmp", transform=train_tfm)
|
|
test_set = DatasetFolder("pose_data2/test", loader=lambda x: Image.open(x), extensions="bmp", transform=test_tfm)
|
|
valid_set = DatasetFolder("pose_data2/val", loader=lambda x: Image.open(x), extensions="bmp", transform=test_tfm)
|
|
|
|
train_loader = DataLoader(train_set, batch_size=batch_size, shuffle=True)
|
|
test_loader = DataLoader(test_set, batch_size=batch_size, shuffle=True)
|
|
valid_loader = DataLoader(valid_set, batch_size=batch_size, shuffle=True)
|
|
|
|
model_path = "model.ckpt"
|
|
|
|
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
model = models.resnet50()
|
|
model.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3,
|
|
bias=False)
|
|
model.fc = nn.Linear(2048, 8)
|
|
model = model.to(device)
|
|
print(model)
|
|
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
|
|
criterion = nn.CrossEntropyLoss()
|
|
|
|
best_acc = -1
|
|
for epoch in range(num_epoch):
|
|
##Training
|
|
running_loss = 0.0
|
|
total = 0
|
|
correct = 0
|
|
for i, data in enumerate(train_loader):
|
|
inputs, labels = data
|
|
inputs = inputs.to(device)
|
|
labels = labels.to(device)
|
|
optimizer.zero_grad()
|
|
|
|
outputs = model(inputs)
|
|
|
|
loss = criterion(outputs, labels)
|
|
loss.backward()
|
|
|
|
optimizer.step()
|
|
|
|
running_loss += loss.item()
|
|
total += labels.size(0)
|
|
_,predicted = torch.max(outputs.data,1)
|
|
#print(predicted)
|
|
#print("label",labels)
|
|
correct += (predicted == labels).sum().item()
|
|
train_acc = correct / total
|
|
|
|
print(f"[ Train | {epoch + 1:03d}/{num_epoch:03d} ] loss = {running_loss:.5f}, acc = {train_acc:.5f}")
|
|
|
|
##Validation
|
|
model.eval()
|
|
|
|
valid_loss = 0.0
|
|
total = 0
|
|
correct = 0
|
|
for i, data in enumerate(valid_loader):
|
|
inputs, labels = data
|
|
inputs = inputs.to(device)
|
|
labels = labels.to(device)
|
|
|
|
with torch.no_grad():
|
|
outputs = model(inputs)
|
|
|
|
loss = criterion(outputs, labels)
|
|
running_loss += loss.item()
|
|
total += labels.size(0)
|
|
_,predicted = torch.max(outputs.data,1)
|
|
correct += (predicted == labels).sum().item()
|
|
|
|
valid_acc = correct / total
|
|
print(f"[ Valid | {epoch + 1:03d}/{num_epoch:03d} ] loss = {running_loss:.5f}, acc = {valid_acc:.5f}")
|
|
if valid_acc > best_acc:
|
|
best_acc = valid_acc
|
|
torch.save(model.state_dict(), model_path)
|
|
print('saving model with acc {:.3f}'.format(valid_acc))
|
|
|
|
|
|
|
|
##Testing
|
|
model = models.resnet50()
|
|
model.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3,
|
|
bias=False)
|
|
model.fc = nn.Linear(2048, 8)
|
|
model = model.to(device)
|
|
model.load_state_dict(torch.load(model_path))
|
|
model.eval()
|
|
|
|
with torch.no_grad():
|
|
correct = 0
|
|
total = 0
|
|
|
|
for i, data in enumerate(test_loader):
|
|
inputs, labels = data
|
|
|
|
inputs = inputs.to(device)
|
|
labels = labels.to(device)
|
|
|
|
outputs = model(inputs)
|
|
_,predicted = torch.max(outputs.data,1)
|
|
|
|
total += labels.size(0)
|
|
correct += (predicted == labels).sum().item()
|
|
# for k in range(batch_size):
|
|
# if predicted[k] != labels[k]:
|
|
# print(inputs[k])
|
|
|
|
#print(predicted)
|
|
#print("labels:",labels)
|
|
print('Test Accuracy:{} %'.format((correct / total) * 100))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|