一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

CNN卷積神經(jīng)網(wǎng)絡(luò)原理講解+圖片識別應(yīng)用(附源碼)

 jarest 2019-11-28

一、機器如何識圖

先給大家出個腦筋急轉(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ò)識別圖片,一般需要的步驟有:

  1. 卷積層初步提取特征

  2. 池化層提取主要特征

  3. 全連接層將各部分特征匯總

  4. 產(chǎn)生分類器,進行預(yù)測識別

1、卷積層工作原理

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

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

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

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

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

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

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

 

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

                                                                            

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

我們就可以認為:現(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*4的數(shù)字矩陣?yán)?,以步長2*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ò)學(xué)習(xí)很類似,我們需要把池化層輸出的張量重新切割成一些向量,乘上權(quán)重矩陣,加上偏置值,然后對其使用ReLU激活函數(shù),用梯度下降法優(yōu)化參數(shù)既可。

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

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

  1. from tensorflow.examples.tutorials.mnist import input_data
  2. import tensorflow as tf
  3. #讀取MNIST數(shù)據(jù)集
  4. mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
  5. sess = tf.InteractiveSession()
  6. #預(yù)定義輸入值X、輸出真實值Y placeholder為占位符
  7. x = tf.placeholder(tf.float32, shape=[None, 784])
  8. y_ = tf.placeholder(tf.float32, shape=[None, 10])
  9. keep_prob = tf.placeholder(tf.float32)
  10. x_image = tf.reshape(x, [-1,28,28,1])
  • MNIST是Google的很經(jīng)典的一個做圖像識別的數(shù)據(jù)集,圖片大小是28*28的,需要先下載才能使用。

  • x、y_現(xiàn)在都是用占位符表示,當(dāng)程序運行到一定指令,向x、y_傳入具體的值后,就可以代入進行計算了

  • shape=[None, 784]是數(shù)據(jù)維度大小——因為MNIST數(shù)據(jù)集中每一張圖片大小都是28*28的,計算時候是將28*28的二維數(shù)據(jù)轉(zhuǎn)換成一個一維的、長度為784的新向量。None表示其值大小不定,意即選中的x、y_的數(shù)量暫時不定

  • keep_prob 是改變參與計算的神經(jīng)元個數(shù)的值。(下有詳細說明)

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

  1. def weight_variable(shape):
  2. # 產(chǎn)生隨機變量
  3. # truncated_normal:選取位于正態(tài)分布均值=0.1附近的隨機值
  4. initial = tf.truncated_normal(shape, stddev=0.1)
  5. return tf.Variable(initial)
  6. def bias_variable(shape):
  7. initial = tf.constant(0.1, shape=shape)
  8. return tf.Variable(initial)

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

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

  1. def conv2d(x, W):
  2. # stride = [1,水平移動步長,豎直移動步長,1]
  3. return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
  4. def max_pool_2x2(x):
  5. # stride = [1,水平移動步長,豎直移動步長,1]
  6. 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ū)域每次向右移動兩格,向下移動兩格 

可以得到:當(dāng)我們的卷積層步長值越大,得到的輸出圖像的規(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、第一次卷積+池化

  1. #卷積層1網(wǎng)絡(luò)結(jié)構(gòu)定義
  2. #卷積核1:patch=5×5;in size 1;out size 32;激活函數(shù)reLU非線性處理
  3. W_conv1 = weight_variable([5, 5, 1, 32])
  4. b_conv1 = bias_variable([32])
  5. h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) #output size 28*28*32
  6. h_pool1 = max_pool_2x2(h_conv1) #output size 14*14*32#卷積層2網(wǎng)絡(luò)結(jié)構(gòu)定義

 

  • 圖片集是黑白單色,x_image 中的圖片尺寸參數(shù)最后一個 = 1,彩色 = 3

  • 這里的卷積核大小是5*5的,輸入的通道數(shù)是1,輸出的通道數(shù)是32

  • 卷積核的值這里就相當(dāng)于權(quán)重值,用隨機數(shù)列生成的方式得到

  • 由于MNIST數(shù)據(jù)集圖片大小都是28*28,且是黑白單色,所以準(zhǔn)確的圖片尺寸大小是28*28*1(1表示圖片只有一個色層,彩色圖片都是3個色層——RGB),所以經(jīng)過第一次卷積后,輸出的通道數(shù)由1變成32,圖片尺寸變?yōu)椋?8*28*32(相當(dāng)于拉伸了高)

  • 再經(jīng)過第一次池化(池化步長是2),圖片尺寸為14*14*32

