这部分作业需要安装pytorch,安装教程看主页或自行百度
直接上代码
import numpy as np
import pandas as pd
import os
import cv2
import torch
torch.cuda.is_available()
def readfile(path,label):
img_dir = sorted(os.listdir(path))
x = np.zeros((len(img_dir),128,128,3),dtype = np.uint8)
y = np.zeros(len(img_dir),dtype = np.uint8)
for i , file in enumerate(img_dir):
x [i,:,:] = cv2.resize(cv2.imread(os.path.join(path,file)),(128,128))
if label:
y[i] = int(file.split('_')[0])
if label:
return x, y
else:
return y
workspace_dir ='C:\\Users\\13554\\jupyter practice\\lihongyi\\hw3\\food-11'
print("Reading data")
train_x , train_y = readfile(os.path.join(workspace_dir,"training"),True)
print("Size of training data = {}".format(len(train_x)))
val_x , val_y = readfile(os.path.join(workspace_dir,"validation"),True)
print("Size of validation data = {}".format(len(val_x)))
import torchvision.transforms as transforms
train_transform = transforms.Compose([
transforms.ToPILImage(),
transforms.RandomHorizontalFlip(p=0.5),
transforms.RandomVerticalFlip(p=0.5),
transforms.RandomRotation(degrees=(0,180)),
transforms.RandomPerspective(distortion_scale=0.3,p=0.5),
transforms.ToTensor(),
])
test_transform = transforms.Compose([
transforms.ToPILImage(),
transforms.ToTensor(),
])
from torch.utils.data import DataLoader,Dataset
class ImgDataset(Dataset):
def __init__(self,x,y=None,transform=None):
self.x = x
self.y = y
if y is not None:
self.y = torch.LongTensor(y)
self.transform = transform
def __len__(self):
return len(self.x)
def __getitem__(self,index):
X = self.x[index]
if self.transform is not None:
X = self.transform(X)
if self.y is not None:
Y = self.y[index]
return X,Y
else:
return X
batch_size = 64
train_set = ImgDataset(train_x,train_y,train_transform)
val_set = ImgDataset(val_x,val_y,test_transform)
train_loader = DataLoader(train_set,batch_size = batch_size,shuffle = True)
val_loader = DataLoader(val_set,batch_size = batch_size ,shuffle=False)
import torch.nn as nn
class Classifier(nn.Module):
def __init__(self):
super(Classifier,self).__init__()
self.cnn = nn.Sequential(
nn.Conv2d(3,64,3,1,1),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.MaxPool2d(2,2,0),
nn.Conv2d(64,128,3,1,1),
nn.BatchNorm2d(128),
nn.ReLU(),
nn.MaxPool2d(2,2,0),
nn.Conv2d(128, 256, 3, 1, 1),
nn.BatchNorm2d(256),
nn.ReLU(),
nn.MaxPool2d(2, 2, 0),
nn.Conv2d(256, 512, 3, 1, 1),
nn.BatchNorm2d(512),
nn.ReLU(),
nn.MaxPool2d(2, 2, 0),
nn.Conv2d(512, 512, 3, 1, 1),
nn.BatchNorm2d(512),
nn.ReLU(),
nn.MaxPool2d(2, 2, 0),
)
self.fc = nn.Sequential(
nn.Linear(512*4*4,1024),
nn.ReLU(),
nn.Linear(1024,512),
nn.ReLU(),
nn.Linear(512,11)
)
def forward(self,x):
out = self.cnn(x)
out = out.view(out.size()[0],-1)
return self.fc(out)
model = Classifier().cuda()
loss = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(),lr = 0.001,betas=(0.9,0.999),eps=1e-8,weight_decay=0.0005)
num_epoch = 300
val_bestacc=0
train_bestacc=0
for epoch in range(num_epoch):
train_acc = 0.0
train_loss = 0.0
val_acc = 0.0
val_loss = 0.0
model.train()
for i,data in enumerate(train_loader):
optimizer.zero_grad()
train_pred = model(data[0].cuda())
batch_loss = loss(train_pred,data[1].cuda() )
batch_loss.backward()
optimizer.step()
train_acc += np.sum(np.argmax(train_pred.cpu().data.numpy(),axis = 1) == data[1].numpy())
train_loss += batch_loss.item()
model.eval()
with torch.no_grad():
for i,data in enumerate(val_loader):
val_pred = model(data[0].cuda())
batch_loss = loss(val_pred,data[1].cuda())
val_acc += np.sum(np.argmax(val_pred.cpu().data.numpy(),axis = 1) == data[1].numpy())
val_loss += batch_loss.item()
print('[%03d/%03d] Train Acc: %3.6f Loss: %3.6f | Val Acc: %3.6f loss: %3.6f' % \
(epoch + 1, num_epoch, train_acc/train_set.__len__(), train_loss/train_set.__len__(), val_acc/val_set.__len__(), val_loss/val_set.__len__()))
if(val_acc>val_bestacc):
val_bestacc=val_acc
if(train_acc>train_bestacc):
train_bestacc=train_acc
print('train_bestacc: %3.6f | val_bestacc: %3.6f'%(train_bestacc/train_set.__len__(),val_bestacc/val_set.__len__()))