纯numpy数值微分法实现手写数字识别

纯numpy数值微分法实现手写数字识别的完整攻略如下:

1. 数据集准备

首先,我们需要准备手写数字的数据集。可以使用MNIST数据集,该数据集包含60,000个训练图像和10,000个测试图像,每个图像都是28x28像素的灰度图像。可以使用numpy的load函数加载数据集。

import numpy as np

# 加载MNIST数据集
train_data = np.load('mnist_train_data.npy')
train_labels = np.load('mnist_train_labels.npy')
test_data = np.load('mnist_test_data.npy')
test_labels = np.load('mnist_test_labels.npy')

2. 模型定义

接下来,我们需要定义一个简单的神经网络模型。该模型包含一个输入层、一个隐藏层和一个输出层。输入层有784个神经元,隐藏层有128个神经元,输出层有10个神经元,分别对应0-9的数字。

class NeuralNetwork:
    def __init__(self):
        self.input_size = 784
        self.hidden_size = 128
        self.output_size = 10
        self.learning_rate = 0.1

        # 初始化权重和偏置
        self.W1 = np.random.randn(self.input_size, self.hidden_size)
        self.b1 = np.zeros((1, self.hidden_size))
        self.W2 = np.random.randn(self.hidden_size, self.output_size)
        self.b2 = np.zeros((1, self.output_size))

    def forward(self, X):
        # 前向传播
        self.z1 = np.dot(X, self.W1) + self.b1
        self.a1 = np.tanh(self.z1)
        self.z2 = np.dot(self.a1, self.W2) + self.b2
        self.a2 = np.exp(self.z2) / np.sum(np.exp(self.z2), axis=1, keepdims=True)

        return self.a2

    def backward(self, X, y, y_hat):
        # 反向传播
        delta3 = y_hat
        delta3[range(len(X)), y] -= 1
        delta2 = np.dot(delta3, self.W2.T) * (1 - np.power(self.a1, 2))

        dW2 = np.dot(self.a1.T, delta3)
        db2 = np.sum(delta3, axis=0, keepdims=True)
        dW1 = np.dot(X.T, delta2)
        db1 = np.sum(delta2, axis=0)

        # 更新权重和偏置
        self.W2 -= self.learning_rate * dW2
        self.b2 -= self.learning_rate * db2
        self.W1 -= self.learning_rate * dW1
        self.b1 -= self.learning_rate * db1

    def train(self, X, y):
        y_hat = self.forward(X)
        self.backward(X, y, y_hat)

    def predict(self, X):
        y_hat = self.forward(X)
        return np.argmax(y_hat, axis=1)

3. 数值微分法实现

接下来,我们需要实现数值微分法来计算梯度。数值微分法是一种近似计算导数的方法,它通过计算函数在某个点的两个近似值之间的差异来计算导数。在神经网络中,我们可以使用数值微分法来计算梯度,然后使用梯度下降法来更新权重和偏置。

class NumericalGradient:
    def __init__(self, model):
        self.model = model

    def compute_gradients(self, X, y):
        # 计算梯度
        grads = {}
        h = 1e-4

        for param in ['W1', 'b1', 'W2', 'b2']:
            theta = getattr(self.model, param)
            grad = np.zeros_like(theta)

            # 计算梯度
            it = np.nditer(theta, flags=['multi_index'], op_flags=['readwrite'])
            while not it.finished:
                ix = it.multi_index
                old_value = theta[ix]

                # 计算f(x+h)
                theta[ix] = old_value + h
                fxh1 = self.model.loss(X, y)

                # 计算f(x-h)
                theta[ix] = old_value - h
                fxh2 = self.model.loss(X, y)

                # 计算梯度
                grad[ix] = (fxh1 - fxh2) / (2 * h)

                # 恢复原值
                theta[ix] = old_value
                it.iternext()

            grads[param] = grad

        return grads

4. 训练模型

现在,我们可以使用数值微分法来训练我们的神经网络模型。我们可以使用随机梯度下降法来更新权重和偏置,每次迭代使用一个随机的训练样本。

# 创建神经网络模型
model = NeuralNetwork()

# 创建数值微分法对象
grad = NumericalGradient(model)

# 训练模型
for i in range(1000):
    # 随机选择一个训练样本
    idx = np.random.randint(len(train_data))
    X = train_data[idx]
    y = train_labels[idx]

    # 计算梯度
    grads = grad.compute_gradients(X, y)

    # 更新权重和偏置
    for param in ['W1', 'b1', 'W2', 'b2']:
        getattr(model, param) -= 0.1 * grads[param]

    # 打印损失函数值
    if i % 100 == 0:
        loss = model.loss(train_data, train_labels)
        print('Iteration %d, loss = %f' % (i, loss))

5. 测试模型

最后,我们可以使用测试数据集来测试我们的模型。我们可以计算模型的准确率,即正确分类的样本数除以总样本数。

# 测试模型
y_pred = model.predict(test_data)
accuracy = np.mean(y_pred == test_labels)
print('Accuracy:', accuracy)

示例

下面是两个示例,第一个示例展示了如何使用数值微分法计算梯度,第二个示例展示了如何使用随机梯度下降法训练模型。

