iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 2
1
AI & Data

從零.4開始我的深度學習之旅:從 用tf.data處理資料 到 用tf.estimator或tf.keras 訓練模型系列 第 2

一、用skeleton code解釋tensorflow model程式執行方式(tf.keras) ep.2

文章說明

本篇是接續一、用skeleton code解釋tensorflow model程式執行方式(tf.keras) ep.1,這第一篇主要要講的是我學到的一個具彈性的程式碼要怎麼寫,才能在要擴充時,少點架構的修改,可以專注於深度學習需要花時間處理的部分:資料、與模型本身。

其中第2段與第3段的內容都在ep.1,還沒看過的可以先去看。

 

前情提要

前面第2段我有介紹一下datasets的具體架構,還有他的label的存法不同,但是都是一樣的道理。

常見的label像是,segmentation任務,會直接用影像的全部pixel去做標記,所以這類的label基本上就會直接是2d影像,像brats的資料也是類似情況,只不過他是3d影像;

那classification的任務最直觀的作法,是用資料夾去命名,同名的資料夾內就放同一個種類的object,當然應該也會有用影像名稱直接命名的,不過這個如果是手動搜集,除非寫程式改檔名,否則一個一個改的效率太低。

類似detection的任務,通常會給bounding box,需要取得的是bounding box的「左上角與右下角的座標」,或是「左上角的座標與bbox長還有bbox寬」。那這類資料的label通常會用json檔去保存,所以在解析這類dataset時,就需要去了解他的json檔裡,把task需要的資訊給拿出來,其他沒用的就忽略掉。

 

那第3段的部分,是大概統整了深度學習的應用,它完整要做的事會有哪些步驟,我之前在練習時以為做完Step1, 7, 11就可以了,可是做完其實很空虛,因為什麼東西都沒有留下。

後來加進Step8, 10感覺好像有點東西了,但是每次調參數都很像是在擲筊在賭博,最初試著訓練幾個模型後發現糟了,完全忘記之前的模型,是用什麼參數訓練的。主要的原因是同時會有很多東西在改動,不只是參數,有時候程式跑一跑就會有bug,或是要加入新的程式進去,在這樣子的情況下,要怎麼比較模型之間的差異?

之後有時間我會考慮把它做成流程圖,不過那是之後的事情了。

 

文章分段:

  1. 文章說明
  2. 簡介datasets
  3. 描述模型訓練的流程
  4. 程式架構:上程式的虛擬碼,預告要寫的檔案、功能有哪些
  5. 主程式的實際撰寫,註明程式開始不能單跑的地方
  6. 總結

前面大概回憶過ep.1講的2、3段,ep.2就接著從第4段開始吧!

 

程式架構

真的在建立與訓練模型時,要撰寫的程式有幾個功能要做到:

  1. 處理資料的程式
    • 可以擷取 raw data 中的 data 與 label,作為一組 train sample
    • train sample進入model前需要做的前處理
    • 可以把 train sample 載入 model 的 input layer
    • ...
  2. 模型建立
    • 模型本身寫成可呼叫的程式或class
    • 能有系統的為數百層tensor layer命名
    • 撰寫或呼叫不同的loss與optimizer
    • 載入訓練過的模型參數
    • ...
  3. 實驗記錄
    • 紀錄訓練中的loss和score變化(進階:不論中斷與否均可紀錄)
    • 紀錄每次模型訓練時使用的hyper parameter
    • 紀錄訓練的模型參數
    • ...

要把以上功能納進組織良好的程式裡,取決於工程師的經驗與習慣。越是有經驗的工程師,往後架構的改動次數亦會減少,不過沒經驗也不要擔心,一切從模仿開始,仿著仿著就會有經驗開始累積了。

下面我仿造之前實習的地方,還有tensorflow的deeplab的程式架構,是我覺得整理起來比較容易的架構。

目前,我的作法是這樣的,如果出現兩種情況,我就會把project獨立出來。

 

使用不同的深度學習平台/框架,分開

第一種情況是使用的深度學習平台/框架不同,顯而易見的原因,就是因為程式架構與寫法太不同了,有時候甚至連使用的語言也不同;另外,雖然pytorch跟tensorflow都是用python撰寫,但程式的呼叫上就有極大的不同;再舉一個例子,甚至是tensorflow本身,除了有scratch的寫法,還有調用tf.estimator跟tf.keras的不同。

為了不讓一個月後的自己爆炸,出現這種情況無論如何一定得分開。

 

不同的任務與應用方向,分開

第二種情況是task不同,我會將project獨立出來,也就是說,如果都是在做相同的segmentation task,不論是找車子,還是找腦瘤或是找各種物件,我都會放在同一個project裡面。原因有幾個:通常相同task的模型可以互通有無、tfrecord的格式類似、資料前處理的方法類似、用來評分的metric亦可以通共有無,基於以上幾個原因,我認為同task就併在同個project,然後task不同的話就分開。

 
 
在接續講下去之前,先說明一下,因為接下來的部分,會涉及到寫程式的部分,也就會開始有特定的程式語言出現。我目前主要用的是tensorflow框架,也是我這次的主題,所以接下來的虛擬碼與程式撰寫,都會圍繞著tensorflow及python展開。至於其他框架的部分...就以後再說。

