學習筆記TF029:實現進階捲積網路

来源:http://www.cnblogs.com/libinggen/archive/2017/07/24/7231075.html
-Advertisement-
Play Games

經典數據集CIFAR-10,60000張32x32彩色圖像,訓練集50000張,測試集10000張。標註10類,每類圖片6000張。airplance、automobile、bird、cat、deer、dog、frog、horse、ship、truck。沒有任何重疊。CIFAR-100,100類標註 ...


經典數據集CIFAR-10,60000張32x32彩色圖像,訓練集50000張,測試集10000張。標註10類,每類圖片6000張。airplance、automobile、bird、cat、deer、dog、frog、horse、ship、truck。沒有任何重疊。CIFAR-100,100類標註。深度學習之父 Geoffrey Hinton和學生Alex Krizhevsky、Vinod Nair收集。圖片源於80 million tiny images數據集。State-of-the-art 3.5%錯誤率,GPU訓練十幾小時。詳細Benchmark和排名在 http://rodrigob.github.io/are_we_there_yet/build/classification_datasets_results.html 。LeCun,現有捲積神經網路已經解決CIFAR-10數據集問題。

根據Alex cuda-convnet模型修改,3000個batch,每個batch 128個樣本,達到73%正確率。GTX1080單顯卡幾十秒模型訓練時間。CPU慢很多。如用100k batch 結合學習速度decay(每隔一段時間下降學習速率一個比率),正確率可到86%。模型訓練參數100萬個,預測四則運算總量2000萬次。對weights進行L2正則化。圖片翻轉、隨機剪切等數據增強,製造更多樣本。每個捲積-最大池化層後用LRN層,增強模型泛化能力。

下載TensorFlow Models庫,使用其中提供CIFAR-10數據類。git clone https://github.com/tensorflow/models.git。models/tutorials/image/cifar10。

載入常用庫,NumPy、time,TensorFlow Models自動下載、讀取CIFAR-10數據類。

定義batch_size,訓練輪數max_steps,下載CIFAR-10數據預設路徑。

定義初始化weight函數,tf.truncated_normal截斷正態分佈初始化權重。Weight加L2 loss ,做L2 正則化。減少特征或懲罰不重要特征權重,緩解特征過多導致過擬合。正則化幫助找到該懲罰的特征權重。為使用某個特征,需付出loss代價。L1正則製造稀疏特征,大部分無用特征權重被置0。L2正則讓特征權重不過大,特征權重較平均。wl控制L2 loss大小,tf.nn.l2_loss函數計算weight L2 loss,tf.multiply L2 loss 乘以wl,得最後 weight loss。tf.add_to_collection weight loss統一存在collection losses,計算神經網路總體loss使用。

用cifar10類下載數據集,解壓、展開到預設位置。

用cifar10_input類 distorted_inputs函數產生訓練數據,包括特征、label,返回封裝tensor,每次執行生成一個batch_size數量樣本。Data Augmentation(數據增強),cifar10_input.distorted_inputs函數,隨機水平翻轉(tf.image.random_flip_left_right)、隨機剪切一塊24x24圖片(tf.random_crop)、設置隨機亮度對比度(tf.image.random_brightness、tf.image.random_contrast),數據標準化(tf.image.per_image_whitening,數據減均值,除方差,保證數據零均值,方差1)。獲得更多樣本,帶雜訊,一張圖片樣本變多張圖片,擴大樣本量,提高準確率。數據增強操作耗費大量CPU時間,distored_inputs用16個獨立線程加速任務,函數內部產生線程池,通過TensorFlow queue調度。

用cifar10_input.inputs函數生成測試數據,裁剪圖片正中間24x24大小區塊,數據標準化。

創建輸入數據placeholderx,特征、label。設定placeholder數據尺寸,batch_size定義網路結構要用,數據尺寸第一個值樣本條數需要預先設定,不能設None。數據尺寸的圖片尺寸為24x24,裁剪後大小,顏色通道數3,彩色RGB三通道。

