一、前述
Keras 適合快速體驗 ,keras的設計是把大量內部運算都隱藏了,用戶始終可以用theano或tensorflow的語句來寫擴展功能並和keras結合使用。
二、安裝
Pip install --upgrade keras
三、Keras模型之序列模型
序列模型屬於通用模型的一種,因為很常見,所以這里單獨列出來進行介紹,這種模型各層之間是依次順序的線性關系,在第k層和第k+1層之間可以加上各種元素來構造神經網絡
這些元素可以通過一個列表來制定,然后作為參數傳遞給序列模型來生成相應的模型。
第一種方式
from keras.models import Sequential from keras.layers import Dense from keras.layers import Activation # Dense相當於構建一個全連接層,32指的是全連接層上面神經元的個數 layers = [Dense(32, input_shape=(784,)), Activation('relu'), Dense(10), Activation('softmax')] model = Sequential(layers) model.summary()
第二種方式:
from keras.models import Sequential from keras.layers import Dense from keras.layers import Activation model = Sequential() model.add(Dense(32, input_shape=(784,))) model.add(Activation('relu')) model.add(Dense(10)) model.add(Activation('softmax'))
結果:
四、Keras模型之通用模型
通用模型可以用來設計非常復雜、任意拓撲結構的神經網絡,例如有向無環圖網絡類似於序列模型,通用模型通過函數化的應用接口來定義模型使用函數化的應用接口有好多好處,比如:決定函數執行結果的唯一要素是其返回值,而決定返回值的唯一要素則是其參數,這大大減輕了代碼測試的工作量
在通用模型中,定義的時候,從輸入的多維矩陣開始,然后定義各層及其要素,最后定義輸出層將輸入層和輸出層作為參數納入通用模型中就可以定義一個模型對象
代碼:
# 通用模型 # 通用模型可以用來設計非常復雜、任意拓撲結構的神經網絡,例如有向無環圖網絡 # 類似於序列模型,通用模型通過函數化的應用接口來定義模型 # 使用函數化的應用接口有好多好處,比如:決定函數執行結果的唯一要素是其返回值,而決定 # 返回值的唯一要素則是其參數,這大大減輕了代碼測試的工作量 # 在通用模型中,定義的時候,從輸入的多維矩陣開始,然后定義各層及其要素,最后定義輸出層 # 將輸入層和輸出層作為參數納入通用模型中就可以定義一個模型對象 from keras.layers import Input from keras.layers import Dense from keras.models import Model # 定義輸入層 input = Input(shape=(784,)) # 定義各個連接層,假設從輸入層開始,定義兩個隱含層,都有64個神經元,都使用relu激活函數 x = Dense(64, activation='relu')(input)#把上一層輸出結果給下一層的輸入 x = Dense(64, activation='relu')(x) # 定義輸出層,使用最近的隱含層作為參數 y = Dense(10, activation='softmax')(x)#整個邏輯從輸入到輸出全都在y里面了 # 所有要素都齊備以后,就可以定義模型對象了,參數很簡單,分別是輸入和輸出,其中包含了 # 中間的各種信息 model = Model(inputs=input, outputs=y) # 當模型對象定義完成之后,就可以進行編譯(定義損失函數,通過什么方式優化(優化器),等等)了,並對數據進行擬合,擬合的時候也有兩個參數 # 分別對應於輸入和輸出 model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy']) model.fit(data, labels)#data是輸入數據的X labels是Y
五、Keras實現手寫識別體案例
import numpy as np from keras.datasets import mnist from keras.models import Sequential from keras.layers import Dense from keras.layers import Dropout from keras.layers import Flatten from keras.layers.convolutional import Conv2D from keras.layers.convolutional import MaxPooling2D #Conv2D 圖片是3通道 Conv1D 單聲道或者雙聲道 # 先讀入數據 (X_train, y_train), (X_test, y_test) = mnist.load_data("../test_data_home") # 看一下數據集的樣子 print(X_train[0].shape)#X_train是很多張圖片[0]是第一張 print(y_train[0]) # 下面把訓練集中的手寫黑白字體變成標准的四維張量形式,即(樣本數量,長,寬,1) # 1是channel通道 # 並把像素值變成浮點格式 # X_train.shape[0]取得是行的數量 X_train = X_train.reshape(X_train.shape[0], 28, 28, 1).astype('float32') X_test = X_test.reshape(X_test.shape[0], 28, 28, 1).astype('float32') # 由於每個像素值都介於0到255,所以這里統一除以255,把像素值控制在0-1范圍 X_train /= 255 #X_train是一個矩陣 這里相當於里面每個數都除以255 X_test /= 255 # 由於輸入層需要10個節點,所以最好把目標數字0-9做成One Hot編碼的形式 def tran_y(y):#自己定義的One_hot編碼格式 先定義10個零 然后在對應個數上填1 y_ohe = np.zeros(10) y_ohe[y] = 1 return y_ohe # 把標簽用One Hot編碼重新表示一下 y_train_ohe = np.array([tran_y(y_train[i]) for i in range(len(y_train))])#列表生成器 y_test_ohe = np.array([tran_y(y_test[i]) for i in range(len(y_test))]) # 搭建卷積神經網絡 model = Sequential() # 添加一層卷積層,構造64個過濾器(卷積核),每個過濾器(卷積核)覆蓋范圍是3*3*1 # 過濾器步長為1,圖像四周補一圈0,並用relu進行非線性變化 model.add(Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding='same', input_shape=(28, 28, 1), activation='relu'))#activation如果不設置,就是線性的 # 添加一層最大池化層 model.add(MaxPooling2D(pool_size=(2, 2)))#默認Strides是和池化維度一樣 這里是2*2 池化默認一般不做padding # 設立Dropout層,Dropout的概率為0.5 model.add(Dropout(0.5)) # 重復構造,搭建深度網絡 model.add(Conv2D(128, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.5)) model.add(Conv2D(256, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.5)) # 把當前層節點展平 model.add(Flatten()) # 構造全連接層神經網絡層 model.add(Dense(128, activation='relu')) model.add(Dense(64, activation='relu')) model.add(Dense(32, activation='relu')) model.add(Dense(10, activation='softmax')) # 定義損失函數,一般來說分類問題的損失函數都選擇采用交叉熵 # adagrad自適應的調整學習率的隨機梯度下降算法 因為自適應所以會比較耗時間 model.compile(loss='categorical_crossentropy', optimizer='adagrad', metrics=['accuracy']) # 放入批量樣本,進行訓練 model.fit(X_train, y_train_ohe, validation_data=(X_test, y_test_ohe)#驗證集作用邊訓練邊測試 在每一個step中都會驗證 , epochs=20, batch_size=128) #epochs是迭代多少輪次 學完一輪是整個數據集/128 這里面有20輪 # 在測試集上評價模型的准確率 # verbose : 進度表示方式。0表示不顯示數據,1表示顯示進度條 scores = model.evaluate(X_test, y_test_ohe, verbose=0)#evaluate就是評估准確率
延伸結論:
最后一個卷積層到第一個全連接層的參數是最多的
結果: