1、知識點
""" 基礎知識: 1、神經網絡(neural networks)的基本組成包括輸入層、隱藏層、輸出層。而卷積神經網絡的特點在於隱藏層分為卷積層和池化層(pooling layer,又叫下采樣層) 2、卷積層:通過在原始圖像上平移來提取特征,每一個特征就是一個特征映射 a)提取特征:定義一個過濾器(也稱觀察窗口,奇數大小,值為權重)大小,步長 b)移動越過圖片: 1、VALID:不越過,直接停止觀察(一般不用) 2、SAME:直接越過,則對圖像零填充(padding過程) 影響因素:窗口大小,步長,零填充,窗口數目 矩陣大小公式計算: 輸入體積大小:H1*W1*D1 四個超參數:Filter數量K、Filter大小F、步長S、零填充大小P 輸出體積大小 H2*W2*D2 H2=(H1-F+2P)/S+1 #如果有小數,要注意 W2=(W1-F+2P)/S+1 D2=K 卷積API:tf.nn.conv2d(input, filter, strides=, padding=, name=None)計算給定4-D input和filter張量的2維卷積 input:給定的輸入張量,具有[batch,heigth,width,channel],類型為float32,64 ,channel為圖片的通道數,batch為圖片的數量 filter:指定過濾器的大小,[filter_height, filter_width, in_channels, out_channels] ,其中,in_channels=channel ,out_channels為過濾器的數量 strides:strides = [1, stride, stride, 1],步長 padding:“SAME”, “VALID”,使用的填充算法的類型,使用“SAME”。其中”VALID”表示滑動超出部分舍棄,“SAME”表示填充,使得變化后height,width一樣大 3、激活函數(Relu),增加激活函數相當於增加了網絡的非線性分割能力 1、機器學習使用:sigmoid ,公式:f(x) = 1/1+e^(-x) 2、深度學習使用:Relu ,公式為:f(x) = max(0,x) 3、API:tf.nn.relu(features, name=None) features:卷積后加上偏置的結果 return:結果 4、池化層:通過特征后稀疏參數來減少學習的參數,降低網絡的復雜度,(最大池化和平均池化) 1、池化計算矩陣大小公式和卷積一樣 2、API:tf.nn.max_pool(value, ksize=, strides=, padding=,name=None)輸入上執行最大池數 value:4-D Tensor形狀[batch, height, width, channels] ksize:池化窗口大小,[1, ksize, ksize, 1] strides:步長大小,[1,strides,strides,1] padding:“SAME”, “VALID”,使用的填充算法的類型,使用“SAME” 5、dropout:防止過擬合,直接使一些數據失效,小型網絡用不到
6、不采用sigmoid函數作為激活函數的原因?
第一、采用sigmoid等函數,反向傳播求取誤差梯度時,計算量相對大,而采用Relu激活函數,震哥哥過程的計算節省很多
第二、對於深層網絡,sigmoid函數反向傳播時,很容易就會出現梯度消失等情況
7、tf.one_hot(indices,depth)
indices:數據集標簽
depth:類別數
卷積神經網絡實現流程:
1、准備數據
2、建立模型
a)准備數據占位符
b)卷積、激活、池化操作
c)全連接層,建立矩陣表達式
3、計算交叉熵損失
4、梯度下降求出損失
5、計算准確率
6、初始化變量
7、開始訓練
手寫字網絡結構設計:
輸入數據:[None,784] [None.10]
一卷積層:
卷積:32個filer,5*5 ,strides=1,padding="SAME" ,輸入:[None,28,28,1] 輸出:[None,28,28,32]
激活:輸出 [None,28,28,32]
池化:2*2,strides=2,padding="SAME" 輸出 [None,14,14,32]
二卷積層:
卷積:64個filer,5*5 ,strides=1,padding="SAME" ,輸入:[None,14,14,32] 輸出:[None,14,14,64]
激活:輸出 [None,14,14,64]
池化: 2*2,strides=2 ,輸出:[None,7,7,64]
全連接層:
形狀改變:[None,7,7,64] -->[None,7*7*64]
權重:[7*7*10]
偏置:[10]
輸出:[None,10]
輸出:[3,5,7] -->softmax轉為概率[0.04,0.16,0.8] ---> 交叉熵計算損失值 (目標值和預測值的對數)
"""
2、代碼
# coding = utf-8 import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data #定義一個初始化權重的函數 def weight_variables(shape): w = tf.Variable(tf.random_normal(shape=shape,mean=0.0,stddev=1.0)) return w #定義一個初始化偏置的函數 def bais_variables(shape): b = tf.Variable(tf.constant(0.0,shape=shape)) return b def model(): """ 自定義卷積模型 :return: """ #1、准備數據的占位符 x[None,784] y_true[None,10] with tf.variable_scope("data"): x = tf.placeholder(tf.float32,[None,784]) y_true = tf.placeholder(tf.int32,[None,10]) #2、一卷積層 卷積: 5*5*1,32個,strides=1 激活: tf.nn.relu 池化 with tf.variable_scope("conv1"): #隨機初始化權重,[5,5,1,32]--->5,5為過濾器大小,1為輸入的圖像通道數,32為過濾器的數量 w_conv1 = weight_variables([5,5,1,32]) b_conv1 =bais_variables([32]) #對x進行形狀的改變[None,784] --->[None,28,28,1] # 改變形狀,不知道的參數填寫-1 x_reshape= tf.reshape(x,[-1,28,28,1]) #strides=[1,1,1,1],表示上下左右移動步長都為1 [None, 28, 28, 1]-----> [None, 28, 28, 32] x_relu1 = tf.nn.relu(tf.nn.conv2d(x_reshape,w_conv1,strides=[1,1,1,1],padding="SAME")+b_conv1) #池化 2*2 ,strides2 [None, 28, 28, 32]---->[None, 14, 14, 32] x_pool1 = tf.nn.max_pool(x_relu1,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME") #3、二卷積層 with tf.variable_scope("conv2"): # 隨機初始化權重, 權重:[5, 5, 32, 64] 偏置[64] w_conv2 = weight_variables([5, 5, 32, 64]) b_conv2 = bais_variables([64]) # 卷積,激活,池化計算 # [None, 14, 14, 32]-----> [None, 14, 14, 64] x_relu2 = tf.nn.relu(tf.nn.conv2d(x_pool1,w_conv2,strides=[1,1,1,1],padding="SAME")+b_conv2) # 池化 2*2, strides 2, [None, 14, 14, 64]---->[None, 7, 7, 64] x_pool2 =tf.nn.max_pool(x_relu2,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME") #4、全連接層 [None, 7, 7, 64]--->[None, 7*7*64]*[7*7*64, 10]+ [10] =[None, 10] with tf.variable_scope("conv2"): # 隨機初始化權重, w_fc = weight_variables([7*7*64, 10]) b_fc = bais_variables([10]) #修改形狀[None, 7, 7, 64] --->None, 7*7*64] x_fc_reshape = tf.reshape(x_pool2,[-1,7*7*64]) #進行矩陣運算,得出每個樣本的10個結果 y_predict = tf.matmul(x_fc_reshape,w_fc)+b_fc ######收集和合並變量#### tf.summary.histogram("w1",w_conv1) tf.summary.histogram("b1",b_conv1) tf.summary.histogram("w2",w_conv2) tf.summary.histogram("b2",b_conv2) tf.summary.histogram("wfc",w_conv1) tf.summary.histogram("bfc",b_conv1) merged =tf.summary.merge_all() return x,y_true,y_predict,merged def conv_fc(): # 獲取數據 minist = input_data.read_data_sets("./data/mnist/input_data/", one_hot=True) x,y_true,y_predict,merged = model() # 3、計算交叉熵損失 with tf.variable_scope("cross_entropy"): # 求取平均交叉熵損失 loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_predict)) # 4、梯度下降求出損失 with tf.variable_scope("optimizer"): train_op = tf.train.GradientDescentOptimizer(0.0001).minimize(loss) # 5、計算准確率 with tf.variable_scope("accuracy"): equal_list = tf.equal(tf.argmax(y_true, 1), tf.argmax(y_predict, 1)) # equal_list None個樣本 [1,0,1,1,0,0,0......] accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32)) # 7、初始化變量 init_op = tf.global_variables_initializer() ##########收集變量############# tf.summary.scalar("losses",loss) tf.summary.scalar("accuracy",accuracy) merged1 = tf.summary.merge_all() with tf.Session() as sess: sess.run(init_op) fileWriter = tf.summary.FileWriter("./event/",graph=sess.graph) for i in range(1000): # 取出數據的特征自和目標值 mnist_x, mnist_y = minist.train.next_batch(50) # 訓練 sess.run(train_op, feed_dict={x: mnist_x, y_true: mnist_y}) summary = sess.run(merged,feed_dict={x: mnist_x, y_true:mnist_y}) summary1 = sess.run(merged1, feed_dict={x: mnist_x, y_true: mnist_y}) fileWriter.add_summary(summary,i) fileWriter.add_summary(summary1, i) print("訓練第%d步,准確率為:%f" % (i, sess.run(accuracy, feed_dict={x: mnist_x, y_true: mnist_y}))) return None if __name__ == "__main__": conv_fc()
3、發展歷程
4、卷積與池化輸出矩陣維度計算公式
5、損失計算-交叉熵損失公式
6、SoftMax回歸計算公式
7、激活函數-Relu