<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 八、將預訓練的 CNN 用于遷移學習 遷移學習很棒。 實際上,在一本充滿奇妙事物的書中,這可能是我必須告訴您的最奇妙的事物。 如果沒有,那也許至少是我可以教給您的最有用和最實用的深度學習技術。 遷移學習可以幫助您解決深度學習問題,尤其是計算機視覺問題,而涉及問題范圍的數據和數據卻很少。 在本章中,我們將討論什么是遷移學習,什么時候應該使用它,最后討論如何在 Keras 中進行遷移學習。 我們將在本章介紹以下主題: * 遷移學習概述 * 何時應使用遷移 * 源/目標數量和相似性的影響 * Keras 的遷移學習 # 遷移學習概述 在第 7 章和“卷積神經網絡”中,我們訓練了約 50,000 個觀測值的卷積神經網絡,并且由于網絡和問題的復雜性,在開始訓練的短短幾個周期后,我們過擬合了。 如果您還記得的話,我曾評論說我們的訓練集中有 50,000 個觀察結果對于計算機視覺問題不是很大。 確實如此。 計算機視覺問題喜歡數據,而我們可以提供給他們的數據越多,它們的表現就越好。 我們可能認為計算機視覺技術最先進的深度神經網絡通常在稱為 **ImageNet** 的數據集上進行訓練。 [`ImageNet`數據集](http://www.image-net.org/)是包含 120 萬張圖像的 1,000 個分類器。 這還差不多! 如此龐大的數據集使研究人員能夠構建真正復雜的深度神經網絡,以檢測復雜的特征。 當然,在 120 萬張圖像上訓練有時具有 100 多個層的模型的價格很高。 訓練可能需要數周和數月,而不是數小時。 但是,如果我們可以從一個最先進的,多層的,經過數百萬張圖像訓練的網絡開始,然后僅使用少量數據將該網絡應用于我們自己的計算機視覺問題,該怎么辦? 那就是**遷移學習**! 要使用遷移學習,我們將執行以下步驟: 1. 從訓練非常大的復雜計算機視覺問題的模型開始; 我們將其稱為我們的源域 2. 刪除網絡的最后一層(`softmax`層),并可能刪除其他完全連接的層 3. 將最后幾層替換為適合我們新問題的層,我們將其稱為目標域 4. 凍結所有已訓練的層,使其權重不變 5. 在目標域數據上訓練網絡 如果我們在這里停止,這通常被稱為特征提取,因為我們正在使用在源域上訓練的網絡來提取目標域的視覺特征。 然后,我們使用栓接到該特征提取網絡上的相對較小的神經網絡來執行目標域任務。 根據我們的目標和數據集,這可能就足夠了。 可選地,我們將通過解凍一些或所有凍結的層來微調整個網絡,然后通常以很小的學習率再次進行訓練。 我們將在短期內討論何時使用微調,但是請確保我們涵蓋了首先使用遷移學習的一些原因。 # 何時應使用遷移 當您的數據有限且存在解決類似問題的網絡時,遷移學習會非常有效。 您可以使用遷移學習將最先進的網絡和大量數據帶入一個其他小的問題。 那么,什么時候應該使用遷移學習? 隨時可以! 但是,我希望您首先考慮兩個規定。 我們將在以下各節中討論它們。 # 數據有限 關于計算機視覺和遷移學習,我最常被問到的問題是:我必須擁有多少張圖像? 這是一個很難回答的問題,因為,正如我們將在下一節中看到的那樣,更多通常更好。 一個更好的問題可能是:我可以使用幾張圖像來充分解決我的業務問題? 那么,我們的數據集有多有限? 盡管遠非科學,但我已經建立了使用多達 2,000 張圖像進行二分類任務的有用模型。 更簡單的任務和更多樣化的圖像集通常可以在較小的數據集下獲得更令人滿意的結果。 根據經驗,您至少需要幾千張某類的圖像,而通常最好使用 10 至 2 萬張圖像。 # 常見問題域 如果您的目標域至少與源域有些相似,那么遷移學習會很有效。 例如,假設您正在將圖像分類為包含貓或狗。 有許多`ImageNet`訓練有素的圖像分類器非常適合用于此類型或問題。 相反,讓我們想象我們的問題是將 CT 掃描或 MRI 歸類為是否包含腫瘤。 此目標域與`ImageNet`源域非常不同。 這樣,雖然使用遷移學習可能(并且可能會)有好處,但我們將需要更多的數據,并且可能需要進行一些微調才能使網絡適應此目標域。 # 源/目標數量和相似性的影響 直到最近,很少有人研究數據量和源/目標域相似性對遷移學習表現的影響。 但是,這是一個對遷移學習的可用性很重要的主題,也是我撰寫的主題。 在我的同事撰寫的[《調查數據量和域相似性對遷移學習應用的影響》](https://arxiv.org/pdf/1712.04008.pdf)中,對這些主題進行了一些實驗。 這就是我們發現的東西。 # 更多數據總是有益的 Google 研究人員在《重新研究深度學習周期數據的不合理有效性》中進行的幾次實驗中,構建了一個內部數據集,其中包含 3 億個觀測值,顯然比`ImageNet`大得多。 然后,他們在該數據集上訓練了幾種最先進的架構,從而使模型顯示的數據量從 1000 萬增加到 3000 萬,1 億,最后是 3 億。 通過這樣做,他們表明模型表現隨用于訓練的觀察次數的對數線性增加,這表明在源域中,更多的數據總是有幫助。 但是目標域呢? 我們使用了一些類似于我們在遷移學習過程中可能使用的類型的數據集重復了 Google 實驗,包括我們將在本章稍后使用的`Dogs versus Cats`數據集。 我們發現,在目標域中,模型的表現隨用于訓練的觀察次數的對數線性增加,就像在源域中一樣。 更多數據總是有幫助的。 # 源/目標域相似度 遷移學習的獨特之處在于您擔心源域和目標域之間的相似度。 經過訓練以識別人臉的分類器可能不會輕易遷移到識別各種架構的目標領域。 我們進行了源和目標盡可能不同的實驗,以及源和目標域非常相似的實驗。 毫不奇怪,當遷移學習應用中的源域和目標域非常不同時,與相似時相比,它們需要更多的數據。 它們也需要更多的微調,因為當域在視覺上非常不同時,特征提取層需要大量的學習。 # Keras 的遷移學習 與本書中的其他示例不同,在這里我們將需要涵蓋目標域問題,源域問題以及我們正在使用的網絡架構。 我們將從目標域的概述開始,這是我們要解決的問題。 然后,我們將介紹網絡最初經過訓練的源域,并簡要介紹我們將使用的網絡架構。 然后,我們將在本章的其余部分中將問題聯系在一起。 我們需要分別考慮兩個域,因為它們的大小和相似性與網絡表現密切相關。 目標和源的類型越近,結果越好。 # 目標域概述 在本章的示例中,我將使用 Kaggle 的`Dogs versus Cats`數據集。 該數據集包含 25,000 張貓和狗的圖像。 每個類別之間達到完美平衡,每個類別 12,500。 可以從[這里](https://www.kaggle.com/c/dogs-vs-cats/data)下載數據集。 這是一個二分類問題。 每張照片都包含狗或貓,但不能同時包含兩者。 該數據集由 Jeremy Elson 等人于 2007 年組裝。 ,它目前托管在 [www.kaggle.com](https://www.kaggle.com/) 上。 它是完全免費下載和用于學術用途的,但是它確實需要一個 Kaggle 帳戶并接受其最終用戶許可。 一樣,這是一個了不起的數據集,因此我在此處包括使用說明。 # 源域概述 我們將從在 ImageNet 上訓練的深度神經網絡開始。 如果您從“遷移學習概述”部分中回顧過,`ImageNet`是一個 1,000 類分類器,訓練了大約 120 萬張圖像。 `ImageNet`數據集中都包含狗和貓的圖像,因此在這種情況下,我們的目標域實際上與我們的源域非常相似。 # 源網絡架構 我們將使用 [**Inception-V3** 網絡架構](https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Szegedy_Rethinking_the_Inception_CVPR_2016_paper.pdf)。 與您到目前為止在本書中所看到的相比,Inception 架構很有趣并且非常復雜。 如果您從第 7 章,“卷積神經網絡”中回想起,我們必須圍繞網絡架構做出的決定之一就是選擇過濾器大小。 對于每一層,我們必須決定是否應使用例如`3 x 3`過濾器,而不是`5 x 5`過濾器。 當然,也許根本就不需要另一次卷積。 也許像池化之類的東西可能更合適。 因此,如果我們在每一層都做所有事情,該怎么辦? 這就是開始的動機。 該架構基于一系列模塊或稱為**初始模塊**的構建塊。 在每個初始模塊中,先前的激活都賦予`1 x 1`卷積,`3 x 3`卷積,`5 x 5`卷積和最大池化層。 然后將輸出連接在一起。 Inception-V3 網絡由幾個相互堆疊的 Inception 模塊組成。 最后兩層都完全連接,輸出層是 1,000 個神經元 softmax。 通過使用`keras.applications.inception_v3`中的`InceptionV3`類,我們可以加載 Inception-V3 網絡及其權重。 Keras 的網絡動物園中有幾個流行的網絡,它們都位于`keras.applications`內部。 只需多一點工作就可以加載在 TensorFlow 中創建的模型。 也可以轉換在其他架構中訓練的模型,但這不在快速參考的范圍之內。 要加載 Inception,我們只需要實例化一個`InceptionV3`對象,它是 Keras 模型,如以下代碼所示: ```py from keras.applications.inception_v3 import InceptionV3 base_model = InceptionV3(weights='imagenet', include_top=False) ``` 您可能會注意到,我們在這里說了`include_top=False`,這表明我們不需要網絡的頂層。 這免除了我們手動清除它們的工作。 第一次運行此代碼時,它將下載 Inception-V3 網絡架構并保存權重并將其緩存給我們。 現在,我們只需要添加我們自己的完全連接的層即可。 # 遷移網絡架構 我們將用更適合我們的用例的全連接層替換最后兩層。 由于我們的問題是二分類,因此我們將使用激活`sigmoid`的單個神經元替換輸出層,如以下代碼所示: ```py # add a global spatial average pooling layer x = base_model.output x = GlobalAveragePooling2D()(x) # let's add a fully-connected layer x = Dense(1024, activation='relu')(x) # and a logistic layer predictions = Dense(1, activation='sigmoid')(x) # this is the model we will train model = Model(inputs=base_model.input, outputs=predictions) ``` 注意,我們在這里使用`GlobalAveragePooling2D`層。 該層將前一層的 4D 輸出平坦化為 2D 層,通過求平均將其適合于我們的全連接層。 通過指定`pooling='avg' or 'max'`來加載基本模型時,也可以完成此操作。 這是您如何處理此問題的電話。 至此,我們已經準備好訓練網絡。 但是,在執行此操作之前,我們需要記住凍結基本模型中的層,以免新的完全連接的層瘋狂地試圖學習時它們的權重不變。 為此,我們可以使用以下代碼遍歷各層并將其設置為不可訓練: ```py for layer in base_model.layers: layer.trainable = False ``` # 數據準備 我們將首先從 [Kaggle](https://www.kaggle.com/c/dogs-vs-cats/data) 下載數據,然后將`train.zip`解壓縮到本書的`Chapter08`目錄中。 現在,您將擁有一個名為`train/`的目錄,其中包含 25,000 張圖像。 每個名稱都將類似于`cat.number.jpg`。 我們想移動這些數據,以便我們為訓練,驗證和測試創建單獨的目錄。 這些目錄中的每一個都應具有貓和狗的目錄。 這都是非常無聊且平凡的工作,因此,我創建了`data_setup.py`來為您執行此操作。 一旦運行它,數據將在本章的其余部分中全部格式化。 完成后,您將擁有一個具有以下結構的數據目錄: ![](https://img.kancloud.cn/65/04/65041aff0c5c5d5e6d1e286e8da9de07_308x242.jpg) # 數據輸入 快速瀏覽圖像應使您確信我們的圖像的分辨率和大小均不同。 正如您從第 7 章,“卷積神經網絡”,所了解的那樣,我們需要這些圖像的大小與神經網絡的輸入張量一致。 這是一個非常現實的問題,您將經常面對計算機視覺任務。 雖然當然可以使用 [**ImageMagick**](http://www.imagemagick.org) 之類的程序來批量調整圖像大小,但 Keras `ImageDataGenerator`類可用于快速調整圖像大小,這就是我們要做的。 Inception-V3 期望`299 x 299 x 3`圖像。 我們可以在數據生成器中指定此目標大小,如以下代碼所示: ```py train_datagen = ImageDataGenerator(rescale=1./255) val_datagen = ImageDataGenerator(rescale=1./255) train_generator = train_datagen.flow_from_directory( train_data_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='binary') validation_generator = val_datagen.flow_from_directory( val_data_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='binary') ``` 如果需要,我們當然可以在這里使用數據增強,但是我們實際上并不需要它。 我們在這里最有趣的事情可能是使用數據生成器的`flow_from_directory()`方法。 此方法采用一條路徑,并根據該路徑生成一批圖像。 它為我們完成了將映像從磁盤中取出的所有工作。 由于它一次執行一批,因此即使不需要時,我們甚至不必將所有 50,000 個圖像保留在 RAM 中。 很酷吧? # 訓練(特征提取) 對于此模型,我們將訓練兩次。 對于第一輪訓練,我們將通過凍結網絡的訓練來進行 10 個周期的特征提取,僅調整完全連接的層權重,如我們在“遷移網絡架構”部分中所討論的。 然后,在下一部分中,我們將解凍某些層并再次進行訓練,對另外 10 個周期進行微調,如以下代碼所示: ```py data_dir = "data/train/" val_dir = "data/val/" epochs = 10 batch_size = 30 model = build_model_feature_extraction() train_generator, val_generator = setup_data(data_dir, val_dir) callbacks_fe = create_callbacks(name='feature_extraction') # stage 1 fit model.fit_generator( train_generator, steps_per_epoch=train_generator.n // batch_size, epochs=epochs, validation_data=val_generator, validation_steps=val_generator.n // batch_size, callbacks=callbacks_fe, verbose=1) scores = model.evaluate_generator(val_generator, steps=val_generator.n // batch_size) print("Step 1 Scores: Loss: " + str(scores[0]) + " Accuracy: " + str(scores[1])) ``` 在前面的示例中,我們使用`ImageDataGenerator`的`n`屬性來了解可用于生成器的圖像總數,并將每個周期的步驟定義為該數目除以批量大小。 此代碼的其余部分應該很熟悉。 如前所述,我們只需要訓練大約 10 個周期。 現在,讓我們看一下 TensorBoard 中的訓練過程: ![](https://img.kancloud.cn/6b/e2/6be2c6dc7b7738fc82e59feca088675e_475x566.png) 如您所見,即使經過一個周期,網絡的表現仍然非常好。 直到大約第 7 個階段,我們都取得了非常微弱的表現提升。在第 7 個階段,我們達到了最佳表現,導致 0.9828 的精度和 0.0547 的損失。 # 訓練(微調) 為了微調網絡,我們需要解凍一些凍結的層。 您可以解凍多少層,并且可以解凍任意數量的網絡。 實際上,在大多數情況下,我們僅看到解凍最頂層的好處。 在這里,我僅解凍最后一個初始塊,該塊從圖的`249`層開始。 以下代碼描述了此技術: ```py def build_model_fine_tuning(model, learning_rate=0.0001, momentum=0.9): for layer in model.layers[:249]: layer.trainable = False for layer in model.layers[249:]: layer.trainable = True model.compile(optimizer=SGD(lr=learning_rate, momentum=momentum), loss='binary_crossentropy', metrics= ['accuracy']) return model ``` 另請注意,我對**隨機梯度下降**使用的學習率非常低,因此需要進行微調。 重要的是,此時應緩慢移動重物,以免在錯誤的方向上發生太大的飛躍。 我不建議使用`adam`或`rmsprop`進行微調。 以下代碼描述了微調機制: ```py callbacks_ft = create_callbacks(name='fine_tuning') # stage 2 fit model = build_model_fine_tuning(model) model.fit_generator( train_generator, steps_per_epoch=train_generator.n // batch_size, epochs=epochs, validation_data=val_generator, validation_steps=val_generator.n // batch_size, callbacks=callbacks_ft, verbose=2) scores = model.evaluate_generator(val_generator, steps=val_generator.n // batch_size) print("Step 2 Scores: Loss: " + str(scores[0]) + " Accuracy: " + str(scores[1])) ``` 我們可以再次查看 TensorBoard 圖,以了解我們在進行微調后是否能得到任何收益: ![](https://img.kancloud.cn/fb/95/fb9567d96ccf7c6c6b67ecccc3848e00_473x585.png) 毫無疑問,我們的模型確實可以改進,但是只有很少的改進。 雖然規模很小,但您會注意到驗證損失正在努力改善,并且可能顯示出一些過擬合的跡象。 在這種情況下,微調幾乎沒有帶來任何好處,但并非總是如此。 在此示例中,目標域和源域非常相似。 如前所述,由于源域和目標域不同,您從微調中獲得的收益將增加。 # 總結 在本章中,我們介紹了遷移學習,并演示了如何使用在源域上進行預訓練的網絡如何極大地縮短訓練時間,并最終改善我們的深度神經網絡的表現。 我希望您喜歡這項技術,它是我的最愛之一,因為它非常實用,而且我通常會從中獲得很好的效果。 在下一章中,我們將從計算機視覺過渡到可以記住先前輸入的網絡,使它們成為預測序列中下一項的理想選擇。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看