首先,我们可以使用深度神经网络来实现手写体数字识别。以下是一个示例代码:
“`python
import gzip
import numpy as np
import matplotlib.pyplot as plt
# 加载数据
def load_data():
with gzip.open(‘mnist.pkl.gz’, ‘rb’) as f:
train_data, valid_data, test_data = pickle.load(f, encoding=’latin1′)
return train_data, valid_data, test_data
# 可视化图像
def visualize_data(images, labels):
fig, axes = plt.subplots(2, 5, figsize=(10, 4))
for i, ax in enumerate(axes.flat):
ax.imshow(images[i].reshape(28, 28), cmap=’binary’)
ax.set_xticks([])
ax.set_yticks([])
ax.set_title(labels[i])
plt.show()
# 标准化图像像素
def normalize_data(data):
mean = np.mean(data)
std = np.std(data)
normalized_data = (data – mean) / std
return normalized_data
# 打包样本
def pack_samples(images, labels):
samples = [(image, label) for image, label in zip(images, labels)]
return samples
# 设计神经网络参数
input_size = 784 # 输入层大小(28×28)
hidden_size = 128 # 隐藏层大小
output_size = 10 # 输出层大小(0-9的数字)
# 加载数据
train_data, valid_data, test_data = load_data()
# 可视化部分数据
visualize_data(train_data[0][:10], train_data[1][:10])
# 标准化数据
train_images = normalize_data(train_data[0])
train_labels = train_data[1]
# 打包样本
train_samples = pack_samples(train_images, train_labels)
# MLP神经网络
class MLP:
def __init__(self, input_size, hidden_size, output_size):
self.input_size = input_size
self.hidden_size = hidden_size
self.output_size = output_size
# 初始化权重和偏置
self.weights1 = np.random.randn(self.input_size, self.hidden_size)
self.bias1 = np.zeros(self.hidden_size)
self.weights2 = np.random.randn(self.hidden_size, self.output_size)
self.bias2 = np.zeros(self.output_size)
def forward(self, x):
# 前向传播
self.hidden_layer = np.dot(x, self.weights1) + self.bias1
self.hidden_activation = self.sigmoid(self.hidden_layer)
self.output_layer = np.dot(self.hidden_activation, self.weights2) + self.bias2
self.output_activation = self.softmax(self.output_layer)
return self.output_activation
def sigmoid(self, x):
return 1 / (1 + np.exp(-x))
def softmax(self, x):
exps = np.exp(x – np.max(x))
return exps / np.sum(exps, axis=1, keepdims=True)
def train(self, x, y, learning_rate=0.1):
# 反向传播和参数更新
output = self.forward(x)
error = output – y
grad_output = error / x.shape[0]
grad_weights2 = np.dot(self.hidden_activation.T, grad_output)
grad_bias2 = np.sum(grad_output, axis=0)
grad_hidden = np.dot(grad_output, self.weights2.T) * self.sigmoid_derivative(self.hidden_layer)
grad_weights1 = np.dot(x.T, grad_hidden)
grad_bias1 = np.sum(grad_hidden, axis=0)
self.weights2 -= learning_rate * grad_weights2
self.bias2 -= learning_rate * grad_bias2
self.weights1 -= learning_rate * grad_weights1
self.bias1 -= learning_rate * grad_bias1
def sigmoid_derivative(self, x):
return self.sigmoid(x) * (1 – self.sigmoid(x))
# 创建MLP模型
model = MLP(input_size, hidden_size, output_size)
# 训练模型
for epoch in range(10):
for image, label in train_samples:
image = image.reshape(1, -1)
label = np.eye(output_size)[label].reshape(1, -1)
model.train(image, label)
# 测试模型
test_images = normalize_data(test_data[0])
test_labels = test_data[1]
correct = 0
for image, label in zip(test_images, test_labels):
image = image.reshape(1, -1)
output = model.forward(image)
prediction = np.argmax(output)
if prediction == label:
correct += 1
accuracy = correct / len(test_labels)
print("测试集准确率:", accuracy)
“`
这段代码使用了MNIST数据集进行手写体数字识别。首先,通过`load_data`函数加载数据集,然后使用`visualize_data`函数可视化部分数据。接下来,使用`normalize_data`函数对图像像素进行标准化处理。然后,使用`pack_samples`函数将图像和标签打包成样本。接着,定义了一个MLP类作为神经网络模型,包括前向传播、反向传播和参数更新的方法。最后,创建MLP模型并进行训练和测试。
请注意,这只是一个简单的示例代码,实际应用中可能需要进行更多的调优和改进。