Lời giải cho bài toán Landmark Identification Challenge

classification

#1

1. Giới thiệu chung

Các bạn có thể xem bài viết Hướng dẫn cuộc thi Landmark Identification Challenge để biết nhiều hơn về cuộc thi.

Mục đích của bài viết này, mình muốn trình bày những bước mà team mình đã làm để đạt được giải nhì cuộc thi Landmark Identification Challenge. Ngoài ra mình xin phép được nói một chút về bài toán Voice Gender/Accent Classification để các bạn có thể so sánh giữa hai bài toán có điều gì giống và khác nhau.

Solution được mình opensource tại đây

2. Exploratory Data Analysis (EDA)

Đây là bước cực kỳ quan trọng trong mỗi cuộc thi về Data science, Machine Learning hay Deep Learning. Mình giành khoảng 2 ngày để phân tích data. Việc phân tích data sẽ có định hướng tốt với chiến thuật training.

Công cụ mình sử dụng cho việc phân tích data bao gồm: jupyter notebook, pandas, matplot,… Nếu bạn nào muốn học thêm về pandas, visualization, các bạn có thể xem thêm tại

2.1 Kiểm tra phân phối của các label

Chúng ta cần kiểm tra phân phối của các label trong bài toán Landmark, xem nó là balanced hay imbalanced data.

Nhìn vào đây ta có thể thấy rõ đây là bài toán imbalanced data

Tương tự như vậy, chúng ta có thể kiểm tra phân phối các label trong bài toán Voice.

Đây cũng là bài toán imbalanced data

2.2 Kiểm tra file trùng nhau

Trong hầu hết các competition, data mình nhận được đều là raw data. Chúng có thể chứa nhiễu. Nhiễu ở đây có thể do lỗi tính toán khi thu thập data hay do người ra đề “cố tính” làm như vậy :smiley: . Ở đây mình nghĩ Zalo chắc hẳn không cho đề bài quá dễ như thế này đâu.

Phát hiện đầu tiên của mình ở bài Landmark là có những ảnh giống nhau, được khéo léo đổi tên và được gắn sang label khác. Đây chính là nhiễu mình cần phải tìm ra. Việc này quan trọng trong quá trình training. Để làm được điều này rất đơn giản. Các bạn dùng checksum MD5 là ra :slight_smile:. Kết quả mình tìm được ở bài Landmark là: Có 844 bức ảnh mà trong đó có ít nhất 2 bức ảnh trùng mã MD5 và ở ít nhất 2 label khác nhau. Điều này đóng góp đến chiến thuật training như thế nào, mong các bạn đón đọc phần sau nhé.

Tương tự như vậy, với bài Voice thì data tinh vi hơn. Có những file nhạc trùng tên nhau và thậm chí trùng cả mã MD5 nhưng ở 2 hay nhiều label khác nhau.

2.3 Kiểm tra qua data một lượt

Việc xem qua ảnh của dataset đóng vai trò quan trọng. Nó sẽ giúp các bạn định hướng được những augment nào cần được sử dụng. Mình rút ra được một vài đặc điểm sau:

  • Có ảnh có chất lượng tốt và không tốt (ảnh mờ, ánh sáng cao,…)
  • Có ảnh bị lệch đi khi được chụp
  • Ảnh có thể chụp bị ngược (tùy thuộc vào máy anh sử dụng).

3. Model selection

Không có bất kỳ một công thức nào cho việc chọn model :smile: . Mỗi model sẽ đạt performance tốt cho những tập data khác nhau. Sau đây là một số kinh nghiệm của mình

  • Với mình, trong các bài toán về Computer Vision, model yêu thích của mình là Resnet50
  • Mình dựa vào performance của model tại đây để chọn model tốt từ trên xuống dưới. Tùy theo phần cứng của bạn, model tốt sẽ nặng và khó train.

Trước đó, bọn mình có chọn một model làm base, đó là SEResnet50_3x4d. Từ đó, những ý tưởng mới (như thêm augment, thay đổi data,…) đều được train ở model này. Nếu nó tốt, thì các model còn lại cũng có thể tốt và ngược lại. Chúng ta tránh không nên build nhiều model một lúc khi không biết ý tưởng đó có hiệu quả hay không.

Cuối cùng, team mình lựa chọn được ra 4 models phù hợp đó là:

  • SEResnet50_32x4d
  • InceptionV4
  • Xception
  • Densenet161

Việc lựa chọn model này dựa vào quá trình probe leader board.

