[오늘의 일지]
딥러닝 프로젝트 - 베이스라인 코드 수정
[상세 내용]
베이스라인 코드 수정
LSTM
- 강사님께서 제시해 준 LSTM의 베이스라인 코드에서 몇 가지 수정할 부분이 있었고 또 기능적인 측면에서 추가해면 좋을 거 같은 것들이 있었습니다. 우선 강사님의 코드에서는 모델을 학습을 시킬 때 for문에서 미니배치를 통해 분리된 데이터들이 각각의 학습을 진행한 후에 각 배치마다 loss 값이 나오는데 마지막 배치의 loss값만 출력되는 것 같았습니다. 원래의 loss값은 하나의 루프의 로스 값을 모두 더해서 배치 사이즈로 나눠줘야만 loss값의 평균을 출력하는 게 정상입니다. 그래서 코드를 모두 수정했습니다. 그리고 기존 코드에서는 학습만 할 수 있게 되어있었는데 학습 후에 test를 거쳐서 한 번 더 성능을 파악했습니다. 그리고 loss값이 정체되었을 때를 가정하여 얼리 스탑핑 기능도 추가했고 또 성능이 머무른다고 판단될 때에 러닝레이트를 줄여주는 기능까지 추가했습니다. 그리고 데이터 전처리 부분에서 정규화를 시켜주는 과정도 했습니다. 그런데 아직 캐글에서 제출하는 부분은 해결하지 못했습니다.
# 정규화
x_cols = [c for c in data_interpolated.columns if c not in ['row_id', 'time_id', 'date_id', 'target']]
y_cols = ["target"]
means = data_interpolated[x_cols].mean(0)
stds = data_interpolated[x_cols].std(0)
def normalize_features(x):
return (x - means) / (stds+1e-8)
def get_xy(df):
x = df[x_cols]
x = normalize_features(x)
y = df[y_cols]
return x.values, y.values
# 데이터 분리 로드(train, test)
def get_dataloaders(df, batch_size=512):
(x,y) = get_xy(df)
x_tensor = torch.Tensor(x).to(device)
y_tensor = torch.Tensor(y).to(device)
full_dataset = TensorDataset(x_tensor, y_tensor)
train_dataset, test_dataset = random_split(full_dataset, [0.8,0.2])
train_dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, drop_last=True)
test_dataloader = DataLoader(test_dataset, batch_size=min(batch_size*4, len(test_dataset)), drop_last=True)
return (train_dataloader, test_dataloader)
# early stopping 추가
class EarlyStopper:
def __init__(self, patience=5, min_delta=0.00001):
self.best_model = None
self.patience = patience
self.min_delta = min_delta
self.counter = 0
self.min_validation_loss = float('inf')
def get_best_model(self):
return self.best_model
def early_stop(self, validation_loss, model):
if validation_loss < self.min_validation_loss:
print(f"New best loss: {validation_loss:>.4f}")
self.min_validation_loss = validation_loss
self.counter = 0
self.best_model = model
elif validation_loss > (self.min_validation_loss + self.min_delta):
self.counter += 1
if self.counter >= self.patience:
return True
return False
# 최종 모델 학습
# Move the model to GPU
model = model.to(device)
# Loss and optimizer
criterion = nn.L1Loss()
optimizer = torch.optim.AdamW(model.parameters(), lr=0.0001, weight_decay=0.00001)
early_stopper = EarlyStopper(patience=5, min_delta=0.00001)
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, 'min', patience=5, factor=0.5, verbose=True)
# Training loop
num_epochs = 1000
for epoch in range(num_epochs):
model.train()
train_loss = 0
for X, y in tqdm(train_dataloader):
# Reshape the data for LSTM (batch_size, sequence_length, input_size)
X = X.unsqueeze(1).to(device)
y = y.to(device)
# Forward pass
outputs = model(X)
loss = criterion(outputs, y)
train_loss += loss.item()
# Backward pass and optimization
optimizer.zero_grad()
loss.backward()
optimizer.step()
model.eval()
test_loss = 0
with torch.no_grad():
for X, y in test_dataloader:
X, y = X.unsqueeze(1).to(device), y.to(device) # Reshape test data
pred = model(X)
test_loss += criterion(pred, y).item()
train_loss /= len(train_dataloader)
test_loss /= len(test_dataloader)
print(f"Epoch [{epoch+1}/{num_epochs}], Train_Loss: {train_loss:>.5f}, Test_Loss: {test_loss:>.5f}")
scheduler.step(test_loss)
# early stopper
if early_stopper.early_stop(test_loss, model):
print("Early stopping triggered.")
break
print("Training finished.")
[마무리]
오늘은 LSTM 모델의 코드를 수정해서 학습이 가능하도록 했습니다. 다른 부분은 다 괜찮았는데 캐글에서 제출을 위한 코드를 짜는 것이 생각보다 어려웠던 거 같습니다. 이제 내일은 아마도 DNN을 위한 코드를 분석해 보고 수정하는 과정을 통해서 학습 효과를 올릴 수 있도록 노력해봐야 할 거 같습니다.
반응형
'AI > AI 부트캠프' 카테고리의 다른 글
[AI 부트캠프] DAY 83 - 딥러닝 프로젝트 8 (0) | 2023.11.17 |
---|---|
[AI 부트캠프] DAY 82 - 딥러닝 프로젝트 7 (0) | 2023.11.16 |
[AI 부트캠프] DAY 80 - 딥러닝 프로젝트 5 (0) | 2023.11.14 |
[AI 부트캠프] DAY 79 - 딥러닝 프로젝트 4 (0) | 2023.11.11 |
[AI 부트캠프] DAY 78 - 딥러닝 프로젝트 3 (0) | 2023.11.10 |
댓글