翼虎正時(shí)皮帶多久更換 翼虎正時(shí)皮帶多久更換一次
2024-07-01
更新時(shí)間:2024-07-01 18:01:24作者:佚名
千彩手寫(xiě)識(shí)別系統(tǒng)(手寫(xiě)識(shí)別系統(tǒng)怎么安裝)2018-08-30 09:33程序員小新人學(xué)習(xí)
手寫(xiě)數(shù)字識(shí)別算法的設(shè)計(jì)與實(shí)現(xiàn)
本文使用python基于TensorFlow設(shè)計(jì)手寫(xiě)數(shù)字識(shí)別算法,并編程實(shí)現(xiàn)GUI界面,構(gòu)建手寫(xiě)數(shù)字識(shí)別系統(tǒng)。這是本人的本科畢業(yè)論文課題,當(dāng)然,這個(gè)也是機(jī)器學(xué)習(xí)的基本問(wèn)題。本博文不會(huì)以論文的形式展現(xiàn),而是以編程實(shí)戰(zhàn)完成機(jī)器學(xué)習(xí)項(xiàng)目的角度去描述。
項(xiàng)目要求:本文主要解決的問(wèn)題是手寫(xiě)數(shù)字識(shí)別,最終要完成一個(gè)識(shí)別系統(tǒng)。
設(shè)計(jì)識(shí)別率高的算法,實(shí)現(xiàn)快速識(shí)別的系統(tǒng)。
1 LeNet-5模型的介紹
本文實(shí)現(xiàn)手寫(xiě)數(shù)字識(shí)別,使用的是卷積神經(jīng)網(wǎng)絡(luò),建模思想來(lái)自LeNet-5,如下圖所示:
這是原始的應(yīng)用于手寫(xiě)數(shù)字識(shí)別的網(wǎng)絡(luò),我認(rèn)為這也是最簡(jiǎn)單的深度網(wǎng)絡(luò)。
LeNet-5不包括輸入,一共7層,較低層由卷積層和最大池化層交替構(gòu)成,更高層則是全連接和高斯連接。
LeNet-5的輸入與BP神經(jīng)網(wǎng)路的不一樣。這里假設(shè)圖像是黑白的,那么LeNet-5的輸入是一個(gè)32*32的二維矩陣。同時(shí),輸入與下一層并不是全連接的,而是進(jìn)行稀疏連接。本層每個(gè)神經(jīng)元的輸入來(lái)自于前一層神經(jīng)元的局部區(qū)域(55),卷積核對(duì)原始圖像卷積的結(jié)果加上相應(yīng)的閾值,得出的結(jié)果再經(jīng)過(guò)激活函數(shù)處理,輸出即形成卷積層(C層)。卷積層中的每個(gè)特征映射都各自共享權(quán)重和閾值,這樣能大大減少訓(xùn)練開(kāi)銷(xiāo)。降采樣層(S層)為減少數(shù)據(jù)量同時(shí)保存有用信息,進(jìn)行亞抽樣。
第一個(gè)卷積層(C1層)由6個(gè)特征映射構(gòu)成,每個(gè)特征映射是一個(gè)2828的神經(jīng)元陣列,其中每個(gè)神經(jīng)元負(fù)責(zé)從55的區(qū)域通過(guò)卷積濾波器提取局部特征。一般情況下,濾波器數(shù)量越多,就會(huì)得出越多的特征映射,反映越多的原始圖像的特征。本層訓(xùn)練參數(shù)共6(55+1)=156個(gè),每個(gè)像素點(diǎn)都是由上層55=25個(gè)像素點(diǎn)和1個(gè)閾值連接計(jì)算所得,共2828156=122304個(gè)連接。
S2層是對(duì)應(yīng)上述6個(gè)特征映射的降采樣層(pooling層)。pooling層的實(shí)現(xiàn)方法有兩種,分別是max-pooling和mean-pooling,LeNet百思特網(wǎng)-5采用的是mean-pooling,即取nn區(qū)域內(nèi)像素的均值。C1通過(guò)22的窗口區(qū)域像素求均值再加上本層的閾值,然后經(jīng)過(guò)激活函數(shù)的處理,得到S2層。pooling的實(shí)現(xiàn),在保存圖片信息的基礎(chǔ)上,減少了權(quán)重參數(shù),降低了計(jì)算成本,還能控制過(guò)擬合。本層學(xué)習(xí)參數(shù)共有1*6+6=12個(gè),S2中的每個(gè)像素都與C1層中的22個(gè)像素和1個(gè)閾值相連,共6(22+1)1414=5880個(gè)連接。
S2層和C3層的連接比較復(fù)雜。C3卷積層是由16個(gè)大小為1010的特征映射組成的,當(dāng)中的每個(gè)特征映射與S2層的若干個(gè)特征映射的局部感受野(大小為55)相連。其中,前6個(gè)特征映射與S2層連續(xù)3個(gè)特征映射相連,后面接著的6個(gè)映射與S2層的連續(xù)的4個(gè)特征映射相連,然后的3個(gè)特征映射與S2層不連續(xù)的4個(gè)特征映射相連,最后一個(gè)映射與S2層的所有特征映射相連。此處卷積核大小為55,所以學(xué)習(xí)參數(shù)共有6(355+1)+9(455+1)+1(655+1)=1516個(gè)參數(shù)。而圖像大小為2828,因此共有151600個(gè)連接。
S4層是對(duì)C3層進(jìn)行的降采樣,與S2同理,學(xué)習(xí)參數(shù)有161+16=32個(gè),同時(shí)共有16(22+1)55=2000個(gè)連接。
C5層是由120個(gè)大小為11的特征映射組成的卷積層,而且S4層與C5層是全連接的,因此學(xué)習(xí)參數(shù)總個(gè)數(shù)為120(1625+1)=48120個(gè)。
F6是與C5全連接的84個(gè)神經(jīng)元,所以共有84(120+1)=10164個(gè)學(xué)習(xí)參數(shù)。
卷積神經(jīng)網(wǎng)絡(luò)通過(guò)通過(guò)稀疏連接和共享權(quán)重和閾值,大大減少了計(jì)算的開(kāi)銷(xiāo),同時(shí),pooling的實(shí)現(xiàn),一定程度上減少了過(guò)擬合問(wèn)題的出現(xiàn),非常適合用于圖像的處理和識(shí)別。
2 手寫(xiě)數(shù)字識(shí)別算法模型的構(gòu)建
2.1 各層設(shè)計(jì)
有了第一節(jié)的基礎(chǔ)知識(shí),在這基礎(chǔ)上,進(jìn)行完善和改進(jìn)。
輸入層設(shè)計(jì)
輸入為2828的矩陣,而不是向量。
激活函數(shù)的選取
Sigmoid函數(shù)具有光滑性、魯棒性和其導(dǎo)數(shù)可用自身表示的優(yōu)點(diǎn),但其運(yùn)算涉及指數(shù)運(yùn)算,反向傳播求誤差梯度時(shí),求導(dǎo)又涉及乘除運(yùn)算,計(jì)算量相對(duì)較大。同時(shí),針對(duì)本文構(gòu)建的含有兩層卷積層和降采樣層,由于sgmoid函數(shù)自身的特性,在反向傳播時(shí),很容易出現(xiàn)梯度消失的情況,從而難以完成網(wǎng)絡(luò)的訓(xùn)練。因此,本文設(shè)計(jì)的網(wǎng)絡(luò)使用ReLU函數(shù)作為激活函數(shù)。
ReLU的表達(dá)式:
卷積層設(shè)計(jì)
本文設(shè)計(jì)卷積神經(jīng)網(wǎng)絡(luò)采取的是離散卷積,卷積步長(zhǎng)為1,即水平和垂直方向每次運(yùn)算完,移動(dòng)一個(gè)像素。卷積核大小為55。
降采樣層
本文降采樣層的pooling方式是max-pooling,大小為22。
輸出層設(shè)計(jì)
輸出層設(shè)置為10個(gè)神經(jīng)網(wǎng)絡(luò)節(jié)點(diǎn)。數(shù)字0~9的目標(biāo)向量如下表所示:
2.2 網(wǎng)絡(luò)模型的總體結(jié)構(gòu)
其實(shí),本文網(wǎng)絡(luò)的構(gòu)建,參考自TensorFlow的手寫(xiě)數(shù)字識(shí)別的官方教程的,讀者有興趣也可以詳細(xì)閱讀。
2.3 編程實(shí)現(xiàn)算法
本文使用Python,調(diào)用TensorFlow的api完成手寫(xiě)數(shù)字識(shí)別的算法。
注:本文程序運(yùn)行環(huán)境是:Win10,python3.5.2。當(dāng)然,也可以在Linux下運(yùn)行,由于TensorFlow對(duì)py2和py3兼容得比較好,在Linux下可以在python2.7中運(yùn)行。
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
“””
Created on Fri Feb 17 19:50:49 2017
@author: Yonghao Huang
“””
#import modules
import numpy as np
import matplotlib.pyplot as plt
import 百思特網(wǎng)tensorflow as tf
import time
from datetime import timedelta
import math
from tensorflow.examples.tutorials.mnist import input_data
def new_weights(shape):
return tf.Variable(tf.truncated_normal(shape,stddev=0.05))
def new_biases(length):
return tf.Variable(tf.constant(0.1,shape=length))
def conv2d(x,W):
return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding=’SAME’)
def max_pool_2x2(inputx):
return tf.nn.max_pool(inputx,ksize=[1,2,2,1],strides=[1,2,2,1],padding=’SAME’)
#import data
data = input_data.read_data_sets(“./data”, one_hot=True) # one_hot means [0 0 1 0 0 0 0 0 0 0] stands for 2
print(“Size of:”)
print(“–Training-set:\t\t{}”.format(len(data.train.labels)))
print(“–Testing-set:\t\t{}”.format(len(data.test.labels)))
print(“–Validation-set:\t\t{}”.format(len(data.validation.labels)))
data.test.cls = np.argmax(data.test.labels,axis=1) # show the real test labels: [7 2 1 …, 4 5 6], 10000values
x = tf.placeholder(“float”,shape=[None,784],name=’x’)
x_image = tf.reshape(x,[-1,28,28,1])
y_true = tf.placeholder(“float”,shape=[None,10],name=’y_true’)
y_true_cls = tf.argmax(y_true,dimension=1)
# Conv 1
layer_conv1 = {“weights”:new_weights([5,5,1,32]),
“biases”:new_biases([32])}
h_conv1 = tf.nn.relu(conv2d(x_image,layer_conv1[“weights”])+layer_conv1[“biases”])
h_pool1 = max_pool_2x2(h_conv1)
# Conv 2
layer_conv2 = {“weights”:new_weights([5,5,32,64]),
“biases”:new_biases([64])}
h_conv2 = tf.nn.relu(conv2d(h_pool1,layer_conv2[“weights”])+layer_conv2[“biases”])
h_pool2 = max_pool_2x2(h_conv2)
# Full-connected layer 1
fc1_layer = {“weights”:new_weights([7*7*64,1024]),
“biases”:new_biases([1024])}
h_pool2_flat = tf.reshape(h_pool2,[-1,7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat,fc1_layer[“weights”])+fc1_layer[“biases”])
# Droupout Layer
keep_prob = tf.placeholder(“float”)
h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)
# Full-connected layer 2
fc2_layer = {“weights”:new_weights([1024,10]),
“biases”:new_weights([10])}
# Predicted class
y_pred = tf.nn.softmax(tf.matmul(h_fc1_drop,fc2_layer[“weights”])+fc2_layer[“biases”]) # The output is like [0 0 1 0 0 0 0 0 0 0]
y_pred_cls = tf.argmax(y_pred,dimension=1) # Show the real predict number like ‘2’
# cost function to be optimized
cross_entropy = -tf.reduce_mean(y_true*tf.log(y_pred))
optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(cross_entropy)
# Performance Measures
correct_prediction = tf.equal(y_pred_cls,y_true_cls)
accuracy = tf.reduce_mean(tf.cast(correct_prediction,”float”))
with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
train_batch_size = 50
def optimize(num_iterations):
total_iterations=0
start_time = time.time()
for i in range(total_iterations,total_iterations+num_iterations):
x_batch,y_true_batch = data.train.next_batch(train_batch_size)
feed_dict_train_op = {x:x_batch,y_true:y_true_batch,keep_prob:0.5}
feed_dict_train = {x:x_batch,y_true:y_true_batch,keep_prob:1.0}
sess.run(optimizer,feed_dict=feed_dict_train_op)
# Print status every 100 iterations.
if i%100==0:
# Calculate the accuracy on the training-set.
acc = sess.run(accuracy,feed_dict=feed_dict_train)
# Message for printing.
msg = “Optimization Iteration:{0:>6}, Training Accuracy: {1:>6.1%}”
# Print it.
print(msg.format(i+1,acc))
# Update the total number of iterations performed
total_iterations += num_iterations
# Ending time
end_time = time.time()
# Difference between start and end_times.
time_dif = end_time-start_time
# Print the time-usage
print(“Time usage:”+str(timedelta(seconds=int(round(time_dif)))))
test_batch_size = 256
def print_test_accuracy():
# Number of images in the test-set.
num_test = len(data.test.images)
cls_pred = np.zeros(shape=num_test,dtype=np.int)
i = 0
while i < num_test:
# The ending index for the next batch is denoted j.
j = min(i+test_batch_size,num_test)
# Get the images from the test-set between index i and j
images = data.test.images[i:j, :]
# Get the associated labels
labels = data.test.labels[i:j, :]
# Create a feed-dict with these images and labels.
feed_dict={x:images,y_true百思特網(wǎng):labels,keep_prob:1.0}
# Calculate the predicted class using Tensorflow.
cls_pred[i:j] = sess.run(y_pred_cls,feed_dict=feed_dict)
# Set the start-index for the next batch to the
# end-index of the current batch
i = j
cls_true = data.test.cls
correct = (cls_true==cls_pred)
correct_sum = correct.sum()
acc = float(correct_sum) / num_test
# Print the accuracy
msg = “Accuracy on Test-Set: {0:.1%} ({1}/{2})”
print(msg.format(acc,correct_sum,num_test))
# Performance after 10000 optimization iterations
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
運(yùn)行結(jié)果顯示:測(cè)試集中準(zhǔn)確率大概為99.2%。
我還寫(xiě)了一些輔助函數(shù),可以查看部分識(shí)別錯(cuò)誤的圖片,
還可以查看混淆矩陣,
2.3 實(shí)現(xiàn)手寫(xiě)識(shí)別系統(tǒng)
最后,將訓(xùn)練好的參數(shù)保存,封裝進(jìn)一個(gè)GUI界面中,形成一個(gè)手寫(xiě)識(shí)別系統(tǒng)。
系統(tǒng)中還添加了一點(diǎn)圖像預(yù)處理的操作,比如灰度化,圖像信息的歸一化等,更貼近實(shí)際應(yīng)用。
系統(tǒng)可進(jìn)行快速識(shí)別,如下圖
3 總結(jié)
本文實(shí)現(xiàn)的系統(tǒng)其實(shí)是基于卷積神經(jīng)網(wǎng)絡(luò)的手寫(xiě)數(shù)字識(shí)別系統(tǒng)。該系統(tǒng)能快速實(shí)現(xiàn)手寫(xiě)數(shù)字識(shí)別,成功識(shí)別率高。缺點(diǎn):只能正確識(shí)別單個(gè)數(shù)字,圖像預(yù)處理還不夠,沒(méi)有進(jìn)行圖像分割,讀者也可以自行添加,進(jìn)行完善。
4 收獲
本人之前的本科期間,雖然努力學(xué)習(xí)高數(shù)、線性代數(shù)和概率論,但是沒(méi)有認(rèn)真學(xué)習(xí)過(guò)機(jī)器學(xué)習(xí),本人是2017年才開(kāi)始系統(tǒng)學(xué)習(xí)機(jī)器學(xué)習(xí)相關(guān)知識(shí),而且本科畢業(yè)論文也選擇了相關(guān)的課題,雖然比較基礎(chǔ),但是認(rèn)真完成后,有一種學(xué)以致用的滿足感,同時(shí)也激勵(lì)著我進(jìn)行更深入的理論學(xué)習(xí)和實(shí)踐探討,與所有讀者共勉。
==================================
2018年5月13日更新
源碼分享鏈接:
https://pan.baidu.com/s/1BNlifR3DvIvTO5qkOTTpsQ
========================================
2018年6月6日更新更新??!
python(TensorFlow)實(shí)現(xiàn)手寫(xiě)字符識(shí)別
此處的“手寫(xiě)字符”,其實(shí)指的是notMNIST數(shù)據(jù)庫(kù)中的手寫(xiě)字符,其實(shí)和MNIST數(shù)據(jù)庫(kù)是一樣的。這里實(shí)現(xiàn)手寫(xiě)字符識(shí)別,主要是展示TensorFlow框架的可拓展性很強(qiáng),具體來(lái)說(shuō),就是可以通過(guò)改動(dòng)少部分的代碼,從而實(shí)現(xiàn)一個(gè)新的識(shí)別功能。
NotMnist數(shù)據(jù)庫(kù)
這個(gè)數(shù)據(jù)庫(kù)和MNIST數(shù)據(jù)庫(kù)基本一樣,只是把10個(gè)數(shù)字換成了10個(gè)字母,即:A,B,C,D,E,F,G,H,I,J,K
當(dāng)然,這個(gè)數(shù)據(jù)庫(kù)的識(shí)別難度大一些,因?yàn)閿?shù)據(jù)噪聲更多一些,詳情讀者可以搜一搜了解一下。
實(shí)戰(zhàn)
將NotMNIST數(shù)據(jù)庫(kù)下載以后,放在本博文上述的網(wǎng)絡(luò)中,基本不需要修改代碼,直接訓(xùn)練,即可得到一個(gè)能識(shí)別字符的網(wǎng)絡(luò)模型。
最后在測(cè)試集中的準(zhǔn)確率,比MNIST的會(huì)低一些,大概為96%左右。
本文也將訓(xùn)練好的網(wǎng)絡(luò)模型封裝在和上述系統(tǒng)相似的GUI系統(tǒng)中,
識(shí)別效果還可以!
同樣,將卷積卷積層可視化。
結(jié)語(yǔ)
TensorFlow框架可拓展性很強(qiáng),只要設(shè)計(jì)好了網(wǎng)絡(luò),就能很容易的實(shí)現(xiàn)出來(lái);同時(shí),使用基本的CNN識(shí)別整體架構(gòu)也是大同小異的,很多識(shí)別任務(wù)是通用的。當(dāng)然,在具體的實(shí)踐中需要得到接近完美的效果,還是要下很大功夫的!努力學(xué)習(xí)吧,加油!
(如果你/您有什么有趣的想法,可以在下面留言,如果我也感興趣同時(shí)又有時(shí)間的話,我會(huì)嘗試做一做,^_^)