4. Data train

Ban đầu mình có dùng cross validation với tỉ lệ 90-10 cho train và validation. Qua thời gian train, chúng mình nhận thấy các models đều hội tụ tại một điểm (epoch 26) nên mình quyết định train toàn bộ data đến epoch 26 đó. Việc tăng thêm data đã giúp cho việc tăng thêm độ chính xác của những class ít dữ liệu. Qua đó mình thấy rằng điểm số LB của mình cũng được improve.

Mình không biết việc này có dẫn đến overfit tập train hay không. Mình sẽ chờ Zalo mở lại submission và kiểm tra lại điều này :smiley:

5. Training params

  • Batch size: 32
  • Image size: 320 hoặc 288. Bọn mình ưu tiên train với high resolution là 320. Tuy nhiên phần cứng giới hạn nên có mạng chỉ train được với 288 là Densenet161.
  • Densenet không dùng dropout, các mạng khác thì có. Ở đây mình xin nhắc lại là không có công thức để chọn dropout hợp lý. Tất cả đều cần thử, hãy thử nó khi bạn hết ý tưởng

6. Augmentation

Qua việc phân tích data (EDA) phía trên, mình chọn được một số augment như sau

  • Resize
  • RandomRotation (15 degree)
  • RandomCrop
  • RandomHorizontalFlip
  • ColorJitter
  • Normalize (0.5)

7. Test time augment

Mình sử dụng 12TTA (Cái này mình học từ fastai):

  • Normalize
  • HorizontalFlip
  • Resize + Five crops (4 corners + 1 center)
  • Resize + HorizontalFlip + Five crops (4 corners + 1 center)

Về cơ bản những augment nào được sử dụng trong quá trình training thì khi dùng TTA có thể giúp ích.

8. Ensemble

Qua việc prob Leader board thì mình thấy rằng:

  • Với một model, sử dụng mean average cho 12TTA tốt hơn gmean
  • Với nhiều model, sử dụng gmean cho toàn bộ tốt hơn mean

Cho những bạn nào chưa biết về gmean, các bạn có thể tham khảo tại đây

9. What does not work

  • Qua quá trình EDA trên, mình phát hiện có những label nhiễu. Có hai hướng để giải quyết vấn đề này:

    • Xóa những label đó đi
    • Gắn nhãn lại

    Tuy nhiên, do số lượng label lớn nên mình khó có thể ngồi gán nhãn lại label. Vậy nên, mình chọn phương pháp là xóa label đó đi. Ban đầu khi training, mình nhận thấy các accuracy của model tăng lên rất nhanh so với không clean. Tuy nhiên, khi model đạt trạng thái bão hòa thì kết quả không thay đổi so với việc không clean label (1)

  • Sử dụng semi-supervised learning. Lý do mình nghĩ đến cách này là vì, khi mình clean label phía trên, kết quả không thay đổi nhiều so với không clean. Như vậy model vẫn có thể hoạt động tốt khi có một chút nhiễu. Mình dùng best models để predict tập testset. Sau đó dùng 60% tập testset để train. Mình chấp nhận một phần nhiễu nhỏ nhưng bù lại thêm được data. Tuy nhiên kết quả không thay đổi khi dùng cách này (2).

Từ (1) và (2), mình nghĩ model của mình có thể đạt đến stable với dataset này.

Từ hai cái fail trên, các bạn có thể thấy được sự quan trọng của EDA. Nó sẽ giúp mình đưa ra những kết luận tốt cho chiến thuật training. Mặc dù hai điều này không hoạt động tốt ở bài toán Landmark, nhưng nó đạt hiệu quả cao trong bài toán Voice (giúp mình tăng được 1% accuracy)

10. What does work

Những điều giúp mình từng bước đạt được performance tốt trong bài toán này là:

  • Train với high resolution sẽ tăng đc performance (Thử cách này nếu bạn có một vài con “trâu”)
  • Densenet không có dropout tốt hơn có Dropout. Các mạng còn lại mình chưa test.
  • Train full data ???
  • Chọn điểm convex (epoch 26)

11. What could not done

Trong cuộc thi này, có một bước mà mình quên mất và đã bỏ qua (thật ra là không có nhiều thời gian :smiley:) . Đó là quá trình kiểm tra ngược.