第一個捲積層,variable_with_weight_loss 函數創建捲積核參數初始化。捲積核大小5x5,3個顏色通道,64個捲積核,設置weight初始化函數標準差0.05。wl(weight loss)設0。tf.nn.conv2d函數對輸入數據image_holder捲積操作,步長stride設1,padding模式SAME,bias初始化0,捲積結果加bias,用ReLU激活函數非線化。用尺寸3x3,步長2x2最大池化層處理數據,尺寸、步長不一致,增加數據豐富性。tf.nn.lrn函數,LRN,處理結果。

LRN起於Alex用CNN參加ImageNet比賽論文。LRN模仿生物神經系統側抑制機制,對局部神經元活動創建競爭環境,響應較大值變得相對更大,抑制其他反饋較小神經元,增強模型泛化能力。用LRN後CNN Top1錯誤率降低1.4%。LRN對無上限邊界激活函數ReLU有用,從附近多個捲積核響應(Response)挑選較大反饋,不適合固定邊界能抑制過大值激活函數Sigmoid。

第二個捲積層,捲積核尺寸第三維度輸入通道數64,bias值全初始化0.1。先進行LRN層處理,再用最大池化層。

全連接層,把前面兩個捲積層輸出結果全部flatten,tf.reshape函數把每個樣本變成一維向量。get_shape函數獲取數據扁平化長度。variable_with_weight_loss函數初始化全連接層weight,隱含節點384,正態分佈標準差0.04,bias初始化0.1。設非零weight loss值0.04,所有參數被L2正則約束,避免過擬合。ReLU激活函數非線性化。

第二個全連接層,隱含節點192。

最後一層,先創建weight,正態分佈標準差設上一隱含層節點數倒數,不計入L2正則。Softmax操作放在計算loss部分,不需要對inference輸出softmax處理,就可以獲得最終分類,直接比較inference輸出各類數值大小。

整個捲積神經網路從輸入到輸出流程。設計CNN,安排捲積層、池化層、全連接層分佈和順序,超參數設置、Trick使用。捲積神經網路結構:
conv1:捲積層和ReLU激活函數
pool1:最大池化
norm1:LRN
conv2:捲積層和ReLU激活函數
norm2:LRN
pool2:最大池化
local3:全連接層和ReLU激活函數
local4:全連接層和ReLU激活函數
logits:模型Inference輸出結果

計算CNN loss。softmax計算和cross entropy loss 計算合在一起,tf.nn.sparse_softmax_cross_entropy_with_logits。tf.reduce_mean計算cross entropy均值,tf.add_to_collection 添加cross entropy loss 到整體losses collection。tf.add_n整體losses collection 全部loss求和,得最終loss,包括cross entropy loss,和後兩個連接層weight L2 loss。Logits節點、label_placeholder傳入loss小孩子數,獲得最終loss。

優化器選擇Adam Optimizer,學習速率1e-3。

tf.nn.in_top_k函數求輸出結果top k準確率,預設top 1,輸出分類最高類準確率。

tf.InteractiveSession創建預設session ,初始化全部模型參數。

啟動圖片數據增強線程隊列,16個線程加速。

訓練。每個step訓練過程,session run方法執行images_train、 labels_train計算,獲得batch訓練數據,傳入train_op和loss計算。記錄每個step時間,每隔10個step計算展示當前loss、每秒鐘訓練樣本數量、訓練batch數據時間,監控整個訓練過程。GTX 1080,每秒訓練1800個樣本,batch_size 128,每個batch 0.066s。損失loss,開始4.6,3000步訓練下降到1.0。

評測模型測試集準確率。測試集10000個樣本,使用固定batch_size,逐個batch輸入測試數據。計算全部樣本評測完batch數量。每個step用session run方法獲取images_test、labels_test的batch,執行top_k_op計算模型 batch top 1預測正確樣本數。彙總所有預測正確結果,求全部測試樣本預測正確數量。

列印準確率評測結果計算。

73%準確率。持續增加max_steps,期望準確率逐漸增加。max_steps較大,用學習速率衰減(decay)的SGD訓練,接近86%。L2正則,LRN層提升模型準確率,提升框泛化性。

