分别利用手写 BP 网络和卷积神经网络 (CNN) 完成汉字识别任务

分别利用手写 BP 网络和卷积神经网络 (CNN) 完成汉字识别任务

一、源码地址

https://github.com/busyforest/CharClassify

二、文件结构
  • CharClassify_BP 目录:用手写 BP 网络实现对 12 个汉字分类。

    • train_data 目录:训练数据,其中每个汉字的第 1-500 个 .bmp 文件用作训练集,501-620用作测试集。
    • weights 目录:保存训练出来的网络的权重参数。
    • CharClassify_Cross_L2.py :实现汉字分类模型的训练。
    • Test.py :将测试集中的图片依次取出并利用 image_to_vector() 转换,进行识别,根据输出概率最大的 index 进行选择,打印识别结果并统计正确率。
  • CharClassify_CNN 目录:实现 CNN 网络分类任务。

    • Le_Net5_model.py :根据 Yann LeCun 的论文 Gradient-Based Learning Applied to Document Recognition ,构造了一个 Le_Net5 卷积神经网络。
    • train.py :载入数据集,用 CPU 训练该网络。
    • train_GPU.py :载入数据集,用 GPU 训练该网络。
    • test.py :用测试集测试该网络的正确率。
    • train_data_CNN :用于 CNN 网络的训练集和测试集,和 BP 网有所不同,CNN 的数据集以文件夹的形式载入,所以我手动把测试集和训练集分成了 testtrain 两个文件夹。
    • model.pkl :训练好的模型以 .pkl 文件形式保存在这里。
三、原理简介

我们分别使用普通的 BP 网络和卷积神经网络进行 12 个手写汉字识别任务。数据集和测试集均为 128x128 的 .bmp 格式的灰度图像,可以自己准备数据集,并相应修改代码中处理文件的方法。

  • 关于 BP 网络

    BP 网络的原理已经在我上一篇文章中介绍过,参见 手写BP网络拟合一元非线性函数(附数学原理公式推导)。在本次任务中,我们采用一个简单的三层神经网络来实现。其中中间层激活函数使用 sigmoid,输出层激活函数使用 softmax。损失函数采用 Cross-Entrophy。

    • softmax函数将一个向量中的每个元素转换为一个[0,1]范围内的概率值,并且这些概率值的总和为1。这样,输出向量中的每个元素都可以解释为一个特定类别的概率。对于一个输入向量 ( x ) ,Softmax 函数的计算公式为:

      softmax ( x i ) = e x i ∑ j e x j \text{softmax}(x_i) = \frac{e^{x_i}}{\sum_{j} e^{x_j}} softmax(xi)=jexjexi

      在汉字分类任务中,神经网络会输出每个类别的得分(在这里表现为归一化之前的概率),Softmax 函数将这些得分转换为归一化之后的概率分布,从而确定汉字最有可能属于哪个类别。

    • Cross-entropy(交叉熵损失函数):交叉熵是用来评估当前训练得到的概率分布与真实分布的差异情况。 它刻画的是实际输出(概率)与期望输出(概率)的距离,也就是交叉熵的值越小, 两个概率分布就越接近。

    • 交叉熵损失函数的优势在于当梯度小的时候权重更新的就相应更慢,梯度大的时候更新更快。 这解决了 sigmoid 在两端梯度很小,权重更新慢的问题。另外,sigmoid 在执行分类任务时很容易落入局部最优解,即使使用梯度下降也难以得到全局最优解。

  • 关于卷积神经网络 (CNN)

    • CNN模型的基本结构如下所示:
      • 输入层:接受手写汉字图片的像素值作为输入。
      • 卷积层:包含多个卷积核,用于提取特征。
      • 池化层:进行下采样,减少参数数量,同时保留特征。
      • 全连接层:将池化层输出展平,连接到一个或多个全连接层。 输出层:使用 softmax 函数将全连接层的输出转换为类别概率
    • 源码中的 CNN 部分调用 pytorch 库实现了一个简单的 LeNet5,结构如下:
      • 卷积层C1:6个5x5的卷积核,输出6个特征图,使用ReLU激活函数。
      • 最大池化层S2:2x2的窗口进行下采样。
      • 卷积层C3:16个5x5的卷积核,输出16个特征图,使用ReLU激活函数。
      • 最大池化层S4:2x2的窗口进行下采样。
      • 卷积层C5:120个5x5的卷积核。
      • 全连接层F6:连接120个神经元的隐藏层。
      • 输出层Output:输出10个类别的结果

    更多关于 LeNet5 及卷积神经网络的内容可参见这篇论文 Gradient-based learning applied to document recognition

四、代码简析

1、关于 BP 网络

import datetime

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image


def cross_entropy(y_true, y_pred):
    return -np.sum(y_true * np.log(y_pred))


def sigmoid(x):
    return 1 / (1 + np.exp(-x))


def sigmoid_derivative(x):
    return x * (1 - x)


def softmax(x):
    exp_x = np.exp(x - np.max(x))
    return exp_x / np.sum(exp_x)


def recognize(index):
    switcher = {
   
   
        1: "博",
        2: "学",
        3: "笃",
        4: "志",
        5: "切",
        6: "问",
        7: "近",
        8: "思",
        9: "自",
        10: "由",
        11: "无",
        12: "用"

    }
    return switcher.get(index, "nothing")


def image_to_vector(i, j):
    image = Image.open("train_data/train/{}/{}.bmp".format(i, j))
    # 获取图像的尺寸
    width, height = image.size
    # 创建一个空的NumPy数组来存储灰度值
    gray_array = np.empty((height, width), dtype=np.uint8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

busyforest

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值