競賽選題 卷積神經網絡手寫字符識別 - 深度學習

文章目錄

  • 0 前言
  • 1 簡介
  • 2 LeNet-5 模型的介紹
    • 2.1 結構解析
    • 2.2 C1層
    • 2.3 S2層
      • S2層和C3層連接
    • 2.4 F6與C5層
  • 3 寫數字識別算法模型的構建
    • 3.1 輸入層設計
    • 3.2 激活函數的選取
    • 3.3 卷積層設計
    • 3.4 降采樣層
    • 3.5 輸出層設計
  • 4 網絡模型的總體結構
  • 5 部分實現代碼
  • 6 在線手寫識別
  • 7 最后

0 前言

🔥 優質競賽項目系列,今天要分享的是

🚩 卷積神經網絡手寫字符識別 - 深度學習

該項目較為新穎,適合作為競賽課題方向,學長非常推薦!

🥇學長這里給一個題目綜合評分(每項滿分5分)

  • 難度系數:3分
  • 工作量:3分
  • 創新點:4分

🧿 更多資料, 項目分享:

https://gitee.com/dancheng-senior/postgraduate

在這里插入圖片描述

1 簡介

該設計學長使用python基于TensorFlow設計手寫數字識別算法,并編程實現GUI界面,構建手寫數字識別系統。

這是學長做的深度學習demo,大家可以用于畢業設計。

這里學長不會以論文的形式展現,而是以編程實戰完成深度學習項目的角度去描述。

項目要求:主要解決的問題是手寫數字識別,最終要完成一個識別系統。

設計識別率高的算法,實現快速識別的系統。

2 LeNet-5 模型的介紹

學長實現手寫數字識別,使用的是卷積神經網絡,建模思想來自LeNet-5,如下圖所示:

在這里插入圖片描述

2.1 結構解析

這是原始的應用于手寫數字識別的網絡,我認為這也是最簡單的深度網絡。

LeNet-5不包括輸入,一共7層,較低層由卷積層和最大池化層交替構成,更高層則是全連接和高斯連接。

LeNet-5的輸入與BP神經網路的不一樣。這里假設圖像是黑白的,那么LeNet-5的輸入是一個32*32的二維矩陣。同
時,輸入與下一層并不是全連接的,而是進行稀疏連接。本層每個神經元的輸入來自于前一層神經元的局部區域(5×5),卷積核對原始圖像卷積的結果加上相應的閾值,得出的結果再經過激活函數處理,輸出即形成卷積層(C層)。卷積層中的每個特征映射都各自共享權重和閾值,這樣能大大減少訓練開銷。降采樣層(S層)為減少數據量同時保存有用信息,進行亞抽樣。

2.2 C1層

第一個卷積層(C1層)由6個特征映射構成,每個特征映射是一個28×28的神經元陣列,其中每個神經元負責從5×5的區域通過卷積濾波器提取局部特征。一般情況下,濾波器數量越多,就會得出越多的特征映射,反映越多的原始圖像的特征。本層訓練參數共6×(5×5+1)=156個,每個像素點都是由上層5×5=25個像素點和1個閾值連接計算所得,共28×28×156=122304個連接。

2.3 S2層

S2層是對應上述6個特征映射的降采樣層(pooling層)。pooling層的實現方法有兩種,分別是max-pooling和mean-
pooling,LeNet-5采用的是mean-
pooling,即取n×n區域內像素的均值。C1通過2×2的窗口區域像素求均值再加上本層的閾值,然后經過激活函數的處理,得到S2層。pooling的實現,在保存圖片信息的基礎上,減少了權重參數,降低了計算成本,還能控制過擬合。本層學習參數共有1*6+6=12個,S2中的每個像素都與C1層中的2×2個像素和1個閾值相連,共6×(2×2+1)×14×14=5880個連接。

S2層和C3層連接

S2層和C3層的連接比較復雜。C3卷積層是由16個大小為10×10的特征映射組成的,當中的每個特征映射與S2層的若干個特征映射的局部感受野(大小為5×5)相連。其中,前6個特征映射與S2層連續3個特征映射相連,后面接著的6個映射與S2層的連續的4個特征映射相連,然后的3個特征映射與S2層不連續的4個特征映射相連,最后一個映射與S2層的所有特征映射相連。

此處卷積核大小為5×5,所以學習參數共有6×(3×5×5+1)+9×(4×5×5+1)+1×(6×5×5+1)=1516個參數。而圖像大小為28×28,因此共有151600個連接。

S4層是對C3層進行的降采樣,與S2同理,學習參數有16×1+16=32個,同時共有16×(2×2+1)×5×5=2000個連接。
C5層是由120個大小為1×1的特征映射組成的卷積層,而且S4層與C5層是全連接的,因此學習參數總個數為120×(16×25+1)=48120個。