5、第二次卷積+池化

  1. #卷積核2:patch=5×5;in size 32;out size 64;激活函數(shù)reLU非線性處理
  2. W_conv2 = weight_variable([5, 5, 32, 64])
  3. b_conv2 = bias_variable([64])
  4. h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) #output size 14*14*64
  5. h_pool2 = max_pool_2x2(h_conv2) #output size 7 *7 *64

 

  • 這里的卷積核大小也是5*5的,第二次輸入的通道數(shù)是32,輸出的通道數(shù)是64

  • 第一次卷積+池化輸出的圖片大小是14*14*32,經(jīng)過第二次卷積后圖片尺寸變?yōu)椋?4*14*64

  • 再經(jīng)過第二次池化(池化步長是2),最后輸出的圖片尺寸為7*7*64

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

  1. # 全連接層1
  2. W_fc1 = weight_variable([7*7*64,1024])
  3. b_fc1 = bias_variable([1024])
  4. h_pool2_flat = tf.reshape(h_pool2, [-1,7*7*64]) #[n_samples,7,7,64]->>[n_samples,7*7*64]
  5. h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
  6. h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) # 減少計算量dropout
  7. # 全連接層2
  8. W_fc2 = weight_variable([1024, 10])
  9. b_fc2 = bias_variable([10])
  10. prediction = tf.matmul(h_fc1_drop, W_fc2) + b_fc2
  • 全連接層的輸入就是第二次池化后的輸出,尺寸是7*7*64,全連接層1有1024個神經(jīng)元

  • tf.reshape(a,newshape)函數(shù),當(dāng)newshape = -1時,函數(shù)會根據(jù)已有的維度計算出數(shù)組的另外shape屬性值

  • keep_prob 是為了減小過擬合現(xiàn)象。每次只讓部分神經(jīng)元參與工作使權(quán)重得到調(diào)整。只有當(dāng)keep_prob = 1時,才是所有的神經(jīng)元都參與工作

  • 全連接層2有10個神經(jīng)元,相當(dāng)于生成的分類器

  • 經(jīng)過全連接層1、2,得到的預(yù)測值存入prediction 中

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

  1. #二次代價函數(shù):預(yù)測值與真實值的誤差
  2. loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=prediction))
  3. #梯度下降法:數(shù)據(jù)太龐大,選用AdamOptimizer優(yōu)化器
  4. train_step = tf.train.AdamOptimizer(1e-4).minimize(loss)
  5. #結(jié)果存放在一個布爾型列表中
  6. correct_prediction = tf.equal(tf.argmax(prediction,1), tf.argmax(y_,1))
  7. #求準(zhǔn)確率
  8. accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
  • 由于數(shù)據(jù)集太龐大,這里采用的優(yōu)化器是AdamOptimizer,學(xué)習(xí)率是1e-4

  • tf.argmax(prediction,1)返回的是對于任一輸入x預(yù)測到的標(biāo)簽值,tf.argmax(y_,1)代表正確的標(biāo)簽值

  • correct_prediction 這里是返回一個布爾數(shù)組。為了計算我們分類的準(zhǔn)確率,我們將布爾值轉(zhuǎn)換為浮點數(shù)來代表對與錯,然后取平均值。例如:[True, False, True, True]變?yōu)閇1,0,1,1],計算出準(zhǔn)確率就為0.75

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

  1. for i in range(1000):
  2. batch = mnist.train.next_batch(50)
  3. if i % 100 == 0:
  4. train_accuracy = accuracy.eval(feed_dict={x: batch[0], y_: batch[1], keep_prob: 1.0})
  5. print("step", i, "training accuracy", train_accuracy)
  6. train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})
  7. #保存模型參數(shù)
  8. saver.save(sess, './model.ckpt')
  9. 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)元參與工作

  • 當(dāng)完成訓(xùn)練時,程序會保存學(xué)習(xí)到的參數(shù),不用下次再訓(xùn)練

  • 特別提醒:運行非常占內(nèi)存,而且運行到最后保存參數(shù)時,有可能卡死電腦

  • 特別提醒:運行非常占內(nèi)存,而且運行到最后保存參數(shù)時,有可能卡死電腦

  • 特別提醒:運行非常占內(nèi)存,而且運行到最后保存參數(shù)時,有可能卡死電腦

 

四、源碼及效果展示

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

 

效果展示如下: 

 訓(xùn)練700次時候,成功率已經(jīng)到達98%,越往后學(xué)習(xí),準(zhǔn)確率越高,但是 特別提醒:運行非常占內(nèi)存,而且運行到最后保存參數(shù)時,有可能卡死電腦 特別提醒:運行非常占內(nèi)存,而且運行到最后保存參數(shù)時,有可能卡死電腦 特別提醒:運行非常占內(nèi)存,而且運行到最后保存參數(shù)時,有可能卡死電腦

結(jié)束語:自己也是通過學(xué)習(xí)前輩們的講解,自己慢慢摸索的,學(xué)習(xí)就是自我填坑的過程,希望我們都能堅持下來,也希望這篇能幫到你,朋友。

