直接上代码
from sklearn.datasets import make_moons
NUM_SAMPLES = 1000
RANDOM_SEED = 42
X, y = make_moons(n_samples = NUM_SAMPLES,
noise = 0.07,
random_state = RANDOM_SEED)
# Turn data into DataFrame
import pandas as pd
data_df = pd.DataFrame({"X0": X[:, 0],
"X1": X[:, 1],
"y": y})
# Visualize the data on a plot
import matplotlib.pyplot as plt
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.RdYlBu)
# Turn data into tensors
import torch
X = torch.tensor(X, dtype = torch.float)
y = torch.tensor(y, dtype = torch.float)
# Split the data into train and test sets
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X,
y,
test_size = 0.2,
random_state = RANDOM_SEED)
from torch import nn
class MoonModelV0(nn.Module):
def __init__(self, in_features, out_features, hidden_units):
super().__init__()
self.layer1 = nn.Linear(in_features = in_features,
out_features = hidden_units)
self.layer2 = nn.Linear(in_features = hidden_units,
out_features = hidden_units)
self.layer3 = nn.Linear(in_features = hidden_units,
out_features = out_features)
self.relu = nn.ReLU()
def forward(self, x):
return self.layer3(self.relu(self.layer2(self.relu(self.layer1(x)))))
model_0 = MoonModelV0(in_features = 2,
out_features = 1,
hidden_units = 10).to("cpu")
# Setup a binary classification commpatible loss function and optimizer
loss_fn = nn.BCEWithLogitsLoss()
optimizer = torch.optim.SGD(params = model_0.parameters(),
lr = 0.1)
# Calculate the accuracy
from torchmetrics import Accuracy
acc_fn = Accuracy(task="multiclass", num_classes = 2).to("cpu")
torch.manual_seed(RANDOM_SEED)
epochs = 1000
for epoch in range(epochs):
## Training
model_0.train()
y_logits = model_0(X_train).squeeze()
y_pred_probs = torch.sigmoid(y_logits)
y_pred = torch.round(y_pred_probs)
loss = loss_fn(y_logits, y_train)
acc = acc_fn(y_pred, y_train.int())
optimizer.zero_grad()
loss.backward()
optimizer.step()
## Testing
model_0.eval()
with torch.inference_mode():
test_logits = model_0(X_test).squeeze()
test_pred = torch.round(torch.sigmoid(test_logits))
test_loss = loss_fn(test_logits, y_test)
test_acc = acc_fn(test_pred, y_test.int())
if epoch % 100 == 0:
print(f"Epoch: {epoch} | Loss: {loss:.2f} Acc: {acc:.2f} | Test loss: {test_loss:.2f} Test acc: {test_acc:.2f}")
# Plot the model predictions
import numpy as np
def plot_decision_boundary(model, X, y):
model.to("cpu")
X, y = X.to("cpu"), y.to("cpu")
x_min, x_max = X[:, 0].min() - 0.1, X[:, 0].max() + 0.1
y_min, y_max = X[:, 1].min() - 0.1, X[:, 1].max() + 0.1
xx, yy = np.meshgrid(np.linspace(x_min, x_max, 101),
np.linspace(y_min, y_max, 101))
X_to_pred_on = torch.from_numpy(np.column_stack((xx.ravel(), yy.ravel()))).float()
model.eval()
with torch.inference_mode():
y_logits = model(X_to_pred_on)
# Test for multi-class or binary and adjust logits to prediction labels
if len(torch.unique(y)) > 2:
y_pred = torch.softmax(y_logits, dim=1). argmax(dim=1)
else:
y_pred = torch.round(torch.sigmoid(y_logits))
# Reshape preds and plot
y_pred = y_pred.reshape(xx.shape).detach().numpy()
plt.contourf(xx, yy, y_pred, cmap=plt.cm.RdYlBu, alpha = 0.7)
plt.scatter(X[:, 0], X[:, 1], c = y, s = 40, cmap = plt.cm.RdYlBu)
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
# Plot decision boundaries for training and test sets
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.title("Train")
plot_decision_boundary(model_0, X_train, y_train)
plt.subplot(1, 2, 2)
plt.title("Test")
plot_decision_boundary(model_0, X_test, y_test)
结果如下:
Epoch: 0 | Loss: 0.70 Acc: 0.37 | Test loss: 0.69 Test acc: 0.50
Epoch: 100 | Loss: 0.39 Acc: 0.82 | Test loss: 0.40 Test acc: 0.76
Epoch: 200 | Loss: 0.24 Acc: 0.88 | Test loss: 0.24 Test acc: 0.89
Epoch: 300 | Loss: 0.20 Acc: 0.91 | Test loss: 0.19 Test acc: 0.94
Epoch: 400 | Loss: 0.17 Acc: 0.93 | Test loss: 0.15 Test acc: 0.94
Epoch: 500 | Loss: 0.12 Acc: 0.95 | Test loss: 0.11 Test acc: 0.96
Epoch: 600 | Loss: 0.08 Acc: 0.98 | Test loss: 0.07 Test acc: 0.99
Epoch: 700 | Loss: 0.06 Acc: 0.99 | Test loss: 0.05 Test acc: 1.00
Epoch: 800 | Loss: 0.04 Acc: 0.99 | Test loss: 0.03 Test acc: 1.00
Epoch: 900 | Loss: 0.03 Acc: 1.00 | Test loss: 0.02 Test acc: 1.00
点个赞呗~