선형 회귀 또는 로지스틱 회귀는 비선형 문제는 풀 수 없다
선형 계층 사이에 비선형 활성화 함수를 넣어 비선형 함수로 만들 수 있다.
신경망의 깊이와 너비는 하이퍼 파라미터로 깊이가 깊고 너비가 넓을수록 복잡한 함수를 배울 수 있는 수용 능력이 높아짐
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['TARGER'] = boston.target
'''
/usr/local/lib/python3.8/dist-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function load_boston is deprecated; `load_boston` is deprecated in 1.0 and will be removed in 1.2.
The Boston housing prices dataset has an ethical problem. You can refer to
the documentation of this function for further details.
...
housing = fetch_openml(name="house_prices", as_frame=True)
for the Ames housing dataset.
warnings.warn(msg, category=FutureWarning)
'''
scaler = StandardScaler()
scaler.fit(df.values[:,:-1])
df.values[:,:-1] = scaler.transform(df.values[:,:-1]).round(4)
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]
n_epochs = 200000
learning_rate = 1e-4
print_interval = 10000
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(x))
h = self.act(self.linear3(x))
y = self.linear4(h)
return y
model = MyModel(x.size(-1),y.size(-1))
print(model)
'''
MyModel(
(linear1): Linear(in_features=13, out_features=3, bias=True)
(linear2): Linear(in_features=3, out_features=3, bias=True)
(linear3): Linear(in_features=3, out_features=3, bias=True)
(linear4): Linear(in_features=3, out_features=1, bias=True)
(act): ReLU()
)
'''
# nn.Sequential 클래스 활용
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)),
)
print(model)
'''
Sequential(
(0): Linear(in_features=13, out_features=3, bias=True)
(1): LeakyReLU(negative_slope=0.01)
(2): Linear(in_features=3, out_features=3, bias=True)
(3): LeakyReLU(negative_slope=0.01)
(4): Linear(in_features=3, out_features=3, bias=True)
(5): LeakyReLU(negative_slope=0.01)
(6): Linear(in_features=3, out_features=3, bias=True)
(7): LeakyReLU(negative_slope=0.01)
(8): Linear(in_features=3, out_features=1, bias=True)
)
'''
optimizer = optim.SGD(model.parameters(), lr = learning_rate)
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 = %.4f'%(i +1, loss))
'''
Epoch 10000: loss = 10.3824
Epoch 20000: loss = 9.6467
Epoch 30000: loss = 9.6246
...
Epoch 180000: loss = 9.1355
Epoch 190000: loss = 9.1348
Epoch 200000: loss = 9.1341
'''
df = pd.DataFrame(torch.cat([y, y_hat], dim = 1).detach().numpy(), columns = ['y','y_hat'])
sns.pairplot(df, height =5)
plt.show()