TensorFlow卷積神經網絡構建

卷積構造方法

激活函數

    在神經網絡中,激活函數的作用是能夠給神經網絡加入一些非線性因素,使得神經網絡可以更好地解決較爲複雜的問題
    在神經網絡中,我們有很多的非線性函數來作爲激活函數,比如連續的平滑非線性函數(sigmoid,tanh和softplus),連續但不平滑的非線性函數(relu,relu6和relu_x)和隨機正則化函數(dropout)
    所有的激活函數都是單獨應用在每個元素上面的,並且輸出張量的維度和輸入張量的維度一樣

tf.nn.relu(features, name = None):這個函數的作用是計算激活函數relu,即max(features, 0)

在這裏插入圖片描述

tf.nn.relu6(features, name = None):這個函數的作用是計算激活函數relu6,即min(max(features, 0), 6)

在這裏插入圖片描述

tf.nn.softplus(features, name = None):這個函數的作用是計算激活函數softplus,即log( exp( features ) + 1)

在這裏插入圖片描述

tf.sigmoid(x, name = None):這個函數的作用是計算 x 的 sigmoid 函數。具體計算公式爲 y = 1 / (1 + exp(-x))

在這裏插入圖片描述

tf.tanh(x, name = None):這個函數的作用是計算 x 的 tanh 函數。具體計算公式爲 ( exp(x) - exp(-x) ) / ( exp(x) + exp(-x) )

在這裏插入圖片描述

Dropout 防止過擬合

    當訓練數據量比較小時,可能會出現因爲追求最小差值導致訓練出來的模型極度符合訓練集,但是缺乏普適性,不能表達訓練數據之外的數據
本來有普適性的模型被訓練成了具有訓練集特殊性
在這裏插入圖片描述
以至於對於真實的數據產生了錯誤
在這裏插入圖片描述
解決方案:讓一部分神經網絡不工作 是係數變簡單些
tf.nn.dropout(x, keep_prob, noise_shape = None, seed = None, name = None)
在這裏插入圖片描述

卷積層

    卷積操作是使用一個二維的卷積核在一個批處理的圖片上進行不斷掃描。具體操作是將一個卷積核在每張圖片上按照一個合適的尺寸在每個通道上面進行掃描
    tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)
這個函數的作用是對一個四維的輸入數據 input 和四維的卷積核 filter 進行操作,然後對輸入數據進行一個二維的卷積操作,最後得到卷積之後的結果
    tf.nn.bias_add(value, bias, name = None):這個函數的作用是將偏差項 bias 加到 value 上面

池化層

    池化操作是利用一個矩陣窗口在輸入張量上進行掃描,並且將每個矩陣窗口中的值通過取最大值,平均值或者XXXX來減少元素個數 相當於降維
    Maxpooling 就是在這個區域內選出最能代表邊緣的值,然後丟掉那些沒多大用的信息
    tf.nn.max_pool(value, ksize, strides, padding, name=None):這個函數的作用是計算池化區域中元素的最大值
 

代碼實現

import numpy as np
import tensorflow as tf

# 卷積
input_ = np.random.randn(1,32,32,1)
filter_ = np.random.randn(5,5,1,8) #輸出8
conv1 = tf.nn.conv2d(input_,filter_,[1,1,1,1],'VALID')
conv1
#<tf.Tensor 'Conv2D:0' shape=(1, 28, 28, 8) dtype=float64>

# 激活,數據的值改變,形狀不變
conv1 = tf.nn.relu(conv1)
conv1

# 池化
pool1 = tf.nn.max_pool(conv1,[1,2,2,1],[1,2,2,1],'SAME')
pool1 
#步幅是2 執行完後就變成了14*14 當conv1爲25*25時 SAME就會起作用補一個
#<tf.Tensor 'MaxPool:0' shape=(1, 14, 14, 8) dtype=float64>

# 第二層卷積
filter2_ = np.random.randn(5,5,8,20)
conv2 = tf.nn.conv2d(pool1,filter2_,[1,1,1,1],'VALID')
conv2
#<tf.Tensor 'Conv2D_1:0' shape=(1, 10, 10, 20) dtype=float64>

# 第二層池化
pool2 = tf.nn.max_pool(conv2,[1,2,2,1],[1,2,2,1],'SAME')
pool2
#<tf.Tensor 'MaxPool_1:0' shape=(1, 5, 5, 20) dtype=float64>

# 第三層卷積
filter3_ = tf.random_normal(shape = (5,5,20,120),dtype=tf.float64)
conv3 = tf.nn.conv2d(pool2,filter3_,[1,1,1,1],'VALID')
conv3
#tf.Tensor 'Conv2D_3:0' shape=(1, 1, 1, 120) dtype=float64>

# 全連接層
full = tf.reshape(conv3,shape = (1,120))
W = tf.random_normal(shape = [120,9],dtype=tf.float64)
fc = tf.matmul(full,W)
fc
#<tf.Tensor 'MatMul_1:0' shape=(1, 9) dtype=float64>

nd = np.random.randn(30)
nd
#array([-0.12560285,  0.12933899, -1.3299502 , -0.39066039,  0.450362  ,
#        0.09520731,  1.18649637, -0.0540407 , -1.26440829,  0.01215905,
        #0.6911983 ,  0.09960611, -0.31772857,  1.33419137, -0.44841172,
       #-1.08744641, -0.13443044,  1.09703064, -1.31288774, -0.04314629,
        #2.30861232,  1.25730727,  0.96198465, -0.81695384,  0.79015532,
        #0.70142942, -0.3247638 , -0.0416249 , -0.37326343,  1.11335996])