2.4 F6與C5層

F6是與C5全連接的84個神經元,所以共有84×(120+1)=10164個學習參數。

卷積神經網絡通過通過稀疏連接和共享權重和閾值,大大減少了計算的開銷,同時,pooling的實現,一定程度上減少了過擬合問題的出現,非常適合用于圖像的處理和識別。

3 寫數字識別算法模型的構建

3.1 輸入層設計

輸入為28×28的矩陣,而不是向量。

在這里插入圖片描述

3.2 激活函數的選取

Sigmoid函數具有光滑性、魯棒性和其導數可用自身表示的優點,但其運算涉及指數運算,反向傳播求誤差梯度時,求導又涉及乘除運算,計算量相對較大。同時,針對本文構建的含有兩層卷積層和降采樣層,由于sgmoid函數自身的特性,在反向傳播時,很容易出現梯度消失的情況,從而難以完成網絡的訓練。因此,本文設計的網絡使用ReLU函數作為激活函數。

在這里插入圖片描述

3.3 卷積層設計

學長設計卷積神經網絡采取的是離散卷積,卷積步長為1,即水平和垂直方向每次運算完,移動一個像素。卷積核大小為5×5。

3.4 降采樣層

學長設計的降采樣層的pooling方式是max-pooling,大小為2×2。

3.5 輸出層設計

輸出層設置為10個神經網絡節點。數字0~9的目標向量如下表所示:

在這里插入圖片描述

4 網絡模型的總體結構

在這里插入圖片描述

5 部分實現代碼

使用Python,調用TensorFlow的api完成手寫數字識別的算法。

注:我的程序運行環境是:Win10,python3.。

當然,也可以在Linux下運行,由于TensorFlow對py2和py3兼容得比較好,在Linux下可以在python2.7中運行。

?

#!/usr/bin/env python2# -*- coding: utf-8 -*-"""@author: 丹成學長 Q746876041"""#import modulesimport numpy as npimport matplotlib.pyplot as plt#from sklearn.metrics import confusion_matriximport tensorflow as tfimport timefrom datetime import timedeltaimport mathfrom tensorflow.examples.tutorials.mnist import input_datadef 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 datadata = input_data.read_data_sets("./data", one_hot=True) # one_hot means [0 0 1 0 0 0 0 0 0 0] stands for 2print("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], 10000valuesx = 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 1layer_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 2layer_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 1fc1_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 Layerkeep_prob = tf.placeholder("float")h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)# Full-connected layer 2fc2_layer = {"weights":new_weights([1024,10]),"biases":new_weights([10])}# Predicted classy_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 optimizedcross_entropy = -tf.reduce_mean(y_true*tf.log(y_pred))optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(cross_entropy)# Performance Measurescorrect_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 = 50def optimize(num_iterations):total_iterations=0start_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 performedtotal_iterations += num_iterations# Ending timeend_time = time.time()# Difference between start and end_times.time_dif = end_time-start_time# Print the time-usageprint("Time usage:"+str(timedelta(seconds=int(round(time_dif)))))test_batch_size = 256def 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 = 0while 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 jimages = data.test.images[i:j, :]# Get the associated labelslabels = data.test.labels[i:j, :]# Create a feed-dict with these images and labels.feed_dict={x:images,y_true: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 batchi = jcls_true = data.test.clscorrect = (cls_true==cls_pred)correct_sum = correct.sum()acc = float(correct_sum) / num_test# Print the accuracymsg = "Accuracy on Test-Set: {0:.1%} ({1}/{2})"print(msg.format(acc,correct_sum,num_test))# Performance after 10000 optimization iterationsoptimize(num_iterations=10000)print_test_accuracy()savew_hl1 = layer_conv1["weights"].eval()saveb_hl1 = layer_conv1["biases"].eval()savew_hl2 = layer_conv2["weights"].eval()saveb_hl2 = layer_conv2["biases"].eval()savew_fc1 = fc1_layer["weights"].eval()saveb_fc1 = fc1_layer["biases"].eval()savew_op = fc2_layer["weights"].eval()saveb_op = fc2_layer["biases"].eval()np.save("savew_hl1.npy", savew_hl1)np.save("saveb_hl1.npy", saveb_hl1)np.save("savew_hl2.npy", savew_hl2)np.save("saveb_hl2.npy", saveb_hl2)np.save("savew_hl3.npy", savew_fc1)np.save("saveb_hl3.npy", saveb_fc1)np.save("savew_op.npy", savew_op)np.save("saveb_op.npy", saveb_op)

