tensorflow—卷積神經網絡(例:手寫數字識別)

傳統的神經網絡中的不足:
在這裏插入圖片描述
上圖中,我們需要計算的權值非常多,就需要大量的樣本訓練,我們模型的構建,需要根據數據的大小來建立,防止過擬合,以及欠擬合。

因此,cnn算法通過感受野和權值共享減少了神經網絡需要訓練的參數個數,如圖:
**加粗樣式**
所以,卷積算法操作如下:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
上述卷積核,步長是1
在這裏插入圖片描述
4=11+11+11+11,依此類推。
上述的卷積核,類似於一個濾波器,例如下圖:
在這裏插入圖片描述
上述圖片經過不同的卷積核得出不同的特徵圖,不同卷積核可以對圖片不同的特徵進行採樣。

在卷積神經網絡中分爲卷積層和池化層
池化中:在這裏插入圖片描述max-pooling即爲取44中最大值組成22的池化結果
mean-pooling即爲分爲幾個區域取其中的平均值
另外還有個隨機池化,即爲在幾個區域中找到幾個隨機數據

卷積操作:在這裏插入圖片描述

same padding:給外部補零,得到一個比原平面大的平面,然後卷積窗口採樣後,得到一個和原來一樣大的平面
valid padding:得到一個比原來平面小的平面,不會超出平面外部

所以:在這裏插入圖片描述
cnn結構如下:在這裏插入圖片描述
例如,一張圖片,操作如下:卷積-池化-卷積-池化-卷積-池化-全連接層-結果。
通過tensorflow-cnn卷積網絡實現手寫數字識別:

import  tensorflow as tf#9.50
from tensorflow.examples.tutorials.mnist import input_data
#載入數據集
mnist=input_data.read_data_sets("MNNIST_data",one_hot=True)#下載網上的數據集
#print(mnist)
#每個批次的大小,每次放入100張圖片放入神經網絡訓練。
batch_size=100
#計算一共有多少批次
n_bach=mnist.train.num_examples//batch_size#//整除
#初始化權值
def weight_variable(shape):
    inital=tf.truncated_normal(shape,stddev=0.1)
    return tf.Variable(inital)
#初始化偏置值
def bias_variable(shape):
    initial=tf.constant(0.1,shape=shape)
    return tf.Variable(initial)
#卷積層
def conv2d(x,W):
    return  tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME')
    #使用了這個庫,tf.nn.conv2d
#池化層
def max_pool_2(x):
    return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
#定義兩個placeholder
x=tf.placeholder(tf.float32,[None,784])#784列
y=tf.placeholder(tf.float32,[None,10])#0-9,10個數字
#改變x的格式轉爲4d向量[batch,in_height,in_width,in_channels]
x_image=tf.reshape(x,[-1,28,28,1])

#初始化第一個卷積層的權值和偏置值
W_conv1=weight_variable([5,5,1,32])#採用5*5的採樣窗口,32個卷積核從1個平面抽取特徵
b_conv1=bias_variable([32])#每個卷積核一個偏置值
#把x_image和權值向量進行卷積,再加上偏置值,然後應用於relu激活函數
h_conv1=tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1)
h_pool1=max_pool_2(h_conv1)#進行max-pooling

#初始化第二個卷積層的權值和偏置值
W_conv2=weight_variable([5,5,32,64])#採用5*5的採樣窗口,32個卷積核從1個平面抽取特徵
b_conv2=bias_variable([64])#每個卷積核一個偏置值
#把x_image和權值向量進行卷積,再加上偏置值,然後應用於relu激活函數
h_conv2=tf.nn.relu(conv2d(h_pool1,W_conv2)+b_conv2)
h_pool2=max_pool_2(h_conv2)#進行max-pooling

#初始化第一個全連接的權值
W_fcl=weight_variable([7*7*64,1024])#上一場有7*7*64個神經元,全連接層有1024個神經元
b_fcl=bias_variable([1024])#1024個節點
#把池化層2的輸出扁平化維一維
h_pool2_flat=tf.reshape(h_pool2,[-1,7*7*64])
#求第一個全連接的輸出
h_fcl=tf.nn.relu(tf.matmul(h_pool2_flat,W_fcl)+b_fcl)
#keep_prob表示神經元的輸出概率
keep_prob=tf.placeholder(tf.float32)
h_fcl_drop=tf.nn.dropout(h_fcl,keep_prob)

#初始化第二個全連接層
W_fc2=weight_variable([1024,10])
b_fc2=bias_variable([10])
#計算輸出
prediction=tf.nn.softmax(tf.matmul(h_fcl_drop,W_fc2)+b_fc2)
#交叉熵代價函數
cross_entropy=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=prediction))
#使用Adamoptimizer進行優化
train_step=tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
#結果存放在一個布爾列表中
correct_prediction=tf.equal(tf.argmax(prediction,1),tf.argmax(y,1))#argmax返回一維張量中最大值所在位置
#求準確率
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
with tf.Session()as sess:
    sess.run(tf.global_variables_initializer())
    #把所有圖片訓練21次
    for epoch in range(21):
        # 執行一次,即爲把訓練集的所有圖片循環一次
        for batch in range(n_bach):
            #獲取100張圖片,圖片數據保存在_xs,標籤保存在ys
            batch_xs,batchys=mnist.train.next_batch(batch_size)
            sess.run(train_step,feed_dict={x:batch_xs,y:batchys,keep_prob:0.7})
        #傳進測試集,數據集的數據
        acc=sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels,keep_prob:1.0})
        print("第"+str(epoch)+"準確率:"+str(acc))







其中,第一次的準確率就可以達到0.9554.在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章