.
└── projects
     ├──project1
     |    ├── core/
     |    ├── datasets/
     |    ├── logs/
     |    ├── models/
     |    ├── evaluate.py
     |    ├── predict.py
     |    ├── README.md
     |    └── train.py
     ├── project2
     |    └── ...
     ├── .gitignore
     ├── CHANGELOG.md
     └── README.md

那每個project內部都會有四個資料夾core/datasets/logs/models/,還有三個主要程式,trainpredictevaluate,接下來我會依序講解每個的用途是什麼。

core/

.
└── core/
     ├── unet.py
     ├── backbone/
     └── ...

deeplab中,core/資料夾是用來放:自己製作的layer,還有backbone(feature extractor)的地方,能呼叫到完整的模型架構,是寫在上層的model.py裡。

 

題外話,先撇開架構不提,前段提到的backbone也是深度學習領域中需要了解的概念。我第一次接觸到這個名詞是在論文裡,上下翻完論文以及去找過網路上關於backbone的解釋後,對於如何實際應用還是一知半解。而我真正理解它,是在讀完實習待的地方用的模型才有了具體的概念。我之後的文章會再帶到這個部分,有興趣的可以再來看。

 

而我這裡沒有model.py,我是直接將模型與backbone都統一放在core/,這邊要誠實說的是,我目前使用的backbone都還是安裝來的程式,還沒有成功的把別人分享的程式抽取出要的部分放入,還是有bug無法解決。

這裏想推薦正在使用keras API進行segmentation task的人一個github:qubvel的segmentation_models,裡面有寫得超棒的架構,想要自己寫一個靈活的keras模型的人可以拿來參考。

datasets/

datasets這個資料夾的結構蠻龐大的,主要原因是因為每個dataset的儲存方式都不太一樣,尤其是公開資料集,每個都會有自己的規則。

那這個部分要做的功能就是,將各個dataset,透過tf.data API,轉成統一的儲存結構,一旦把資料的儲存結構統一,就可以用相同的程式架構將資料轉換成tensor,進行前處理或是進入模型之中。

先給你們看完整的資料夾架構。

.
└── datasets              
     ├── DATASET_NAME
     |    ├── annotations/
     |    |    ├── ***_seg.nii.gz or
     |    |    ├── ***.png or
     |    |    ├── ***.json
     |    |    └── ...
     |    ├── data/
     |    |    ├──pred/
     |    |    ├──train/
     |    |    └──val/
     |    └── tfrecords
     |         ├──DATASET_NAME_pred.tfrecord
     |         ├──DATASET_NAME_train.tfrecord
     |         └──DATASET_NAME_val.tfrecord  
     |
     ├── build_DATASET_NAME_to_tfrecord.py
     ├── build_data.py
     ├── data_generater.py
     ├── preprocesses.py
     ├── tfrecord2image_DATASET_NAME_format.py
     └── ... 

首先想說明下面程式的部分,build_DATASET_NAME_to_tfrecord.py就是根據不同dataset去處理,可以先看deeplab/datasets略窺一二,它本身有提供ade20k、cityscapes、voc2012三個dataset的處理方式。基本功能是將raw data轉成tfrecord。

build_data.py算是是決定tfrecord架構的地方,像deeplab的build_data.py136行的地方就是他訂定的基本segmentation需要用到的資料。

data_generater.py是處理tfrecord轉成模型可用的data的程式,我的寫法就不是參考deeplab的寫法了,之後會再解釋。

preprocesses.py就是集結了所有可以通用的前處理的地方,這個部分也留待之後闡述。

tfrecord2image_DATASET_NAME_format.py:這個程式是在將tfrecord裡面的東西,轉回來視覺化地呈現,基本也算是build_to_tfreocrd的測試程式碼,一樣之後細談。

 

最後是我略過的dataset本身的部分,我上面列出的部分是一種存放方式的舉例,大部分情況,由於dataset的所佔的容量很大,它通常會被另外放在別的硬碟提供取用,而內層的tfrecords/就是存放build好的tfrecord。

 

天阿,時間差不多了,今天也花了大概3個小時的時間,才把第4段講到一個小段落而已,我知道我還有2個資料夾和3個主要程式沒有解釋,但其實他們的架構也比較簡單,所以我決定把他們和實際的程式碼留到明天再繼續講。

一樣,感謝你的觀看,請不要吝嗇留下你的建言,讓還在學習的我能夠多開開眼界。

或是有什麼部分是你想要知道的更多的或是我沒有講清楚的部分,可以留言讓我知道,我會再把他們穿插進我的文章裡,再次謝謝你的觀看。


上一篇
一、用skeleton code解釋tensorflow model程式執行方式(tf.keras) ep.1
下一篇
一、用skeleton code解釋tensorflow model程式執行方式(tf.keras) ep.3
系列文
從零.4開始我的深度學習之旅:從 用tf.data處理資料 到 用tf.estimator或tf.keras 訓練模型30

尚未有邦友留言

立即登入留言