纯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日

相关文章

  • numpy中hstack vstack stack concatenate函数示例详解

    在NumPy中,我们可以使用hstack、vstack、stack和concatenate函数来合并数组。以下是对这些函数的详细攻略: hstack函数 hstack函数可以将多个数组按水平方向(列方向)合并。以下是一个使用hstack函数合并数组的示例: import numpy as np # 创建两个一维数组 a = np.array([1, 2, 3…

    python 2023年5月14日
    00
  • Numpy array数据的增、删、改、查实例

    以下是关于“Numpy数组数据的增、删、改、查实例”的完整攻略。 Numpy数组简介 Numpy是Python的一个科学计算库,提了高效的数组和矩阵运算。Numpy中的数组是一个多维数组对象,可以用于存储和处理大量数据。 创建Numpy数组 在Numpy中,可以使用array()函数创建一个。下面是一个示例代码,演示如何创建一个Numpy数组: import…

    python 2023年5月14日
    00
  • python numpy中cumsum的用法详解

    以下是关于“Python Numpy中cumsum的用法详解”的完整攻略。 cumsum简介 cumsum是Numpy中的一个函数,用于计数组元素的累加和。cumsum函数返回一个新的数组,其中个元素都是原始数组中前面所有元素的和。 cumsum函数的语法 cumsum函数语法如下: numpysum(arr, axis=None, dtype=None, …

    python 2023年5月14日
    00
  • python保存大型 .mat 数据文件报错超出 IO 限制的操作

    在Python中,我们可以使用scipy.io库来读取和保存.mat格式的数据文件。但是,当我们要保存大型.mat数据文件时,可能会遇到超出IO限制的操作报错。本文将详细讲解如何解决这个问题,并提供两个示例说明。 问题描述 当我们要保存大型.mat数据文件时,可能会遇到以下报错: OSError: [Errno 27] File too large 这是因为…

    python 2023年5月14日
    00
  • 关于Python常用函数中NumPy的使用

    Python常用函数之NumPy库的使用 NumPy库的基本概念 NumPy是Python中一个非常流行的学计算库,提供了许多常用函数和工具。Py的要点是提供高效的多维,可以快速数学运算和数据处理。 安装NumPy库 在使用NumPy库之前需要先安装它。可以使用pip命令来安装NumPy库。在命令行中输入以下命令: pip install numpy 导入N…

    python 2023年5月13日
    00
  • 使用Pytorch搭建模型的步骤

    使用Pytorch搭建模型的步骤 Pytorch是一个流行的深度学习框架,可以用于搭建各种类型的神经网络模型。本攻略将介绍使用Pytorch搭建模型的步骤。以下是整个攻略的步骤: 导入必要库。可以使用以下命令导入必要的库: import torch import torch.nn as nn import torch.optim as optim 定义模型。…

    python 2023年5月14日
    00
  • pytorch读取图像数据转成opencv格式实例

    在PyTorch中,读取图像数据并将其转换为OpenCV格式是一种常见的图像处理技术。以下是将PyTorch读取的图像数据转换为OpenCV格式的完整攻略,包括代码实现的步骤和示例说明: 导入库 import cv2 import torch from torchvision import transforms 这个示例中,我们导入了OpenCV、PyTor…

    python 2023年5月14日
    00
  • Python3安装tensorflow及配置过程

    Python3安装TensorFlow及配置过程 本攻略将介绍如何在Python3中安装TensorFlow,并提供一些常见问题的解决方案。 1. 安装Python3 首先,我们需要安装Python3。可以从Python官网下载适合自己操作系统的版本:https://www.python.org/downloads/ 安装完成后,打开命令行窗口,输入以下命令…

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