用python语言设计一个神经网络,用于解决二分类问题。数据是随机生成的二维平面上的2条圆环,每条圆环属于一个类。基于PyTorch编写代码,训练网络,实现分类,并可视化分类边界。 输出结果参考 epoch loss test loss 。还要输出图像
时间: 2024-11-27 08:09:07 浏览: 3
为了使用Python和PyTorch设计一个简单的神经网络来解决这个二分类问题,我们首先需要导入必要的库,然后生成数据、创建模型、定义损失函数和优化器,接着训练网络并可视化结果。以下是完整的代码示例:
```python
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
import numpy as np
import matplotlib.pyplot as plt
# 数据生成
class RingDataset(Dataset):
def __init__(self, n_samples=500, radius=1.5, noise=0.1):
self.n_samples = n_samples
self.radius = radius
self.noise = noise
self.x1 = np.random.uniform(-radius, radius, (n_samples,))
self.y1 = np.zeros(n_samples)
self.x2 = np.random.uniform(radius, 2*radius, (n_samples,))
self.y2 = np.ones(n_samples)
def __len__(self):
return self.n_samples
def __getitem__(self, idx):
x = torch.tensor(np.stack([self.x1[idx], self.x2[idx]]), dtype=torch.float)
y = torch.tensor(np.array([self.y1[idx], self.y2[idx]]), dtype=torch.long) # one-hot encoding
return x, y
# 定义模型
class NeuralNetwork(nn.Module):
def __init__(self, input_dim=2, hidden_dim=8, output_dim=2):
super(NeuralNetwork, self).__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.relu = nn.ReLU()
self.dropout = nn.Dropout(0.2)
self.fc2 = nn.Linear(hidden_dim, output_dim)
def forward(self, x):
out = self.fc1(x)
out = self.relu(out)
out = self.dropout(out)
out = self.fc2(out)
return out
# 训练设置
input_dim = 2
hidden_dim = 8
output_dim = 2
learning_rate = 0.001
num_epochs = 100
dataset = RingDataset()
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
model = NeuralNetwork(input_dim, hidden_dim, output_dim)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
def train(epoch):
model.train()
for data, target in dataloader:
optimizer.zero_grad()
output = model(data)
loss = criterion(output, target)
loss.backward()
optimizer.step()
if (epoch+1) % 10 == 0:
print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item()}")
# 训练并保存模型
for epoch in range(num_epochs):
train(epoch)
# 测试
model.eval()
test_loss = 0
with torch.no_grad():
for data, _ in dataloader:
output = model(data)
test_loss += criterion(output, data[:, 1]).item() # 使用one-hot编码的实际类别计算测试损失
print(f"Test Loss: {test_loss / len(dataloader)}")
# 可视化
x_test, y_test = [], []
for _, (data, _) in enumerate(dataloader):
x_test.extend(data[:, 0].numpy())
y_test.extend((data[:, 1] == 1).numpy()) # 将标签转换为布尔值
x_test, y_test = np.array(x_test), np.array(y_test)
plt.scatter(x_test[y_test], x_test[~y_test], c=['red', 'blue'])
decision_boundary = model(torch.tensor(x_test)).argmax(dim=1).numpy()
plt.plot(x_test[decision_boundary == 0], y_test[decision_boundary == 0], color='gray', linestyle='--')
plt.xlabel('X1'), plt.ylabel('X2')
plt.title('Classification Boundary')
plt.show()
```
运行此代码后,你会看到每个训练周期的损失输出以及测试集的损失。最后,它会绘制出两个类别的点和分类边界的图。注意这只是一个基本的示例,实际应用中可能需要调整网络结构、学习率等参数以获得更好的性能。
阅读全文