- 昨天看過 Linear Regression 的部分了,那我們今天來還債 XDD
- 大家還記得在 Day-09 那醜陋的 Logistic Regression Python code 嗎 QQ,我們今天就用 Pytorch 一樣來解決一下問題,並且看看如果要利用 Pytorch 改寫的話,應該如何去改寫吧~
一樣上 Code~
- Pytorch 的 Logistic Regression 建立
# 1) model build
# sigmoid function 交給了 torch.sigmoid
class LogisticRegression(nn.Module):
def __init__(self, input_dim):
super(LogisticRegression, self).__init__()
# define layers
self.linear = nn.Linear(input_dim, 1)
def forward(self, x):
y_predicted = torch.sigmoid(self.linear(x))
return y_predicted
model = LogisticRegression(n_features)
- loss function 的 Cross Entropy 也交給 Pytorch 的 Binary Cross Entropy
# BCE stands for Binary Cross Entropy
criterion = nn.BCELoss()
- Optimizer 一樣麻煩我們的 Gradient Descent
# SGD stands for stochastic gradient descent
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
完整版
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
# 0) data import and preprocessing
from sklearn import datasets
iris = datasets.load_iris()
# print(iris.DESCR)
# use pandas as dataframe and merge features and targetsf
feature = pd.DataFrame(iris.data, columns=iris.feature_names)
target = pd.DataFrame(iris.target, columns=['target'])
iris_data = pd.concat([feature, target], axis=1)
# keep only sepal length in cm, sepal width in cm and target
iris_data = iris_data[['sepal length (cm)', 'sepal width (cm)', 'target']]
# keep only Iris-Setosa and Iris-Versicolour classes
iris_data = iris_data[iris_data.target <= 1]
iris_data.head(5)
feature = iris_data[['sepal length (cm)', 'sepal width (cm)']]
target = iris_data[['target']]
n_samples, n_features = feature.shape
# split training data and testing data
from sklearn.model_selection import train_test_split
feature_train, feature_test, target_train, target_test = train_test_split(
feature, target, test_size=0.3, random_state=4
)
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
feature_train = sc.fit_transform(feature_train)
feature_test = sc.fit_transform(feature_test)
target_train = np.array(target_train)
target_test = np.array(target_test)
# change data to torch
feature_train = torch.from_numpy(feature_train.astype(np.float32))
feature_test = torch.from_numpy(feature_test.astype(np.float32))
target_train = torch.from_numpy(target_train.astype(np.float32))
target_test = torch.from_numpy(target_test.astype(np.float32))
# 1) model build
# sigmoid function 交給了 torch.sigmoid
class LogisticRegression(nn.Module):
def __init__(self, input_dim):
super(LogisticRegression, self).__init__()
# define layers
self.linear = nn.Linear(input_dim, 1)
def forward(self, x):
y_predicted = torch.sigmoid(self.linear(x))
return y_predicted
model = LogisticRegression(n_features)
# 2) loss and optimizer
learning_rate = 0.01
# BCE stands for Binary Cross Entropy
criterion = nn.BCELoss()
# SGD stands for stochastic gradient descent
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
# 3) Training loop
epochs = 100
for epoch in range(epochs):
# forward pass and loss
y_predicted = model(feature_train)
loss = criterion(y_predicted, target_train)
# backward pass
loss.backward()
# optimizer
optimizer.step()
# init optimizer
optimizer.zero_grad()
if (epoch + 1) % 10 == 0:
print(f'epoch {epoch + 1}: loss = {loss:.8f}')
# checking testing accuracy
with torch.no_grad():
y_predicted = model(feature_test)
y_predicted_cls = y_predicted.round()
acc = y_predicted_cls.eq(target_test).sum() / float(target_test.shape[0])
print(f'accuracy = {acc: .4f}')
每日小結
- 可以看到我們已經可以裡用 PyTorch 靈活的建立需要的 Model 來做到訓練跟預測的狀況了
- Logistic Regression 跟昨天的 Linear Regression 並沒有太大的差別,主要差別就差在多了一個 sigmoid function,而 Pytorch 也有提供 sigmoid function
- 那今天再示範一次前面已經寫過的東西想強調的部分就是,在 Pytorch Model Class 的撰寫過程中,最重要的就是
__init__
跟 forward()
了,因為他們分別宣告了要層層傳遞的部分和要執行的流程,也就是說,我們在上面的例子可以看到 forward()
裡面說明了我們實際上是先做一次 linear 計算,之後才做 sigmoid,這也代表著如果今天遇到一個未知網路,我們都可以裡用撰寫者寫的 forward()
function 去理解這個神經網路是如何傳遞資料的,因此整個 Model 最重要的可以說是這個部份了
- 我們到現在基本上快要整個 Code 都用 Pytorch 來改造了,只差最後一個部份了,就是我們的資料集,讓我們明天來看看 Pytorch 的 Dataset 跟 Dataloader 吧~