bpnn算法实现手写数字识别,要求使用mnist数据集,使用Python语言,不用keras,TensorFlow等框架
时间: 2024-02-06 20:04:18 浏览: 87
好的,我可以为您提供一个简单的bpnn算法实现手写数字识别的Python代码。这个代码使用了mnist数据集,但是没有使用任何深度学习框架,完全是手写的代码。代码如下:
```python
import numpy as np
import struct
def load_mnist_data(data_path):
with open(data_path + 'train-images.idx3-ubyte', 'rb') as f:
train_images = f.read()
with open(data_path + 'train-labels.idx1-ubyte', 'rb') as f:
train_labels = f.read()
with open(data_path + 't10k-images.idx3-ubyte', 'rb') as f:
test_images = f.read()
with open(data_path + 't10k-labels.idx1-ubyte', 'rb') as f:
test_labels = f.read()
# 解析数据集
train_images = parse_images(train_images)
train_labels = parse_labels(train_labels)
test_images = parse_images(test_images)
test_labels = parse_labels(test_labels)
return train_images, train_labels, test_images, test_labels
def parse_images(data):
magic, num, rows, cols = struct.unpack_from('>IIII', data)
offset = struct.calcsize('>IIII')
images = np.empty((num, rows, cols))
for i in range(num):
image = struct.unpack_from('>784B', data, offset)
offset += struct.calcsize('>784B')
images[i] = np.array(image).reshape(28, 28)
return images
def parse_labels(data):
magic, num = struct.unpack_from('>II', data)
offset = struct.calcsize('>II')
labels = np.empty(num)
for i in range(num):
label = struct.unpack_from('>B', data, offset)
offset += struct.calcsize('>B')
labels[i] = label
return labels
def sigmoid(x):
return 1.0 / (1.0 + np.exp(-x))
def sigmoid_derivative(x):
return x * (1.0 - x)
class NeuralNetwork:
def __init__(self, input_size, hidden_size, output_size):
self.weights1 = np.random.randn(input_size, hidden_size)
self.weights2 = np.random.randn(hidden_size, output_size)
def forward(self, x):
self.z2 = np.dot(x, self.weights1)
self.a2 = sigmoid(self.z2)
self.z3 = np.dot(self.a2, self.weights2)
y_hat = sigmoid(self.z3)
return y_hat
def backward(self, x, y, y_hat, learning_rate):
delta3 = (y_hat - y) * sigmoid_derivative(y_hat)
d_weights2 = np.dot(self.a2.T, delta3)
delta2 = np.dot(delta3, self.weights2.T) * sigmoid_derivative(self.a2)
d_weights1 = np.dot(x.T, delta2)
self.weights1 -= learning_rate * d_weights1
self.weights2 -= learning_rate * d_weights2
def train(self, x, y, learning_rate):
y_hat = self.forward(x)
self.backward(x, y, y_hat, learning_rate)
def predict(self, x):
y_hat = self.forward(x)
return np.argmax(y_hat, axis=1)
if __name__ == '__main__':
train_images, train_labels, test_images, test_labels = load_mnist_data('data/mnist/')
train_images = train_images.reshape(train_images.shape[0], -1)
test_images = test_images.reshape(test_images.shape[0], -1)
input_size = train_images.shape[1]
hidden_size = 100
output_size = 10
nn = NeuralNetwork(input_size, hidden_size, output_size)
num_epochs = 100
batch_size = 100
learning_rate = 0.1
num_batches = train_images.shape[0] // batch_size
for epoch in range(num_epochs):
for i in range(num_batches):
batch_start = i * batch_size
batch_end = batch_start + batch_size
x = train_images[batch_start:batch_end]
y = np.zeros((batch_size, output_size))
y[np.arange(batch_size), train_labels[batch_start:batch_end].astype(int)] = 1
nn.train(x, y, learning_rate)
train_acc = np.mean(nn.predict(train_images) == train_labels)
test_acc = np.mean(nn.predict(test_images) == test_labels)
print('Epoch: %d, Train accuracy: %f, Test accuracy: %f' % (epoch, train_acc, test_acc))
```
这个代码的思路是:首先加载mnist数据集,然后定义一个包含一个隐层的神经网络,使用随机初始化的权重对神经网络进行训练。训练时每次读入一个batch的数据,然后使用反向传播算法对权重进行更新。最后输出训练和测试集上的准确率。
阅读全文