keras创建模型
關于Keras模型
Keras有兩種類型的模型,序貫模型(Sequential)和函數式模型(Model),函數式模型應用更為廣泛,序貫模型是函數式模型的一種特殊情況。
Sequential models:這種方法用于實現一些簡單的模型。你只需要向一些存在的模型中添加層就行了。
Functional API:Keras的API是非常強大的,你可以利用這些API來構造更加復雜的模型,比如多輸出模型,有向無環圖等等。
兩類模型有一些方法是相同的:
model.summary():打印出模型概況model.get_config():返回包含模型配置信息的Python字典。模型也可以從它的config信息中重構回去 config = model.get_config() model = Model.from_config(config) # or, for Sequential: model = Sequential.from_config(config) model.get_layer():依據層名或下標獲得層對象model.get_weights():返回模型權重張量的列表,類型為numpy arraymodel.set_weights():從numpy array里將權重載入給模型,要求數組具有與model.get_weights()相同的形狀。model.to_json:返回代表模型的JSON字符串,僅包含網絡結構,不包含權值。可以從JSON字符串中重構原模型: from models import model_from_json json_string = model.to_json() model = model_from_json(json_string) model.to_yaml:與model.to_json類似,同樣可以從產生的YAML字符串中重構模型 from models import model_from_yaml yaml_string = model.to_yaml() model = model_from_yaml(yaml_string) model.save_weights(filepath):將模型權重保存到指定路徑,文件類型是HDF5(后綴是.h5)model.load_weights(filepath, by_name=False):從HDF5文件中加載權重到當前模型中, 默認情況下模型的結構將保持不變。如果想將權重載入不同的模型(有些層相同)中,則設置by_name=True,只有名字匹配的層才會載入權重快速開始序貫(Sequential)模型
序貫模型是多個網絡層的線性堆疊,也就是“一條路走到黑”。
可以通過向Sequential模型傳遞一個layer的list來構造該模型。
也可以通過.add()方法一個個的將layer加入模型中
model = Sequential() model.add(Dense(32, input_shape=(784,)))#layers.Dense 意思是這個神經層是全連接層 model.add(Activation('relu'))指定輸入數據的shape
模型需要知道輸入數據的shape,因此,Sequential的第一層需要接受一個關于輸入數據shape的參數,后面的各個層則可以自動的推導出中間數據的shape,因此不需要為每個層都指定這個參數。有幾種方法來為第一層指定輸入數據的shape。
傳遞一個input_shape的關鍵字參數給第一層,input_shape是一個tuple類型的數據,其中也可以填入None,如果填入None則表示此位置可能是任何正整數。數據的batch大小不應包含在其中。有些2D層,如Dense,支持通過指定其輸入維度input_dim來隱含的指定輸入數據shape。一些3D的時域層支持通過參數input_dim和input_length來指定輸入shape。如果你需要為輸入指定一個固定大小的batch_size(常用于stateful RNN網絡),可以傳遞batch_size參數到一個層中,例如你想指定輸入張量的batch大小是32,數據shape是(6,8),則你需要傳遞batch_size=32和input_shape=(6,8) model = Sequential() model.add(Dense(32, input_dim=784))model = Sequential() model.add(Dense(32, input_shape=784))編譯
在訓練模型之前,我們需要通過compile來對學習過程進行配置。compile接收三個參數
優化器optimizer:該參數可指定為已預定義的優化器名,如rmsprop、adagrad,或一個Optimizer類的對象,詳情見optimizers損失函數loss:該參數為模型試圖最小化的目標函數,它可為預定義的損失函數名,如categorical_crossentropy、mse,也可以為一個損失函數。詳情見losses指標列表metrics:對分類問題,我們一般將該列表設置為metrics=['accuracy']。指標可以是一個預定義指標的名字,也可以是一個用戶定制的函數.指標函數應該返回單個張量,或一個完成metric_name - > metric_value映射的字典.請參考性能評估 # For a multi-class classification problem model.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['accuracy'])# For a binary classification problem model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['accuracy'])# For a mean squared error regression problem model.compile(optimizer='rmsprop',loss='mse')# For custom metrics import keras.backend as Kdef mean_pred(y_true, y_pred):return K.mean(y_pred)model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['accuracy', mean_pred]) compile(self, optimizer, loss, metrics=None, sample_weight_mode=None) optimizer:字符串(預定義優化器名)或優化器對象,參考優化器 loss:字符串(預定義損失函數名)或目標函數,參考損失函數 metrics:列表,包含評估模型在訓練和測試時的網絡性能的指標,典型用法是metrics=['accuracy'] sample_weight_mode:如果你需要按時間步為樣本賦權(2D權矩陣),將該值設為“temporal”。默認為“None”,代表按樣本賦權(1D權)。在下面fit函數的解釋中有相關的參考內容。 kwargs:使用TensorFlow作為后端請忽略該參數,若使用Theano作為后端,kwargs的值將會傳遞給 K.function model = Sequential() model.add(Dense(32, input_shape=(500,))) model.add(Dense(10, activation='softmax')) model.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['accuracy'])訓練
Keras以Numpy數組作為輸入數據和標簽的數據類型。訓練模型一般使用fit函數,該函數的詳情見這里。下面是一些例子。
# For a single-input model with 2 classes (binary classification):model = Sequential() model.add(Dense(32, activation='relu', input_dim=100)) model.add(Dense(1, activation='sigmoid')) model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['accuracy'])# Generate dummy data import numpy as np data = np.random.random((1000, 100)) labels = np.random.randint(2, size=(1000, 1))# Train the model, iterating on the data in batches of 32 samples model.fit(data, labels, epochs=10, batch_size=32) # For a single-input model with 10 classes (categorical classification):model = Sequential() model.add(Dense(32, activation='relu', input_dim=100)) model.add(Dense(10, activation='softmax')) model.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['accuracy'])# Generate dummy data import numpy as np data = np.random.random((1000, 100)) labels = np.random.randint(10, size=(1000, 1))# Convert labels to categorical one-hot encoding one_hot_labels = keras.utils.to_categorical(labels, num_classes=10)# Train the model, iterating on the data in batches of 32 samples model.fit(data, one_hot_labels, epochs=10, batch_size=32)fit
fit(self, x, y, batch_size=32, epochs=10, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0)本函數將模型訓練nb_epoch輪,其參數有:
x:輸入數據。如果模型只有一個輸入,那么x的類型是numpy array,如果模型有多個輸入,那么x的類型應當為list,list的元素是對應于各個輸入的numpy arrayy:標簽,numpy arraybatch_size:整數,指定進行梯度下降時每個batch包含的樣本數。訓練時一個batch的樣本會被計算一次梯度下降,使目標函數優化一步。epochs:整數,訓練的輪數,每個epoch會把訓練集輪一遍。verbose:日志顯示,0為不在標準輸出流輸出日志信息,1為輸出進度條記錄,2為每個epoch輸出一行記錄callbacks:list,其中的元素是keras.callbacks.Callback的對象。這個list中的回調函數將會在訓練過程中的適當時機被調用,參考回調函數validation_split:0~1之間的浮點數,用來指定訓練集的一定比例數據作為驗證集。驗證集將不參與訓練,并在每個epoch結束后測試的模型的指標,如損失函數、精確度等。注意,validation_split的劃分在shuffle之前,因此如果你的數據本身是有序的,需要先手工打亂再指定validation_split,否則可能會出現驗證集樣本不均勻。validation_data:形式為(X,y)的tuple,是指定的驗證集。此參數將覆蓋validation_spilt。shuffle:布爾值或字符串,一般為布爾值,表示是否在訓練過程中隨機打亂輸入樣本的順序。若為字符串“batch”,則是用來處理HDF5數據的特殊情況,它將在batch內部將數據打亂。class_weight:字典,將不同的類別映射為不同的權值,該參數用來在訓練過程中調整損失函數(只能用于訓練)sample_weight:權值的numpy array,用于在訓練時調整損失函數(僅用于訓練)。可以傳遞一個1D的與樣本等長的向量用于對樣本進行1對1的加權,或者在面對時序數據時,傳遞一個的形式為(samples,sequence_length)的矩陣來為每個時間步上的樣本賦不同的權。這種情況下請確定在編譯模型時添加了sample_weight_mode='temporal'。initial_epoch: 從該參數指定的epoch開始訓練,在繼續之前的訓練時有用。fit函數返回一個History的對象,其History.history屬性記錄了損失函數和其他指標的數值隨epoch變化的情況,如果有驗證集的話,也包含了驗證集的這些指標變化情況
evaluate
evaluate(self, x, y, batch_size=32, verbose=1, sample_weight=None)本函數按batch計算在某些輸入數據上模型的誤差,其參數有:
x:輸入數據,與fit一樣,是numpy array或numpy array的list y:標簽,numpy array batch_size:整數,含義同fit的同名參數 verbose:含義同fit的同名參數,但只能取0或1 sample_weight:numpy array,含義同fit的同名參數predict
predict(self, x, batch_size=32, verbose=0)Keras Sequential models
導入和構建序列模型。
from keras.models import Sequential models = Sequential()接下來我們可以向模型中添加 Dense(full connected layer),Activation,Conv2D,MaxPooling2D函數。
from keras.layers import Dense, Activation, Conv2D, MaxPooling2D, Flatten, Dropoutmodel.add(Conv2D(64, (3,3), activation='relu', input_shape = (100,100,32))) # This ads a Convolutional layer with 64 filters of size 3 * 3 to the graph以下是如何將一些最流行的圖層添加到網絡中。我已經在卷積神經網絡教程中寫了很多關于圖層的描述。
#卷積層這里我們使用一個卷積層,64個卷積核,維度是33的,之后采用 relu 激活函數進行激活,輸入數據的維度是 100100*32。注意,如果是第一個卷積層,那么必須加上輸入數據的維度,后面幾個這個參數可以省略。
model.add(Conv2D(64, (3,3), activation='relu', input_shape = (100,100,32)))#MaxPooling 層
指定圖層的類型,并且指定赤的大小,然后自動完成赤化操作,酷斃了!
model.add(MaxPooling2D(pool_size=(2,2)))全連接層
這個層在 Keras 中稱為被稱之為 Dense 層,我們只需要設置輸出層的維度,然后Keras就會幫助我們自動完成了。
model.add(Dense(256, activation='relu'))#Dropout
model.add(Dropout(0.5))#扁平層
model.add(Flatten())數據輸入
網絡的第一層需要讀入訓練數據。因此我們需要去制定輸入數據的維度。因此,input_shape參數被用于制定輸入數據的維度大小。
model.add(Conv2D(32, (3,3), activation='relu', input_shape=(224, 224, 3)))在這個例子中,數據輸入的第一層是一個卷積層,輸入數據的大小是 224*224*3 。
以上操作就幫助你利用序列模型構建了一個模型。接下來,讓我們學習最重要的一個部分。一旦你指定了一個網絡架構,你還需要指定優化器和損失函數。我們在Keras中使用compile函數來達到這個功能。比如,在下面的代碼中,我們使用 rmsprop 來作為優化器,binary_crossentropy 來作為損失函數值。
model.compile(loss='binary_crossentropy', optimizer='rmsprop')如果你想要使用隨機梯度下降,那么你需要選擇合適的初始值和超參數:
from keras.optimizers import SGD sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True) model.compile(loss='categorical_crossentropy', optimizer=sgd)現在,我們已經構建完了模型。接下來,讓我們向模型中輸入數據,在Keras中是通過 fit函數來實現的。你也可以在該函數中指定 batch_size 和 epochs 來訓練。
model.fit(x_train, y_train, batch_size = 32, epochs = 10, validation_data(x_val, y_val))最后,我們使用 evaluate 函數來測試模型的性能。
score = model.evaluate(x_test, y_test, batch_size = 32)函數式模型接口
Keras的函數式模型為Model,即廣義的擁有輸入和輸出的模型,我們使用Model來初始化一個函數式模型
from keras.models import Model from keras.layers import Input, Densea = Input(shape=(32,)) b = Dense(32)(a) model = Model(inputs=a, outputs=b)在這里,我們的模型以a為輸入,以b為輸出,同樣我們可以構造擁有多輸入和多輸出的模型
model = Model(inputs=[a1, a2], outputs=[b1, b3, b3])常用Model屬性
model.layers:組成模型圖的各個層 model.inputs:模型的輸入張量列表 model.outputs:模型的輸出張量列表Model模型方法
compile
compile(self, optimizer, loss, metrics=None, loss_weights=None, sample_weight_mode=None)本函數編譯模型以供訓練,參數有
optimizer:優化器,為預定義優化器名或優化器對象,參考優化器
loss:損失函數,為預定義損失函數名或一個目標函數,參考損失函數
metrics:列表,包含評估模型在訓練和測試時的性能的指標,典型用法是metrics=[‘accuracy’]如果要在多輸出模型中為不同的輸出指定不同的指標,可像該參數傳遞一個字典,例如metrics={‘ouput_a’: ‘accuracy’}
sample_weight_mode:如果你需要按時間步為樣本賦權(2D權矩陣),將該值設為“temporal”。默認為“None”,代表按樣本賦權(1D權)。如果模型有多個輸出,可以向該參數傳入指定sample_weight_mode的字典或列表。在下面fit函數的解釋中有相關的參考內容。
kwargs:使用TensorFlow作為后端請忽略該參數,若使用Theano作為后端,kwargs的值將會傳遞給 K.function
【Tips】如果你只是載入模型并利用其predict,可以不用進行compile。在Keras中,compile主要完成損失函數和優化器的一些配置,是為訓練服務的。predict會在內部進行符號函數的編譯工作(通過調用_make_predict_function生成函數)
fit(self, x=None, y=None, batch_size=32, epochs=1, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0)使用Keras API開發VGG卷積神經網絡
VGG:VGG卷積神經網絡是牛津大學在2014年提出來的模型。當這個模型被提出時,由于它的簡潔性和實用性,馬上成為了當時最流行的卷積神經網絡模型。它在圖像分類和目標檢測任務中都表現出非常好的結果。在2014年的ILSVRC比賽中,VGG 在Top-5中取得了92.3%的正確率。 該模型有一些變種,其中最受歡迎的當然是 vgg-16,這是一個擁有16層的模型。你可以看到它需要維度是 224*224*3 的輸入數據。
讓我們來寫一個獨立的函數來完整實現這個模型。
img_input = Input(shape=input_shape)# Block 1x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv1')(img_input)x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv2')(x)x = MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(x)# Block 2x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv1')(x)x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv2')(x)x = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x)# Block 3x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv1')(x)x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv2')(x)x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv3')(x)x = MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x)# Block 4x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv1')(x)x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv2')(x)x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv3')(x)x = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x)# Block 5x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv1')(x)x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv2')(x)x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3')(x)x = MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x)x = Flatten(name='flatten')(x)x = Dense(4096, activation='relu', name='fc1')(x)x = Dense(4096, activation='relu', name='fc2')(x)x = Dense(classes, activation='softmax', name='predictions')(x)我們可以將這個完整的模型,命名為 vgg16.py。
在這個例子中,我們來運行 imageNet 數據集中的某一些數據來進行測試。具體代碼如下
model = applications.VGG16(weights='imagenet')img = image.load_img('cat.jpeg', target_size=(224, 224))x = image.img_to_array(img)x = np.expand_dims(x, axis=0)x = preprocess_input(x)preds = model.predict(x)for results in decode_predictions(preds):for result in results:print('Probability %0.2f%% => [%s]' % (100*result[2], result[1]))建模示例
DEBUG = False # 建模 if DEBUG:model = Sequential()model.add(Convolution2D(32, 5, 5, border_mode='valid', input_shape=(60, 200, 1), name='conv1'))model.add(Activation('relu'))model.add(MaxPooling2D(pool_size=(2,2)))model.add(Convolution2D(32, 3, 3, name='conv2'))model.add(Activation('relu'))model.add(MaxPooling2D(pool_size=(2,2)))model.add(Flatten())# model.add(Reshape((20, 60)))# model.add(LSTM(32))model.add(Dense(512))model.add(Activation('relu'))model.add(Dense(216))model.add(Activation('softmax'))else:model = model_from_json(open('model/ba_cnn_model2.json').read())model.load_weights('model/ba_cnn_model2.h5')# 編譯 model.compile(loss='mse', optimizer='adam', metrics=['accuracy'], class_mode='categorical') model.summary()# 繪圖 plot(model, to_file='model.png', show_shapes=True)# 訓練 check_pointer = ModelCheckpoint('./model/train_len_size1.h5', monitor='val_loss', verbose=1, save_best_only=True) model.fit(x_train, y_train, batch_size=32, nb_epoch=5, validation_split=0.1, callbacks=[check_pointer])json_string = model.to_json() with open('./model/ba_cnn_model2.json', 'w') as fw:fw.write(json_string) model.save_weights('./model/ba_cnn_model2.h5')# 測試 y_pred = model.predict(x_test, verbose=1) cnt = 0 for i in range(len(y_pred)):guess = ctable.decode(y_pred[i])correct = ctable.decode(y_test[i])if guess == correct:cnt += 1if i%10==0:print '--'*10, iprint 'y_pred', guessprint 'y_test', correct print cnt/float(len(y_pred))
參考文獻
Keras TensorFlow教程:如何從零開發一個復雜深度學習模型
keras中文文檔
快速開始序貫(Sequential)模型
Sequential模型接口
函數式模型接口
keras可視化pydot graphviz問題
總結
- 上一篇: 网络克隆--机房利器(acer自带还原)
- 下一篇: keras中的回调函数