運行結果顯示:測試集中準確率大概為99.2%。

在這里插入圖片描述
查看混淆矩陣

在這里插入圖片描述

6 在線手寫識別

請添加圖片描述

在這里插入圖片描述

7 最后

🧿 更多資料, 項目分享:

https://gitee.com/dancheng-senior/postgraduate

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/40635.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/40635.shtml
英文地址,請注明出處:http://en.pswp.cn/web/40635.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++內存的一些知識點

一、內存分區 在C中&#xff0c;內存主要分為以下幾個區域&#xff1a; 代碼區&#xff1a;存放函數體的二進制代碼。 全局/靜態存儲區&#xff1a;存放全局變量和靜態變量&#xff0c;這些變量在程序的整個運行期間都存在。常量存儲區&#xff1a;存放常量&#xff0c;這些值…

學懂C#編程:實用方法——string字符串指定連接符拼接之 string.Join 的詳細用法

在C#中&#xff0c;string.Join 方法用于將一個字符串數組或集合中的元素連接成一個單一的字符串&#xff0c;并在每個元素之間插入指定的分隔符。這個方法非常有用&#xff0c;特別是在需要將多個字符串合并成一個字符串時。以下是 string.Join 方法的詳細用法&#xff1a; 方…

WPF UI 界面布局 魔術棒 文字筆記識別 技能提升 布局功能擴展與自定義 繼承Panel的對象,測量與排列 系列七

應用開發第一步 功能分類&#xff1a;頁面上的功能區域劃分。。。。需求分析 業務邏輯 數據流 功能模塊 UI/UX 編碼 測試 發布 功能開發與布局 不用顯式的方式設定元素的尺寸 不使用屏幕坐標來指定位置 Grid 功能最強大&#xff0c;布局最靈活的容器…

卷積神經網絡:目標檢測的黃金鑰匙

標題&#xff1a;卷積神經網絡&#xff1a;目標檢測的黃金鑰匙 卷積神經網絡&#xff08;CNN&#xff09;是深度學習中用于處理具有網格結構數據&#xff08;如圖像&#xff09;的強大工具。在目標檢測任務中&#xff0c;CNN不僅提升了檢測的準確性&#xff0c;還極大地推動了…

開發個人Go-ChatGPT--5 模型管理 (一)

開發個人Go-ChatGP–5 模型管理 (一) 背景 開發一個chatGPT的網站&#xff0c;后端服務如何實現與大模型的對話&#xff1f;是整個項目中開發困難較大的點。 如何實現上圖的聊天對話功能&#xff1f;在開發后端的時候&#xff0c;如何實現stream的響應呢&#xff1f;本文就…

Vue-Router4.0 報“Cannot read property ‘forEach‘ of undefined”

Vue-Router4.0在創建路由時 報“Cannot read property ‘forEach‘ of undefined” 解決辦法 將路由規則名稱更改為routes&#xff0c;否則報錯 import { createWebHashHistory, createRouter } from vue-router; // 創建路由規定 const routes [{path: /login,name: login,co…

Linux Docker 防火墻設置 放通 MySQL(3306) Redis(6379) 端口

Linux Docker 防火墻設置 放通 MySQL(3306) Redis(6379) 端口&#xff0c;使用firewalld 防火墻或iptables &#xff0c;因此嘗試重新啟動 firewalld 服務&#xff0c;添加防火墻規則&#xff0c;并檢查防火墻狀態。以下是詳細步驟&#xff1a; 1. 啟動 firewalld 服務 首先啟…

qt opencv 應用舉例

在Qt中使用OpenCV可以實現各種圖像處理和計算機視覺任務。以下是一些Qt與OpenCV聯合應用的具體舉例&#xff1a; 1. 圖像讀取與顯示 讀取圖像&#xff1a;使用OpenCV的imread函數可以方便地讀取各種格式的圖像文件&#xff0c;如.bmp、.jpg、.png等。這個函數返回一個Mat對象…

【Unity數據交互】Unity中使用二進制進行數據持久化

&#x1f468;?&#x1f4bb;個人主頁&#xff1a;元宇宙-秩沅 &#x1f468;?&#x1f4bb; hallo 歡迎 點贊&#x1f44d; 收藏? 留言&#x1f4dd; 加關注?! &#x1f468;?&#x1f4bb; 本文由 秩沅 原創 &#x1f468;?&#x1f4bb; 專欄交流&#x1f9e7;&…

SqlSugar分表筆記

1、使用SqlSugar的分表功能時&#xff0c;.net要使用.net core&#xff1b; 我開始使用的是.net freamwork4.72&#xff0c;程序報異常&#xff0c;沒能解決&#xff0c;換到.net core下面就正常&#xff1b; 2、SqlSugar自帶分表支持按季度、月、周、日進行分表&#x…

