2017年5月17日 星期三

Deep learning Class Activation Map


學如不及,猶恐失之啊! 沒時間不是藉口,還是得趁有空時把研究的東西記下來,以免之後忘記。

用deep learning做classification時,結果總是每一類的機率,但是到底NN是從圖像的哪個部分判斷出他是屬於哪一類的機率呢? 這時候就可以用classificaiton的visualization來幫助我們確認NN有學習到我們認為應該要學到的部分了。

主要有兩總方法:

這裡介紹:

Learning Deep Features for Discriminative Localization

主要概念可以這樣想,我們在output最後一層conv時,其實已經隱含了每個class的權重,而對於每一個NN我們在最後做fine-tuning之後加上一個Global Average Polling (GAP)層+ Dense層來求得feature map對於每一類的weight,然後利用這組weight挑選想要做Activation Map的Cass後,乘上最後一層feature map,疊加起來就可以知道相對於這個Class的Activation Map,所以對於任何網路,只要在想要可視化的conv層後加上GAP,就可以實現可視化。

具體公式如下:



fk(x,y)代表了空間座標上x, y的feature map value,Fk代表了做完GAP之後的結果


接著對於每一類(小寫c)的weight(W)的output結果,我們可以寫出如下公式:




具體來說就是weight乘上GAP的結果,Sc就是類的預測結果,這時我們可以發現(1)式,weight可以直接乘上feature map:





(2)的Mc(x,y)就是疊加後的activation map。


配合這裡的實作講解,將自己的dataset配置一下,即便可以完成實作自己train的model的Activation Map,但Keras 的坑有點多,首先會遇上第一個坑: order of shape not match,主要是因為pre train model是用Theano build的,但我是用Tensorflow當backend,所以model的結構會有點不一樣,所以要加上"",但仍會有錯這裡我找不到解法了,改成用Keras 1.2.2就過了,殘念,有空再去查原因為何。


Prediction時會遇到第二個坑,說我們沒有feed LEARNING_PHASE這個參數,主要是因為我們使用tensorflow backend,有需參數設置是必須的,在predict時加上:

#We didn't use it in training mode (parameter 1), because there will converge very slowly
K.set_learning_phase(0)
查Api 0代表test mode,1代表training mode,traing不需加上.

Ok,pass了. 別高興太早,第三個坑會遇到optimizer_weights的problem.
網路上分享比較快的作法是直接delete掉optimizer_weights,算是一個workaround:

f = h5py.File(camconfig.VIS_MODEL_PATH, 'r+')
if 'optimizer_weights' in f:
    del f['optimizer_weights']
f.close()

下面就看看結果啦,我是用inception v3對自己的dataset做fine-tuning, dataset一共有四個類別(front, side, back, mask),下面的Class結果是人像正面,可以看出判斷是否為人像的正面還是取決於臉部的特徵.












2017年4月28日 星期五

Kaggle Competition - The Nature Conservancy Fisheries Monitoring


The Nature Conservancy Fisheries Monitoring
這是我之前參加的一個Kaggle舉辦的比賽,為期大概四五個月,但實際上我參加時間不到一個月,來筆記下我學到的東西。
Problem Statement,簡單來說就是有六類魚,一個other類,再一個No fish的種類一共有八類

  • Albacore Tuna
  • Bigeye Tuna
  • Dolphinfish
  • Moonfish
  • Shark
  • Yellowfin Tuna
  • Others
  • No Fish 
要做分類的競賽,但注意是每一張圖片只會有一類。如下圖(reference Felix Yu, will be mentioned later):




很多人以為這應該是一個分類問題,但實際上它是一個object detection的問題,因為魚相對於背景的占比差異實在大,背景過大造成無法有效的判斷出分類。

這個比賽看似簡單,其實是一個困難的問題,原因如下:
  • 要用少量資料(<3000)去預測大量資料(>1w)。
  • 類分布相當不平均,ALB的魚種幾乎占了全部的1/2。
  • 這似乎是用camera連續攝影的截圖,有很多張是一樣的圖片,很容易造成overfitting。
  • 下面這個種魚實在太像,連肉眼都很難分辨。
Ambiguous Labels


