在当今人工智能技术飞速发展的背景下,深度学习技术已成为推动进步的关键力量。特别是在AI领域的诸多应用中,OCR技术已经成为文本识别和图像处理的一个重要分支,传统的OCR技术往往需要人工干预,不仅耗时而且效率不高。而基于深度学习的OCR检测系统,则能够实现自动化的字符识别和缺陷检测。
任务目标
任务难点
1)深度学习的相关算法理解需要有充足的线性代数与高等数学知识储备。
2)程序建模存在一定难度,从模型选择、相关调试到训练数据集有较大的挑战性。
3)程序设计涉及的相关编程语言需要较为坚实的基础,涉及深度学习部分内容需要从头开始学习积累。
4)为了实现最终的OCR系统的便捷性,需要尝试实现离线与在线识别两种功能,同时增加Web端或微信小程序平台的在线识别功能,具有较大的挑战。
工作条件
1.硬件条件
CPU:2.4GHZ Inter(R) Core i5-9300H
显卡:1650Ti
2.软件条件
操作系统:WIN10
开发语言:Python
开发环境:PyCharm、Anaconda
代码(部分)
python 代码: #导入必要的编程库
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets
from tensorflow.python.framework import ops
ops.reset_default_graph()
# 开始计算图会话
sess = tf.Session()
# 加载数据,转化图像为28×28的数组
data_dir = 'temp'
mnist = read_data_sets(data_dir)
train_xdata = np.array([np.reshape(x, (28,28)) for x in mnist.train.images])
test_xdata = np.array([np.reshape(x, (28,28)) for x in mnist.test.images])
train_labels = mnist.train.labels
test_labels = mnist.test.labels
# 设置模型参数。由于图像是灰度图,所以该图像的深度为1,即颜色通道数为1
batch_size = 100
learning_rate = 0.005
evaluation_size = 500
image_width = train_xdata[0].shape[0]
image_height = train_xdata[0].shape[1]
target_size = max(train_labels) + 1
num_channels = 1 # 颜色通道= 1
generations = 500
eval_every = 5
conv1_features = 25
conv2_features = 50
max_pool_size1 = 2
max_pool_size2 = 2
fully_connected_size1 = 100
#为数据集声明占位符。同时,声明训练数据集变量和测试数据集变量。实例中的训练批量大小和评估大小可以根据实际训练和评估的机器物理内存来调整
x_input_shape = (batch_size, image_width, image_height, num_channels)
x_input = tf.placeholder(tf.float32, shape=x_input_shape)
y_target = tf.placeholder(tf.int32, shape=(batch_size))
eval_input_shape = (evaluation_size, image_width, image_height, num_channels)
eval_input = tf.placeholder(tf.float32, shape=eval_input_shape)
eval_target = tf.placeholder(tf.int32, shape=(evaluation_size))
# 声明卷积层的权重和偏置,权重和偏置的参数在前面的步骤中已设置
conv1_weight = tf.Variable(tf.truncated_normal([4, 4, num_channels, conv1_features],
stddev=0.1, dtype=tf.float32))
conv1_bias = tf.Variable(tf.zeros([conv1_features], dtype=tf.float32))
conv2_weight = tf.Variable(tf.truncated_normal([4, 4, conv1_features, conv2_features],
stddev=0.1, dtype=tf.float32))
conv2_bias = tf.Variable(tf.zeros([conv2_features], dtype=tf.float32))
# 声明全联接层的权重和偏置
resulting_width = image_width // (max_pool_size1 * max_pool_size2)
resulting_height = image_height // (max_pool_size1 * max_pool_size2)
full1_input_size = resulting_width * resulting_height * conv2_features
full1_weight = tf.Variable(tf.truncated_normal([full1_input_size, fully_connected_size1],
stddev=0.1, dtype=tf.float32))
full1_bias = tf.Variable(tf.truncated_normal([fully_connected_size1], stddev=0.1, dtype=tf.float32))
full2_weight = tf.Variable(tf.truncated_normal([fully_connected_size1, target_size],
stddev=0.1, dtype=tf.float32))
full2_bias = tf.Variable(tf.truncated_normal([target_size], stddev=0.1, dtype=tf.float32))
#声明算法模型。首先,创建一个模型函数my_conv_net(),注意该函数的层权重和偏置。当然,为了最后两层全连接层能有效工作,我们将前层卷积层的结构摊平
def my_conv_net(input_data):
# 第一层:Conv-ReLU-MaxPool层
conv1 = tf.nn.conv2d(input_data, conv1_weight, strides=[1, 1, 1, 1], padding='SAME')
relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_bias))
max_pool1 = tf.nn.max_pool(relu1, ksize=[1, max_pool_size1, max_pool_size1, 1],
strides=[1, max_pool_size1, max_pool_size1, 1], padding='SAME')
# 第二层:Conv-ReLU-MaxPool层
conv2 = tf.nn.conv2d(max_pool1, conv2_weight, strides=[1, 1, 1, 1], padding='SAME')
relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_bias))
max_pool2 = tf.nn.max_pool(relu2, ksize=[1, max_pool_size2, max_pool_size2, 1],
strides=[1, max_pool_size2, max_pool_size2, 1], padding='SAME')
# 将输出转换为下一个完全连接层的1xN层
final_conv_shape = max_pool2.get_shape().as_list()
final_shape = final_conv_shape[1] * final_conv_shape[2] * final_conv_shape[3]
flat_output = tf.reshape(max_pool2, [final_conv_shape[0], final_shape])
#第一个全连接层
fully_connected1 = tf.nn.relu(tf.add(tf.matmul(flat_output, full1_weight), full1_bias))
# 第二个全连接层
final_model_output = tf.add(tf.matmul(fully_connected1, full2_weight), full2_bias)
return(final_model_output)
#声明训练模型
model_output = my_conv_net(x_input)
test_model_output = my_conv_net(eval_input)
# 因为实例的预测结果不是多分类,而仅仅是一类,所以使用softmax函数作为损失函数
loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(model_output, y_target))
# 创建训练集和测试集的预测函数。同时,创建对应的准确度函数,评估模型的准确度
prediction = tf.nn.softmax(model_output)
test_prediction = tf.nn.softmax(test_model_output)
# 创建精度函数
def get_accuracy(logits, targets):
batch_predictions = np.argmax(logits, axis=1)
num_correct = np.sum(np.equal(batch_predictions, targets))
return(100. * num_correct/batch_predictions.shape[0])
# 创建一个优化器,声明训练步长,
my_optimizer = tf.train.MomentumOptimizer(learning_rate, 0.9)
train_step = my_optimizer.minimize(loss)
# 初始化所有的模型变量
init = tf.initialize_all_variables()
sess.run(init)
# 开始训练模型。遍历迭代随机选择批量数据进行训练。我们在训练集批量数据和预测集批量数据上评估模型,保存损失函数和准确度。我们看到,在迭代500次之后,测试数据集上的准确度达到96%~97%。
train_loss = []
train_acc = []
test_acc = []
for i in range(generations):
rand_index = np.random.choice(len(train_xdata), size=batch_size)
rand_x = train_xdata[rand_index]
rand_x = np.expand_dims(rand_x, 3)
rand_y = train_labels[rand_index]
train_dict = {x_input: rand_x, y_target: rand_y}
sess.run(train_step, feed_dict=train_dict)
temp_train_loss, temp_train_preds = sess.run([loss, prediction], feed_dict=train_dict)
temp_train_acc = get_accuracy(temp_train_preds, rand_y)
if (i+1) % eval_every == 0:
eval_index = np.random.choice(len(test_xdata), size=evaluation_size)
eval_x = test_xdata[eval_index]
eval_x = np.expand_dims(eval_x, 3)
eval_y = test_labels[eval_index]
test_dict = {eval_input: eval_x, eval_target: eval_y}
test_preds = sess.run(test_prediction, feed_dict=test_dict)
temp_test_acc = get_accuracy(test_preds, eval_y)
# 记录及列印结果
train_loss.append(temp_train_loss)
train_acc.append(temp_train_acc)
test_acc.append(temp_test_acc)
acc_and_loss = [(i+1), temp_train_loss, temp_train_acc, temp_test_acc]
acc_and_loss = [np.round(x,2) for x in acc_and_loss]
print('Generation # {}. Train Loss: {:.2f}. Train Acc (Test Acc): {:.2f} ({:.2f})'.format(*acc_and_loss))
# 使用Matplotlib模块绘制损失函数和准确度,如图8-11所示
eval_indices = range(0, generations, eval_every)
# Plot loss over time
plt.plot(eval_indices, train_loss, 'k-')
plt.title('Softmax Loss per Generation')
plt.xlabel('Generation')
plt.ylabel('Softmax Loss')
plt.show()
# 准确度(Plot train and test accuracy)
plt.plot(eval_indices, train_acc, 'k-', label='Train Set Accuracy')
plt.plot(eval_indices, test_acc, 'r--', label='Test Set Accuracy')
plt.title('Train and Test Accuracy')
plt.xlabel('Generation')
plt.ylabel('Accuracy')
plt.legend(loc='lower right')
plt.show()
效果(部分)

