keras+卷积神经网络HWDB手写汉字识别

写在前面

HWDB手写汉字数据集来自于中科院自动化研究所,下载地址:

http://www.nlpr.ia.ac.cn/databases/download/feature_data/HWDB1.1trn_gnt.zip

http://www.nlpr.ia.ac.cn/databases/download/feature_data/HWDB1.1tst_gnt.zip

源码

在github上找到源码,下载地址:https://github.com/integeruser/CASIA-HWDB1.1-cnn

按照github上的提示操作:

(1)解压

unzip HWDB1.1trn_gnt.zip
Archive:  HWDB1.1trn_gnt.zip
  inflating: HWDB1.1trn_gnt.alz
unalz HWDB1.1trn_gnt.alz

[error]The program 'unalz' is currently not installed. To run 'unalz' please ask your administrator to install the package 'unalz'

这是出现了错误,只能从windows上解压。

alz解压工具下载链接:http://xz.198424.com/soft2/alzip_cn.zip

(2)建立文件夹并将数据集移动到该文件夹下

mkdir HWDB1.1trn_gnt
mv *.gnt HWDB1.1trn_gnt/

(3) 将数据集转换为HDF5二进制数据格式

python3 1-gnt_to_dataset.py HWDB1.1trn_gnt/ HWDB1.1tst_gnt/

(4) 从HDF5数据集中提取200个字符类的子集

python3 2-dataset_to_subset.py HWDB1.1.hdf5

(5)在子集上训练网络

python3 3-train_subset.py HWDB1.1subset.hdf5

得到精确率如下图所示:

(6)测试

python3 4-draw_results.py HWDB1.1subset.hdf5 model-xx.json weights-xx-xx.hdf5

提示

1. 如果从HDF5数据集中提取多个字符个字符类的子集

更改2-dataset_to_subset.py代码。

2. HWDB可视化(将gnt转为png)

代码参考网址:https://zhuanlan.zhihu.com/p/24698483?refer=burness-DL

# -*- coding: utf-8 -*-
"""
Created on Wed Aug 29 16:45:08 2018

@author: Administrator
"""

import os
import numpy as np
import struct
from PIL import Image

    
data_dir = './data'
# train_data_dir = "../data/HWDB1.1trn_gnt"
train_data_dir = os.path.join(data_dir, 'HWDB1.1trn_gnt')
test_data_dir = os.path.join(data_dir, 'HWDB1.1tst_gnt')


def read_from_gnt_dir(gnt_dir=train_data_dir):
    def one_file(f):
        header_size = 10
        while True:
            header = np.fromfile(f, dtype='uint8', count=header_size)
            if not header.size: break
            sample_size = header[0] + (header[1]<<8) + (header[2]<<16) + (header[3]<<24)
            tagcode = header[5] + (header[4]<<8)
            width = header[6] + (header[7]<<8)
            height = header[8] + (header[9]<<8)
            if header_size + width*height != sample_size:
                break
            image = np.fromfile(f, dtype='uint8', count=width*height).reshape((height, width))
            yield image, tagcode
    for file_name in os.listdir(gnt_dir):
        if file_name.endswith('.gnt'):
            file_path = os.path.join(gnt_dir, file_name)
            with open(file_path, 'rb') as f:
                for image, tagcode in one_file(f):
                    yield image, tagcode
char_set = set()
for _, tagcode in read_from_gnt_dir(gnt_dir=train_data_dir):
    tagcode_unicode = struct.pack('>H', tagcode).decode('gb2312')
    char_set.add(tagcode_unicode)
char_list = list(char_set)
char_dict = dict(zip(sorted(char_list), range(len(char_list))))
print(len(char_dict))
print("char_dict=",char_dict)

