從零開始深度學習0521——keras基本知識+GAP理解

Keras 中經常可以看到

K.image_data_format() == 'channels_first' 

https://img-blog.csdnimg.cn/20181121112301750.png

 

 

 

 

深度學習中 Flatten層 的作用 <  GAP

 

Flatten層的實現在Keras.layers.core.Flatten()類中。

作用:

Flatten層用來將輸入“壓平”,即把多維的輸入一維化,常用在從卷積層到全連接層的過渡。Flatten不影響batch的大小。

 

from keras.models import Sequential

from keras.layers.core import Flatten

from keras.layers.convolutional import Convolution2D

from keras.utils.vis_utils import plot_model

 

model = Sequential()

model.add(Convolution2D(64,3,3,border_mode="same",input_shape=(3,32,32)))

model.add(Flatten())

plot_model(model, to_file='Flatten.png', show_shapes=True)

 

爲了更好的理解Flatten層作用,我把這個神經網絡進行可視化如下圖:

https://img-blog.csdn.net/2018062910431435?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3Byb2dyYW1fZGV2ZWxvcGVy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70

 

 flatten層用來扁平參數用,一般用在卷積層與全鏈接層之間,可以從vgg16網絡中可以看出,但是在後來的網絡中用GlobalAveragePooling2D代替了flatten層,可以從vgg16與inceptionV3網絡對比看出。從參數的對比可以看出,顯然這種改進大大的減少了參數的使用量,避免了過擬合現象。

 

 

GlobalAveragePooling2D 層 全局池化層 還可以不在乎輸入圖像的大小

 

一般在全連接後會有激活函數來做分類,假設這個激活函數是一個多分類softmax,那麼全連接網絡的作用就是將最後一層卷積得到的feature map stretch成向量,對這個向量做乘法,最終降低其維度,然後輸入到softmax層中得到對應的每個類別的得分。全連接層如此的重要,以至於全連接層過多的參數重要到會造成過擬合

 

在最後一個卷積層後,加上GAP 不管前面輸出是多少  通過GAP後都變成了1*1*chinnal

所以就可以不在乎原始圖像輸入是多少,然後繼續接下往下做

 

去掉fc層 換成GAP 我們叫全卷積神經網絡  fully convlation network

 

在卷積層之後,用GAP替代FC全連接層。有兩個有點:一是GAP在特徵圖與最終的分類間轉換更加簡單自然;二是不像FC層需要大量訓練調優的參數,降低了空間參數會使模型更加健壯,抗過擬合效果更佳。

 

假設卷積層的最後輸出是h × w × d 的三維特徵圖,具體大小爲6 × 6 × 3,經過GAP轉換後,變成了大小爲 1 × 1 × 3 的輸出值,也就是每一層 h × w 會被平均化成一個值。

 

GAP的使用一般在卷積層之後,輸出層之前:

 

GAP GMP Flatten 對比

https://www.cnblogs.com/hutao722/p/10008581.html

 

對GAP的解釋

https://www.jianshu.com/p/510072fc9c62

結論:

從本實驗看出,在數據集有限的情況下,採用經典模型進行遷移學習時,GMP表現不太穩定,FC層由於訓練參數過多,更易導致過擬合現象的發生,而GAP則表現穩定,優於FC層。當然具體情況具體分析,我們拿到數據集後,可以在幾種方式中多訓練測試,以尋求最優解決方案。

 

 

 

Tensorflow 寫法

 

# detach original VGG fc layers and
# reconstruct your own fc layers serve for your own purpose