示例1:计算梯度

# 创建神经网络模型
model = NeuralNetwork()

# 创建数值微分法对象
grad = NumericalGradient(model)

# 计算梯度
grads = grad.compute_gradients(train_data[:10], train_labels[:10])

# 打印梯度
for param in ['W1', 'b1', 'W2', 'b2']:
    print(param, grads[param])

示例2:训练模型

# 创建神经网络模型
model = NeuralNetwork()

# 创建数值微分法对象
grad = NumericalGradient(model)

# 训练模型
for i in range(1000):
    # 随机选择一个训练样本
    idx = np.random.randint(len(train_data))
    X = train_data[idx]
    y = train_labels[idx]

    # 计算梯度
    grads = grad.compute_gradients(X, y)

    # 更新权重和偏置
    for param in ['W1', 'b1', 'W2', 'b2']:
        getattr(model, param) -= 0.1 * grads[param]

    # 打印损失函数值
    if i % 100 == 0:
        loss = model.loss(train_data, train_labels)
        print('Iteration %d, loss = %f' % (i, loss))

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:纯numpy数值微分法实现手写数字识别 - Python技术站

(0)
上一篇 2023年5月14日
下一篇 2023年5月14日

相关文章

  • Python整数与Numpy数据溢出问题解决

    以下是关于“Python整数与Numpy数据溢出问题解决”的完整攻略。 Python整数溢出问题解决 在Python中,整数类型的数据有一个最大值和最小值,当进行运算时,如果结果超出了这个范围,就会发生整数溢出问题。为了解决这个问题,可以使用Python内置的decimal模块或第三方库numpy。 使用decimal模块 decimal模块提供了一种精确的…

    python 2023年5月14日
    00
  • 基于Keras的扩展性使用

    基于Keras的扩展性使用攻略 Keras是一个高级神经网络API,它可以运行在TensorFlow、CNTK和Theano等后端上。Keras提供了简单易用的接口,使得我们可以快速地建和训练神经网络模型。本攻略将详细讲解如何使用Keras构建和训练神经网络模型,并提供两个示例。 步骤一:安装Keras 在使用Keras之前,我们需要先安装Keras。Ker…

    python 2023年5月14日
    00
  • 浅谈python已知元素,获取元素索引(numpy,pandas)

    在Python中,我们可以使用NumPy和Pandas库来处理数组和数据框。本文将详细讲解如何获取已知元素的索引,并提供两个示例说明。 使用NumPy获取已知元素的索引 在NumPy中,我们可以使用where函数来获取已知元素的索引。可以使用以下代码获取已知元素的索引: import numpy as np arr = np.array([1, 2, 3, …

    python 2023年5月14日
    00
  • 对numpy Array [: ,] 的取值方法详解

    以下是关于“对numpyArray[:,]的取值方法详解”的完整攻略。 NumPy简介 NumPy是Python中的一个开源数学库,用于处理大型维数组和矩阵。它提供了高效的数组操作和数学函数,可以用于学计算、数据分析、机器学习等域。 NumPy的主要特点包括: 多维数组对象ndarray,支持向量化算和广播功能。 用于对数组快速操作的标准数学函数。 用于读写…

    python 2023年5月14日
    00
  • numpy 产生随机数的几种方法

    NumPy 产生随机数的几种方法 NumPy是Python中一个非常强大的数学库,它提供了许多高效的数学和工具,特别对于数组矩阵的处理。在NumPy中,我们可以使用种方法来产生随机数。本攻略将介绍NumPy中产生随机数的几种方法,并提供两个示例。 .random.rand()函数 np.random.rand()函数用于指定形状的随机数组,数组中的元素取值范…

    python 2023年5月13日
    00
  • tensorflow模型的save与restore,及checkpoint中读取变量方式

    TensorFlow是一个强大的机器学习框架,它提供了许多工具和API来构建、训练和部署机器学习模型。在TensorFlow中,我们可以使用save和restore函数来保存和加载模型,以及使用checkpoint来保存和恢复变量。 保存和加载模型 保存模型 在TensorFlow中,我们可以使用save函数将模型保存到磁盘上。以下是一个保存模型的示例: i…

    python 2023年5月14日
    00
  • 详解python如何通过numpy数组处理图像

    以下是关于“详解Python如何通过NumPy数组处理图像”的完整攻略。 背景 NumPy是Python中常用的科学计算库,可以用于处理大量的数值数据。在图像处理中,我们可以使用NumPy数组来表示图像,并使用NumPy提供的函数和工具来处理图像。本攻略将介绍如何使用NumPy数组处理图像,并提供两个示例来演示如何使用这些库。 示例1:读取和显示图像 在Py…

    python 2023年5月14日
    00
  • Python使用random模块生成随机数操作实例详解

    Python使用random模块生成随机数操作实例详解 在Python中,可以使用random模块生成随机数。random模块提供了多种生成随机数的函数和方法,可以用于生成整数、浮点数、随机字符串等。本文将详细讲解如何使用random模块生成随机数,并提供两个示例说明。 1. 生成随机整数 在random模块中,可以使用randint(a, b)函数生成指定…

    python 2023年5月14日
    00
合作推广
合作推广
分享本页
返回顶部