日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > 卷积神经网络 >内容正文

卷积神经网络

【深度学习】5:CNN卷积神经网络原理

發(fā)布時間:2023/12/14 卷积神经网络 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【深度学习】5:CNN卷积神经网络原理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言:先坦白的說,深度神經(jīng)網(wǎng)絡(luò)的學習在一開始對我造成的困擾還是很大的,我也是通過不斷地看相關(guān)的視頻資料、文獻講解嘗試去理解記憶。畢竟這些內(nèi)容大多都是不可查的,我們看到的都只是輸入輸出的東西,里面的內(nèi)部運作以及工作原理,都需要沉心靜思。

這篇CNN卷積神經(jīng)網(wǎng)絡(luò)的原理介紹,也是自己通過收集來的資料閱讀、理解、操練后,有了一定的見解后才拙筆,里面的內(nèi)容我會盡量詳盡,不清楚明白的地方,望大家慧眼指出。

-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------

一、機器如何識圖

先給大家出個腦筋急轉(zhuǎn)彎:在白紙上畫出一個大熊貓,一共需要幾種顏色的畫筆?——大家應(yīng)該都知道,只需要一種黑色的畫筆,只需要將大熊貓黑色的地方涂上黑色,一個大熊貓的圖像就可以展現(xiàn)出來。

我們畫大熊貓的方式,其實和媽媽們的十字繡很接近——在給定的格子里,繡上不同的顏色,最后就可以展現(xiàn)出一幅特定的“圖片”。而機器識圖的方式正好和繡十字繡的方式相反,現(xiàn)在有了一幅圖片,機器通過識別圖片中每個格子(像素點)上的顏色,將每個格子里的顏色都用數(shù)字類型存儲,得到一張很大的數(shù)字矩陣,圖片信息也就存儲在這張數(shù)字矩陣中。

上圖中每一個格子代表一個像素點,像素點里的數(shù)字代表顏色碼,顏色碼范圍是[0,255],(各式各樣的顏色都是由紅、綠、藍三色組成,每個顏色都是0~255之間數(shù)字)
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
我們在得到的一張大數(shù)字矩陣的基礎(chǔ)上開展卷積神經(jīng)網(wǎng)絡(luò)識別工作:
機器識圖的過程:機器識別圖像并不是一下子將一個復(fù)雜的圖片完整識別出來,而是將一個完整的圖片分割成許多個小部分,把每個小部分里具有的特征提取出來(也就是識別每個小部分),再將這些小部分具有的特征匯總到一起,就可以完成機器識別圖像的過程了
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------

二、卷積神經(jīng)網(wǎng)絡(luò)原理介紹