以下為當時我採用的方法:
  • Faster RCNN => 採用了此物體偵測方法,Paper 
  • Data augmentation (only HUE) =>只做了HUE的data augmentation,由於照片裡面會有晚上夜釣的情形,所以會有透過夜視鏡所呈現的照片(night fish)
  • Clips (0.04 and 0.96) => 由於評分標準是採用 log loss:
  • 我們求出來的機率分布範圍是0~1,在極值的情況(0.0001)會產生很大的懲罰,所以clips 0.02~0.98是一個很好的手法。
  • Run in 60000 inter, batch size 16
結果是0.90 in public leaderboard (254/2293)。


以上都不是重點,重點是由第八名的Felix Fu所撰寫的參賽完整心得分享 (Thanks again):

我們缺少了:
  • 強化的Data augmentation
  • 更深的classification model
  • Model ensemble (因為是offline 所以盡情用吧)
  • Establishing a GOOD Local Validation (這個意思是Felix發現,我們自己在做local validation的時候,需要用不一樣的船隻做測試,這樣才能避免魚跟船過度關聯,因為同一艘船有可能捕的魚種都比較相同,但如果測試資料集給的是沒出現過的魚種,就會造成很大的影響)
    從這個競賽可以發現,少量資料(這個比賽是3000筆),去預測大量資料的侷限性(測試資料有一萬筆),必須去避免目標物分背景過度相關而造成與不相干的物體overfitting。

2017年4月27日 星期四

Deep learning fine tuning


最近要開始整理deeep learning學到的東西了,不然學了又忘,忘了又學。
    Deep learning fine tuning, 通常指的是fine tuning + pretrain model. 使用時機在於像是VGG16 or Inception 這種前人大神發明的net, 我們如果想要拿來train自己的model時, 因為類數不同, 需要做修改, 另外, 如果直接train, 需要很多的時間才能達到我們想要的結果, 不然就是結果太於overfitting我們的樣本. 一個方法就是將經過像是imageNet等等大規模學習後的model參數, 拿來做pre train, 而我們只需要重寫top的output layers.

    實作fine tuning有一點需要注意, 就是需要將不是top level的weight frozen, 在這篇paper "How transferable are features in deep neuralnetworks?" 指出:
    The choice of whether or not to fine-tune the first n layers of the target network depends on the size of the target dataset and the number of parameters in the first n layers. If the target dataset is small and the number of parameters is large, fine-tuning may result in overfitting, so the features are often left frozen. On the other hand, if the target dataset is large or the number of parameters is small, so that overfitting is not a problem.

    所以結論就是如果資料量夠大(>1w筆)是可以不用作frozen的. 這邊以keras使用inception v3為例:

#不包含top 的layer
base_model = InceptionV3(weights='imagenet', include_top=False)
x = base_model.output
# 將原本的GAP layer加回
x = GlobalAveragePooling2D()(x)
predictions = Dense(nb_classes, activation='softmax')(x)
# 將原本的GAP layer加回
# this is the model we will train
model = Model(input=base_model.input, output=predictions)

# first: train only the top layers (which were randomly initialized)
# i.e. freeze all convolutional InceptionV3 layers
for layer in base_model.layers:
layer.trainable = False

但在VGG16中
base_model = VGG16(weights='imagenet', include_top=False)
input = Input(shape=(224,224,3),name = 'image_input')
output_vgg16_conv = base_model(input)

#Add the fully-connected layers
x = Flatten(name='flatten')(output_vgg16_conv)
#原本的下面這兩個layer必須拿掉, 這人理解是因為在fineturning時, 如果資料量太小, 如果增加太多ReLu output layer會讓資料太過於失去原本的特性而無法收斂?這個會在查明原因
#x = Dense(4096, activation='relu', name='fc1')(x)
#x = Dense(4096, activation='relu', name='fc2')(x)

x = Dense(nb_classes, activation='softmax', name='predict')(x)


以上是我的理解, 有錯歡迎指正




Deep learning Class Activation Map

學如不及,猶恐失之啊! 沒時間不是藉口,還是得趁有空時把研究的東西記下來,以免之後忘記。 用deep learning做classification時,結果總是每一類的機率,但是到底NN是從圖像的哪個部分判斷出他是屬於哪一類的機率呢? 這時候就可以用classificai...