self.flatten = tf.reshape(pool5, [-1, 7*7*512])
self.fc6 = tf.layers.dense(self.flatten, 256, tf.nn.relu, name='fc6'#tf.layers.dense 可以一步建立最普通的隱藏層
self.out = tf.layers.dense(self.fc6, 1, name='out')

 

 

 

 

 

Dense層 == Fc

Dense即全連接層,邏輯上等價於這樣一個函數:

權重W爲m*n的矩陣.

輸入x爲n維向量.

激活函數Activation.

偏置bias.

輸出向量out爲m維向量.

out=Activation(Wx+bias).

即一個線性變化加一個非線性變化產生輸出.

 

 

爲什麼卷積層池化層玩需要將向量進行壓縮,扁平

把分佈式特徵 representation 映射到樣本標記空間

就是它把特徵representation整合到一起,輸出爲一個值。

這樣做,有一個什麼好處?

就是大大減少特徵位置對分類帶來的影響。

 

舉個簡單的例子

 

從上圖我們可以看出,貓在不同的位置,輸出的 feature 值相同,但是位置不同。對於電腦來說,特徵值相同,但是特徵值位置不同,那分類結果也可能不一樣,而這時全連接層 filter 的作用就相當於

喵在哪我不管    我只要喵

於是我讓filter去把這個喵找到,實際就是把 feature map 整合成一個值:這個值大,哦,有喵;這個值小,那就可能沒喵,和這個喵在哪關係不大了有沒有,魯棒性有大大增強了

因爲空間結構特性被忽略了,所以全連接層不適合用於在方位上找 Pattern 的任務,比如 segmentation。

 

 

一些CNN網絡最後爲什麼要有2個全連接層

 

寫的太好了,生動,容易理解

https://blog.csdn.net/weixin_40903337/article/details/100074878

泰勒公式都知道吧,意思就是用多項式函數去擬合光滑函數。我們這裏的全連接層中一層的一個神經元就可以看成一個多項式,我們用許多神經元去擬合數據分佈,但是隻用一層 fully-connected layer 有時候沒法解決非線性問題,而如果有兩層或以上 fully-connected layer 就可以很好地解決非線性問題了。

 

我們都知道,全連接層之前的作用是提取特徵,全連接層的作用是分類

 

 

 

random.seed()

seed()方法改變隨機數生成器的種子

 

seed()沒有參數時,每次生成的隨機數是不一樣的,而當seed()有參數時,每次生成的隨機數是一樣的,同時選擇不同的參數生成的隨機數也不一樣

 

做圖片分類任務時使用img_to_array

 

image = cv2.imread(imagePath)

image = cv2.resize(image, (norm_size, norm_size))

image = img_to_array(image)

data.append(image)

 

img_to_array是keras下的一個方法,主要作用就是把numpy矩陣中的整數轉換成浮點數。

訓練和預測時Keras對圖片讀取處理方式不同,加入img_to_array會降低差距

網絡性能影響挺大的,使用了以後val_acc與val_loss更加接近訓練acc與loss

 

 

 

 

to_categorical()

 

# convert the labels from integers to vectors

labels = to_categorical(labels, num_classes=CLASS_NUM) 

 

to_categorical就是將類別向量轉換爲二進制(只有0和1)的矩陣類型表示。其表現爲將原有的類別向量轉換爲獨熱編碼的形式

 

to_categorical最爲keras中提供的一個工具方法,從以上代碼運行可以看出,將原來類別向量中的每個值都轉換爲矩陣裏的一個行向量,從左到右依次是0,1,2,...8個類別。2表示爲[0. 0. 1. 0. 0. 0. 0. 0. 0.],只有第3個爲1,作爲有效位,其餘全部爲0。

 

 

 

爲什麼要用one-hot編碼

將離散型特徵使用one-hot編碼,確實會讓特徵之間的距離計算更加合理

one-hot編碼,是爲了更合理地計算歐式距離

 

比如,有一個離散型特徵,代表工作類型,該離散型特徵,共有三個取值,不使用one-hot編碼,其表示分別是x_1 = (1), x_2 = (2), x_3 = (3)。兩個工作之間的距離是,(x_1, x_2) = 1, d(x_2, x_3) = 1, d(x_1, x_3) = 2。那麼x_1和x_3工作之間就越不相似嗎?顯然這樣的表示,計算出來的特徵的距離是不合理。那如果使用one-hot編碼,則得到x_1 = (1, 0, 0), x_2 = (0, 1, 0), x_3 = (0, 0, 1),那麼兩個工作之間的距離就都是sqrt(2).即每兩個工作之間的距離是一樣的,顯得更合理

 

使用onehot的直接原因是現在多分類cnn網絡的輸出通常是softmax層,而它的輸出是一個概率分佈,從而要求輸入的標籤也以概率分佈的形式出現,進而算交叉熵之類。

 

對於離散型特徵,基於樹的方法是不需要使用one-hot編碼的,例如隨機森林等。基於距離的模型,都是要使用one-hot編碼,例如神經網絡等。

 

 

在keras中model.fit_generator()和model.fit()有什麼區別

 

https://blog.csdn.net/Hodors/article/details/97500808

首先Keras中的fit()函數傳入的x_train和y_train是被完整的加載進內存的,當然用起來很方便,但是如果我們數據量很大,那麼是不可能將所有數據載入內存的,必將導致內存泄漏,這時候我們可以用fit_generator函數來進行訓練。

 

 

 

詳細理解全連接層

 

  

這一步卷積一個非常重要的作用

就是把分佈式特徵representation映射到樣本標記空間

就是它把特徵representation整合到一起,輸出爲一個值

這樣做,有一個什麼好處?

就是大大減少特徵位置對分類帶來的影響

 

爲什麼全連接層可以實現分類

https://www.cnblogs.com/inception6-lxc/p/9939691.html

 

 

 

運行python3程序 出現如下錯誤

ModuleNotFoundError: No module named '__main__.model'; '__main__' is not a p

 

不知道原因

直接使用相對路徑會出現問題

解決辦法是不使用當前路徑的  .

from automationtest_frame.output.logger import Logger

同時

1、把automationtest_frame 的上級路徑放到系統path裏

2、把autimation_frame的上級目錄作爲工程目錄打開

 

 

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