机器学习 - 使用 make_moons 做 binary classification (含代码)

直接上代码

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

结果1

结果2


点个赞呗~

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值