728x90
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 |