이미지, 텍스트, 음성과 같은 데이터는 비선형 데이터일 뿐만 아니라 높은 차원의 공간에 분포하는 데이터입니다. 이러한 데이터를 이용할 때는 비선형 함수 형태를 근사계산하여야 합니다.
하지만 이전 게시물에서 소개했던 linear regression model(선형 회귀 모델)과 logistic regression model(로지스틱 회귀 모델)로는 비선형 문제를 해결할 수 없습니다.
따라서 layer를 깊게 쌓아올린 deep neural network를 이용해야 합니다. 이때, layer 사이에 비선형 함수(activation function)을 꼭 끼워 넣어야 비선형성을 구현할 수 있습니다.
Activation function으로 사용되는 sigmoid와 tanh의 경우 gradient의 값이 0으로 수렴하게 되어 weight parameter update에 문제가 생깁니다. 이러한 Gradient Vanishing Problem을 보완하는 activation function에는 ReLU와 leaky ReLU가 있습니다.
Activation function 관련 게시물
Load Dataset
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_boston
boston = load_boston()
df = pd.DataFrame(boston.data, columns=boston.feature_names)
df["TARGET"] = boston.target
scaler = StandardScaler()
scaler.fit(df.values[:, :-1])
df.values[:, :-1] = scaler.transform(df.values[:, :-1]).round(4)
Train Model
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
data = torch.from_numpy(df.values).float()
y = data[:, -1:]
x = data[:, :-1]
print(x.shape, y.shape)
torch.Size([506, 13]) torch.Size([506, 1])
epochs = 100000
lr = 1e-4
print_interval = 5000
relu = nn.ReLU()
leaky_relu = nn.LeakyReLU(0.1)
class MyModel(nn.Module):
def __init__(self, input_dim, output_dim):
self.input_dim = input_dim
self.output_dim = output_dim
super().__init__()
self.linear1 = nn.Linear(input_dim, 3)
self.linear2 = nn.Linear(3, 3)
self.linear3 = nn.Linear(3, 3)
self.linear4 = nn.Linear(3, output_dim)
self.act = nn.ReLU()
def forward(self, x):
h = self.act(self.linear1(x))
h = self.act(self.linear2(h))
h = self.act(self.linear3(h))
y = self.linear4(h)
return y
model = MyModel(x.size(-1), y.size(-1))
model = nn.Sequential(
nn.Linear(x.size(-1), 3),
nn.LeakyReLU(),
nn.Linear(3, 3),
nn.LeakyReLU(),
nn.Linear(3, 3),
nn.LeakyReLU(),
nn.Linear(3, 3),
nn.LeakyReLU(),
nn.Linear(3, y.size(-1)),
)
optimizer = optim.SGD(model.parameters(),
lr=lr)
for i in range(n_epochs):
y_hat = model(x)
loss = F.mse_loss(y_hat, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (i + 1) % print_interval == 0:
print('Epoch %d: loss=%.4e' % (i + 1, loss))