經(jīng)過博友的反應(yīng),現(xiàn)已增加測試代碼

  1. # -*- coding:utf-8 -*-
  2. from tensorflow.examples.tutorials.mnist import input_data
  3. import tensorflow as tf
  4. import os
  5. os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
  6. def weight_variable(shape):
  7. # 產(chǎn)生隨機變量
  8. # truncated_normal:選取位于正態(tài)分布均值=0.1附近的隨機值
  9. initial = tf.truncated_normal(shape, stddev=0.1)
  10. return tf.Variable(initial)
  11. def bias_variable(shape):
  12. initial = tf.constant(0.1, shape=shape)
  13. return tf.Variable(initial)
  14. def conv2d(x, W):
  15. # stride = [1,水平移動步長,豎直移動步長,1]
  16. return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
  17. def max_pool_2x2(x):
  18. # stride = [1,水平移動步長,豎直移動步長,1]
  19. return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
  20. #讀取MNIST數(shù)據(jù)集
  21. mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
  22. sess = tf.InteractiveSession()
  23. #預(yù)定義輸入值X、輸出真實值Y placeholder為占位符
  24. x = tf.placeholder(tf.float32, shape=[None, 784])
  25. y_ = tf.placeholder(tf.float32, shape=[None, 10])
  26. keep_prob = tf.placeholder(tf.float32)
  27. x_image = tf.reshape(x, [-1,28,28,1])
  28. #print(x_image.shape) #[n_samples,28,28,1]
  29. #卷積層1網(wǎng)絡(luò)結(jié)構(gòu)定義
  30. #卷積核1:patch=5×5;in size 1;out size 32;激活函數(shù)reLU非線性處理
  31. W_conv1 = weight_variable([5, 5, 1, 32])
  32. b_conv1 = bias_variable([32])
  33. h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) #output size 28*28*32
  34. h_pool1 = max_pool_2x2(h_conv1) #output size 14*14*32#卷積層2網(wǎng)絡(luò)結(jié)構(gòu)定義
  35. #卷積核2:patch=5×5;in size 32;out size 64;激活函數(shù)reLU非線性處理
  36. W_conv2 = weight_variable([5, 5, 32, 64])
  37. b_conv2 = bias_variable([64])
  38. h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) #output size 14*14*64
  39. h_pool2 = max_pool_2x2(h_conv2) #output size 7 *7 *64
  40. # 全連接層1
  41. W_fc1 = weight_variable([7*7*64,1024])
  42. b_fc1 = bias_variable([1024])
  43. h_pool2_flat = tf.reshape(h_pool2, [-1,7*7*64]) #[n_samples,7,7,64]->>[n_samples,7*7*64]
  44. h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
  45. h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) # 減少計算量dropout
  46. # 全連接層2
  47. W_fc2 = weight_variable([1024, 10])
  48. b_fc2 = bias_variable([10])
  49. prediction = tf.matmul(h_fc1_drop, W_fc2) + b_fc2
  50. #結(jié)果存放在一個布爾型列表中
  51. correct_prediction = tf.equal(tf.argmax(prediction,1), tf.argmax(y_,1))
  52. #求準(zhǔn)確率
  53. accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
  54. saver = tf.train.Saver() # defaults to saving all variables
  55. sess.run(tf.global_variables_initializer())
  56. saver.restore(sess, './model.ckpt') # 和之前保存的文件名一致
  57. print("test accuracy %g"% sess.run(accuracy,feed_dict={x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))
  58. print("test accuracy %g"% accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))

測試準(zhǔn)確率高達96.6%

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    亚洲第一区欧美日韩在线| 综合久综合久综合久久| 99久久精品国产日本| 少妇人妻精品一区二区三区| 高清一区二区三区四区五区| 五月天丁香亚洲综合网| 爱在午夜降临前在线观看| 人妻一区二区三区在线| 在线日韩欧美国产自拍| 国产一区二区三区精品免费| 人妻人妻人人妻人人澡| 日韩在线一区中文字幕| 欧美性欧美一区二区三区| 欧美激情床戏一区二区三| 午夜资源在线观看免费高清| 久久国产精品熟女一区二区三区| 深夜日本福利在线观看| 亚洲欧美黑人一区二区 | 日韩高清毛片免费观看| 国产免费一区二区三区不卡| 我要看日本黄色小视频| 我要看日本黄色小视频| 插进她的身体里在线观看骚| 国产精品内射婷婷一级二级| 亚洲综合天堂一二三区| 日韩人妻少妇一区二区| 中文字幕人妻一区二区免费| 亚洲av日韩av高潮无打码| 色综合久久中文综合网| 国产一区二区三区丝袜不卡| 亚洲国产av在线观看一区| 老司机精品国产在线视频| 大香蕉伊人精品在线观看| 欧美日韩综合在线精品| 国产99久久精品果冻传媒| 精品人妻一区二区三区免费| 色婷婷日本视频在线观看| 中文字幕中文字幕一区二区| 狠狠做深爱婷婷久久综合| 中文字幕欧美精品人妻一区| 操白丝女孩在线观看免费高清|