専門ユニット2/山内研セミナー(2021/12/15)

関連サイトと資料

Google Colaboratory

from google.colab import drive
drive.mount('/content/drive')
    


import os
import torch
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
  
# path to store data and/or load from
path2data = '/content/drive/MyDrive/data'
if os.path.exists(path2data) == False:
	os.makedirs(path2data)
  
train_data = datasets.FashionMNIST(path2data,train=True,download=True, transform=transforms.ToTensor())
val_data = datasets.FashionMNIST(path2data, train=False, download=True, transform=transforms.ToTensor())
  
batch_size = 128
train_dl = torch.utils.data.DataLoader(train_data, batch_size=batch_size, shuffle=True)
val_dl = torch.utils.data.DataLoader(val_data, batch_size=batch_size)
    
from torch import nn
import torch
    
class FlattenLayer(nn.Module):
	def forward(self, x):
		sizes = x.size()
		return x.view(sizes[0], -1)
  
conv_net = nn.Sequential(
	nn.Conv2d(1, 32, 5),
	nn.MaxPool2d(2),
	nn.ReLU(),
	nn.BatchNorm2d(32),
	nn.Dropout2d(0.25),
	nn.Conv2d(32, 64, 5),
	nn.MaxPool2d(2),
	nn.ReLU(),
	nn.BatchNorm2d(64),
	nn.Dropout2d(0.25),
	FlattenLayer()
)
  
test_input = torch.ones(1, 1, 28, 28)
conv_output_size = conv_net(test_input).size()[-1]
print(conv_output_size)
  
mlp = nn.Sequential(
	nn.Linear(conv_output_size, 200),
	nn.ReLU(),
	nn.BatchNorm1d(200),
	nn.Dropout(0.25),
	nn.Linear(200, 10)
)
  
net = nn.Sequential(
	conv_net,
	mlp
)
    
def eval_net(model, data_loader, device):
	model.eval()
	ys = []
	ypreds = []
	for x, y in data_loader:
		x = x.to(device)
		y = y.to(device)
  
		with torch.no_grad():
			_, y_pred = model(x).max(1)
		ys.append(y)
		ypreds.append(y_pred)
  
	ys = torch.cat(ys)
	ypreds = torch.cat(ypreds)
  
	acc = (ys == ypreds).float().sum() / len(ys)
	return acc.item()
    
import tqdm
  
def train_net(num_epochs, model, train_loader, val_loader, opt, loss_fn, device):
	train_losses = []
	train_acc = []
	val_acc = []
  
	for epoch in range(num_epochs):
		running_loss = 0.0
		model.train()
		n = 0
		n_acc = 0
		for i, (xx, yy) in tqdm.tqdm(enumerate(train_loader), total=len(train_loader)):
			xx = xx.to(device)
			yy = yy.to(device)
			h = model(xx).to(device)
			loss = loss_fn(h, yy)
			opt.zero_grad()
			loss.backward()
			opt.step()
			running_loss += loss.item()
			n += len(xx)
			_, y_pred = h.max(1)
			n_acc += (yy == y_pred).float().sum().item()
  
		train_losses.append(running_loss / i)
  
		train_acc.append(n_acc / n)
		val_acc.append(eval_net(model, val_loader, device))
  
		print(f'epoch:{epoch}, train_losses:{train_losses[-1]}, train_acc:{train_acc[-1]}, val_acc:{val_acc[-1]}', flush=True)
    
import time
import torch
from torch import optim
from torch import nn
  
device = torch.device('cuda:0')
net.to(device)
  
loss_func = nn.CrossEntropyLoss()
opt = optim.Adam(net.parameters())
  
t1 = time.time()
num_epochs=20
train_net(num_epochs, net, train_dl, val_dl, opt, loss_func, device)
t2 = time.time()
elapsed_time = t2-t1
print(f'経過時間: {elapsed_time} [sec]')