最佳假朋友
暂无点赞
木匠的祈祷
暂无点赞
致胜王牌
暂无点赞
科帕兰卡德斯勒
暂无点赞
第一班
暂无点赞
仙书奇谭
暂无点赞
哈泰利
暂无点赞
人间一天
暂无点赞
女心理师之心迷水影
暂无点赞
九月五日
暂无点赞
我和我的第二故乡
暂无点赞
周围有婴儿的哭声吗
暂无点赞
通灵少年
暂无点赞
羞羞的铁拳
暂无点赞
爸不得找到你
暂无点赞
我听说你买灵魂
暂无点赞
倒数回击
暂无点赞
乘风破浪
暂无点赞
黑便士信
暂无点赞
音乐是怎么变成免费午餐的
暂无点赞
肚假情真
暂无点赞
宗师叶问
暂无点赞
米克与诡计
暂无点赞
巴佐迪
暂无点赞
2人三足
暂无点赞
三人冷水澡
暂无点赞
王者归来
暂无点赞
钟无艳
暂无点赞
穷养攻略
暂无点赞
俱乐部的目的
暂无点赞
我要怎么感动你
暂无点赞
梦之婚礼
暂无点赞
第二幕
暂无点赞
花街时代
暂无点赞
世界将颤抖
暂无点赞
梦之园
暂无点赞
乐一通大电影地球爆炸之日
暂无点赞
船
暂无点赞
唐伯虎点秋香
暂无点赞
人鱼童话
暂无点赞
407航班
暂无点赞
烈火中
暂无点赞
奇迹
暂无点赞
妖猫传
暂无点赞
关机一小时
暂无点赞
亨利休格的神奇故事
暂无点赞
午夜迷案
暂无点赞
克雷格费格森我超开心
暂无点赞
相扑男孩
暂无点赞
诺拉
暂无点赞
克利须那教派
暂无点赞
弹头奇兵
暂无点赞
3年8班
暂无点赞
外星人启示录
暂无点赞
没有屋顶的房子
暂无点赞
喜剧片的黄金时代
暂无点赞