# this is a recap # a training pipeline generally consists of 3 steps: # 1. Design model (input, output size, forward pass (layers)) # 2. Construct loss and optimizer # 3. Training loop # - forward pass: compute prediction # - backward pass: gradient computation # - update parameters # (iterate step 3) import torch import torch.nn as nn import numpy as np from sklearn import datasets from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split # import matplotlib.pyplot as plt # 0. data preparation bc = datasets.load_breast_cancer() X, y = bc.data, bc.target n_samples, n_features = X.shape # 569 30 # split data into training and test data X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1234) # scale sc = StandardScaler() X_train = sc.fit_transform(X_train) X_test = sc.transform(X_test) X_train = torch.from_numpy(X_train.astype(np.float32)) X_test = torch.from_numpy(X_test.astype(np.float32)) y_train = torch.from_numpy(y_train.astype(np.float32)) y_test = torch.from_numpy(y_test.astype(np.float32)) # reshape y y_train = y_train.view(-1, 1) # y_train.view(y_train.shape[0], 1) y_test = y_test.view(-1, 1) X_train = X_train.to('cuda') X_test = X_test.to('cuda') y_train = y_train.to('cuda') y_test = y_test.to('cuda') # 1. model # f = wx + b, sigmoid at the end class LogReg(nn.Module): def __init__(self, n_input_features): super(LogReg, self).__init__() self.linear = nn.Linear(n_input_features, 1) def forward(self, x): y_pred = torch.sigmoid(self.linear(x)) return y_pred model = LogReg(n_features) model = model.to('cuda') # 2. loss + optimizer learning_rate = .0001 criterion = nn.BCELoss() # binary cross entropy #accuracy at lr = .0001, n_epochs = 100000 # optimizer = torch.optim.SGD(model.parameters(), lr = learning_rate) # 0.93 # optimizer = torch.optim.Adam(model.parameters(), lr = learning_rate) # 0.96 # optimizer = torch.optim.AdamW(model.parameters(), lr = learning_rate) # 0.96 optimizer = torch.optim.SGD(model.parameters(), lr = learning_rate, momentum=0.9) # 0.95 # 3. training n_epochs = 100000 for epoch in range(n_epochs): # forward pass and loss y_pred = model(X_train) loss = criterion(y_pred, y_train) # backward pass loss.backward() # updates and zero gradients optimizer.step() optimizer.zero_grad() if (epoch+1) % (10000) == 0: print(f'{(epoch+1)/n_epochs*100:.1f}% Epoch {epoch+1:>8}: loss = {loss.item():.5f}') # evaluation with torch.no_grad(): # don't track these operations for the gradient computation y_pred = model(X_test) y_pred_cls = y_pred.round() acc = y_pred_cls.eq(y_test).sum() / float(y_test.shape[0]) print(f'Accuracy = {acc:.4f}')