Seed 고정

seed = 22

random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
  • torch.backends.cudnn.deterministic = True - 같은 input에 대해 결과 재현이 가능하도록 한다.
  • torch.backends.cudnn.benchmark = False - 하드웨어에 따라 최적화된 알고리즘을 사용할 수 있도록 한다. (따라서 옵션을 끈다)

CustomDataset

from torch.utils.dataset import Dataset

class CustomDataset():
    def __init__(self):
	
    def __len__(self):
        return len(x)

    def __getitem__(self):
        return x, y
  • __init__(self) - 변수 선언 및 초기화
  • __len__(self) - 데이터 개수 반환
  • __getitem__(self) - 데이터 한 개를 반환
  • torch.utils.data.Dataset을 상속받아 아래의 메서드를 overriding한다.
  • test데이터의 경우는 y가 없기 때문에, input data 인 x만 반환하도록 만들어야 한다.

DataLoader

from torch.utils.dataset import DataLoader

train_dataset = CustomDataset(train_x, train_y)
train_dataloader = DataLoader(train_dataset, batch_size=32, shuffle=True)
  • Dataset을 배치 사이즈에 맞게 공급해주는 역할을 한다.
  • train_x와 train_y를 순회하며 반환한다.

Model 작성

def train(model, optimizer, train_dataloader, val_dataloader, device):
	model.to(device)
	criterion = torch.nn.CrossEntropyLoss().to(device)

	best_val_score = 0
	best_model = None

	for epoch in range(1, EPOCHS+1):
		model.train()
		train_loss = []
		for data, labels in iter(train_dataloader):
			data = data.to(device)
			labels = labels.to(device)
			
			optimizer.zero_grad()

			output = model(data)
			loss = criterion(output, y)

			loss.backward()
			optimizer.step()

			train_loss.append(loss.item())
		_val_loss, _val_score = validation(model, criterion, val_dataloader, device)
		_train_loss = np.mean(train_loss)
		print(f'Epoch {epoch}, Train Loss : {_train_loss:.6f}, Val Loss : {_val_loss:.6f}, Val F1 : {_val_score:.6f}')

	if best_val_score < _val_score:
		best_val_score = _val_score
		best_model = model

    return model
  • 연산을 위한 device 얻는다.
  • 데이터에 대한 연산을 위해 nn.Module을 상속받는다.
  • __init__(self) - 변수 선언 및 초기화
  • super(Model, self).__init__() - 부모 클래스(nn.Module) 초기화
  • forward - forward propagation 수행 함수

Train

def train(model, optimizer, train_dataloader, val_dataloader, device):
	model.to(device)
	criterion = torch.nn.CrossEntropyLoss().to(device)

	best_val_score = 0
	best_model = None

	for epoch in range(1, EPOCHS+1):
		model.train()
		train_loss = []
		for data, labels in iter(train_dataloader):
			data = data.to(device)
			labels = labels.to(device)
			
			optimizer.zero_grad()

			output = model(data)
			loss = criterion(output, y)

			loss.backward()
			optimizer.step()

			train_loss.append(loss.item())
		_val_loss, _val_score = validation(model, criterion, val_dataloader, device)
		_train_loss = np.mean(train_loss)
		print(f'Epoch {epoch}, Train Loss : {_train_loss:.6f}, Val Loss : {_val_loss:.6f}, Val F1 : {_val_score:.6f}')

	if best_val_score < _val_score:
		best_val_score = _val_score
		best_model = model

    return model
  • criterion - Loss function 정의
  • model.to(device) - 모델에 장치(cpu, gpu) 할당
  • x.to(device) - 데이터 장치 할당
  • optimizer.zero_grad() - gradient값 0으로 초기 (backward전에 초기화 해야 학습 가능)
  • loss = criterion(output, y) - model의 output으로 Loss 계산
  • loss.backward() - 구한 Loss를 통해 backward propagation 수행(기울기 계산)
  • optimizer.step() - 기울기 업데이트

Validation

def validation(model, criterion, val_dataloader, device):
	model.eval()
	val_loss = []
	preds, trues = [], []
	
	with torch.no_grad():
		for data, labels in iter(val_dataloader):
			data = data.to(device)
			labels = data.to(device)
			
			preds = model(data)
			loss = criterion(preds, labels)

			val_loss.append(loss.item())

			preds += preds.argmax(1).detach().cpu().numpy().tolist()
			trues += labels.detach().cpu().numpy().tolist()
		
		_val_loss = np.mean(val_loss)

	_val_loss = np.mean(val_loss)

_val_score = f1_score(trues, preds, average='macro')
return _val_loss, _val_score
  • model.eval() - dropout, batchnorm 등 train에 사용한 layer가 비활성화된다.
  • loss.item() - loss의 스칼라 값을 가져온다.
  • detach().cpu().numpy().tolist() - numpy의 list 변환을 위한 메모리 변경

Model Train

model = Model()
optimizer = torch.optim.Adam(params=model.parameters())

infer_model = train(model, optimizer, train_dataloader, val_dataloader, device)

'ML_DL > 딥러닝 공부하기' 카테고리의 다른 글

[Loss Function] Cross Entropy  (0) 2023.04.30
[Preprocessing] Categorical Feature Encoding  (0) 2023.04.25
Model Ensemble  (0) 2023.03.24
Macro-F1 score  (0) 2023.03.21
Bias와 Variance  (0) 2023.01.30

+ Recent posts