Quá trình này được tóm tắt như sau: Khi model của bạn được train xong, qua việc dự đoán tập validation mình cần kiểm tra confusion matrix và những bức ảnh mà predict lỗi. Mình sẽ phải đặt ra câu hỏi là:

  • Tại sao bức ảnh đó lại dự đoán lỗi?
  • Tại sao nó là label x nhưng bị nhầm sang label y

Những bức ảnh bị lỗi như vậy thường có một đặc điểm nào đó không giống với những bức ảnh còn lại. Điều này khiến cho model không thể khái quát (generalize) những feature của bức ảnh đó. Việc trả lời được câu hỏi này, mình có thể tìm ra một model khác mà predict bức ảnh này không bị lỗi. Điều này rất tốt cho việc blending.

Cám ơn anh Nguyễn Cảnh Thướng đã nhắc em, nhưng rất tiếc em không có thời gian làm việc này :disappointed_relieved:

12. Further improvement

  • Thử stack thay vì blending
  • Nếu có thể hãy train full size ảnh
  • Thử sức với những model khác

13. Lesson learn.

Việc mình tụt hạng ở private có thể do hai nguyên nhân:

  • Overfit tập train
  • Distribution của private test khác. Cái này chắc chỉ có Zalo mới biết :smiley: . Bọn mình k xử lý vấn đề unblanced data (vì dùng sampling của pytorch quá lâu). Trong tập private test có nhiều ảnh của những label ít data trong tập training sẽ dẫn đến shake-up ở đây.

14. Others:

  • Bọn mình có 3GPU
    • Titan X, TitanXP (Thank rich’s teammate anh Toàn Bùi)
    • P100
  • Thời gian train một model trung bình là 15h.

Cám ơn các bạn đã đọc hết bài viết này. Hi vọng những chia sẻ trên giúp ích cho mọi người :smiley:


[Chia sẻ] Bài toán Landmark Identification từ cuộc thi Zalo AI Challenge
#2

Bài chia sẻ rất tâm huyết. Cám ơn bạn rất nhiều.


#3

Rất mong có được nhiều bài chia sẻ tâm huyết và chi tiết như này nữa. Cảm ơn tác giả


#4

Mình rất muốn tham gia cuộc thi này nhưng khổ nỗi không kiếm được team để trao đổi, 2 nữa là không có GPU để chạy. Nhưng cũng rất cám ơn về kinh nghiệm cũng như những phân tích quý giá của bạn :D. Rất mong chờ được tiếp tục đọc những bài viết tâm huyết và kinh nghiệm phân tích quý báu của bạn cho các challenge khác nữa.


#5

@ngxbac

E chào anh.

E có một chút thắc mắc khi chạy lại phần code của anh. Trong file jupyter make_submit phần anh dùng ensemble để combine các kết quả lại với nhau. Theo em hiểu là anh có 4 model đã train, sau đó predict trên tập test ra result xác suất. Dùng softmax để chuẩn hóa xác suất. R sau đó là dùng gmean để chọn ra giá trị phù hợp. Chỉ có điều khi em run và print cái shape của xác suất thì hk hiểu lắm

VD:

In:  test_pred1['px'].shape
Out: torch.Size([14356, 103, 12])

Em hiểu 14356 là số lượng tập test, 103 là số lượng classes, nhưng còn 12 là gì vậy anh? Em không hiểu phần này, hi vọng a có thể giải đáp. Em cám ơn ạ.


#6

Chào bạn,

12 ở đây là kết quả predict của 12TTA mà mình đã nêu ở phần 7 bạn nhé. Mỗi model sẽ predict 12 lần tập testset. Mỗi một lần như vậy được gọi là một test time augment.


#7

Hi Bắc,

Cám ơn bạn đã chia sẻ solution, cách bạn làm EDA và dùng MD5 để phát hiện các ảnh nhiễu trong bộ train rất ấn tượng!!


#8

Em đã hiểu rồi. Cám ơn anh đã giải thích :smiley:


#9

Em cám ơn anh :smiley:.

Em cần phải học từ team anh nhiều. Lần sau có compet anh nhớ tham gia nhé. :party_parrot:


#10

lần nào mình cũng tham gia mà, chỉ có điều là không được dzo top thôi :smiley:


#11

Hơi tiếc là mình biết cuộc thi này quá muộn. Mình dùng resnet_152 train mất hơn 1 ngày mà cũng chỉ đc error~0.63, sao ở LeaderBoard có đồng chí error<1% được nhỉ???


#12

Đoạn này mình không hiểu lắm, bạn nào giải thích rõ hơn giúp mình được không? Xin cảm ơn