一.感知器模型
给定样本集 ,使用python编写感知器模型,并测试样本点的类别
1.数据集
我们的数据集由三个二维特征向量组成,X = [(4, 4), (5, 4), (1, 1)]
,以及相对应的标签 Y = [1, 1, -1]
。这里,正类用 1
表示,负类用 -1
表示。
2.感知器的Python实现
首先,我们定义一个Perceptron
类,它包含了以下方法:
①构造函数 __init__(self, eta=1, n_iter=10)
这个方法会初始化学习率eta
和迭代次数n_iter
。学习率决定了模型权重调整的幅度,迭代次数则是模型在整个训练数据集上运行的次数。
②训练方法 fit(self, X, y)
该方法负责模型的训练过程。它初始化权重向量self.w_
为全零向量,其大小为特征数量加上偏置项。然后,它进入两个嵌套循环,外层循环遍历每一次迭代,内层循环遍历每个训练样本。权重的更新基于模型预测和真实标签之间的误差。
③辅助方法 net_input(self, X)
这个方法计算权重向量和特征向量的点积,加上偏置项,其结果是决策函数的值。
④预测方法 predict(self, X)
这个方法使用net_input
方法的输出来预测新样本的类别。如果点积结果大于等于零,预测类别为1
,否则为-1
。
3.训练模型
创建Perceptron
实例时,我们设置学习率为0.01
,迭代次数为10
。然后使用我们的数据集来训练模型。
4.完整代码
import numpy as np
import matplotlib.pyplot as plt
# 定义感知器类
class Perceptron:
def __init__(self, eta=1, n_iter=10):
self.eta = eta # 学习率
self.n_iter = n_iter # 迭代次数
def fit(self, X, y):
self.w_ = np.zeros(1 + X.shape[1]) # 初始化权重向量
self.errors_ = [] # 错误分类的次数记录
for _ in range(self.n_iter):
errors = 0
for xi, target in zip(X, y):
update = self.eta * (target - self.predict(xi))
self.w_[1:] += update * xi # 更新权重
self.w_[0] += update # 更新偏置项
errors += int(update != 0.0)
self.errors_.append(errors)
return self
def net_input(self, X):
return np.dot(X, self.w_[1:]) + self.w_[0] # 计算净输入
def predict(self, X):
return np.where(self.net_input(X) >= 0.0, 1, -1) # 预测类别
# 创建训练数据
p_x = np.array([[4, 4], [5, 4], [1, 1]])
y = np.array([1, 1, -1])
# 可视化训练数据
for i in range(len(p_x)):
if y[i] == 1:
plt.plot(p_x[i][0], p_x[i][1], 'ro')
else:
plt.plot(p_x[i][0], p_x[i][1], 'bo')
# 训练感知器模型
model = Perceptron(0.01, 10)
model.fit(p_x, y)
# 打印权重
print(model.w_)
# 预测新样本并可视化
result = model.predict([0, 1])
print(result)
# 可视化新的预测点
if result == 1:
plt.plot(0, 1, 'ro')
else:
plt.plot(0, 1, 'bo')
plt.show()
5.结果
经过十次迭代后感知器权重为(0.02,0.02),偏置值为-0.04 。由此预测样本点(0,1)的标签为-1 。
二.人工神经网络
1.简介
手写数字识别是计算机视觉中的一个重要任务,它涉及识别和分类手写数字的图像。我们将使用PyTorch库来构建一个深度神经网络,该网络可以学习如何识别0到9的手写数字。
2.数据准备
首先,我们需要准备训练和测试数据。我们将使用MNIST数据集,它包含大量的手写数字图像,每个图像都标有相应的数字。以下是数据准备的代码:
import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
# 设置批处理大小、学习率和训练次数
batch_size = 200
learning_rate = 1e-4
num_epochs = 50
# 是否下载MNIST数据集
download_mnist = True
# 创建训练数据集和测试数据集
train_dataset = datasets.MNIST(
root='D:\A学习文件\寒假学习过程',
train=True,
transform=transforms.ToTensor(),
download=download_mnist
)
test_dataset = datasets.MNIST(
root='D:\A学习文件\寒假学习过程',
train=False,
transform=transforms.ToTensor(),
download=download_mnist
)
# 创建数据加载器,用于分批训练和测试
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
在这里,我们使用torchvision
库加载MNIST数据集,并将数据转换为张量。我们还创建了训练和测试数据加载器,以便在训练和测试时分批处理数据。
3.构建神经网络模型
接下来,我们将构建一个简单的神经网络模型,用于手写数字识别。这个模型包含一个输入层、两个隐藏层和一个输出层。以下是模型的代码:
import torch.nn as nn
class NeuralNetwork(nn.Module):
def __init__(self, input_dim, hidden_dim1, hidden_dim2, output_dim):
super(NeuralNetwork, self).__init__()
self.layer1 = nn.Linear(input_dim, hidden_dim1)
self.layer2 = nn.Linear(hidden_dim1, hidden_dim2)
self.layer3 = nn.Linear(hidden_dim2, output_dim)
def forward(self, x):
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
return x
这个神经网络具有三个全连接层,它们将输入图像数据映射到输出类别。其中,input_dim
表示输入的维度(MNIST图像的扁平化表示),hidden_dim1
和 hidden_dim2
表示两个隐藏层的维度,output_dim
表示输出的维度(类别数)。
4.模型训练和测试
现在,我们已经准备好了数据和模型,接下来是模型的训练和测试部分。以下是这两个阶段的代码:
import torch.optim as optim
from torch.autograd import Variable
# 创建神经网络模型
model = NeuralNetwork(28 * 28, 300, 100, 10)
# 如果可用GPU,将模型转移到GPU上
if torch.cuda.is_available():
model = model.cuda()
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
# 训练循环
for epoch in range(num_epochs):
print('Epoch {}'.format(epoch + 1))
running_loss = 0.0
running_acc = 0.0
# 开始训练
for i, data in enumerate(train_loader, 1):
img, label = data
img = img.view(img.size(0), -1)
if torch.cuda.is_available():
img = Variable(img).cuda()
label = Variable(label).cuda()
else:
img = Variable(img)
label = Variable(label)
out = model(img)
loss = criterion(out, label)
running_loss += loss.item() * label.size(0)
pred = torch.max(out, 1)
num_correct = (pred[1] == label).sum()
running_acc += num_correct.item()
optimizer.zero_grad()
loss.backward()
optimizer.step()
print('Finish {} epoch, Loss: {:.6f}, Acc: {:.6f}'.format(
epoch + 1, running_loss / (len(train_dataset)), running_acc / len(train_dataset)
))
# 测试
model.eval()
eval_loss = 0
eval_acc = 0
for data in test_loader:
img, label = data
img = img.view(img.size(0), -1)
if torch.cuda.is_available():
img = Variable(img).cuda()
label = Variable(label).cuda()
else:
img = Variable(img)
label = Variable(label)
out = model(img)
loss = criterion(out, label)
eval_loss += loss.item() * label.size(0)
_, pred = torch.max(out, 1)
num_correct = (pred == label).sum()
eval_acc += num_correct.item()
print('Test Loss: {:.6f}, Acc: {:.6f}'.format(
eval_loss / (len(test_dataset)), eval_acc / len(test_dataset)
))
在这个部分,我们首先创建了神经网络模型,定义了损失函数和优化器。然后,我们进行了模型的训练和测试。训练循环中,我们遍历了训练数据加载器中的批次数据,计算损失并更新模型参数。测试循环中,我们使用测试数据对模型进行评估并计算损失和准确率。