用CNN卷積神經(jīng)網(wǎng)絡(luò)識別圖片,一般需要的步驟有:

  • 卷積層初步提取特征
  • 池化層提取主要特征
  • 全連接層將各部分特征匯總
  • 產(chǎn)生分類器,進行預(yù)測識別
  • 1、卷積層工作原理

    卷積層的作用:就是提取圖片每個小部分里具有的特征

    假定我們有一個尺寸為6?66*66?6 的圖像,每一個像素點里都存儲著圖像的信息。我們再定義一個卷積核(相當于權(quán)重),用來從圖像中提取一定的特征。卷積核與數(shù)字矩陣對應(yīng)位相乘再相加,得到卷積層輸出結(jié)果。

    (429 = 18x1+54x0+51x1+55x0+121x1+75x0+35x1+24x0+204x1)
    卷積核的取值在沒有以往學習的經(jīng)驗下,可由函數(shù)隨機生成,再逐步訓(xùn)練調(diào)整

    當所有的像素點都至少被覆蓋一次后,就可以產(chǎn)生一個卷積層的輸出(下圖的步長為1)

    機器一開始并不知道要識別的部分具有哪些特征,是通過與不同的卷積核相作用得到的輸出值,相互比較來判斷哪一個卷積核最能表現(xiàn)該圖片的特征——比如我們要識別圖像中的某種特征(比如曲線),也就是說,這個卷積核要對這種曲線有很高的輸出值,對其他形狀(比如三角形)則輸出較低。卷積層輸出值越高,就說明匹配程度越高,越能表現(xiàn)該圖片的特征

    卷積層具體工作過程:
    比如我們設(shè)計的一個卷積核如下左,想要識別出來的曲線如下右:

    現(xiàn)在我們用上面的卷積核,來識別這個簡化版的圖片——一只漫畫老鼠

    當機器識別到老鼠的屁股的時候,真實區(qū)域數(shù)字矩陣與卷積核相乘作用后,輸出較大:6600

    而用同一個卷積核,來識別老鼠的耳朵的時候,輸出則很小:0

    我們就可以認為:現(xiàn)有的這個卷積核保存著曲線的特征,匹配識別出來了老鼠的屁股是曲線的。我們則還需要其他特征的卷積核,來匹配識別出來老鼠的其他部分。卷積層的作用其實就是通過不斷的改變卷積核,來確定能初步表征圖片特征的有用的卷積核是哪些,再得到與相應(yīng)的卷積核相乘后的輸出矩陣

    2、池化層工作原理

    池化層的輸入就是卷積層輸出的原數(shù)據(jù)與相應(yīng)的卷積核相乘后的輸出矩陣
    池化層的目的:

    • 為了減少訓(xùn)練參數(shù)的數(shù)量,降低卷積層輸出的特征向量的維度
    • 減小過擬合現(xiàn)象,只保留最有用的圖片信息,減少噪聲的傳遞

    最常見的兩種池化層的形式:

    • 最大池化:max-pooling——選取指定區(qū)域內(nèi)最大的一個數(shù)來代表整片區(qū)域
    • 均值池化:mean-pooling——選取指定區(qū)域內(nèi)數(shù)值的平均值來代表整片區(qū)域

    舉例說明兩種池化方式:(池化步長為2,選取過的區(qū)域,下一次就不再選取)

    4?44*44?4的數(shù)字矩陣里,以步長2?22*22?2選取區(qū)域,比如上左將區(qū)域[1,2,3,4]中最大的值4池化輸出;上右將區(qū)域[1,2,3,4]中平均值5/2池化輸出

    3、全連接層工作原理

    卷積層和池化層的工作就是提取特征,并減少原始圖像帶來的參數(shù)。然而,為了生成最終的輸出,我們需要應(yīng)用全連接層來生成一個等于我們需要的類的數(shù)量的分類器。

    全連接層的工作原理和之前的神經(jīng)網(wǎng)絡(luò)學習很類似,我們需要把池化層輸出的張量重新切割成一些向量,乘上權(quán)重矩陣,加上偏置值,然后對其使用ReLU激活函數(shù),用梯度下降法優(yōu)化參數(shù)既可。

    三、卷積神經(jīng)網(wǎng)絡(luò)代碼解析

    1、數(shù)據(jù)集的讀取,以及數(shù)據(jù)預(yù)定義

    from tensorflow.examples.tutorials.mnist import input_data #讀取MNIST數(shù)據(jù)集 mnist = input_data.read_data_sets('MNIST_data', one_hot=True) #預(yù)定義輸入值X、輸出真實值Y placeholder為占位符 x = tf.placeholder(tf.float32, shape=[None, 784]) y_ = tf.placeholder(tf.float32, shape=[None, 10]) keep_prob = tf.placeholder(tf.float32) x_image = tf.reshape(x, [-1,28,28,1])
    • MNIST是Google的很經(jīng)典的一個做圖像識別的數(shù)據(jù)集,圖片大小是28?2828*2828?28的,需要先下載才能使用。MNIST數(shù)據(jù)集下載鏈接, 密碼: jcam
    • x、y_現(xiàn)在都是用占位符表示,當程序運行到一定指令,向x、y_傳入具體的值后,就可以代入進行計算了
    • shape=[None, 784]是數(shù)據(jù)維度大小——因為MNIST數(shù)據(jù)集中每一張圖片大小都是28?2828*2828?28的,計算時候是將28?2828*2828?28的二維數(shù)據(jù)轉(zhuǎn)換成一個一維的、長度為784的新向量。None表示其值大小不定,意即選中的x、y_的數(shù)量暫時不定
    • keep_prob 是改變參與計算的神經(jīng)元個數(shù)的值。(下有詳細說明)

    2、權(quán)重、偏置值函數(shù)

    def weight_variable(shape):# 產(chǎn)生隨機變量initial = tf.truncated_normal(shape, stddev=0.1)return tf.Variable(initial)def bias_variable(shape):initial = tf.constant(0.1, shape=shape)return tf.Variable(initial)

    truncated_normal()函數(shù):選取位于正態(tài)分布均值=0.1附近的隨機值

    3、卷積函數(shù)、池化函數(shù)定義

    def conv2d(x, W):#stride = [1,水平移動步長,豎直移動步長,1]return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')def max_pool_2x2(x):# stride = [1,水平移動步長,豎直移動步長,1]return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding='SAME')
    • 輸入x是圖片信息矩陣,W是卷積核的值
    • 卷積層conv2d()函數(shù)里strides參數(shù)要求第一個、最后一個參數(shù)必須是1;
    • 第二個參數(shù)表示:卷積核每次向右移動的步長
    • 第三個參數(shù)表示:卷積核每次向下移動的步長

    在上面卷積層的工作原理中,有展示strides=[1, 1, 1, 1]的動態(tài)圖,
    下面展示strides=[1, 2, 2, 1]時的情況:可以看到高亮的區(qū)域每次向右移動兩格,向下移動兩格

    可以得到:當我們的卷積層步長值越大,得到的輸出圖像的規(guī)格就會越小。為了使得到的圖像的規(guī)格和原圖像保持一樣的大,在輸入圖像四周填充足夠多的 0 邊界就可以解決這個問題,這時padding的參數(shù)就為“SAME”(利用邊界保留了更多信息,并且也保留了圖像的原大小)下圖:

    padding的另一個可選參數(shù)為“VALID”,和“SAME”不同的是:不用0來填充邊界,這時得到的圖像的規(guī)格就會小于原圖像。新圖像尺寸大小 = 原數(shù)據(jù)尺寸大小-卷積核尺寸大小+1(一般我們選用的padding都為“SAME”)

    池化函數(shù)用簡單傳統(tǒng)的2x2大小的模板做max pooling,池化步長為2,選過的區(qū)域下次不再選取

    4、第一次卷積+池化

    x_image = tf.reshape(x, [-1,28,28,1])# 卷積層1網(wǎng)絡(luò)結(jié)構(gòu)定義 # 卷積核1:patch=5×5;in size 1;out size 32;激活函數(shù)reLU非線性處理 W_conv1 = weight_variable([5, 5, 1, 32]) b_conv1 = bias_variable([32]) # output size 28*28*32 h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) # output size 14*14*32 h_pool1 = max_pool_2x2(h_conv1)
    • 圖片集是黑白單色,x_image 中的圖片尺寸參數(shù)最后一個 = 1,彩色 = 3
    • 這里的卷積核大小是5?55*55?5的,輸入的通道數(shù)是1,輸出的通道數(shù)是32
    • 卷積核的值這里就相當于權(quán)重值,用隨機數(shù)列生成的方式得到
    • 由于MNIST數(shù)據(jù)集圖片大小都是28?2828*2828?28,且是黑白單色,所以準確的圖片尺寸大小是28?28?128*28*128?28?1(1表示圖片只有一個色層,彩色圖片都RGB3個色層),所以經(jīng)過第一次卷積后,輸出的通道數(shù)由1變成32,圖片尺寸變?yōu)?#xff1a;28?28?3228*28*3228?28?32(相當于拉伸了高)
    • 再經(jīng)過第一次池化,池化步長是2?22*22?2,相當于每四個小格子池化成一個數(shù)值,所以經(jīng)過池化后圖片尺寸為14?14?3214*14*3214?14?32

    5、第二次卷積+池化

    #卷積層2網(wǎng)絡(luò)結(jié)構(gòu)定義 #卷積核2:patch=5×5;in size 32;out size 64;激活函數(shù)reLU非線性處理 W_conv2 = weight_variable([5, 5, 32, 64]) b_conv2 = bias_variable([64]) # output size 14*14*64 h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) # output size 7 *7 *64 h_pool2 = max_pool_2x2(h_conv2)
    • 這里的卷積核大小也是5?55*55?5的,第二次輸入的通道數(shù)是32,輸出的通道數(shù)是64
    • 第一次卷積+池化輸出的圖片大小是14?14?3214*14*3214?14?32,經(jīng)過第二次卷積后圖片尺寸變?yōu)?#xff1a;14?14?6414*14*6414?14?64
    • 再經(jīng)過第二次池化(池化步長也是2?22*22?2),最后輸出的圖片尺寸為7?7?647*7*647?7?64

    6、全連接層1、全連接層2

    # 全連接層1 W_fc1 = weight_variable([7*7*64,1024]) b_fc1 = bias_variable([1024]) h_pool2_flat = tf.reshape(h_pool2, [-1,7*7*64]) h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1) h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) # 全連接層2 W_fc2 = weight_variable([1024, 10]) b_fc2 = bias_variable([10]) prediction = tf.matmul(h_fc1_drop, W_fc2) + b_fc2
    • 全連接層的輸入就是第二次池化后的輸出,尺寸是7?7?647*7*647?7?64,全連接層1設(shè)置有1024個神經(jīng)元
    • tf.reshape(a,newshape)函數(shù),當newshape = -1時,函數(shù)會根據(jù)已有的維度計算出數(shù)組的另外shape屬性值
    • keep_prob 是為了減小過擬合現(xiàn)象。每次只讓部分神經(jīng)元參與工作使權(quán)重得到調(diào)整。只有當keep_prob = 1時,才是所有的神經(jīng)元都參與工作
    • 全連接層2設(shè)置有10個神經(jīng)元,相當于生成的分類器
    • 經(jīng)過全連接層1、2,得到的預(yù)測值存入prediction 中

    7、梯度下降法優(yōu)化、求準確率

    #二次代價函數(shù):預(yù)測值與真實值的誤差 loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=prediction)) #梯度下降法:數(shù)據(jù)太龐大,選用AdamOptimizer優(yōu)化器 train_step = tf.train.AdamOptimizer(1e-4).minimize(loss) #結(jié)果存放在一個布爾型列表中 correct_prediction = tf.equal(tf.argmax(prediction,1), tf.argmax(y_,1)) #求準確率 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    • 由于數(shù)據(jù)集太龐大,這里采用的優(yōu)化器是AdamOptimizer,學習率是1e-4
    • tf.argmax(prediction,1)返回的是對于任一輸入x預(yù)測到的標簽值,tf.argmax(y_,1)代表正確的標簽值
    • correct_prediction 這里是返回一個布爾數(shù)組。為了計算我們分類的準確率,我們將布爾值轉(zhuǎn)換為浮點數(shù)來代表對與錯,然后取平均值。例如:[True, False, True, True]變?yōu)閇1,0,1,1],計算出準確率就為0.75

    8、其他說明、保存參數(shù)

    for i in range(1000):batch = mnist.train.next_batch(50)if i%100 == 0:train_accuracy = accuracy.eval(feed_dict={x:batch[0], y_: batch[1], keep_prob: 1.0})print("step",i, "training accuracy",train_accuracy)train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})''' #保存模型參數(shù) saver.save(sess, './model.ckpt') print("test accuracy %g"%accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0})) '''
    • batch 是來源于MNIST數(shù)據(jù)集,一個批次包含50條數(shù)據(jù)
    • feed_dict=({x: batch[0], y_: batch[1], keep_prob: 0.5}語句:是將batch[0],batch[1]代表的值傳入x,y_;
    • keep_prob = 0.5 只有一半的神經(jīng)元參與工作

    當完成訓(xùn)練時,程序會保存學習到的參數(shù),不用下次再訓(xùn)練
    特別提醒:運行非常占內(nèi)存,而且運行到最后保存參數(shù)時,有可能卡死電腦

    四、源碼及效果展示

    # -*- coding:utf-8 -*- # -*- author:zzZ_CMing # -*- 2018/01/24;14:14 # -*- python3.5from tensorflow.examples.tutorials.mnist import input_data import tensorflow as tf import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'def weight_variable(shape):# 產(chǎn)生隨機變量# truncated_normal:選取位于正態(tài)分布均值=0.1附近的隨機值initial = tf.truncated_normal(shape, stddev=0.1)return tf.Variable(initial)def bias_variable(shape):initial = tf.constant(0.1, shape=shape)return tf.Variable(initial)def conv2d(x, W):#stride = [1,水平移動步長,豎直移動步長,1]return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')def max_pool_2x2(x):# stride = [1,水平移動步長,豎直移動步長,1]return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding='SAME')#讀取MNIST數(shù)據(jù)集 mnist = input_data.read_data_sets('MNIST_data', one_hot=True) sess = tf.InteractiveSession()#預(yù)定義輸入值X、輸出真實值Y placeholder為占位符 x = tf.placeholder(tf.float32, shape=[None, 784]) y_ = tf.placeholder(tf.float32, shape=[None, 10]) keep_prob = tf.placeholder(tf.float32) x_image = tf.reshape(x, [-1,28,28,1]) #print(x_image.shape) #[n_samples,28,28,1]#卷積層1網(wǎng)絡(luò)結(jié)構(gòu)定義 #卷積核1:patch=5×5;in size 1;out size 32;激活函數(shù)reLU非線性處理 W_conv1 = weight_variable([5, 5, 1, 32]) b_conv1 = bias_variable([32]) h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) #output size 28*28*32 h_pool1 = max_pool_2x2(h_conv1) #output size 14*14*32#卷積層2網(wǎng)絡(luò)結(jié)構(gòu)定義 #卷積核2:patch=5×5;in size 32;out size 64;激活函數(shù)reLU非線性處理 W_conv2 = weight_variable([5, 5, 32, 64]) b_conv2 = bias_variable([64]) h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) #output size 14*14*64 h_pool2 = max_pool_2x2(h_conv2) #output size 7 *7 *64# 全連接層1 W_fc1 = weight_variable([7*7*64,1024]) b_fc1 = bias_variable([1024]) h_pool2_flat = tf.reshape(h_pool2, [-1,7*7*64]) #[n_samples,7,7,64]->>[n_samples,7*7*64] h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1) h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) # 減少計算量dropout# 全連接層2 W_fc2 = weight_variable([1024, 10]) b_fc2 = bias_variable([10]) prediction = tf.matmul(h_fc1_drop, W_fc2) + b_fc2 #prediction = tf.nn.softmax(stf.matmul(h_fc1_drop, W_fc2) + b_fc2)#二次代價函數(shù):預(yù)測值與真實值的誤差 loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=prediction)) #梯度下降法:數(shù)據(jù)太龐大,選用AdamOptimizer優(yōu)化器 train_step = tf.train.AdamOptimizer(1e-4).minimize(loss) #結(jié)果存放在一個布爾型列表中 correct_prediction = tf.equal(tf.argmax(prediction,1), tf.argmax(y_,1)) #求準確率 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))saver = tf.train.Saver() # defaults to saving all variables sess.run(tf.global_variables_initializer())for i in range(1000):batch = mnist.train.next_batch(50)if i%100 == 0:train_accuracy = accuracy.eval(feed_dict={x:batch[0], y_: batch[1], keep_prob: 1.0})print("step",i, "training accuracy",train_accuracy)train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})''' #保存模型參數(shù) saver.save(sess, './model.ckpt') print("test accuracy %g"%accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0})) '''

    效果展示如下:

    訓(xùn)練700次時候,成功率已經(jīng)到達98%,越往后學習,準確率越高

    特別提醒:由于我的電腦配置比較低,運行耗時較長,而且在保存參數(shù)時候還會出現(xiàn)卡死情況,大家請注意。
    -----------------------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------------------

    系列推薦:

    【監(jiān)督學習】1:KNN算法實現(xiàn)手寫數(shù)字識別的三種方法
    -----------------------------------------------------------------------------------------------------------------------------
    【無監(jiān)督學習】1:K-means算法原理介紹,以及代碼實現(xiàn)
    【無監(jiān)督學習】2:DBSCAN算法原理介紹,以及代碼實現(xiàn)
    【無監(jiān)督學習】3:Density Peaks聚類算法(局部密度聚類)
    -----------------------------------------------------------------------------------------------------------------------------
    【深度學習】1:感知器原理,以及多層感知器解決異或問題
    【深度學習】2:BP神經(jīng)網(wǎng)絡(luò)的原理,以及異或問題的解決
    【深度學習】3:BP神經(jīng)網(wǎng)絡(luò)識別MNIST數(shù)據(jù)集
    【深度學習】4:BP神經(jīng)網(wǎng)絡(luò)+sklearn實現(xiàn)數(shù)字識別
    【深度學習】5:CNN卷積神經(jīng)網(wǎng)絡(luò)原理、MNIST數(shù)據(jù)集識別
    【深度學習】8:CNN卷積神經(jīng)網(wǎng)絡(luò)識別sklearn數(shù)據(jù)集(附源碼)
    【深度學習】6:RNN遞歸神經(jīng)網(wǎng)絡(luò)原理、MNIST數(shù)據(jù)集識別
    【深度學習】7:Hopfield神經(jīng)網(wǎng)絡(luò)(DHNN)原理介紹
    -----------------------------------------------------------------------------------------------------------------------------
    TensorFlow框架簡單介紹
    -----------------------------------------------------------------------------------------------------------------------------

    總結(jié)

    以上是生活随笔為你收集整理的【深度学习】5:CNN卷积神经网络原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。