Keras 中經常可以看到
K.image_data_format() == 'channels_first'
深度學習中 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層作用,我把這個神經網絡進行可視化如下圖:
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的上級目錄作爲工程目錄打開