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

classification
deep-learning
computer-vision

#1

Chào mọi người,

Mình có tham gia cuộc thi của Zalo và đang được top-1 bên Final Leaderboard của bài toán Landmark Identification. Mình muốn chia sẻ code và một vài ý tưởng mình đã áp dụng.

Mình có mượn code về model và data preprocessing từ Slim package của Tensorflow: https://github.com/tensorf…/models/tree/master/research/slim

Về bài toán thì anh Tiep VuHuu và một vài bạn cũng đã trao đổi thời gian vừa rồi nên mình ko muốn nói lại nữa. Trên diễn đàn cũng đã có bài chia sẻ của anh @ngxbac khá chất lượng, các bạn có thể tham khảo thêm tại đây.

1. Approach:

  • Cách tiếp cận mà chắc bạn nào cũng nghĩ đến là dựa vào các architectures và pre-trained models đã đạt kết quả tốt từ ImageNet. Sau một hồi loay hoay thì mình rút ra: Inception-ResNet > ResNet-152 > Inception-V4 > …
  • Mình nghĩ là càng về cuối khi cuộc thi sắp kết thúc thì mọi người cũng nhận ra được architecture nào tốt để dùng. Phần này chắc là ai cũng giống nhau.

2. Imbalanced Data:

  • Weighted loss: class nào ít hơn thì penalize nhiều hơn. Cái này mình có implement một vài cách tính weights (linear, log, …) dựa vào tỉ lệ giữa các lớp với nhau để cân đối.
  • Data upsampling: phần này cẩn thận một chút vì dễ bị overfit các lớp có số lượng data ít. Mình ko upsample dựa trực tiếp vào tỷ lệ giữa các lớp mà: lấy log -> sau đấy cutoff threshold = 2 -> rồi lúc đấy mới upsample dựa vào tỷ lệ đấy. Idea là mình thấy khá nhiều lớp ko cần phải thêm data nữa, chỉ một vài lớp rất ít mới cần thêm, và thêm cũng vừa phải vì sợ bị overfit như đã nói ở trên. Mình nhớ ko nhầm thì lớp ít data nhất cũng chỉ tăng thêm 4 lần và số lượng data tăng thêm < 10% so với data gốc. Phần này hơi heuristic, mình cảm thấy hợp lý thì làm thôi chứ cũng ko theo sách vở tài liệu nào cả.
  • Mình ko downsample data vì thấy data cũng ko thực sự lớn lắm.

3. Data Augmentation:

  • Từ Slim package đã có phần preprocessing khá ổn: color distortion, aspect distortion, random cropping, horizontal flipping, …
  • Mình có thêm vào một phần: random rotation (-20 -> 20 degrees) -> central crop 95% để bỏ bớt đi phần viền đen sau khi rotate. Mình ko muốn có thêm feature bất đắc dĩ từ các vùng đen đấy.
  • Có một điều là ảnh sau khi xử lý xong thì về size 299x299 chứ ko phải 224x224. Điều này làm model lớn hơn một chút, có thể capture được nhiều thông tin hơn nhưng trade-off là train lâu hơn.

4. Final Models:

  • Lúc đầu mình có split data theo tỷ lệ 92% training, 8% validation. Sau khi train một vài models thì mình giữ lại 2 Inception-ResNet và 1 ResNet-152 models perform khá tốt.
  • Cuối cùng thì quyết định chia data thành 10 folds rồi train theo kiểu cross-validation. Sau đấy thì gộp toàn bộ models lại với nhau.

Chừng đấy là một vài thứ mà mình muốn chia sẻ, mình cũng ko có quá nhiều tricks. Về phần training hay prediction thế nào thì các bạn có thể xem thêm ở repo github nhé. Ngoài 2 architectures mà mình đã sử dụng thì trong code đã có sẵn các architectures khác như: ResNet-50/101/200, Inception-V4, DenseNet-161, NASNet, PNASNet mà pre-trained models có thể dễ dàng tải về từ Slim package. Các bạn có thể tùy thuộc vào cấu hình phần cứng của mình để sử dụng nhé.

Cheers!


#3

1.

  • Mình train các models độc lập với nhau bạn nhé. Ban đầu mình chia training-validation theo tỉ lệ 92%-8%, sau đấy thì train models từ tập training và đánh giá độ chính xác của models qua tập validation. Mình lưu lại tham số của models khi đạt độ chính xác tốt nhất trên tập validation.
  • Mình dựa vào kết quả của các models trên tập validation để xem models nào tốt hơn.

2.

  • Ảnh mình giữ nguyên 3 channels RGB chứ ko chuyển thành gray bạn nhé. Bộ mnist là do bản chất ảnh gray nên chỉ có 1 channel. Nếu ảnh có đầy đủ cả 3 channels RGB thì mình nên giữ chứ không nên chuyển thành gray vì sẽ làm mất thông tin.
  • Đúng là output của mỗi ảnh sẽ dạng [1,103], nếu output đã qua softmax thì mỗi giá trị sẽ là dự đoán của model về xác suất ảnh đấy thuộc về lớp tương ứng.