一、深度學(xué)習(xí)的基本概念
1.1 基本概念
神經(jīng)網(wǎng)絡(luò):?它從信息處理角度對(duì)人腦神經(jīng)元網(wǎng)絡(luò)進(jìn)行抽象, 建立某種簡(jiǎn)單模型,按不同的連接方式組成不同的網(wǎng)絡(luò)。神經(jīng)網(wǎng)絡(luò)是一種運(yùn)算模型,由大量神經(jīng)元之間相互聯(lián)接構(gòu)成。學(xué)習(xí)如何構(gòu)建和訓(xùn)練神經(jīng)網(wǎng)絡(luò)是入門的重要一步。
神經(jīng)元:?神經(jīng)元模型是一個(gè)包含輸入,輸出與計(jì)算功能的模型。
前向傳播和反向傳播:?它是神經(jīng)網(wǎng)絡(luò)的基本運(yùn)行方式,前向傳播用于計(jì)算輸出,反向傳播用于更新網(wǎng)絡(luò)參數(shù)。
激活函數(shù):?激活函數(shù)決定神經(jīng)元的輸出。學(xué)習(xí)不同的激活函數(shù)以及它們的作用。
損失函數(shù):?損失函數(shù)用于衡量模型的預(yù)測(cè)與實(shí)際結(jié)果之間的差異。了解不同的損失函數(shù)和它們的適用場(chǎng)景。
優(yōu)化算法:?優(yōu)化算法用于更新神經(jīng)網(wǎng)絡(luò)的參數(shù)以最小化損失函數(shù)。了解常用的優(yōu)化算法,如隨機(jī)梯度下降法(SGD)和Adam。
1.2 深度學(xué)習(xí)框架
以下是一些常見的深度學(xué)習(xí)框架:
TensorFlow2:由 Google 開發(fā)的開源框架,簡(jiǎn)單,模塊封裝比較好,容易上手,對(duì)新手比較友好。在工業(yè)界最重要的是模型落地,目前國內(nèi)的大部分企業(yè)支持TensorFlow模型在線部署,不支持Pytorch。
PyTorch:由 Facebook 開發(fā)的開源框架,前沿算法多為PyTorch版本,如果是你高校學(xué)生or研究人員,建議學(xué)這個(gè)。相對(duì)于TensorFlow,Pytorch在易用性上更有優(yōu)勢(shì),更加方便調(diào)試。
Keras:是一個(gè)極簡(jiǎn)的、高度模塊化的神經(jīng)網(wǎng)絡(luò)庫,采用 Python(Python 2.7-3.5.)開發(fā),能夠運(yùn)行在 TensorFlow 和 Theano 任一平臺(tái),旨在完成深度學(xué)習(xí)的快速開發(fā)。
TensorFlow 適合工業(yè)應(yīng)用構(gòu)建大型項(xiàng)目,PyTorch 適合學(xué)術(shù)研究構(gòu)建小型項(xiàng)目。個(gè)人推薦使用 PyTorch,原因很簡(jiǎn)單,因?yàn)楹?jiǎn)單易懂。而且,它還彌補(bǔ)了 Tensorflow 靜態(tài)構(gòu)圖的致命弱點(diǎn)。PyTorch 是可以構(gòu)建動(dòng)態(tài)計(jì)算圖。也就是說你可以隨時(shí)改變神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu),而不影響其計(jì)算過程。而 Tensorflow 這種靜態(tài)圖模塊,一旦搭建好了神經(jīng)網(wǎng)絡(luò), 你想修改結(jié)構(gòu)也不行。
1.3 經(jīng)典模型
學(xué)習(xí)一些經(jīng)典的深度學(xué)習(xí)模型和案例將幫助你更好地理解深度學(xué)習(xí)的應(yīng)用和工作原理。包括:
卷積神經(jīng)網(wǎng)絡(luò)(CNN):常用于圖像識(shí)別和計(jì)算機(jī)視覺任務(wù)的常用模型,是一種專門用來處理具有類似網(wǎng)格結(jié)構(gòu)的數(shù)據(jù)的神經(jīng)網(wǎng)絡(luò)。卷積網(wǎng)絡(luò)在圖像識(shí)別,自然語言處理,災(zāi)難性氣候預(yù)測(cè)、圍棋人工智能等諸多應(yīng)用領(lǐng)域都表現(xiàn)優(yōu)異。卷積神經(jīng)網(wǎng)絡(luò)通常由3個(gè)部分構(gòu)成:卷積層,池化層,全連接層。簡(jiǎn)單來說,卷積層負(fù)責(zé)提取圖像中的局部及全局特征;池化層用來大幅降低參數(shù)量級(jí)(降維);全連接層用于處理“壓縮的圖像信息”并輸出結(jié)果。
循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN):用于序列數(shù)據(jù)建模和自然語言處理任務(wù)的常用模型,傳統(tǒng)神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)比較簡(jiǎn)單,通常為:輸入層 – 隱藏層 – 輸出層。
生成對(duì)抗網(wǎng)絡(luò)(GAN):用于生成新的數(shù)據(jù)樣本的模型。是近年來深度學(xué)習(xí)領(lǐng)域的一個(gè)熱點(diǎn)方向。GAN并不指代某一個(gè)具體的神經(jīng)網(wǎng)絡(luò),而是指一類基于博弈思想而設(shè)計(jì)的神經(jīng)網(wǎng)絡(luò)。GAN由兩個(gè)分別被稱為生成器(Generator)和判別器(Discriminator)的神經(jīng)網(wǎng)絡(luò)組成。其中,生成器從某種噪聲分布中隨機(jī)采樣作為輸入,輸出與訓(xùn)練集中真實(shí)樣本非常相似的人工樣本;判別器的輸入則為真實(shí)樣本或人工樣本,其目的是將人工樣本與真實(shí)樣本盡可能地區(qū)分出來。生成器和判別器交替運(yùn)行,相互博弈,各自的能力都得到升。理想情況下,經(jīng)過足夠次數(shù)的博弈之后,判別器無法判斷給定樣本的真實(shí)性,即對(duì)于所有樣本都輸出50%真,50%假的判斷。此時(shí),生成器輸出的人工樣本已經(jīng)逼真到使判別器無法分辨真假,停止博弈。這樣就可以得到一個(gè)具有“偽造”真實(shí)樣本能力的生成器。
Transformer:用于自然語言處理任務(wù),如機(jī)器翻譯和文本生成。Transformer模型在2017年被google提出,直接基于 Self-Attention 結(jié)構(gòu),取代了之前NLP任務(wù)中常用的RNN神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)。與RNN這類神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)相比,Transformer一個(gè)巨大的優(yōu)點(diǎn)是:模型在處理序列輸入時(shí),可以對(duì)整個(gè)序列輸入進(jìn)行并行計(jì)算,不需要按照時(shí)間步循環(huán)遞歸處理輸入序列。與seq2seq模型類似,Transformer模型結(jié)構(gòu)中的左半部分為編碼器(encoder),右半部分為解碼器(decoder)。
二、經(jīng)典入門Demo實(shí)戰(zhàn)
2.1 深度學(xué)習(xí)原理
“深度學(xué)習(xí)”這四個(gè)字拆解成兩個(gè)詞就是“深度”和“學(xué)習(xí)”?!皩W(xué)習(xí)”大概是我們學(xué)生時(shí)代接觸最頻繁的詞,那時(shí)候的學(xué)習(xí)就是上課、做題,最終通過考試。如果更抽象一點(diǎn)描述,學(xué)習(xí)就是認(rèn)知的過程,從未知到已知的探索與思考過程。最早的學(xué)習(xí),1+1=2,想想我們是怎么學(xué)習(xí)的?伸出一只手指,再伸出一只手指,數(shù)一數(shù),兩只手指那就是2。
這里定義一個(gè)概念,輸入和輸出,輸入就是已知的信息,輸出就是由輸入獲得的認(rèn)知的結(jié)果。我們將一個(gè)從已有的信息,通過計(jì)算、判斷和推理得到結(jié)果的認(rèn)知過程統(tǒng)稱為“學(xué)習(xí)”。
如何讓機(jī)器也可以進(jìn)行學(xué)習(xí)呢?學(xué)術(shù)界為此提出了“神經(jīng)網(wǎng)絡(luò)”的概念。人腦中負(fù)責(zé)活動(dòng)的基本單元是神經(jīng)元,這些神經(jīng)元互相連接成一個(gè)被稱為神經(jīng)網(wǎng)絡(luò)的龐大結(jié)構(gòu)。由此,學(xué)術(shù)界模仿人腦“神經(jīng)網(wǎng)絡(luò)“建立一個(gè)人工神經(jīng)網(wǎng)絡(luò)(ANN),我們通常也簡(jiǎn)稱為神經(jīng)網(wǎng)絡(luò)。
將1+1=2用神經(jīng)網(wǎng)絡(luò)可以表示為如下結(jié)構(gòu)。
我們將“1”、“+”、“1”與“2”同時(shí)作為輸入不斷訓(xùn)練神經(jīng)網(wǎng)絡(luò)(不斷告訴機(jī)器1+1=2),在訓(xùn)練若干次后,神經(jīng)網(wǎng)絡(luò)將會(huì)學(xué)會(huì)“1+1=2”。同樣的,我們將1+2=3放入神經(jīng)網(wǎng)絡(luò)中去,不斷進(jìn)行訓(xùn)練,若干次后神經(jīng)網(wǎng)絡(luò)也將學(xué)會(huì)1+2=3。如此循環(huán)往復(fù),我們可以教會(huì)神經(jīng)網(wǎng)絡(luò)進(jìn)行加法運(yùn)算,進(jìn)而可以讓神經(jīng)網(wǎng)絡(luò)學(xué)會(huì)算術(shù)運(yùn)算,我們把這個(gè)過程稱為深度學(xué)習(xí)。
深度學(xué)習(xí)在生活中的應(yīng)用不僅僅局限于此,在自動(dòng)駕駛、語音識(shí)別、自動(dòng)機(jī)器翻譯、即時(shí)視覺翻譯(拍照翻譯)、目標(biāo)識(shí)別等等領(lǐng)域也都有重要應(yīng)用,例如:手機(jī)上的小愛同學(xué)、地鐵口的人臉識(shí)別…
2.2 一個(gè)手寫數(shù)字的識(shí)別的實(shí)現(xiàn)過程Demo
下面我將通過一個(gè)手寫數(shù)字的識(shí)別的案例來進(jìn)一步講解深度學(xué)習(xí),帶領(lǐng)大家體驗(yàn)一次完整的深度學(xué)習(xí)實(shí)現(xiàn)的全過程。
假設(shè)現(xiàn)在我們手上很多張手寫的數(shù)字圖片,需要通過深度學(xué)習(xí)讓機(jī)器“認(rèn)識(shí)”這些圖片上的數(shù)字,然后告訴我們每一張圖片上的數(shù)字是多少。
那么我們應(yīng)該如何實(shí)現(xiàn)呢?總體的思路如下:
我們先拿出 6 萬張圖片給機(jī)器進(jìn)行學(xué)習(xí)(需要告訴機(jī)器每一個(gè)圖片上寫的是哪一個(gè)數(shù)字)。
在學(xué)習(xí)后,再拿出1萬張機(jī)器沒“見過”的圖片給它進(jìn)行識(shí)別,讓它告訴我們,圖片上寫的是哪一個(gè)數(shù)字。
重復(fù)上面的過程,直到機(jī)器可以認(rèn)識(shí)手寫的數(shù)字。
至此,完成便可實(shí)現(xiàn)手寫數(shù)字識(shí)別這一效果。
程序執(zhí)行步驟:
① 學(xué)習(xí)6萬張圖片上的數(shù)字
② 用1萬張圖片測(cè)試機(jī)器的學(xué)習(xí)效果(這1萬張不參與①的訓(xùn)練)
③ 重復(fù)①、②
現(xiàn)在你需要做的是:了解每一個(gè)模塊實(shí)現(xiàn)的功能,從整體上把握整份代碼。
開發(fā)環(huán)境:
語言環(huán)境:Python3.10.11
編譯器:Jupyter Notebook
深度學(xué)習(xí)框架:TensorFlow 2.4.1
1. 準(zhǔn)備數(shù)據(jù)
導(dǎo)入數(shù)據(jù)
?
?
import tensorflow as tf from tensorflow.keras import datasets, layers, models # 加載數(shù)據(jù)集 (train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data() # 輸出數(shù)據(jù)形狀 train_images.shape, test_images.shape
((60000, 28, 28), (10000, 28, 28))
?
?
準(zhǔn)備好 6 萬張帶有標(biāo)簽的訓(xùn)練圖片讓機(jī)器進(jìn)行學(xué)習(xí)。1 萬張測(cè)試圖片讓機(jī)器進(jìn)行識(shí)別,測(cè)試其是否學(xué)會(huì)了。(60000, 28, 28)?表示為:60000 張 28*28 像素的圖片。
可視化
這里我們用第三方庫?matplotlib?輸出手寫數(shù)字圖片,看看我們的手寫數(shù)字(數(shù)據(jù)集)是什么樣子的。
?
?
import matplotlib.pyplot as plt # 設(shè)置窗口大小為 20*12 單位英寸 plt.figure(figsize=(20,12)) for i in range(20): # 設(shè)置子圖行數(shù)為5,列數(shù)為10,i+1表示第幾個(gè)子圖 plt.subplot(5,10,i+1) # 去掉坐標(biāo)軸刻度 plt.xticks([]) plt.yticks([]) # 顯示圖片 plt.imshow(train_images[i], cmap=plt.cm.binary) # 顯示標(biāo)簽 plt.xlabel(train_labels[i]) plt.show()
?
?
調(diào)整圖片格式
需要將圖片調(diào)整為特定格式程序才可以進(jìn)行學(xué)習(xí)
?
?
#調(diào)整數(shù)據(jù)到我們需要的格式train_images = train_images.reshape((60000, 28, 28, 1))test_images = test_images.reshape((10000, 28, 28, 1))# 輸出數(shù)據(jù)sahpetrain_images.shape,test_images.shape,train_labels.shape,test_labels.shape
((60000, 28, 28, 1), (10000, 28, 28, 1), (60000,), (10000,))
?
?
(60000, 28, 28, 1):表示為:60000張 28*28 的灰度圖片,最后一個(gè)數(shù)字為1時(shí),代表灰度圖片;為3時(shí)代表彩色圖片。
2. 構(gòu)建神經(jīng)網(wǎng)絡(luò)模型
我們將圖片輸入到網(wǎng)絡(luò),圖片首先會(huì)將其數(shù)字化,緊接著通過卷積層提取圖片上這個(gè)數(shù)字的特征,最后通過數(shù)字的特征判斷這個(gè)數(shù)字是哪一個(gè)。結(jié)構(gòu)圖如下:
上面的結(jié)構(gòu)圖中,向我們展示了五層結(jié)構(gòu),那么每一層具體是用來做什么的呢?
輸入層:用于將數(shù)據(jù)輸入到神經(jīng)網(wǎng)絡(luò)
卷積層:使用卷積核提取圖片特征,卷積核相當(dāng)于一個(gè)小型的“特征提取器”
Flatten層:將多維的輸入一維化,常用在卷積層到全連接層的過渡
全連接層:起到“特征提取器”的作用
輸出層:輸出結(jié)果
卷積核與全連接層從某些方面上講都有提取特征的作用,但是所采用的方法是不同的。
這部分為深度學(xué)習(xí)的核心內(nèi)容,就是構(gòu)建模型,先不管這快,現(xiàn)在我們主要任務(wù)是跑通整個(gè)程序,從整體上了解一下深度學(xué)習(xí)是什么。
?
?
model = models.Sequential([ # layers.Conv2D(32, (3, 3), input_shape=(28, 28, 1)), # 卷積層:提取圖片特征 layers.Flatten(), # Flatten層:將二維圖片壓縮為一維形式 layers.Dense(100), # 全連接層:將特征進(jìn)行進(jìn)一步壓縮 layers.Dense(10) # 輸出層:輸出結(jié)果 ]) #?打印網(wǎng)絡(luò)結(jié)構(gòu)
?
?
3. 編譯模型
在這一步,我們需要設(shè)置模型的優(yōu)化器,損失函數(shù)、評(píng)價(jià)函數(shù):
優(yōu)化器:幫助模型更好的訓(xùn)練
損失函數(shù):用于估量預(yù)測(cè)值與真實(shí)值的不一致程度
評(píng)價(jià)函數(shù):評(píng)價(jià)模型的質(zhì)量
?
?
model.compile(optimizer='adam', # adam是優(yōu)化器的一種 loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), # 損失函數(shù)的一種計(jì)算方法 ??????????????metrics=['accuracy'])??#采用準(zhǔn)確率來評(píng)價(jià)模
?
?
4. 訓(xùn)練模型
將數(shù)據(jù)傳入模型進(jìn)行訓(xùn)練,傳入的數(shù)據(jù)分為訓(xùn)練數(shù)據(jù)、驗(yàn)證數(shù)據(jù)兩部分。訓(xùn)練數(shù)據(jù)(訓(xùn)練集)用于訓(xùn)練模型,驗(yàn)證數(shù)據(jù)(驗(yàn)證集)用于監(jiān)測(cè)模型的效果。epochs?表示模型的學(xué)習(xí)輪數(shù)(次數(shù))。
?
?
""" train_images :訓(xùn)練數(shù)據(jù)的圖片 train_labels :訓(xùn)練圖片對(duì)應(yīng)的標(biāo)簽 epochs :訓(xùn)練輪數(shù) validation_data:驗(yàn)證數(shù)據(jù) """ history = model.fit(train_images, train_labels, epochs=3, validation_data=(test_images, test_labels))
?
?
5. 預(yù)測(cè)
?
?
# 打印我們想要進(jìn)行預(yù)測(cè)的圖片 plt.imshow(test_images[1])
?
?
輸出測(cè)試集中第一張圖片的預(yù)測(cè)數(shù)組
?
?
pre = model.predict(test_images) pre[1]
array([ 12.474585 , 1.1173537, 21.654232 , 16.206923 , -10.989567 , 17.235504 , 19.404213 , -22.553476 , 13.221286 , -10.19972 ], dtype=float32)
?
?
這組浮點(diǎn)數(shù)對(duì)應(yīng)著0~9,最大的浮點(diǎn)數(shù)對(duì)應(yīng)著的數(shù)字就是神經(jīng)網(wǎng)絡(luò)的預(yù)測(cè)結(jié)果。
?
?
import numpy as np # 輸出預(yù)測(cè)結(jié)果 pre_num = np.argmax(pre[1]) print("模型的預(yù)測(cè)結(jié)果為:",pre_num)
模型的預(yù)測(cè)結(jié)果為:2
?
?
總結(jié)
我們通過算術(shù)學(xué)習(xí)、手寫數(shù)字識(shí)別了解了什么是深度學(xué)習(xí),也用TensorFlow2實(shí)現(xiàn)了手寫數(shù)字識(shí)別,從整體上了解了一個(gè)深度學(xué)習(xí)程序是什么樣子的,應(yīng)該有哪些步驟
審核編輯:黃飛
?
評(píng)論
查看更多