這是給大家準(zhǔn)備的Keras速成例子 楊照璐 計(jì)算機(jī)視覺、深度學(xué)習(xí)方向從業(yè)者 作者 | 楊照璐(微信號(hào)lwyzl0821) 編輯 | 言有三 這一次我們講講keras這個(gè)簡(jiǎn)單、流行的深度學(xué)習(xí)框架,一個(gè)圖像分類任務(wù)從訓(xùn)練到測(cè)試出結(jié)果的全流程。 相關(guān)的代碼、數(shù)據(jù)都在我們 Git 上,希望大家 Follow 一下這個(gè) Git 項(xiàng)目,后面會(huì)持續(xù)更新不同框架下的任務(wù)。 https://github.com/longpeng2008/LongPeng_ML_Course 01 keras是什么 Keras是一個(gè)非常流行、簡(jiǎn)單的深度學(xué)習(xí)框架,它的設(shè)計(jì)參考了torch,用Python語言編寫,是一個(gè)高度模塊化的神經(jīng)網(wǎng)絡(luò)庫,支持GPU和CPU。能夠在TensorFlow,CNTK或Theano之上運(yùn)行。 Keras的特點(diǎn)是能夠快速實(shí)現(xiàn)模型的搭建, 簡(jiǎn)單方便地讓你實(shí)現(xiàn)從想法到實(shí)驗(yàn)驗(yàn)證的轉(zhuǎn)化,這都是高效地進(jìn)行科學(xué)研究的關(guān)鍵。 02 Keras 安裝配置 Keras的安裝非常簡(jiǎn)單,但是需要先安裝一個(gè)后端框架作為支撐,TensorFlow, CNTK,Theano都可以,但是官網(wǎng)上強(qiáng)烈建議使用TensorFlow作為Keras的后端進(jìn)行使用。本例以TensorFlow 1.4.0 版本作為Keras的后端進(jìn)行測(cè)試。 sudo pip install tensorflow==1.4.0 sudo pip install keras==2.1.4 通過上面兩條命令就可以完成TensorFlow和Keras的安裝,此處需要注意的一點(diǎn)是Keras的版本和TensorFlow的版本要對(duì)應(yīng),否則會(huì)出現(xiàn)意外的錯(cuò)誤。具體版本對(duì)應(yīng)關(guān)系可在網(wǎng)上進(jìn)行查詢。 03 Keras 自定義數(shù)據(jù) 3.1 MNIST實(shí)例 MNIST手寫字符分類被認(rèn)為是深度學(xué)習(xí)框架里的“Hello Word!”,下面簡(jiǎn)單介紹一下MNIST數(shù)據(jù)集案例的測(cè)試。Keras的官方github的example目錄下提供了幾個(gè)MNIST案例的代碼,下載mnist_mlp.py,mnist_cnn.py文件,本地運(yùn)行即可,其他文件讀者也可以自行測(cè)試。 3.2 數(shù)據(jù)定義 前面我們介紹了MNIST數(shù)據(jù)集實(shí)例,很多讀者在學(xué)習(xí)深度學(xué)習(xí)框架的時(shí)候都卡在了這一步,運(yùn)行完MNIST實(shí)例之后無從下手,很大原因可能是因?yàn)椴恢涝趺刺幚碜约旱臄?shù)據(jù)集,這一節(jié)我們通過一個(gè)簡(jiǎn)單的圖像二分類案例,介紹如何實(shí)現(xiàn)一個(gè)自定義的數(shù)據(jù)集。 數(shù)據(jù)處理有幾種方式,一種是像MNIST、CIFAR數(shù)據(jù)集,這些數(shù)據(jù)集的特點(diǎn)是已經(jīng)為用戶打包封裝好了數(shù)據(jù)。用戶只要load_data即可實(shí)現(xiàn)數(shù)據(jù)導(dǎo)入。其實(shí)就是事先把數(shù)據(jù)進(jìn)行解析,然后保存到.pkl 或者.h5等文件中,然后在訓(xùn)練模型的時(shí)候直接導(dǎo)入,輸入到網(wǎng)絡(luò)中;另一種是直接從本地讀取文件,解析成網(wǎng)絡(luò)需要的格式,輸入網(wǎng)絡(luò)進(jìn)行訓(xùn)練。但是實(shí)際情況是,為了某一個(gè)項(xiàng)目我們不可能總是找到相應(yīng)的打包好的數(shù)據(jù)集供使用,這時(shí)候自己建立一個(gè)dataset就十分重要。 Keras提供了一個(gè)圖像數(shù)據(jù)的數(shù)據(jù)增強(qiáng)文件,調(diào)用這個(gè)文件我們可以實(shí)現(xiàn)網(wǎng)絡(luò)數(shù)據(jù)加載的功能。 此處采用keras的processing模塊里的ImageDataGenerator類定義一個(gè)圖像分類任務(wù)的dataset生成器: train_data_dir = '../../../../datas/head/train/' validation_data_dir = '../../../../datas/head/val' # augmentation configuration we will use for training train_datagen = ImageDataGenerator( rescale=1. / 255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True) # augmentation configuration use for testing only rescaling val_datagen = ImageDataGenerator(rescale=1. / 255) train_generator = train_datagen.flow_from_directory( train_data_dir, target_size=(48, 48), batch_size=16) val_generator = val_datagen.flow_from_directory( validation_data_dir, target_size=(48, 48), batch_size=16) 下面簡(jiǎn)單地介紹一下上面的代碼,完整代碼請(qǐng)移步Git工程。 Keras的processing模塊中提供了一個(gè)能夠?qū)崟r(shí)進(jìn)行數(shù)據(jù)增強(qiáng)的圖像生成類ImagGenerator,該類下面有一個(gè)函數(shù)flow_from_directory,顧名思義該函數(shù)就是從文件夾中獲取圖像數(shù)據(jù)。關(guān)于ImageGenerator更多的使用可以參考官方源碼。數(shù)據(jù)集結(jié)構(gòu)組織如下: datas/train/left/*.jpg datas/train/right/*.jpg datas/val/left/*.jpg datas/val/right/*.jpg 此處還需要注意的一點(diǎn)是,我們現(xiàn)在進(jìn)行的是簡(jiǎn)單的圖像分類任務(wù)訓(xùn)練,假如要完成語義分割,目標(biāo)檢測(cè)等任務(wù),則需要自定義一個(gè)類(繼承ImageDataGenerator),具體實(shí)現(xiàn)可以查詢相關(guān)代碼進(jìn)行參考。 04 Keras 網(wǎng)絡(luò)搭建 Keras網(wǎng)絡(luò)模型搭建有兩種形式,Sequential 順序模型和使用函數(shù)式API的 Model 類模型。本教程的例子采用一個(gè)簡(jiǎn)單的三層卷積,以及兩層全連接和一個(gè)分類層組成的網(wǎng)絡(luò)模型。由于函數(shù)式API更靈活方便,因此下面采用函數(shù)式方法搭建模型,模型定義如下: 4.1 函數(shù)式API def simpleconv3(input_shape=(48, 48, 3), classes=2): img_input = Input(shape=input_shape) bn_axis = 3 x = Conv2D(12, (3, 3), strides=(2, 2), padding='same', name='conv1')(img_input) x = BatchNormalization(axis=bn_axis, name='bn_conv1')(x) x = Activation('relu')(x) x = Conv2D(24, (3, 3), strides=(2, 2), padding='same', name='conv2')(x) x = BatchNormalization(axis=bn_axis, name='bn_conv2')(x) x = Activation('relu')(x) x = Conv2D(48, (3, 3), strides=(2, 2), padding='same', name='conv3')(x) x = BatchNormalization(axis=bn_axis, name='bn_conv3')(x) x = Activation('relu')(x) x = Flatten()(x) x = Dense(1200, activation='relu')(x) x = Dense(128, activation='relu')(x) x = Dense(classes, activation='softmax')(x) model = Model(img_input, x) return model x = Conv2D(12, (3, 3), strides=(2, 2), padding='same', name='conv1')(img_input) 即輸出是12通道,卷積核大小3*3,步長(zhǎng)為2,padding='same'表示邊緣補(bǔ)零 x = BatchNormalization(axis=bn_axis, name='bn_conv1')(x) axis表示需要?dú)w一化的坐標(biāo)軸,bn_axis=3,由于采用TensorFlow作為后端,因此這句代碼表示在通道數(shù)坐標(biāo)軸進(jìn)行歸一化。 x = Flatten()(x) 表示將卷積特征圖進(jìn)行拉伸,以便和全連接層Dense()進(jìn)行連接。 x = Dense(1200, activation='relu')(x) Dense()實(shí)現(xiàn)全連接層的功能,1200是輸出維度,‘relu'表示激活函數(shù),使用其他函數(shù)可以自行修改。 最后一層采用‘softmax’激活函數(shù)實(shí)現(xiàn)分類功能。 最終返回Model,包含網(wǎng)絡(luò)的輸入和輸出。 4.2 模型編譯 網(wǎng)絡(luò)搭建完成,在網(wǎng)絡(luò)訓(xùn)練前需要進(jìn)行編譯,包括學(xué)習(xí)方法、損失函數(shù)、評(píng)估標(biāo)準(zhǔn)等,這些參數(shù)分別可以從optimizer、loss、metric模塊中導(dǎo)入。具體代碼如下: from keras.optimizers import SGD from keras.losses import binary_crossentropy from keras.metrics import binary_accuracy from keras.callbacks import TensorBoard tensorboard = TensorBoard(log_dir=('./logs')) loss = binary_crossentropy metrics = [binary_accuracy] optimizer = SGD(lr=0.001, decay=1e-6, momentum=0.9) 其中callbacks模塊包含了TensorBoard, ModelCheckpoint,LearningRateScheduler等功能,分別可以用來可視化模型,設(shè)置模型檢查點(diǎn),以及設(shè)置學(xué)習(xí)率策略。 05 模型訓(xùn)練、測(cè)試 5.1 模型訓(xùn)練 Keras模型訓(xùn)練過程非常簡(jiǎn)單,只需一行代碼,設(shè)置幾個(gè)參數(shù)即可,具體代碼如下: history = model.fit_generator( train_generator, steps_per_epoch=num_train_samples // batch_size, epochs=epochs, callbacks=callbacks, validation_data=val_generator, validation_steps=num_val_samples // batch_size) 首先指定數(shù)據(jù)生成器,train_generator, 前面介紹過;steps_per_epoch是每次epoch循環(huán)的次數(shù),通過訓(xùn)練樣本數(shù)除以batch_size得到;epochs是整個(gè)數(shù)據(jù)集重復(fù)多少次訓(xùn)練。 Keras是高度封裝的,在模型訓(xùn)練過程中,看不到網(wǎng)絡(luò)的預(yù)測(cè)結(jié)果和網(wǎng)絡(luò)的反向傳播過程,只需定義好損失函數(shù),事實(shí)上,網(wǎng)絡(luò)定義中的模型輸出會(huì)包含網(wǎng)絡(luò)的輸入和輸出。 5.2 訓(xùn)練過程可視化 keras可以采用tensorboard實(shí)現(xiàn)訓(xùn)練過程的可視化。執(zhí)行完下面的命令就可以在瀏覽器訪問http://127.0.0.1:6006查看效果。 tensorboard --logdir 日志文件路徑(默認(rèn)路徑=‘./logs’’) 上面是分別是訓(xùn)練和測(cè)試過程的loss和accuracy。 5.3 模型測(cè)試 model = simpleconv3() model.load_weights(model_path, by_name=True) image_path = '../../../../datas/head/train/0/1left.jpg' img = Image.open(image_path) img = img_to_array(img) img = cv2.resize(img, image_size) img = np.expand_dims(img, axis=0) img = preprocess_input(img) result = model.predict(img, batch_size=1) print(result) 以上代碼簡(jiǎn)單介紹一下:模型測(cè)試流程非常清晰,首先加載模型,加載參數(shù)>>將數(shù)據(jù)輸入網(wǎng)絡(luò)>>模型預(yù)測(cè)。 06 模型保存和導(dǎo)入 model = train_model(model, loss, metrics, optimizer, num_epochs) os.mkdir('models') model.save_weights('models/model.h5') 模型訓(xùn)練完成后,僅需用model.save_weights('models/model.h5')一句代碼就可以完成模型的保存。同樣,模型的導(dǎo)入采用model.load_weights(model_path, by_name=True),需要注意的是要設(shè)置by_name=True,這樣就能保證和模型名稱一樣的參數(shù)都能加載到模型,當(dāng)然模型定義要和參數(shù)是匹配的,假如要進(jìn)行fine-tune我們只需保證需要重新訓(xùn)練或者新加的網(wǎng)絡(luò)層的名稱和預(yù)加載模型參數(shù)名稱不一樣就可以。 07 總結(jié) 以上內(nèi)容涵蓋了采用keras進(jìn)行分類任務(wù)的全部流程,從數(shù)據(jù)導(dǎo)入、模型搭建、模型訓(xùn)練、測(cè)試,模型保存和導(dǎo)入幾個(gè)方面分別進(jìn)行了介紹。當(dāng)然這只是一些基本的應(yīng)用,還有一些高級(jí)、個(gè)性化功能需要我們進(jìn)一步學(xué)習(xí),有機(jī)會(huì),下一次介紹一下自定義網(wǎng)絡(luò)層、設(shè)置check_point、特征可視化等特性。 |
|