with tf.Session() as sess:
    ret = sess.run(tf.nn.relu(nd))
    print(ret) #小於0變爲0 大於0不變
#[0.         0.12933899 0.         0.         0.450362   0.09520731
 #1.18649637 0.         0.         0.01215905 0.6911983  0.09960611
 #0.         1.33419137 0.         0.         0.         1.09703064
 #0.         0.         2.30861232 1.25730727 0.96198465 0.
 #0.79015532 0.70142942 0.         0.         0.         1.11335996]

#手寫激活函數
def relu(nd):
    for i,k in enumerate(nd):
        if nd[i] < 0:
            nd[i] = 0
    return nd

relu(nd)
#array([0.        , 0.12933899, 0.        , 0.        , 0.450362  ,
#       0.09520731, 1.18649637, 0.        , 0.        , 0.01215905,
#       0.6911983 , 0.09960611, 0.        , 1.33419137, 0.        ,
#       0.        , 0.        , 1.09703064, 0.        , 0.        ,
#       2.30861232, 1.25730727, 0.96198465, 0.        , 0.79015532,
#       0.70142942, 0.        , 0.        , 0.        , 1.11335996])

卷積神經網絡

import warnings
warnings.filterwarnings('ignore')
import numpy as np
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets('./',one_hot=True)
# 卷積方法
def conv(input_data,filter_,b):
    return tf.nn.conv2d(input_data,filter_,[1,1,1,1],'SAME') + b
# 池化:降維
def pool(input_data):
    return tf.nn.max_pool(input_data,[1,2,2,1],[1,2,2,1],'SAME')
# 變量可以是filter,bias
def gen_v(shape):
    return tf.Variable(initial_value=tf.random_normal(shape = shape,dtype = tf.float64))
第一層卷積
X = tf.placeholder(shape = [None,784],dtype=tf.float64)
y = tf.placeholder(shape = [None,10],dtype=tf.float64)

# 卷積核一般都是小卷積(3,3)、(5,5)
input_data = tf.reshape(X,shape = [-1,28,28,1]) #1維圖片
filter1 = gen_v([3,3,1,32]) #1維輸入圖片 輸出爲32
b1 = gen_v([32])
conv1 = tf.nn.relu(conv(input_data,filter1,b1)) #進行激活
pool1 = pool(conv1)
pool1
<tf.Tensor 'MaxPool_5:0' shape=(?, 14, 14, 32) dtype=float64>
第二層卷積
filter2 = gen_v([3,3,32,64])
b2 = gen_v([64])
conv2 = tf.nn.relu(conv(pool1,filter2,b2))
pool2 = pool(conv2)
pool2
#<tf.Tensor 'MaxPool_6:0' shape=(?, 7, 7, 64) dtype=float64>
第三層卷積
# filter3 = gen_v([3,3,64,64])
# b3 = gen_v([64])
# conv3 = tf.nn.relu(conv(pool2,filter3,b3))
# pool3 = pool(conv3)
# pool3
#<tf.Tensor 'MaxPool_2:0' shape=(?, 4, 4, 64) dtype=float64>
全連接層 1024個神經元
fc = tf.reshape(pool2,shape = [-1,7*7*64])
fc_w = gen_v([7*7*64,1024])
fc_b = gen_v([1024]) #1024個方程
conn = tf.nn.relu(tf.matmul(fc,fc_w) + fc_b)
conn
#<tf.Tensor 'Relu_8:0' shape=(?, 1024) dtype=float64>
dropout防止過擬合
rate = tf.placeholder(dtype=tf.float64)
dp = tf.nn.dropout(conn,rate =rate) #讓一部分不工作 用rate替換
dp
#<tf.Tensor 'dropout_2/mul_1:0' shape=(?, 1024) dtype=float64>
輸出層
out_w = gen_v([1024,10])
out_b = gen_v([10])
out = tf.matmul(dp,out_w) + out_b
out
#<tf.Tensor 'add_45:0' shape=(?, 10) dtype=float64>
y_ = tf.nn.softmax(out) #將其轉化爲概率
y_ = tf.clip_by_value(y_,1e-8,1)
y_
#<tf.Tensor 'clip_by_value_2:0' shape=(?, 10) dtype=float64>
構建損失函數
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits = out))
loss
#<tf.Tensor 'Mean_19:0' shape=() dtype=float64>

# loss = tf.reduce_mean(tf.reduce_sum(tf.multiply(y,tf.log(1/y_)),axis = 1)) #手寫的損失函數
# loss
#<tf.Tensor 'Mean_26:0' shape=() dtype=float64>
優化梯度下降
opt = tf.train.AdamOptimizer(0.001).minimize(loss)
opt #在梯度下降基礎上改進
#<tf.Operation 'Adam_17' type=NoOp>
訓練
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())    
    for i in range(10):
        for j in range(100):
            X_train,y_train = mnist.train.next_batch(550)
            opt_,loss_ = sess.run([opt,loss],feed_dict = {X:X_train,y:y_train,rate:0.5}) #訓練時吧0.5蓋住
            print('裏層循環執行次數:%d。損失是:%0.4f'%(j+1,loss_))
#         計算準確率
        X_validation ,y_validation = mnist.validation.next_batch(2000)
        y_pred = sess.run(y_,feed_dict = {X:X_validation,rate:0})
        accuracy = (np.argmax(y_pred,axis = -1) == np.argmax(y_validation,axis = -1)).mean()
        print('--------------------循環執行%d。準確率是%0.4f-------------------'%(i+1,accuracy))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章