import pickle
f = open('char_dict', 'wb')
pickle.dump(char_dict, f)
f.close()
train_counter = 0
test_counter = 0
for image, tagcode in read_from_gnt_dir(gnt_dir=train_data_dir):
    tagcode_unicode = struct.pack('>H', tagcode).decode('gb2312')
    im = Image.fromarray(image)
    dir_name = './data/train/' + '%0.5d'%char_dict[tagcode_unicode]
    if not os.path.exists(dir_name):
        os.mkdir(dir_name)
    im.convert('RGB').save(dir_name+'/' + str(train_counter) + '.png')
    print("train_counter=",train_counter)
    train_counter += 1
for image, tagcode in read_from_gnt_dir(gnt_dir=test_data_dir):
    tagcode_unicode = struct.pack('>H', tagcode).decode('gb2312')
    im = Image.fromarray(image)
    dir_name = './data/test/' + '%0.5d'%char_dict[tagcode_unicode]
    if not os.path.exists(dir_name):
        os.mkdir(dir_name)
    im.convert('RGB').save(dir_name+'/' + str(test_counter) + '.png')
    print("test_counter=",test_counter)
    test_counter += 1

char_dict文件是汉字和对应的数字label的记录。

char_dict汉字顺序是:

char_dict= {'一': 0, '丁': 1, '七': 2, '万': 3, '丈': 4, '三': 5, '上': 6, '下': 7, '不': 8, '与': 9, '丑': 10, '专': 11, '且': 12, '世': 13, '丘': 14, '丙': 15, '业': 16, '丛': 17, '东': 18, '丝': 19, '丢': 20, '两': 21, '严': 22, '丧': 23, '个': 24, '丫': 25, '中': 26, '丰': 27, '串': 28, '临': 29, '丸': 30, '丹': 31, '为': 32, '主': 33, '丽': 34, '举': 35, '乃': 36, '久': 37, '么': 38, '义': 39, '之': 40, '乌': 41, '乍': 42, '乎': 43, '乏': 44, '乐': 45, '乒': 46, '乓': 47, '乔': 48, '乖': 49, '乘': 50, '乙': 51, '九': 52, '乞': 53, '也': 54, '习': 55, '乡': 56, '书': 57, '买': 58, '乱': 59, '乳': 60, '乾': 61, '了': 62, '予': 63, '争': 64, '事': 65, '二': 66, '于': 67, '亏': 68, '云': 69, '互': 70, '五': 71, '井': 72, '亚': 73, '些': 74, '亡': 75, '亢': 76, '交': 77, '亥': 78, '亦': 79, '产': 80, '亨': 81, '亩': 82, '享': 83, '京': 84, '亭': 85, '亮': 86, '亲': 87, '人': 88, '亿': 89, '什': 90, '仁': 91, '仅': 92, '仆': 93, '仇': 94, '今': 95, '介': 96, '仍': 97, '从': 98, '仑': 99, '仓': 100, '仔': 101, '仕': 102, '他': 103, '仗': 104, '付': 105, '仙': 106, '仟': 107, '代': 108, '令': 109, '以': 110, '仪': 111, '们': 112, '仰': 113, '仲': 114, '件': 115, '价': 116, '任': 117, '份': 118, '仿': 119, '企': 120, '伊': 121, '伍': 122, '伎': 123, '伏': 124, '伐': 125, '休': 126, '众': 127, '优': 128, '伙': 129, '会': 130, '伞': 131, '伟': 132, '传': 133, '伤': 134, '伦': 135, '伪': 136, '伯': 137, '估': 138, '伴': 139, '伶': 140, '伸': 141, '伺': 142, '似': 143, '佃': 144, '但': 145, '位': 146, '低': 147, '住': 148, '佐': 149, '佑': 150, '体': 151, '何': 152, '余': 153, '佛': 154, '作': 155, '你': 156, '佣': 157, '佩': 158, '佬': 159, '佯': 160, '佰': 161, '佳': 162, '使': 163, '侄': 164, '侈': 165, '例': 166, '侍': 167, '侗': 168, '供': 169, '依': 170, '侠': 171, '侣': 172, '侥': 173, '侦': 174, '侧': 175, '侨': 176, '侩': 177, '侮': 178, '侯': 179, '侵': 180, '便': 181, '促': 182, '俄': 183, '俊': 184, '俏': 185, '俐': 186, '俗': 187, '俘': 188, '保': 189, '俞': 190, '信': 191, '俩': 192, '俭': 193, '修': 194, '俯': 195, '俱': 196, '俺': 197, '倍': 198, '倒': 199, '倔': 200, '倘': 201, '候': 202, '倚': 203, '借': 204, '倡': 205, '倦': 206, '倪': 207, '债': 208, '值': 209, '倾': 210, '假': 211, '偏': 212, '做': 213, '停': 214, '健': 215, '偶': 216, '偷': 217, '偿': 218, '傀': 219, '傅': 220, '傈': 221, '傍': 222, '傣': 223, '储': 224, '催': 225, '傲': 226, '傻': 227, '像': 228, '僚': 229, '僧': 230, '僳': 231, '僵': 232, '僻': 233, '儒': 234, '儡': 235, '儿': 236, '允': 237, '元': 238, '兄': 239, '充': 240, '兆': 241, '先': 242, '光': 243, '克': 244, '免': 245, '兑': 246, '兔': 247, '党': 248, '兜': 249, '兢': 250, '入': 251, '全': 252, '八': 253, '公': 254, '六': 255, '兰': 256, '共': 257, '关': 258, '兴': 259, '兵': 260, '其': 261, '具': 262, '典': 263, '兹': 264, '养': 265, '兼': 266, '兽': 267, '冀': 268, '内': 269, '冈': 270, '冉': 271, '册': 272, '再': 273, '冒': 274, '冕': 275, '冗': 276, '写': 277, '军': 278, '农': 279, '冠': 280, '冤': 281, '冬': 282, '冯': 283, '冰': 284, '冲': 285, '决': 286, '况': 287, '冶': 288, '冷': 289, '冻': 290, '净': 291, '凄': 292, '准': 293, '凉': 294, '凋': 295, '凌': 296, '减': 297, '凑': 298, '凛': 299, '凝': 300, '几': 301, '凡': 302, '凤': 303, '凭': 304, '凯': 305, '凰': 306, '凳': 307, '凶': 308, '凸': 309, '凹': 310, '出': 311, '击': 312, '函': 313, '凿': 314, '刀': 315, '刁': 316, '刃': 317, '分': 318, '切': 319, '刊': 320, '刑': 321, '划': 322, '列': 323, '刘': 324, '则': 325, '刚': 326, '创': 327, '初': 328, '删': 329, '判': 330, '刨': 331, '利': 332, '别': 333, '刮': 334, '到': 335, '制': 336, '刷': 337, '券': 338, '刹': 339, '刺': 340, '刻': 341, '刽': 342, '剁': 343, '剂': 344, '剃': 345, '削': 346, '前': 347, '剐': 348, '剑': 349, '剔': 350, '剖': 351, '剥': 352, '剧': 353, '剩': 354, '剪': 355, '副': 356, '割': 357, '剿': 358, '劈': 359, '力': 360, '劝': 361, '办': 362, '功': 363, '加': 364, '务': 365, '劣': 366, '动': 367, '助': 368, '努': 369, '劫': 370, '励': 371, '劲': 372, '劳': 373, '势': 374, '勃': 375, '勇': 376, '勉': 377, '勋': 378, '勒': 379, '勘': 380, '募': 381, '勤': 382, '勺': 383, '勾': 384, '勿': 385, '匀': 386, '包': 387, '匆': 388, '匈': 389, '化': 390, '北': 391, '匙': 392, '匝': 393, '匠': 394, '匡': 395, '匣': 396, '匪': 397, '匹': 398, '区': 399, '医': 400, '匿': 401, '十': 402, '千': 403, '升': 404, '午': 405, '卉': 406, '半': 407, '华': 408, '协': 409, '卑': 410, '卒': 411, '卓': 412, '单': 413, '卖': 414, '南': 415, '博': 416, '卜': 417, '卞': 418, '占': 419, '卡': 420, '卢': 421, '卤': 422, '卧': 423, '卫': 424, '卯': 425, '印': 426, '危': 427, '即': 428, '却': 429, '卵': 430, '卷': 431, '卸': 432, '卿': 433, '厂': 434, '厄': 435, '厅': 436, '历': 437, '厉': 438, '压': 439, '厌': 440, '厕': 441, '厘': 442, '厚': 443, '原': 444, '厢': 445, '厦': 446, '厨': 447, '厩': 448, '去': 449, '县': 450, '叁': 451, '参': 452, '又': 453, '叉': 454, '及': 455, '友': 456, '双': 457, '反': 458, '发': 459, '叔': 460, '取': 461, '受': 462, '变': 463, '叙': 464, '叛': 465, '叠': 466, '口': 467, '古': 468, '句': 469, '另': 470, '只': 471, '叫': 472, '召': 473, '叭': 474, '叮': 475, '可': 476, '台': 477, '史': 478, '右': 479, '叶': 480, '号': 481, '司': 482, '叹': 483, '叼': 484, '吁': 485, '吃': 486, '各': 487, '合': 488, '吉': 489, '吊': 490, '同': 491, '名': 492, '后': 493, '吏': 494, '吐': 495, '向': 496, '吓': 497, '吕': 498, '吗': 499, '君': 500, '吝': 501, '吞': 502, '吟': 503, '吠': 504, '否': 505, '吧': 506, '吨': 507, '吩': 508, '含': 509, '听': 510, '吭': 511, '吮': 512, '启': 513, '吱': 514, '吴': 515, '吵': 516, '吸': 517, '吹': 518, '吻': 519, '吼': 520, '吾': 521, '呀': 522, '呆': 523, '呈': 524, '告': 525, '呐': 526, '呕': 527, '员': 528, '呛'
  • 3
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
基于卷神经网络数字识别是一种常见的图像分类问题。下面是一个简单的步骤来实现这个任务: 1.准备数据集:数字数据集通常包含许多数字的图像和相应的标签。可以使用MNIST数据集,该数据集包含60,000个训练图像和10,000个测试图像,每个图像都是28x28像素的灰度图像。 2.预处理数据集:在训练模型之前,需要对数据进行预处理。可以将像素值缩放到0到1之间,并将标签转换为独热编码。 3.构建卷神经网络:卷神经网络是一种常用的神经网络架构,用于处理图像数据。可以使用Keras构建卷神经网络,该网络由卷层、池化层、扁平层和全连接层组成。 4.训练模型:使用训练数据集训练卷神经网络模型。可以使用反向传播算法和随机梯度下降优化器来训练模型。 5.评估模型:使用测试数据集评估模型的性能。可以计算准确率、精确率、召回率和F1分数等指标来评估模型的性能。 6.使用模型进行预测:使用训练好的模型对新的数字图像进行分类预测。 下面是一个简单的Keras代码示例,用于构建和训练卷神经网络模型: ```python import keras from keras.datasets import mnist from keras.models import Sequential from keras.layers import Dense, Dropout, Flatten from keras.layers import Conv2D, MaxPooling2D # 加载MNIST数据集 (x_train, y_train), (x_test, y_test) = mnist.load_data() # 数据预处理 x_train = x_train.reshape(x_train.shape[0], 28, 28, 1) x_test = x_test.reshape(x_test.shape[0], 28, 28, 1) x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /= 255 x_test /= 255 y_train = keras.utils.to_categorical(y_train, 10) y_test = keras.utils.to_categorical(y_test, 10) # 构建卷神经网络模型 model = Sequential() model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1))) model.add(Conv2D(64, (3, 3), activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(128, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(10, activation='softmax')) # 编译模型 model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adadelta(), metrics=['accuracy']) # 训练模型 model.fit(x_train, y_train, batch_size=128, epochs=12, verbose=1, validation_data=(x_test, y_test)) # 评估模型 score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1]) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

蹦跶的小羊羔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值