This commit is contained in:
shadow
2020-05-01 13:27:42 +08:00
parent 2ad4468647
commit 99d5d78036
11 changed files with 29 additions and 528 deletions

View File

@@ -1,4 +1,18 @@
# Deep_Learning
The design of deep learning
整体内容为本科期间毕业设计
文件待补全 内容待调整
# 基于深度学习的书法字体识别
## 设计说明
- 中华文化源远流长,其中汉字书法字体种类就十分之多,但在很多情况下未经系统学习的人们无法简单的识别其中的汉字,本设计应用深度学习对汉字书法字体识别进行设计,使其能够以较高的准确度识别出目的书法字体。
- 其中数据包括100个汉字书法单字汉字类别有碑帖手写书法古汉字等等。图片全部为单通道灰度jpg宽高不定。
- 模型最后测试集精确度达97.53%,数据来源参考自[TinyMind竞赛](https://www.tinymind.cn/competitions/41#overview)
### 数据集分两部分
- 第一部分每个汉字100张图片共第一部分每汉字100张图片共10000张图片有标签。
- 第二部分测试数据每汉字50张以上图片单字图片数不固定共16346张图片无标签需上传至题目网站进行检测。
- 训练集链接https://pan.baidu.com/s/1ASOns2qH7D80JqZldxvo9A 提取码d3za
- 测试集链接https://pan.baidu.com/s/1fxbO6e_gEJC9gNhaTPcrKg 提取码emqi
### 设计划分
#### 神经网络训练
1. [程序思路](train/README.md)
2. [程序源码](train/train.py)
#### 简单前端界面
1. [程序思路](interface/README.md)
2. [程序源码](interface/interface.py)

11
UI/.idea/UI.iml generated
View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.7 (test) (2)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
</project>

7
UI/.idea/misc.xml generated
View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (test) (2)" project-jdk-type="Python SDK" />
</project>

8
UI/.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/UI.iml" filepath="$PROJECT_DIR$/.idea/UI.iml" />
</modules>
</component>
</project>

205
UI/.idea/workspace.xml generated
View File

@@ -1,205 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="95fd905f-67b2-4530-9e26-cd09031301ca" name="Default Changelist" comment="" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="DatabaseView">
<option name="SHOW_INTERMEDIATE" value="true" />
<option name="GROUP_DATA_SOURCES" value="true" />
<option name="GROUP_SCHEMA" value="true" />
<option name="GROUP_CONTENTS" value="false" />
<option name="SORT_POSITIONED" value="false" />
<option name="SHOW_EMPTY_GROUPS" value="false" />
<option name="AUTO_SCROLL_FROM_SOURCE" value="false" />
<option name="HIDDEN_KINDS">
<set />
</option>
<expand />
<select />
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/UI.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="3614">
<caret line="149" selection-start-line="149" selection-end-line="149" />
<folding>
<element signature="e#43#118#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/tk.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="484">
<caret line="241" column="19" lean-forward="true" selection-start-line="241" selection-start-column="19" selection-end-line="241" selection-end-column="19" />
<folding>
<element signature="e#150#225#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/UI.py" />
<option value="$PROJECT_DIR$/tk.py" />
</list>
</option>
</component>
<component name="ProjectFrameBounds" extendedState="6">
<option name="x" value="814" />
<option name="y" value="80" />
<option name="width" value="1071" />
<option name="height" value="1000" />
</component>
<component name="ProjectView">
<navigator proportions="" version="1">
<foldersAlwaysOnTop value="true" />
</navigator>
<panes />
</component>
<component name="PropertiesComponent">
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
<property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager">
<configuration name="tk" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="UI" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/tk.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<recent_temporary>
<list>
<item itemvalue="Python.tk" />
</list>
</recent_temporary>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="95fd905f-67b2-4530-9e26-cd09031301ca" name="Default Changelist" comment="" />
<created>1557280287689</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1557280287689</updated>
<workItem from="1557280293232" duration="725000" />
<workItem from="1557286639891" duration="920000" />
<workItem from="1557815846845" duration="104000" />
<workItem from="1557816093543" duration="158000" />
<workItem from="1557816330286" duration="121000" />
<workItem from="1558596910623" duration="7881000" />
</task>
<servers />
</component>
<component name="TimeTrackingManager">
<option name="totallyTimeSpent" value="9909000" />
</component>
<component name="ToolWindowManager">
<frame x="-8" y="-8" width="1936" height="1056" extended-state="6" />
<editor active="true" />
<layout>
<window_info content_ui="combo" id="Project" order="0" weight="0.2851524" />
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
<window_info id="Favorites" order="2" side_tool="true" />
<window_info anchor="bottom" id="Message" order="0" />
<window_info anchor="bottom" id="Find" order="1" />
<window_info anchor="bottom" id="Run" order="2" weight="0.27919912" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
<window_info anchor="bottom" id="TODO" order="6" />
<window_info anchor="bottom" id="Docker" order="7" show_stripe_button="false" />
<window_info anchor="bottom" id="Version Control" order="8" />
<window_info anchor="bottom" id="Database Changes" order="9" />
<window_info anchor="bottom" id="Event Log" order="10" side_tool="true" />
<window_info anchor="bottom" id="Terminal" order="11" />
<window_info anchor="bottom" id="Python Console" order="12" />
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
<window_info anchor="right" id="SciView" order="3" visible="true" weight="0.1795284" />
<window_info anchor="right" id="Database" order="4" weight="0.32940018" />
</layout>
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" />
</component>
<component name="com.intellij.coverage.CoverageDataManagerImpl">
<SUITE FILE_PATH="coverage/UI$tk.coverage" NAME="tk Coverage Results" MODIFIED="1558604475663" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/../train.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="880">
<caret line="56" selection-start-line="56" selection-end-line="83" selection-end-column="16" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/UI.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="3614">
<caret line="149" selection-start-line="149" selection-end-line="149" />
<folding>
<element signature="e#43#118#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/tk.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="484">
<caret line="241" column="19" lean-forward="true" selection-start-line="241" selection-start-column="19" selection-end-line="241" selection-end-column="19" />
<folding>
<element signature="e#150#225#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</component>
</project>

289
UI/tk.py
View File

@@ -1,289 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/5/23 14:25
# @Author : shadow
# @Site :
# @File : tk.py
# @Software: PyCharm
from keras.layers import Conv2D, MaxPooling2D, AveragePooling2D, Activation
from keras.layers import Flatten, BatchNormalization, PReLU, Dense, Dropout
from keras.models import Model, Input
from keras.applications.resnet50 import ResNet50
import numpy as np
import tkinter as tk
import tkinter.filedialog
from PIL import Image, ImageTk
import matplotlib.pyplot as plt
import time
import os
import tkinter.font as tkFont
def bn_relu(x):
x = BatchNormalization()(x)
#参数化的ReLU
x = PReLU()(x)
return x
def Alex_model(out_dims, input_shape=(128, 128, 1)):
input_dim = Input(input_shape)
x = Conv2D(96, (20, 20), strides=(2, 2), padding='valid')(input_dim) # 55 * 55 * 96
x = bn_relu(x)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='valid')(x) # 27 * 27 * 96
x = Conv2D(256, (5, 5), strides=(1, 1), padding='same')(x)
x = bn_relu(x)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='valid')(x)
x = Conv2D(384, (3, 3), strides=(1, 1), padding='same')(x)
x = PReLU()(x)
x = Conv2D(384, (3, 3), strides=(1, 1), padding='same')(x)
x = PReLU()(x)
x = Conv2D(256, (3, 3), strides=(1, 1), padding='same')(x)
x = PReLU()(x)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='valid')(x)
x = Flatten()(x)
fc1 = Dense(4096)(x)
dr1 = Dropout(0.2)(fc1)
fc2 = Dense(4096)(dr1)
dr2 = Dropout(0.25)(fc2)
fc3 = Dense(out_dims)(dr2)
fc3 = Activation('softmax')(fc3)
model = Model(inputs=input_dim, outputs=fc3)
return model
def resner50(out_dims, input_shape=(128, 128, 1)):
# input_dim = Input(input_shape)
resnet_base_model = ResNet50(include_top=False, weights=None, input_shape=input_shape)
x = resnet_base_model.output
x = Flatten()(x)
fc = Dense(512)(x)
x = bn_relu(fc)
x = Dropout(0.5)(x)
x = Dense(out_dims)(x)
x = Activation("softmax")(x)
# buid myself model
input_shape = resnet_base_model.input
output_shape = x
resnet50_100_model = Model(inputs=input_shape, outputs=output_shape)
return resnet50_100_model
def my_model(out_dims, input_shape=(128, 128, 1)):
input_dim = Input(input_shape) # 生成一个input_shape的张量
x = Conv2D(32, (3, 3), strides=(2, 2), padding='valid')(input_dim)
x = bn_relu(x)
x = Conv2D(32, (3, 3), strides=(1, 1), padding='valid')(x)
x = bn_relu(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Conv2D(64, (3, 3), strides=(1, 1), padding='valid')(x)
x = bn_relu(x)
x = Conv2D(64, (3, 3), strides=(1, 1), padding='valid')(x)
x = bn_relu(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Conv2D(128, (3, 3), strides=(1, 1), padding='valid')(x)
x = bn_relu(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Conv2D(128, (3, 3), strides=(1, 1), padding='valid')(x)
x = bn_relu(x)
x = AveragePooling2D(pool_size=(2, 2))(x)
x_flat = Flatten()(x)
fc1 = Dense(512)(x_flat)
fc1 = bn_relu(fc1)
dp_1 = Dropout(0.3)(fc1)
fc2 = Dense(out_dims)(dp_1)
fc2 = Activation('softmax')(fc2)
model = Model(inputs=input_dim, outputs=fc2)
return model
def load_image(image):
img = Image.open(image).convert('L')
img = img.resize((128,128))
img = np.array(img)
img = img / 255
img = img.reshape((1,) + img.shape + (1,))
return img
def get_label(image, model, top_k):
prediction = model.predict(image)
predict_list = list(prediction[0])
min_label = min(predict_list)
label_k = []
for i in range(top_k):
label = np.argmax(predict_list)
predict_list.remove(predict_list[label])
predict_list.insert(label, min_label)
label_k.append(label)
return label_k
def label_of_directory(directory):
classes = []
for subdir in sorted(os.listdir(directory)):
if os.path.isdir(os.path.join(directory, subdir)):
classes.append(subdir)
class_indices = dict(zip(classes, range(len(classes))))
return class_indices
def get_key_from_classes(dict, index):
for key, value in dict.items():
if value == index:
return key
# 弹窗
class PopupDialog(tk.Toplevel):
def __init__(self, parent):
super().__init__()
self.title('输出结果')
self.parent = parent # 显式地保留父窗口
sw = self.parent.winfo_screenwidth()
sh = self.parent.winfo_screenheight()
ww = 500
wh = 200
x = (sw-ww) // 2
y = (sh-wh) // 2
self.geometry("%dx%d+%d+%d"%(ww, wh, x, y))
ft = tkFont.Font(family='宋体', size=23)
row1 = tk.Frame(self)
row1.pack(anchor='s', ipady=25)
tk.Label(row1, text=str(self.parent.ans_key), font = ft).pack()
row2 = tk.Frame(self)
row2.pack(fill="x")
tk.Button(row2, text="确认", font = ft, command=self.cancel).pack()
def cancel(self):
self.destroy()
# 主窗
class MyApp(tk.Tk):
def __init__(self):
super().__init__()
self.title('基于深度学习的书法字体识别')
# 程序参数
self.string = tk.StringVar()
self.ans_key = []
# 程序界面
self.setupUI()
def setupUI(self):
# 初始化字体
ft1 = tkFont.Font(family='宋体', size=17) # 地址栏字体
ft2 = tkFont.Font(family='宋体', size=20) # 按钮字体
row1 = tk.Frame(self)
row1.pack(fill="x") # x方向填充
tk.Entry(row1, font=ft1, width=68, textvariable=self.string).pack() # 选择文件地址栏
# 三个按钮
row2 = tk.Frame(self)
row2.pack(fill="x")
tk.Button(row2, text="选择文件", width=10, font=ft2, command = self.choose_file).pack()
row3 = tk.Frame(self)
row3.pack(fill="x")
tk.Button(row3, text="上传", width=10, font=ft2, command = self.upload_file).pack()
row4 = tk.Frame(self)
row4.pack(fill="x")
tk.Button(row4, text="开始识别", width=10, font=ft2, command = self.start).pack()
# 背景图片
row5 = tk.Frame(self)
row5.pack(fill="x")
global img
img = Image.open("D:/Deep_learning_design/汉字/毕设重要版本/UI/back.jpg")
(x, y) = img.size
x //= 2
y //= 2
img = img.resize((x, y))
img = ImageTk.PhotoImage(img)
lab = tk.Label(row5, image=img)
lab.pack()
# 选择文件
def choose_file(self):
selectFileName = tk.filedialog.askopenfilename(title = "选择文件")
self.string.set(selectFileName)
# 上传文件
def upload_file(self):
img = Image.open(self.string.get())
plt.imshow(img)
path = "D:/Deep_learning_design/汉字/毕设重要版本/image_test"
name = time.time()
img.save(path + str(name) + ".jpg")
plt.show()
# 开始识别
def start(self):
img_name = os.listdir(image_path)
img_list = []
for name in img_name:
img_list.append(os.path.join(image_path, name))
img_list.sort()
ans_key = []
for img in img_list:
image = load_image(img)
temp_label = get_label(image, model, 5)
key = get_key_from_classes(class_indices, temp_label[0])
ans_key.append(key)
self.ans_key = ans_key
self.output_ans()
# 输出结果
def output_ans(self):
pw = PopupDialog(self)
self.wait_window(pw)
return
if __name__ == '__main__':
"""
初始化权重
"""
weight_path = 'best_weights_Alex.h5'
image_path = 'D:/Deep_learning_design/汉字/毕设重要版本/image_test'
train_path = "D:/Deep_learning_design/TMD_data/myTrain/train_data"
model = Alex_model(100)
model.load_weights(weight_path)
class_indices = label_of_directory(train_path) # 获取训练集中标签对应汉字序列
"""
界面加载
"""
app = MyApp()
app.mainloop()

View File

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 2.3 MiB

11
train/README.md Normal file
View File

@@ -0,0 +1,11 @@
题目源自https://www.tinymind.cn/competitions/41#overview
## 题目
> 竞赛数据提供100个汉字书法单字包括碑帖手写书法古汉字等等。图片全部为单通道灰度jpg宽高不定。
### 测试集分两部分:
> 第一部分每个汉字100张图片共第一部分每汉字100张图片共10000张图片有标签。
> 第二部分测试数据每汉字50张以上图片单字图片数不固定共16346张图片无标签需上传至题目网站进行检测。
> 训练集链接https://pan.baidu.com/s/1ASOns2qH7D80JqZldxvo9A 提取码d3za
> 测试集链接https://pan.baidu.com/s/1fxbO6e_gEJC9gNhaTPcrKg 提取码emqi