數據增強(Data Augmentation),給單幅圖增加多個副本,提高圖片利用率,防止圖片結構學習過擬合。利用圖片本身性質,圖片冗餘信息量較大,製造不同雜訊,依可識別。神經網路剋服雜訊準確識別,泛化性更好。深度學習只要提供足夠多樣本,準確率可以持續提升。 規模越大越複雜神經網路模型,可以達到準確率水平越高,需要更多數據訓練。Alex cuda-convnet測試結果,CIFAR-10,不數據增強,錯誤最低下降到17%,數據增強,錯誤率下降到11%。

    import cifar10,cifar10_input
    import tensorflow as tf
    import numpy as np
    import time
    max_steps = 3000
    batch_size = 128
    data_dir = '/tmp/cifar10_data/cifar-10-batches-bin'
    def variable_with_weight_loss(shape, stddev, wl):
        var = tf.Variable(tf.truncated_normal(shape, stddev=stddev))
        if wl is not None:
            weight_loss = tf.multiply(tf.nn.l2_loss(var), wl, name='weight_loss')
            tf.add_to_collection('losses', weight_loss)
        return var
    def loss(logits, labels):
        labels = tf.cast(labels, tf.int64)
        cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(
            logits=logits, labels=labels, name='cross_entropy_per_example')
        cross_entropy_mean = tf.reduce_mean(cross_entropy, name='cross_entropy')
        tf.add_to_collection('losses', cross_entropy_mean)
        return tf.add_n(tf.get_collection('losses'), name='total_loss')
  
    ###
    cifar10.maybe_download_and_extract()
    images_train, labels_train = cifar10_input.distorted_inputs(data_dir=data_dir,
                                                            batch_size=batch_size)
    images_test, labels_test = cifar10_input.inputs(eval_data=True,
                                                data_dir=data_dir,
                                                batch_size=batch_size)                                                  
    #images_train, labels_train = cifar10.distorted_inputs()
    #images_test, labels_test = cifar10.inputs(eval_data=True)
    image_holder = tf.placeholder(tf.float32, [batch_size, 24, 24, 3])
    label_holder = tf.placeholder(tf.int32, [batch_size])
    #logits = inference(image_holder)
    weight1 = variable_with_weight_loss(shape=[5, 5, 3, 64], stddev=5e-2, wl=0.0)
    kernel1 = tf.nn.conv2d(image_holder, weight1, [1, 1, 1, 1], padding='SAME')
    bias1 = tf.Variable(tf.constant(0.0, shape=[64]))
    conv1 = tf.nn.relu(tf.nn.bias_add(kernel1, bias1))
    pool1 = tf.nn.max_pool(conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1],
                       padding='SAME')
    norm1 = tf.nn.lrn(pool1, 4, bias=1.0, alpha=0.001 / 9.0, beta=0.75)
    weight2 = variable_with_weight_loss(shape=[5, 5, 64, 64], stddev=5e-2, wl=0.0)
    kernel2 = tf.nn.conv2d(norm1, weight2, [1, 1, 1, 1], padding='SAME')
    bias2 = tf.Variable(tf.constant(0.1, shape=[64]))
    conv2 = tf.nn.relu(tf.nn.bias_add(kernel2, bias2))
    norm2 = tf.nn.lrn(conv2, 4, bias=1.0, alpha=0.001 / 9.0, beta=0.75)
    pool2 = tf.nn.max_pool(norm2, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1],
                       padding='SAME')
    reshape = tf.reshape(pool2, [batch_size, -1])
    dim = reshape.get_shape()[1].value
    weight3 = variable_with_weight_loss(shape=[dim, 384], stddev=0.04, wl=0.004)
    bias3 = tf.Variable(tf.constant(0.1, shape=[384]))
    local3 = tf.nn.relu(tf.matmul(reshape, weight3) + bias3)
    weight4 = variable_with_weight_loss(shape=[384, 192], stddev=0.04, wl=0.004)
    bias4 = tf.Variable(tf.constant(0.1, shape=[192]))                                      
    local4 = tf.nn.relu(tf.matmul(local3, weight4) + bias4)
    weight5 = variable_with_weight_loss(shape=[192, 10], stddev=1/192.0, wl=0.0)
    bias5 = tf.Variable(tf.constant(0.0, shape=[10]))
    logits = tf.add(tf.matmul(local4, weight5), bias5)
    loss = loss(logits, label_holder)
    train_op = tf.train.AdamOptimizer(1e-3).minimize(loss) #0.72
    top_k_op = tf.nn.in_top_k(logits, label_holder, 1)
    sess = tf.InteractiveSession()
    tf.global_variables_initializer().run()
    tf.train.start_queue_runners()
    ###
    for step in range(max_steps):
        start_time = time.time()
        image_batch,label_batch = sess.run([images_train,labels_train])
        _, loss_value = sess.run([train_op, loss],feed_dict={image_holder: image_batch, 
                                                         label_holder:label_batch})
        duration = time.time() - start_time
        if step % 10 == 0:
            examples_per_sec = batch_size / duration
            sec_per_batch = float(duration)
    
            format_str = ('step %d, loss = %.2f (%.1f examples/sec; %.3f sec/batch)')
            print(format_str % (step, loss_value, examples_per_sec, sec_per_batch))
    
    ###
    num_examples = 10000
    import math
    num_iter = int(math.ceil(num_examples / batch_size))
    true_count = 0  
    total_sample_count = num_iter * batch_size
    step = 0
    while step < num_iter:
        image_batch,label_batch = sess.run([images_test,labels_test])
        predictions = sess.run([top_k_op],feed_dict={image_holder: image_batch,
                                                 label_holder:label_batch})
        true_count += np.sum(predictions)
        step += 1
    precision = true_count / total_sample_count
    print('precision @ 1 = %.3f' % precision)

 

