# 模型訓練重點 ## Resnet-34 在卷積神經網路(Convolutional Neural Networks, CNNs)發展的過程中,研究人員發現**隨著網路層數加深,模型性能不但沒有提升,反而可能出現退化(Degradation Problem)**。這個現象並非來自過擬合,而是深層網路在訓練過程中出現了 **梯度消失(Vanishing Gradient)或梯度爆炸(Exploding Gradient)** 的問題,導致網路難以有效學習。 為了緩解這些問題,先前的研究已提出了一些技術手段 - **Batch Normalization(批次正規化)**:透過正規化激活值來穩定數據分佈,促進梯度的有效傳遞,加速模型收斂。 - **更優的激活函數**:例如 ReLU,能有效緩解梯度消失問題。 然而,**即使有這些技術輔助,訓練深層神經網路依然存在困難**。為了突破這個瓶頸,作者提出了一種新的網路架構:**Residual Network(ResNet)**。 ### ResNet 的核心創新:Residual Learning ResNet 的關鍵創新在於**殘差學習(Residual Learning)**,透過設計「**跳接連結(Skip Connections)**」來緩解深層網路的訓練問題。這種結構允許資料在卷積層之間**直接跳接傳遞**,公式表示如下: $y = F(x) + x$ - \(F(x)\):為殘差函數,通常由兩層卷積層組成。 - \(x\):是輸入數據,透過跳接路徑直接傳遞。 - \(y\):是最終的輸出。 這樣的設計有三大優勢: 1. **簡化學習任務** 模型不需要學習完整的映射 \(H(x)\),只需學習殘差 \(F(x) = H(x) - x\),若該層學不到有效特徵,則自然退化為 \(F(x)=0\),確保輸出至少等於輸入,避免性能退化。 2. **促進梯度傳遞** 跳接連結提供了一條**梯度不衰減的路徑**,即使殘差為零,梯度依然能順利傳遞到前面的層,緩解梯度消失問題。 ![{D744117F-9DCB-4B0C-B6DF-E3AD0138EAC0}](https://hackmd.io/_uploads/BJJZibE2ye.png) ### Resnet-34 擁有 34 層深度的 Residual-network ,他與原本深度 CNN 不同的地方在於,使用 **Residual Block(殘差塊)** 來解決深層神經網路訓練中的退化問題 ![image](https://hackmd.io/_uploads/SyVoi-Ehyx.png) #### 整體架構 共分為以下幾個階段 ![{81217A8D-B971-4B83-B299-3C72DDB4B983}](https://hackmd.io/_uploads/SJxj4zN21x.png) 每個(Residual blocks)是由以下幾個component 組成 ![image](https://hackmd.io/_uploads/SkqgSM4hJe.png) ### 推測此篇論文所使用的Resnet-34細節 >"In the experimental setup... the model architecture includes a ResNet-34 for feature extraction"​ 此 Resnet-34 應該與標準架構相同 #### 輸入影像的變化 ![{32CC975A-6DB7-4FAD-B36B-D8E044956436}](https://hackmd.io/_uploads/HJhsPGVnye.png) - 文中沒有特別說明圖片大小所以使用 `224`x`224` - 超音波影像通常為灰階所以channel number 可以從 `3` 改成 `1` - input: `1×224×224` #### 輸出的調整 > "Cardiac Dreamer receives the feature extracted from ResNet-34 (512-dimensional vector)"​ - 最終的特徵維度為 `512` 維向量。 - 標準的ResNet-34分類層原始輸出為 `1000` 維,因此最後的 FC 層應該被移除直接輸出 `512` 維特徵向量。 - ![image](https://hackmd.io/_uploads/S1d43GVh1x.png) #### pre-trained 權重 >"The ResNet-34 backbone is initialized with weights pre-trained on ImageNet to accelerate convergence and improve generalization." "The pre-trained weights are fine-tuned on the ultrasound dataset to adapt the model to the domain-specific features." - ResNet-34 的 backbone 是先在 ImageNet 資料集上進行預訓練的。 - 利用在大型資料集(如 ImageNet)上預訓練好的模型,讓模型已經掌握基礎的影像特徵(如邊緣、紋理)。 ### 相關實作 [連結](https://github.com/Andrewtangtang/UltrasoundNavigator/tree/resnet-34) ## Transformer ### 訓練和推論時的流程(5/7更新) 先梳理一下我們原本認為練和推論時的流程 #### 訓練 原本訓練時的流程如下(先忽略維度的操作) ![image](https://hackmd.io/_uploads/B10W5U5xex.png) - input:影像 - 1. 經過 `Resnet34` 做特徵提取後,將該影像序列的特徵和動作進行 concat 變成 token sequence 進行 attetion 計算, - 2. decoder(這部份還不是很確定怎麼實做)產生 $T_2$ 的 feature $f_2$ - 3. 進入 guidance layer 生成 $f_2$ 到目標平面的動作訊號 - 4. 彙整 $a_{t1->t2}$ 的動作與前面 guidance layer 產生的動作生出最後最適合當前狀態產生的動作訊號 #### 推論 - input:影像序列 - 進入 guidance layer 生成 $f_1$ 到目標平面的動作訊號 ### 矛盾的點 這樣我們訓練 dreamer 的權重在最後推論時完全沒用到我覺得不太合理因此我覺得這個部份或許是我想錯了因為其實推論的流程可以有另外一種走法 #### 新推論流程(我認為下次開會可以討論看看這樣的方法可不可行) - input:當下的影像 - 1. 經過 `Resnet34` 做特徵提取後,我們先使用後面訓練好的 guidance 產生一個預測到目標平面應改要產生的動作 $\hat{a}$ - 2. 我們將該影像的特徵與這個預測的動作進入到之前之前訓練的 dreamer - 3. 進入 guidance layer 生成 $f_2$ 到目標平面的動作訊號 $\hat{a_2}$ - 4. 彙整 $\hat{a_2}$ 的動作與前面 guidance layer 產生的動作生出最後最適合當前狀態產生的動作訊號 $\hat{a_1}$ ### VIT 實做方法 假設要使用上面的方法,那麼 transformer 部份的功能就是利用當前的影像feature及動作去預測未來的影像feature。參看了 VIT 的實做方法後,我認為或許這個地方使用 VIT 的架構是可行的,在這邊可以利用resnet-34 和VIT的混合框架,這樣不僅可解決純transformer 需要大量資料訓練的問題,也可以妥善使用Resnet-34 對於細節特徵抓取的能力。 ![image](https://hackmd.io/_uploads/By34hw9xgx.png) 先複習一下前面講到 Resnet 最後輸出一層會產生的會是 $7*7$ 的feature map 然後會有 512 的 channel,可以參考以下圖,因為原本的 VIT 是根據影像直接切成(一個區塊一個區塊的patch) 對於每個 patch 進行 linear projection 成高維的 token 再進行 attention 計算。 ![image](https://hackmd.io/_uploads/B1uxtjalxe.png) 那這裡我們的 Resnet 假設只是要進行 特徵提取的工作,可以不用走到最後的global average pooling 層,而是在最後的一個stage 當output是 $7*7*512$ 層時我們就去做轉換。 ![image](https://hackmd.io/_uploads/Sklf5ipxxg.png) 那要如何去轉換的得到類似原本 VIT的效果呢? 我們可以知道其實一張 $7*7$ 的feature map 其實相對來說它還是有空間資訊的(等同於將影像做成49個區域然後使用512個channel 來表示他有什麼特徵),因此我覺得在token 方面可以這樣去做設計,把 feature map 同一個區域的 channel 拉開來變成一個 1*512 維向量作為token,來取代原本 VIT 對於 patch 做 embedding的操作,因此全部的影像總共就會有49個512維的 token。這種 hrbrid架構的作法是有被應用過的 [TransUNet: Transformers Make Strong Encoders for Medical Image Segmentation](https://arxiv.org/pdf/2102.04306) ![image](https://hackmd.io/_uploads/SJmiXTTxxl.png) 而我看到 VIT 在輸入 encoder 的地方額外輸入了一個token 作為任務導向的的 token(CLS),他的用意就是為了要去學習並彙整所有patch 的資訊去自己學習出我這個任務應該需要對於哪些patch 有那一些的權重和要求,最後在使用我學習到的這個token 做任務導向的的連結層。所以我認為或許我們也可以把這個 token 放成我們動作的token 作為 CLS 輸入,讓這個token 學習去融合當下的動作,以及其他token的資訊去預測下一個 feature 。把動作當成 token 影像特徵一起輸入,在我看到有其他篇的論文也有做過相同的操作,雖然或許目標和實做方法不同,但是我認為是有操作的可行性,當然做這些文獻探討我認為都屬於紙上談兵,或許真正的情景可能要等真正訓練時的結果才能評估。 ![image](https://hackmd.io/_uploads/H1CP5TTxxl.png) (https://arxiv.org/pdf/2106.01345 ) ![image](https://hackmd.io/_uploads/BkHlz_9lgx.png) https://arxiv.org/abs/2405.15223 ### 動機(摘自論文+自己的理解)(原先的版本) 在 Cardiac Dreamer 中,Transformer 並非用於處理語言模型常見的長序列資訊整合,而是作為一種條件生成模型,學習在當前影像狀態下,給定一組相對位姿(動作),模型應如何預測下一步的潛在特徵。具體來說,透過將影像特徵與動作資訊一同輸入 Transformer 架構,模型能捕捉這兩者之間的關聯性,進而學習「從當前狀態出發,執行某個動作後會轉移到哪個潛在狀態」的映射關係。 ### 我目前閱讀到現在疑惑的問題 我在看完李宏義教授對於 [transformer](https://www.youtube.com/watch?v=n9TlOhRjYoc) 以及 [attention](https://www.youtube.com/watch?v=hYdO9CscNes&t=1401s) 的部分解說以及閱讀該篇論文,我認為可能可以實行的有以下2種方式,雖然各自都有可以實作的方法,但也有許多我認為不合理的地方,還請教授撥空查看,如有我沒設想到的部分請再提出讓我改進或去研究。 首先假設我們的影像經過了 Resnet 經過特徵提取後 pooling 產生了 $1*512$ 的 vector,之後我們取這個 vector 和 action 的 vector 預設為 $1*6$ 當作 token 去進行 transformer 的 attention 的計算與操作。 #### 方法一 ![專題-2](https://hackmd.io/_uploads/HySgekelex.jpg) 不使用decoder,把影像這 512 的 vector 當作一個 token 也把動作也投影到 512 相同到相同維度,利用兩個token 做 multihead-Head Attention 產出下一個影像的影像特徵。 - 這樣做的原因:兩個 token 之間會互相注意(attention),模型可以學習「影像特徵應該對動作注意多少、反之亦然」,達到融合特徵與動作資訊的目的。如果任務只是從當前狀態與動作預測下一步特徵(而不是序列生成),這種結構相對直接、清晰。 - 我認為不合理的原因: - 缺乏方向性:我們在這個dreamer 想要做的是學習映射的關係及當下的feature 經過了這個動作 $a_{t1->2}$ 後產生的影像特徵 $f_{t2}$ ,但是做 attention 的意義我認為是讓特徵可以針對自己以及其他 token 彼此的一個關聯性,可以有幫助更進一步的理解其他 token 對於判斷我這個當下 token 的影響,但是我這樣做好像並沒有辦法去學習到說這個映射的 $f_{t1}$ 到 $f_{t2}$ 的關聯性。也就是說 Self-Attention 本質上好像是在學習一個對等的關聯姓,但無法明確區分「動作如何推動特徵變化」,可能沒有讓模型學會預測未來的feature 這件事。 #### 方法二 ![專題-3](https://hackmd.io/_uploads/HkXWxygglg.jpg) 保留完整的(單 token Encoder + 動作 token Decoder),這樣退化成 encoder 的地方輸入只有一個token 即 512 維的 vector 但是attention 機制退化不做 self-attention ,之後讓動作 token 做query ,去對 encoder 產生的output key/value 做 cross-attention。 - 這樣做的原因: 讓動作 token 主動向影像特徵「query」→ 抽取最相關的 latent 資訊,直接建立「執行動作後特徵如何變化」的映射關係。 - 我認為不合理的原因:Encoder 端只有一個 token,因此,Encoder 的 Self-Attention 實際不會做任何的操作,浪費了自注意力的核心能力,那這樣就等於其實只是我的輸入接了一個 feedforward (全連接層) 後再去與動作的token 做一次 attention 。 ### 目前的觀點 我認為目前可能的情況有可能是以下原因。 - 輸入的維度或許不是單純的 $1*512$ 而是像像 transformer 原始的輪文中是一個 token sequence - 或許其針對影像特徵的處理方法可能是其他處理方法,例如切 patch 或其他形式 - 參考其他篇論文 [Transdreamer](https://arxiv.org/pdf/2202.09481) 的實作方式