ArcGIS Pro SDK (七)編輯 15 版本控制選項

ArcGIS Pro SDK &#xff08;七&#xff09;編輯 15 版本控制選項 文章目錄 ArcGIS Pro SDK &#xff08;七&#xff09;編輯 15 版本控制選項獲取和設置版本控制選項 環境&#xff1a;Visual Studio 2022 .NET6 ArcGIS Pro SDK 3.0 獲取和設置版本控制選項 var vOptions A…

PostgreSQL 技術內幕(十七):FDW 實現原理與源碼解析

對于一定規模的系統而言&#xff0c;數據倉庫往往需要訪問外部數據來完成分析和計算。外部數據包裝器&#xff08;Foreign Data Wrapper&#xff0c; 簡稱 FDW&#xff09;是 PostgreSQL 提供的訪問外部數據源機制。用戶可以使用簡單的 SQL 語句訪問和操作外部數據源&#xff0…

Python面試題:Python 中的生成器(generator)是什么?有什么優點?

在Python中&#xff0c;生成器&#xff08;generator&#xff09;是一種特殊的迭代器&#xff0c;使用yield關鍵字生成值&#xff0c;可以逐個生成序列中的值&#xff0c;而不需要一次性將所有值加載到內存中。生成器函數在定義時使用def關鍵字&#xff0c;并包含一個或多個yie…

[word] Word如何快速生成一段文本 #知識分享#學習方法

Word如何快速生成一段文本 Word如何快速生成一段文本&#xff1f;有時候我們會用一大段文字來做一些功能測試&#xff0c;不少朋友的做法就是臉滾鍵盤&#xff0c;一頓亂按&#xff0c;這樣看起來文筆不通&#xff0c;看著也會比較難受&#xff0c;測試功能的效果也不怎么理想…

uniapp中實現跳轉鏈接到游覽器(安卓-h5)

uniapp中實現跳轉鏈接到游覽器&#xff08;安卓-h5&#xff09; 項目中需要做到跳轉到外部鏈接&#xff0c;網上找了很多都不是很符合自己的要求&#xff0c;需要編譯成app后是跳轉到游覽器打開鏈接&#xff0c;編譯成web是在新窗口打開鏈接。實現的代碼如下&#xff1a; 效果&…

java基于ssm+vue 旅游信息資源平臺

1前臺首頁功能模塊 旅游資源網站 &#xff0c;在系統首頁可以查看首頁、景點信息、酒店信息、客房信息、交流論壇、紅色文化、個人中心、后臺管理、客服等內容&#xff0c;如圖1所示。 圖1系統功能界面圖 用戶登錄、用戶注冊&#xff0c;在注冊頁面可以填寫用戶名、密碼、姓名…

Redis GEO 功能解析

Redis GEO 功能解析 引言 Redis GEO 是 Redis 數據庫提供的一個特殊功能,用于存儲地理位置信息,并支持基于地理位置的查詢。這一功能對于需要處理地理位置數據的現代應用程序來說非常寶貴,如外賣配送、社交媒體、地圖服務等。本文將詳細介紹 Redis GEO 的功能、使用方法,…

DFS之剪枝與優化——AcWing 165. 小貓爬山

DFS之剪枝與優化 定義 DFS之剪枝與優化指的是在執行深度優先搜索(DFS, Depth-First Search)時&#xff0c;采取的一系列策略來減少搜索空間&#xff0c;避免無效計算&#xff0c;從而加速找到問題的解。剪枝是指在搜索過程中&#xff0c;當遇到某些條件不符合解的要求或者可以…

產科管理信息系統源碼:產科電子病歷、高危孕產婦五色管理系統源碼 孕產婦健康管理信息平臺源碼

產科管理信息系統源碼&#xff1a;產科電子病歷、高危孕產婦五色管理系統源碼 孕產婦健康管理信息平臺源碼 產科電子病歷系統是以采集病人在整個醫療護理過程中所產生的各種信息。包括病案首頁、門診病歷、住院病歷、出院記錄、病人病程記錄等全部病歷文書&#xff1b;涵蓋文字…

宿舍報修小程序的設計

管理員賬戶功能包括&#xff1a;系統首頁&#xff0c;個人中心&#xff0c;管理員管理&#xff0c;基礎數據管理&#xff0c;論壇管理&#xff0c;故障上報管理&#xff0c;新聞信息管理&#xff0c;維修人員管理 微信端賬號功能包括&#xff1a;系統首頁&#xff0c;新聞信息…