1.神經網絡的基本組成部分
2.tensorflow實作神經網絡的架構搭建
3.兩個經典的神經網絡執行個體
正文:
1.神經網絡的基本組成部分
一個典型的卷積神經網絡一般由全連接配接層、卷積層和池化層組成。
- 全連接配接層是層與層之間所有神經元節點都兩兩互相連接配接,是以重要的參數隻有兩個,輸入節點個數和輸出節點個數。
- 卷積層的層與層之間的神經元節點是采用部分連接配接的方式,采用塊狀的連接配接方式(這個塊狀叫過濾器),其需要定義的參數有
- 輸入以及輸入的深度
- 過濾器尺寸
- 輸出深度(過濾器深度)
- 過濾的移動步長
- 池化層的連接配接方式與卷積層的連接配接方式一樣,由于池化層不改變輸入的深度(輸出和輸入的深度是一樣的),是以需要指定的參數是過濾器尺寸和過濾器移動步長。另外根據計算方式的不同,常用的池化層有最大池化和平均池化兩種。
2.tensorflow實作神經網絡的架構搭建
tensorflow對神經網絡的實作有很好的函數支援,下面是實作上面的三種網絡層結構的代碼。
import tensorflow as tf
def fc(input_, input_deep, out_deep, name): #全連接配接層
"""參數->輸入、輸入深度、輸出深度、該層的變量名"""
with tf.compat.v1.variable_scope(name):
weight = tf.Variable( #權重
tf.random.truncated_normal([input_deep, out_deep], stddev=0.05),
name="weights")
bias = tf.Variable( #偏置
tf.constant(0.1, dtype=tf.float32, shape=[out_deep]),
name="bias")
net = tf.nn.relu(tf.add(tf.matmul(input_, weight), bias)) #乘加 激活
return net
def conv(input_, input_deep, output_deep, ksize, stride, name):#卷積層
"""參數->輸入、輸入深度、輸出深度、過濾器尺寸、過濾器移動步長、該層的變量名"""
with tf.compat.v1.variable_scope(name):
conv_weights = tf.compat.v1.get_variable( #權重
'weight', [ksize, ksize, input_deep, output_deep],
initializer = tf.truncated_normal_initializer(stddev=0.1))
conv_biases = tf.compat.v1.get_variable( #偏置
'biases', [output_deep], initializer = tf.constant_initializer(0.0))
conv = tf.nn.conv2d( #卷積
input_, conv_weights, strides=[1,stride,stride,1], padding='SAME')
relu = tf.nn.relu(tf.nn.bias_add(conv, conv_biases)) #激活
return relu
def maxpool(input_, ksize, stride, name): #最大池化層
"""參數->輸入、過濾器尺寸、過濾器移動步長、該層的變量名"""
with tf.name_scope(name):
pool = tf.nn.max_pool2d(input_, ksize=[1,ksize,ksize,1], strides=[1,stride,stride,1],
padding='VALID') #最大池化
return pool
在卷積和池化時還需要指定填充方式(padding),填充是利用0填充輸入矩陣,進而使得輸出矩陣的大小不變。padding參數的表示如下。
padding = ‘VALID’ #不使用零填充
padding = ‘SAME’ #使用零填充
填充的方式不同,計算輸出矩陣的尺寸也不同。下面是兩種方式的計算方法,其中 ⌈ ⌉ \lceil\rceil ⌈⌉ 表示向上取整。
padding = ‘VALID’ :
輸 出 的 高 = ⌈ 輸 入 的 高 − 過 濾 器 的 高 + 1 過 濾 器 移 動 步 長 ⌉ 輸出的高 = \lceil \frac{輸入的高-過濾器的高+1}{過濾器移動步長}\rceil 輸出的高=⌈過濾器移動步長輸入的高−過濾器的高+1⌉
輸 出 的 寬 = ⌈ 輸 入 的 寬 − 過 濾 器 的 寬 + 1 過 濾 器 移 動 步 長 ⌉ 輸出的寬 = \lceil \frac{輸入的寬-過濾器的寬+1}{過濾器移動步長}\rceil 輸出的寬=⌈過濾器移動步長輸入的寬−過濾器的寬+1⌉
輸 出 的 深 度 = 過 濾 器 深 度 輸出的深度 = 過濾器深度 輸出的深度=過濾器深度
padding = ‘SAME’:
輸 出 的 高 = ⌈ 輸 入 的 高 過 濾 器 移 動 步 長 ⌉ 輸出的高 = \lceil \frac{輸入的高}{過濾器移動步長}\rceil 輸出的高=⌈過濾器移動步長輸入的高⌉
輸 出 的 寬 = ⌈ 輸 入 的 寬 過 濾 器 移 動 步 長 ⌉ 輸出的寬 = \lceil \frac{輸入的寬}{過濾器移動步長}\rceil 輸出的寬=⌈過濾器移動步長輸入的寬⌉
輸 出 的 深 度 = 過 濾 器 深 度 輸出的深度 = 過濾器深度 輸出的深度=過濾器深度
3.兩個經典的神經網絡執行個體
-
Alexnet神經網絡
下圖為Alexnet的神經網絡結構圖。
(圖檔來源于百度百科) 下面是代碼實作:def alexnet(input_): """alexnet網絡結構""" conv1 = conv(input_, 3, 96, 11, 4,'layer1_conv1') #3為輸入到神經網絡的次元 lrn1 = tf.nn.lrn(conv1,4,bias=1,alpha=1e-3/9,beta=0.75,name="layer2_lrn1") #局部響應歸一化 pool1 = maxpool(lrn1, 3, 2,'layer3_pool1') conv2 = conv(pool1, 96, 256, 5, 1,'layer4_conv2') lrn2 = tf.nn.lrn(conv2,4,bias=1,alpha=1e-3/9,beta=0.75,name="layer5_lrn2") pool2 = maxpool(lrn2, 3, 2,'layer6_pool2') conv3 = conv(pool2, 256, 384, 3, 1,'layer7_conv3') conv4 = conv(conv3, 384, 384, 3, 1,'layer8_conv4') conv5 = conv(conv4, 384, 256, 3, 1,'layer9_conv5') pool3 = maxpool(conv5, 3, 2,'layer10_pool3') pool_shape = pool3.get_shape().as_list() #計算向量長度 長x寬x高(第二、三、四次元,第一維為batch個數) nodes = pool_shape[1] * pool_shape[2] * pool_shape[3] #通過函數變成向量 reshaped = tf.reshape(pool3, [pool_shape[0], nodes]) fc1 = fc(reshaped, nodes, 4096, 'layer11_fc1') fc2 = fc(fc1, 4096, 4096, 'layer12_fc2') fc3 = fc(fc2, 4096, 2, 'layer13_fc3' ) return fc3
神經網絡的輸出的次元應該等于分類的個數,在人臉檢測中,神經網絡用于判定輸入的圖檔是否為人臉,是一個二分類任務,是以在最後一層的輸出次元中應該是2。
2.vgg神經網絡
下表為vgg的神經網絡結構圖,以表格C列的vgg-16為例搭建神經網絡,其中卷積層的過濾器移動步長為1,池化層過濾器的移動步長為2。
(圖檔來源于百度百科)
vgg16代碼實作:
def vgg_16(input_):
"""vgg16網絡結構"""
conv1 = conv(input_, 3, 64, 3, 1,'layer1_conv1')
#3為輸入到神經網絡的次元
conv2 = conv(conv1, 64, 64, 3, 1,'layer2_conv2')
pool1 = maxpool(conv2, 3, 2,'layer3_pool1')
conv3 = conv(pool1, 64, 128, 3, 1,'layer4_conv3')
conv4 = conv(conv3, 128, 128, 3, 1,'layer5_conv4')
pool2 = maxpool(conv4, 3, 2,'layer6_pool2')
conv5 = conv(pool2, 128, 256, 3, 1,'layer7_conv5')
conv6 = conv(conv5, 256, 256, 3, 1,'layer8_conv6')
conv7 = conv(conv6, 256, 256, 1, 1,'layer9_conv7')
pool3 = maxpool(conv7, 3, 2,'layer10_pool3')
conv8 = conv(pool3, 256, 512, 3, 1,'layer11_conv8')
conv9 = conv(conv8, 512, 512, 3, 1,'layer12_conv9')
conv10 = conv(conv9, 512, 512, 1, 1,'layer13_conv10')
pool4 = maxpool(conv10, 3, 2,'layer14_pool4')
conv11 = conv(pool4, 512, 512, 3, 1,'layer15_conv11')
conv12 = conv(conv11, 512, 512, 3, 1,'layer16_conv12')
conv13 = conv(conv12, 512, 512, 1, 1,'layer17_conv13')
pool5 = maxpool(conv13, 3, 2,'layer18_pool5')
pool_shape = pool5.get_shape().as_list()
#計算向量長度 長x寬x高(第二、三、四次元,第一維為batch個數)
nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]
#通過函數變成向量
reshaped = tf.reshape(pool5, [pool_shape[0], nodes])
fc1 = fc(reshaped, nodes, 4096, 'layer19_fc1')
fc2 = fc(fc1, 4096, 4096, 'layer20_fc2')
fc3 = fc(fc2, 4096, 2, 'layer21_fc3' )
soft = tf.nn.softmax(fc3)
return soft
搭建完成網絡之後,可以利用圖檔進行測試,輸入一張圖檔,檢視通過神經網絡後的輸出次元。下面是測試vgg16神經網絡的代碼以及結果展示。
import tensorflow as tf
import cv2
import numpy as np
path = r"C:\Users\user\Desktop\lena.jpg"
tf.compat.v1.reset_default_graph() #先清空計算圖
image = cv2.imread(path, 1)
image_data = tf.image.convert_image_dtype(image,dtype=tf.float32)
with tf.compat.v1.Session() as sess:
image = sess.run(image_data)
image = cv2.resize(image,(224,224))
reshape_xs=np.reshape(image,(1,224,224,3))
y = vgg_16(reshape_xs)
print(y)
#輸出結果為
#Tensor("Softmax:0", shape=(1, 2), dtype=float32)
結語:
如果對你有幫助,就給我一個贊吧,如何有問題,可以在評論區進行讨論。
上一篇:[基于tensorflow的人臉檢測] 基于神經網絡的人臉檢測4——資料集的标簽生成
下一篇:[基于tensorflow的人臉檢測] 基于神經網絡的人臉檢6——資料的存儲與加載