參考資料:
《TensorFlow實踐》

歡迎付費咨詢(150元每小時),我的微信:qingxingfengzi


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 使用Selenium與PhantomJS模擬登錄豆瓣:https://www.douban.com/ ...
  • 作為腳本,python具備了弱類型語言的靈活性,便捷性。這在日常的開發使用中能夠大幅度的減輕開發人員的編碼負擔,開發者也能夠將精力集中在程式的邏輯管理和總體構架設計上。一般而言,隨著經驗的積累,開發人員都能使用python寫出漂亮的代碼,簡潔而美觀。 python也是嚴謹的,從對各類預定義錯誤的設定 ...
  • 知乎的整個網站架構圖如下: 知乎是國內很少的使用Python開發的一個網站,也很多值得我們學習的地方,從知乎讓我們也可以瞭解到一些新的WEB技術。 一、Python框架 知乎目前使用的是Tornado 框架。Tornado 全稱Tornado Web Server,是一個用Python 語言寫成的W ...
  • 一 log4j log4j是Apache的一個開源項目,用於輸出程式的運行狀況。 相比於在程式內部添加System.out.println()做日誌輸出,log4j有如下優點: 可以設定信息輸出的目的地,常用的有控制台、文件等。 根據日誌的嚴重程度,將日誌分為6級,從高到低依次是:fatal、err ...
  • 消息保證送達是指消息發送方保證在任何情況下都會至少一次確定的消息送達。AtleastOnceDelivery是一個獨立的trait,主要作用是對不確定已送達的消息進行補發,這是一種自動的操作,無需用戶干預。既然涉及到消息的補發,就不可避免地影響發送方和接收方之間消息傳遞的順序、接收方重覆收到相同的消 ...
  • 1、函數嵌套 1.1函數的嵌套調用 在調用一個函數的過程中,又調用了其他函數 1.2函數的嵌套定義 在一個函數的內部,又定義另外一個函數 2、名稱空間 2.1名稱空間 名稱空間:存放名字的地方,準確的說名稱空間是存放名字與變數值綁定關係的地方 內置名稱空間:在python解釋器啟動時產生,存放一些p ...
  • 一 概述 1.整合目的 有了Spring以後,所有對象的創建任務都應該交給Spring容器來完成,這樣做不僅是為了降低代碼的耦合度,而且可以利用Spring容器作為代理工廠實現代理。 2.整合目標 將Spring容器中的bean註入Action中,將Action的創建與管理工作交給Spring容器。 ...
  • 一 概述 1.整合目的 將所有對象的創建與管理任務交給Spring容器,降低程式的耦合度。 2.整合途徑 將Spring容器註入到Web容器中。 3.具體實現 使用ServletContextListener監聽ServletContext,當ServletContexxt創建時同時創建Spring ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...