# 利用eBird資料探討全球鳥類功能性特徵與型態多樣性(with MAE Model)
###### tags: `eBird` `Masked Autoencoders` `Vision Transformer` `MAE`
---
#### github
- [eBird_project on github](https://github.com/YunghuiHsu/ebird_project)
## 專案執行歷程
### 0. 資料蒐集與處理
[eBird資料處理筆記](https://hackmd.io/@YungHuiHsu/ryAfJpDN5)
### 1. MAE模型探索、建立baseline()
[Masked Autoencoders(MAE) 模型訓練筆記](https://hackmd.io/@YungHuiHsu/BJFcW5L49)
- 2022.03-09
- [x] 修改腳本、測試參數、進行訓練()
- [x] [建立與整理eBird訓練資料集](https://hackmd.io/RQtHBCIyQ5CqRhDOROHSOw)
- [x] 確認不同版本模型在下游分類任務(Finetune、LinearProbing)的表現
- [x] 以MAE模型建立baseline完成Embedding探索
- eBird pretrain模型值域有多個中心、其中一個中心分布位置左偏(負值)
- [x] XAI視覺化檢視ViT分類模型關注區域-[[Explainable AI] Transformer Interpretability Beyond Attention Visualization。 Transformer可解釋性與視覺化](https://hackmd.io/@YungHuiHsu/rk8ZHeqys)
- [x] Voting找出分科關鍵特徵
- 發現學習到的表徵太過分散在各維度,決定將模型加入稀疏編碼的約束(2022.09)
### 2. 對MAE加入稀疏編碼(sparce coding)的約束,建立MAE_VSC版本模型
[MAE_VSC(Masked Autoencoders with Variational Sparse Coding) 修改與訓練筆記](https://hackmd.io/@YungHuiHsu/ByIooeufi)
- 2022.09-10
- [x] 修改MAE模型加入稀疏約束
- [x] 測試與調整超參數、模型訓練(預計2022.11月底完成)
- [ ] Embedding探索分析(待處理)
- [ ] Voting找出分科關鍵特徵 (待處理)
---
# 零、研究背景資訊
## 研究目標
透過深度學習演算法萃取出鳥類型態的高階抽象特徵,探討鳥類功能性特徵與環境(緯度、海拔)的關聯性
### 一、探索高維抽象特徵
- Encoder版本
- 比較eBird Petrain、iNaturalist Finetune、eBird Finetune(embedding分析使用版本)
#### 1. Embedding的值域分布探索
- [x] 分布是否偏離0、單峰或多峰?
- [x] 各維度之間的相關性矩陣檢視
#### 1-2. umap視覺化檢視
- UMAP Label:
- 分類:取前20大科
- 空間:按緯度
- [x] 確認iNaturalist資料有地理資訊
#### 1-3 緯度與特徵空間
- 按座標切成小格,照緯度呈現特徵空間
- 以地點為單位,按緯度呈現特徵空間?
#### 2. 對各科分類任務的表現,混淆矩陣檢視對於不同類群表現
#### 3. 找出關鍵維度
- 決定分科依據的重要維度,作為後續量化分析降維使用
* (關鍵維度視覺化產生重建影像)
* 平均特徵樣貌(各科或各屬鳥類)
### 二、量化分析高維度的功能性特徵空間
#### 1. 檢視在不同空間尺度上的關聯(緯度、海拔)
* 相對於分類問題,grouping的對象改為空間變量
#### 2. 尋找決定空間尺度變異的關鍵維度/抽象特徵,還原與視覺化
### 待解決問題
:::info
MAE decoder需要id_store(mask)與pos embeddink(patch)還原空間資訊,如果我們自行合成embedding(平均特徵、關鍵特徵做內插等),而非透過MAE encoder產出對應的空間資訊,則無法利用decoder產出對應的重建影像
:::
- 適合Vision Transormer的XAI方法
[XAI文獻搜尋筆記: XAI for Vision Transformer](https://hackmd.io/@YungHuiHsu/SJ204at09)
---
## 資料準備
見[eBird資料處理筆記](https://hackmd.io/RQtHBCIyQ5CqRhDOROHSOw)
:::spoiler
* 產出用於探索latent vectors使用的資料集
* ~~為便於探索分析,使用有1485種鳥類、1.5萬筆的 iNaturalist 2021 Validation dataset~~
* 89萬筆eBird_top100資料、n_class = 11,186
* MAE Encoder(ViT) 產出的Embedding/Latent Vectors
* 形狀為(num_batch, patch_num, embedding_dim)
:::
### Embedding項目
:::spoiler
#### cls token/ gap_token
- shape : (num_batch, embedding_dim)
- ==用來作為下游任務的最後embedding==
- 可視為縮減摘要維度後的patch embedding資訊,便於下游任務使用
- 即對應CNN版Autoencoder中的Latent vectors(num_batch, dim)
#### (pos embedding)
- shape : (num_batch, 1+ num_patch, embedding_dim)
#### (patch embedding)
- shape : (num_batch, num_patch, embedding_dim)
:::
## 模型架構
見[Masked Autoencoders(MAE) 模型訓練筆記]()、[Masked Autoencoders(MAE)論文筆記]()
:::spoiler
* Architecture : MAE base(cls token, norm_pix_loss on/off版本)
* Encoder
- [x] Ebird Pretrain MAE Encoder
- [x] iNaturelist Fine-tune MAE Encoder
* Decoder
- [x] 使用Ebird datadet pretrain的MAE Decoder
* cls_token or gap_token(global ave. pooling)
* 最後匯聚出抽象特徵(shape : embedding_dim)的輸出架構
- [x] cls_token
* 搭配ViT結構特有的類別embedding,為可學習的權重
* 放在圖塊embedding最前面,一起進入 MAE Encoder(ViT)中訓練,在訓練過程中學習到所有圖塊的資訊(經過矩陣相乘)
* MAE 當中的cls_token本身是為符合ViT結構而保留的embedding,在未對應下游任務遷移學習前,裡面的參數權重是無資訊的
- [x] gap_token(global ave .pooling)
* 即Resnet最後一層所用匯聚所有資訊產出最後latent vectors的方法
* 將各patch(不含cls_token)embedding資訊匯集成形狀為(num_batch,embedding_dim)的高維向量
:::
# 一、探索高維抽象特徵
## (內插抽象特徵還原重建影像)
### 方法
:::spoiler
- 取兩張圖像,依序按patch、embedding dimendion位置進行內插
#### 內插對象:latent vectors
- shape : (num_patches+1 ,embedding_dim) = (196+1, 768)
- patch0 是cls_token,decoder解碼時不會用到。要不要做內插不影響結果
#### ids_restore
- 這是圖塊切割給編碼器與解碼器還原的編號,無法內插,因此,這邊的做法為:
- 給定隨機種子,讓兩張圖像的ids_restore與pos embedding一致
- 編碼器在每次前向傳播時,都會呼叫troch.randint()隨機對圖塊產出對應的id,因此要在每次執行model.forward()時均要固定隨機種子
#### 模型架構
##### Encoder
- [x] 使用Ebird datadet pretrain的MAE Encoder
- [ ] 使用iNaturelist datadet LinearProbing 的ViT作為Encoder
- [ ] 使用iNaturelist datadet Finetune 的ViT作為Encoder
##### Decoder
- [x] 使用Ebird datadet pretrain的MAE Decoder
##### 圖塊位置資訊的還原
###### ids_restore
- 用forwar_encoder產出欲內插圖像圖像各自的 id_store
###### pos embedding?
- MAE模型建立時,一起初始化生成,每個圖像應該有各自對應的編碼
- 如果Encoder權重調整過,可能位置編碼無法與decoder對應?
- LP的encoder參數沒動到,理論可以與decoder共享pos embedding權重還原
#### code
:::spoiler
##### 1. 取得影像embedding, id_restore
```python=
seed = 1
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model.to(device)
embeddings = []
rec_imgs = []
ids_restores = []
for img_ in [img, img2]:
x_ = img2tensor(img_).to(device)
# for geting identical ids_restore
torch.manual_seed(seed)
embedding_, mask_, ids_restore_ = model.forward_encoder(x_, mask_ratio=0)
ids_restores.append(ids_restore_)
embedding_ = embedding_.detach().cpu()
embeddings.append(embedding_)
pred_ = model.forward_decoder(embedding_, ids_restore_)
rec_img_ = model.unpatchify(pred_)
rec_imgs.append(rec_img_)
print(ids_restores[0], '\n', ids_restores[1])
assert (ids_restores[0] == ids_restores[1]).all(), "ids_restores not equal"
```
##### 2. 依序按patch、embedding dimendion位置進行內插
```python=
num_inter = 20
num_patch, num_dim = embeddings[0].squeeze(dim=0).shape
interpolate_embedding = []
for idx_d, dim in enumerate(range(num_dim)) :
emb0_d = embeddings[0].squeeze(dim=0)[:,dim] # torch.Size([197])
emb1_d = embeddings[1].squeeze(dim=0)[:,dim] # torch.Size([197])
interpolate_patch = []
for idx_p, p in enumerate(range(num_patch)):
# if p==0 : # skip pos_embedding
# continue
interpolat_p_ = torch.linspace(emb0_d[p], emb1_d[p], num_inter)
interpolate_patch.append(interpolat_p_)
interpolate_patch = torch.einsum('pi->ip', torch.stack(interpolate_patch))
interpolate_embedding.append(interpolate_patch)
print(f'dim : {dim}, {len(interpolate_patch)}. | patch : {p}, {interpolate_patch.shape}', end='\r')
# (768, 24, 197) embedding, interpolate_patch, patches > (24, 197, 768)
interpolate_embedding = torch.einsum('eip->ipe', torch.stack(interpolate_embedding))
print('\n',interpolate_embedding.shape)
```
##### 3. 使用MAE Decoder 重建內插的影像
```python=
# reconstruct interpolated images
assert (ids_restores[0] == ids_restores[1]).all(), "ids_restores not equal"
ids_restore_ = ids_restores[0]
rec_interpolated_imgs = []
for i_ipl, embedding_ in enumerate(interpolate_embedding):
print(i_ipl, embedding_.shape, end='\r')
pred_ = model.forward_decoder(embedding_.unsqueeze(dim=0), ids_restore_)
rec_img_ = model.unpatchify(pred_)
rec_interpolated_imgs.append(rec_img_)
rec_interpolated_imgs = torch.stack(rec_interpolated_imgs).squeeze(dim=1)
print(rec_interpolated_imgs.shape)
```
:::
### 結果
:::spoiler
- 經過MAE編碼重建的兩張影像
- norm_pix_loss on

- norm_pix_loss off

- 將兩張影像的embedding內插重建的影像
- norm_pix_loss on

* 按patch為單位漸變
* 至中間過度區塊兩圖像重疊而非型態輪廓的漸變
- norm_pix_loss off

:::
### 討論
:::spoiler
* 需再探索適合的內插還原方式
* 是否把patch依照背景跟主題切分、檢視、比較與量化漸變程度?
* 是否能找出對於構成鳥類輪廓的關鍵維度?
#### 待處理項目
尋找適合ViT架構的XAI視覺化探索(待蒐集文獻與方法)
:::
## 1. Embedding的值域分布探索
### Distribution for all embedding values
#### Results
##### data x Encoder
:::spoiler
| Data\Encoder | eBird Pretrain | iNat FT | eBird FT |
|:------------:|:------------------------------------------:|:------------------------------------------:|:------------------------------------------:|
| eBird_top100 | |  |  |
| eBird_val |  |  | |
| iNat 2021 |  |  | |
:::
##### setting
:::spoiler
- Ebird Pretrain
- Norm_pix_loss : on
- token : cls
- data
- 同時用iNaturalist與ebird(參照iNaturalist的1486種,每種選10張)資料集進行特徵抽取後檢視分布
:::
:::spoiler 討論
- eBird_top100 x eBird FT 的值域分布範圍相對較廣,但分布仍以0為中心
- Ebird Pretrain MAE Encoder
- 部分維度的均質明顯偏離0(dim=325)
:::spoiler
- dataset : iNaturalist 2021
- 
- dataset : ebird
- 
:::
- eBird與iNat的embedding分布結構相似,不過eBird較集中一些
:::
### Correlation between Dimmensions
檢視embedding各維度間數值之相關性,確認各維度之間的變化是否盡可能獨立
##### 版本
:::spoiler
- data
- eBird_top100: size=890k, n_class=11,186
- eBird_val: size=1.49k, n_classes=1,486
- pretrain模型版本
- norm_pix_loss on
- cls_token
:::
#### 相關矩陣
- Ebird Pretrain版本比iNat Finetune產出的embedding,在各維度間有明顯較高的相關性
:::spoiler
| Ebird Pretrain | iNat Finetune | eBird Finetune |
|:------------------------------------------:| ------------------------------------------ | --- |
| | | |
|  |  | 
|
:::
##### code
:::spoiler
```python=
# 用numpy計算會比在pandas格式快很多。 13.8s vs 155 ms
corr_matrix = np.corrcoef(df_embedding.T)
print(corr_matrix.shape)
# 取矩陣下半三角形
mask = np.triu(np.ones_like(corr_matrix, dtype=bool))
title = f'CorrMatrix_Of_Embedding\n{model_data_version}'
fig, ax = plt.subplots(figsize=(9, 8) )
ax.set_title(title)
sns.heatmap(corr_matrix, vmax=1, vmin=-1, center=0, square=True,
mask=mask,
cmap='vlag', ax=ax)
fig.savefig(f'embedding/{title}.jpg', bbox_inches='tight',)
```
:::
#### 所有維度成對比較的相關性密度分布圖
- Ebird Finetune產出的embeddings在各維度間的相關性較接近0
- Ebird Pretrain版本在各維度間有明顯較高的相關性
- 各特徵維度彼此間的相關性較高、缺乏獨立性
:::spoiler
| Data\Encoder | eBird Pretrain | iNat Finetune | eBird Finetune |
|:------------:|:------------------------------------------:|:------------------------------------------:|:------------------------------------------:|
| eBird_top100 | |  |  |
| eBird_val |  |  | |
:::
##### code
:::spoiler
```python=
# 用numpy計算會比在pandas格式快很多。 13.8s vs 155 ms
corr_matrix = np.corrcoef(df_embedding.T)
print(corr_matrix.shape)
# 取矩陣下半三角形
mask = np.triu(np.ones_like(corr_matrix, dtype=bool))
title = f'CorrMatrix_Of_Embedding\n{model_data_version}'
fig, ax = plt.subplots(figsize=(9, 8) )
ax.set_title(title)
sns.heatmap(corr_matrix, vmax=1, vmin=-1, center=0, square=True,
mask=mask,
cmap='vlag', ax=ax)
fig.savefig(f'embedding/{title}.jpg', bbox_inches='tight',)
```
:::
:::spoiler
```python=
title = f'Correlation_Of_Embedding\n{model_data_version}
xlim=(-1,1)
ylim=(0,1e6)
fig = (pd.DataFrame(np.tril(corr_matrix ,k=-1)) # k=-1 ,排除斜對角的數值(均為1.0)
.stack()
.plot(kind='hist', title=title, bins=100, grid=True, logy=True, xlim=xlim, ylim=ylim)
).get_figure()
fig.savefig(f'embedding/{title}.jpg', bbox_inches='tight',)
;
```
:::
## 2.透過降維視覺化檢視embedding群聚樣貌
Visualization of Embeddings Clustering by dimension reduction
使用umap降維視覺化檢視embedding分群情形
- 實作參考 [mae/visual_mae.ipynb](https://github.com/YunghuiHsu/ebird_project/blob/main/mae/visual_mae.ipynb)`
### 方法
:::spoiler
- 使用資料與encoder版本
- Data : eBird_top100(89萬筆)
- Encoder : eBird Finetune
- 使用umap降維視覺化檢視embedding分群情形
- umap參數設置
- metric: 'eclidean'
- (向量化的cosine距離較不易看出分群趨勢)
- n_neighbors :
- 取值設定在官方建議範圍15-200
- 使用各分類單元資料的均質
- label上色
- 按類群
-類群參照依據iNaturalist 2021 metadata
- 資料抽樣
- 由於89萬筆資料量過大會造成視覺干擾,且使用plotly作圖時資料量太大會造成瀏覽器記憶體爆掉,因此部分資料在呈現時,根據值域座標(umap降維後的數值)抽樣呈現
:::
### 結果
- [umap_Taxon](https://drive.google.com/drive/folders/1RCrige7lPUuIE-lZSM6H6eUC7bDT_Su0?usp=sharing)
:::spoiler
#### 3D Embedding(plotly)_Labelling by Order
- 以類群作為label進行上色,可見embeddings依照類群聚集
##### Order : top10
| top_10 | |
| ------ |:------------------------------------------:|
| view1 |  |
| view2 |  |
##### Order : top10-30
| top_20-30 | |
| --------- |:------------------------------------------:|
| view1 |  |
| view2 |  |
##### Passeriformes(n=20k)

##### Accipitriformes

:::
### 討論
:::spoiler
- 無法從實際照片的圖片特徵map到UMAP降維後的embedding分布位置
- 生態影像不若去背的標本影像背景單純,也許embedding中很大一部分的維度被用來產出複雜的背景資訊?
- 改用棲地類型labelling
- 針對分佈範圍/棲地類型較狹隘的特定類群labelling
- eg:海鳥、水鳥、猛禽、開闊地鳥類
- 是否可能找出/分離出模型產出鳥類影像的特定維度?
- 合成影像測試embedding值域變化與預測結果
- 不同物種
- 不同背景(棲地)
- 如果背景與鳥類主體被綁在一起,維度的容量也反映了背景(棲地)的多樣性?
#### 其他測試想法
- 驗證模型泛化能力
- 用同樣iNat 2021資料Finetune訓練好的model來對eBird做測試
- 在iNat 2021資料集預測準確度達到85.5%(1486種*10張影像)
- 在eBird_eval資料集(1486種*10張影像)top1準確率達95.7%。
- 差距的主要原因在於iNat 2021相對eBird資料品質明顯欠佳,鳥類主體小且模糊
:::
## 3. 使用分群找出各分類單元代表性樣本與離群資料
- 實作參考 [mae/outlier_check.ipynb](https://github.com/YunghuiHsu/ebird_project/blob/main/mae/outlier_check.ipynb)
- [Overview of clustering methods](https://scikit-learn.org/stable/modules/clustering.html#optics)
### 找出離群值
#### 目標與方法
:::spoiler
- 背景與動機:
- 已將89萬筆影像資料由MAE Encoder 取得embeddings,並經由UMAP降至三維的embeddings以類群上標,發現群聚狀態明顯
- 發現部分游離在群聚中心外維資料的資料多為主體相當不明確的影像資料
- 資料特性
- 由於資料分布相當不均勻,因此採用不定數量的群聚讓分群算法,
- 直接根據資料空間分佈與結構進行分群(嘗試不同敏感度)
- 計算演算法分群內的類別標籤的豐富度/均勻度, 挑出豐富度/均勻度高的群去檢視
- UMAP內的分群法已經初步將資料分群後降維,且分群狀態與人為定義的分類單元相當符合,顯示UMAP的分群法已經很好的作出分群,可以利用UMAP分群好的低維度資料最後續分群,也方便後續視覺化檢查資料
- 使用density-based 的演算法,基於Local linkage 的強度來分群(與UMAP係出同源的演算法家族),"固定範圍內如果找不到特定數量的點(連結過少) 或是最終找到的點總數不夠(群太小) 就都視為 outlier"
- 目標
- 利用embedding空間分布特性,幫助找出品質不佳或有問題的資料,如
- 主體很小、
- 手繪圖、
- 腳印、鳥巢等無鳥類主體
- 假設:
- 上述類型影像可能會被推離核心區域,遠離資料分布低機率密度區域
- (如果該類群充滿影像品質不佳的資料,則可能自己聚成一類?)
- 分類單元選擇
- 選擇以"科"為單位
- 249科、科樣本中位數969
- 人力可檢視範圍、各科資料也大致足夠
| | 目 | 科 | 屬 |
|:------:| ------- | ------ |:-----:|
| count | 41 | 249 | 2,295 |
| mean | 21,866 | 3,600 | 390 |
| median | 2,450 | 969 | 186 |
| min | 100 | 1 | 1 |
| max | 203,130 | 39,295 | 8,043 |
- 分群演算法eps(群密度半徑)選擇
- 數值越大,分群數量越小、離群值越少
- 藉由動態指定eps,讓個分類單元切初一定比例的離群值
- 計算每個分類單元內資料間的成對距離,選取較大的數值作為群密度半徑(75%或90%分位數),指定為
- 得到各分類單元分群標籤後,
- 計算各群的豐富,檢視類群豐度最高的群,是否為異常資料(非鳥類為主體)
- 低的類群豐度代表:
- embeddings反映模型學習到的鳥類特徵,資料會因為特徵相近而聚集在一起,那麼群的類群豐度應該會很低
- 高的類群豐度代表:
- 群距內的資料密度聚集不是基於鳥類特徵,可能是反映背景相近而聚集
- 檢視離群資料(label=-1),確認是否均為非鳥類為主體的影像
- 抽樣繪圖檢視分群標籤與資料輪廓
:::
##### 分群演算法選擇
:::spoiler
- 分群演算法選擇
- 密度根據、不受限群形狀、及不受異常值影響(能區分出離群值)分群演算法(DBSCAN、OPTICS, etc.):
- DBSCAN參數設置
- 對分群結果對參數相當敏感
- eps
- The maximum distance between two samples for one to be considered as in the neighborhood of the other.
- This is not a maximum bound on the distances of points within a cluster
- 群的最大密度半徑,越小代表需要的資料密度越高才會判定為"群"
- 依照各分類單元設定為==分類單元內資料間的成對距離的中位數==
- OPTICS
- 參數不敏感(不需手設eps),但計算時間相當耗時
- 根據資料本身的密度分布搜尋適合的密度半徑,可指定搜尋範圍節省計算量
:::
#### 結果範例
- [Cluster](https://drive.google.com/drive/folders/1hRW91hiMLQ-VZM-aY08FxmTMNf2qFTQ-?usp=sharing)
:::spoiler
##### Acanthisittidae
- 
- 
##### Accipitridae
- 
- 
##### Alcidae
- 
- 
##### Balaenicipitidae
- 
- 
:::
#### 討論
:::spoiler
- 離群資料未如預期找出、找出主體過小的資料
- 不清楚的影像未如預期被分到離群值,而是視分類單元本身資料密度與分布被分配到不同的群
- ==部分類分類單元中,主體清楚的影像仍被分配到離群值==
- 主體小的影像可能仍被分配到群中,未被歸類到離群值
- 或許仍含有足夠的表徵資訊可供模型分辨
- 分類單元中,都是這樣身體素質的資料
- 討論
- 部分類群影像資料主體就是相當小,因此整體資料相當分散距離很遠
- 有些主體清楚的影像卻被歸類為離群值
- 可能該類群資料主要都是主體過小的影像,導致主體清楚的影像被歸類在低密度區?
- 檢視幾個類群並非如此
- 可能該主體清楚的影像樣本過少,鄰近找不到特徵相似的資料與其成群
:::
### 找出代表性樣本
#### 目標與方法
:::spoiler
- 目標
- 找出各分類單元代表性樣本,作為後續表徵分析使用
- 方法
- 將各分類單元進行分群,選取最接近中心點(歐式距離)的樣本,檢視影像樣貌
- 由於目標是用於資料探索,使用基於距離、對分群數量不需指定的演算法
- 選擇使用不指定分群數量的BIRCH
- 參數設置
- 設置n_clusters=None,盡可能得到群數比多、分群比較細的結果
- thresholdfloat, default=0.5。群的半徑閾值,使用預設值
:::
#### 結果範例
:::spoiler
##### Accipitridae
- 
- 
##### Alcidae
-
-
:::
#### 討論
:::spoiler
- 資料可能切分的過細,不少分群是將游離的(低密度)的資料點分為一群
- 資料分群很細,但如何挑出具有"代表性"的資料
- 按固定比例取每群接近中心位置的的資料?
:::
---
# 二、探索外觀特徵與科之間的關係
- 方法指引:[Variation Autoencoder and Moth](https://docs.google.com/document/d/1nPLGlZV4Zyc6gQkpfBicruGNJMhlB7ZlPID_-vudlQU/edit#)
- code見 [`mae/findKeyFeatures.ipynb`](https://github.com/YunghuiHsu/ebird_project/blob/main/mae/findKeyFeatures.ipynb)
為進一步了解物種的外觀特徵與科之間的關係,我們首先以代表外觀特徵的 latent vector 為輸入資料,訓練簡單的神經網路模型學習分科,並評估分科表現。為了後續解讀方便,我們將外觀特徵值轉換為非負值。做法是先將對應每張標本影像的 768 維特徵重複堆疊為 768*2 維,保留前 768 維裡的正值,與後 768 維裡的負值並取絕對值,其餘維度設為 0。如此即會得到內容全為非負值的外觀特徵。以此為 input,訓練僅兩層全連接 hidden layers (每層各 256 個神經元) 的簡單模型,學習分科 (248 科),在測試資料集中可達到 93.63% top-1 accuracy。
:::spoiler 為何要進行維度堆疊、轉為正值?
- 在對模型進行backpropogation時,每個維度對類別的梯度大小為:
$\Delta y/ \Delta x$
- 當模型為簡單線性模型,且輸入值均為正值時
- 模型最後的輸出值(在還沒經過活化函數sigmoid或softmax,轉換為0-1的機率分布時),數字越大代表判斷為該類別的傾向越高
- 梯度方向
- 正梯度:使輸出值變大(增加判斷為該類別的傾向),表該權重(維度)對模型判斷為該類別具有積極的影響力
- 負梯度:導致輸出值變小(降低判斷為該類別的傾向)
- 因此,我們藉由將輸入值均轉為正值,來統一輸入值的方向性,以此簡化模型在判斷分科特徵時,對模型判斷有積極影響力的維度,也就是找出有最大梯度值的維度所在
:::
## 分科模型訓練
- 分科模型訓練見[`mae/train_family_classifier.ipynb`](https://github.com/YunghuiHsu/ebird_project/blob/main/mae/train_family_classifier.ipynb)
:::spoiler
- Family which is only has 1 data : Mohoidae
- Extinctd
- Family which Accuracy < 0.7
- 10 Families

:::
## 找出關鍵特徵
- 得到當 N=4, N-union=258 時有最佳的科分群結果,約為總特徵數的 33.59%
- 使用Calinski and Harabasz score
- Silhouette score計算太過費時未採用

:::spoiler 方法指引:[Variation Autoencoder and Moth](https://docs.google.com/document/d/1nPLGlZV4Zyc6gQkpfBicruGNJMhlB7ZlPID_-vudlQU/edit#)
接著我們將找出每科的 top N 個重要分類特徵 (i.e. 對分科有最大影響力的 top N 維度),並將所有科的重要特徵取聯集,得到 N-union 個關鍵特徵。我們視低維度的關鍵特徵為同時具有分辨力 (recognition) 與代表性 (representation) 的蛾標本影像特徵,並用於後續的分析與視覺化的解釋。
我們借用 Grad-CAM 的概念以找出分科的重要外觀特徵,透過反向傳播演算法 (back propagation) 求出分科模型中對應於每個輸入值的 gradient vector,是為特徵關注度向量。我們在此計算每個物種的平均特徵關注度,並以 voting 的方式,決定每個科的重要特徵。
Voting 的規則是,先從物種平均特徵關注度的向量中,找出最大的 N 個值的位置,每個位置視為得到一票;接著算出每個科當中總得票最高的N個位置,即可選出 N 個重要特徵。最後將所有科的重要特徵取聯集,得到 N-union 個關鍵特徵。
我們希望以最小但又具足夠鑑別度的 N 與 N-union 來描述與代表科的特徵。我們窮舉 N = 1 ~ 50 這個範圍中對應的 N-union 個關鍵特徵。基於每個物種在關鍵特徵空間中的 embedding,依科計算分群的三個指標 (~~Silhouette Coefficient~~, Calinski and Harabasz score, 與 Davies-Bouldin score),標準化並加總評估後得到當 N=4, N-union=258 時有最佳的科分群結果,,約為總特徵數的 33.59% (258/768)
:::
## ~~視覺化關鍵特徵~~
:::spoiler 方法指引:[Variation Autoencoder and Moth](https://docs.google.com/document/d/1nPLGlZV4Zyc6gQkpfBicruGNJMhlB7ZlPID_-vudlQU/edit#)
~~為了更進一步理解關鍵特徵的視覺意義,我們對其做 PCA,找出最主要的三軸(解釋度 34.9%)。接著在三軸上均勻取樣並 inverse transform 回關鍵特徵。從 decoder 生成的影像中,可明確看出每一軸在外觀特徵上的意義,是為:展翅大小、翅膀形狀,與翅膀上的紋路(圖5)。~~
:::
- Transformer架構decoder無法使用內插後的數值重建影像
- 需要相對應圖像encode時的位置編碼
---
# 三、量化分析高維度的功能性特徵空間