Cấu trúc thư mục hiện tại mình đang có:
data_sample/
im1.png
im1.json
splitting_datatset_txt/
test.txt
train.txt
val.txt
scripts/
xxxs.py
Trong đó data_sample sẽ chứa hình ảnh và annotation ở dưới dạng json.
File:
test.txt: 220 records
train.txt: 905 records
val.txt: 109 records
Sum: 1234 records
Folder data_original:
2484 records: images + json annotations => 1242 records
Redundant: 1242 - 1234 = 8 images
- Tìm mối liên hệ giữa hình ảnh và json format. Sau đó tạo ground truth từ chúng xem sao !!! Gợi ý sử dụng file từ scripts á.
Kết quả đạt được:
| Original | Sample | Mask (Power lines) |
|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
-
Kiểm tra label tạo ra được có đúng chuẩn hay không ? Tức là đọc dữ liệu ra là được bao nhiêu, mình expect là 0, 1. Thực sự thì dữ liệu đọc ra được là RGB value với line: (255, 255, 255), non-line: (0, 0, 0). Và thông qua phương thức map từ màu sang class trong DataSet của docExtractor thì sẽ chuyển sang map dạng 0, 1.
-
Tách hình ảnh thành kiểu cấu trúc đơn giản hơn (có thể là tương tự như là đối với DocExtractor vậy, để ta có thể tái sử dụng lại được cái loaddata của nó)
Cấu trúc dữ liệu train của DocExtractor:
DataSet
test
train
seq1_xxxx_Labels.png
seq1_xxxx.png
val
seq16_xxxx_Labels.png
seq16_xxxx.png
Cấu trúc dữ liệu mới được tạo ra từ TTPLA dataset
TTPLA_PreprocesseData
test
04_1234_Labels.png
04_1234.jpg
train
04_3456_Labels.png
04_3456.jpg
val
04_789_Labels.png
04_789.jpg
- Kiểm tra số lượng hình ảnh tạo ra được, so khớp với số record ở trong mỗi file annotate về json
Test: 440 images -> 220 records
Train: 1810 images -> 905 records
Val: 218 images -> 109 records
Vậy là trong dữ liệu dư thừa ra 8 bản ghi không thuộc loại nào, bỏ qua mấy cái đó
- Xây dựng mô hình cho cái thuật toán PowerLine segmentation. Tìm kiếm model thực hiện tốt điều này. Mình sẽ chọn UNET++ (backbone Resnet-34)
- Xây dựng DataLoader cho segmentation task, kiểm tra chúng.
- Viết script train model.
- Sau khi đẩy dữ liệu full lên trên Drive, thì mình tính toán giá trị trung bình mean và std của toàn bộ dữ liệu trên đó thử: Kết quả sẽ được note ở đây:
Kết quả:
- Mean: tensor([0.4616, 0.4506, 0.4154])
- Std: tensor([0.2368, 0.2339, 0.2415])
Tuy nhiên, ta cũng nên thử mean và std từ ImageNet, do ta tái sử dụng lại Resnet pretrained:
- Mean: [0.485, 0.456, 0.406]
- Std: [0.229, 0.224, 0.225]
-
Suy nghĩ cách customize hàm
save_checkpoint(self, val_loss, model)của thằngEarlyStoppingsao cho nó sử dụng tất cả các trường như thằngdocExtractorvậy: -
Sử dụng
earlystopingđể có thể save the best model
Ý tưởng của eary stopping:
- B1: Trước khi train model, khởi tạo
early_stopping = EarlyStopping()- B2: Tại mỗi check point mà
val_stat_intervalgây ra, tính toánvalidation loss, sau đó record nó vàoearly_stoppingbằng cáchearly_stopping(valid_loss, model)- B3: Ngay sau khi thực hiện bước 2, kiểm tra xem thử cái trạng thái của
early_stoppingnó như thế nàoif early_stopping.early_stop:, nếu nó báo cần kết thúc thì ta kết thúc và break vòng lặp train.
RESULT: tensor([820755889, 17900111])
WEIGHT (1./RESULT): tensor([1.2184e-09, 5.5866e-08])
-
Test thử việc truyền weight class vào trong
CrossEntropyLoss, kết quả có vẻ khả quan đấy !
-
Hiệu chỉnh code lần cuối cùng rồi đẩy code hoàn chỉnh lên trên đó, sau đó thực hiện train model với full-data
-
Thêm phần resume training
-
Thêm vào logging, cải thiện format logging sao cho nó dễ đọc nhất có thể (Gợi ý sử dụng kiểu log message của PyImage Search)
- Loging bao gồm 2 phần:
Terminal logvàFile log - Đối với
Terminal log, mình sẽ sử dụng trick để điều chỉnh log (Bằng cách thêm các chỉ màu đặc biệt vào trước mỗi log string) - Đối với
File log, mình sẽ sứ dụngloggingcủa python.
- Loging bao gồm 2 phần:
-
Thêm vào trường
data_distributionđể normalize dữ liệu -
Thêm vào
Tensorboard logs:- Xem xét được đường cong huấn luyện
train_lossvàvalidation_loss - Xem xét được performance của model tại điểm
validationbằng cách xem qua ảnh dự đoán của model trên tensorboard (Cái ý này có vẻ dễ thực hiện hơn ý đầu đấy)
- Xem xét được đường cong huấn luyện
-
Viết
tester.pyscript: script này chịu trách nhiệm test performance của model trên tập ảnh test sau khi hoàn tất quá trình train. -
Tái tổ chức lại cấu trúc file sao cho hợp lý nhất (Bao gồm cả cấu trúc code, import bla...)
- Vấn đề lúc
save_state_dict, mình muốn lưu thêm trườngval_loss_minđể lúc pretrain lại sử dụng nó để khởi tạo biến record bên trongEaryStopping.
- Vấn đề lúc
-
Viết thêm
.gitignoređể tránh trường hợp đẩy file có dung lượng lớn lên lên trên Github. -
Tìm hiểu thêm một tính năng nào đó hay ho hỗ trợ code từ github (Ví dụ: Bot, CodeCoverage, ... ) để cái thiện code. (Đã thực hiện với CodeCoverage,...)
-
Viết thêm
ArgumentParservàotrainer.pyscript
-
-
Thực hiện một số tính toán đơn giản dựa trên bộ dữ liệu để có thể có được cấu hình ok ban đầu cho file config:
Mình đã note sẵn trong file
first_try.yml -
Vấn đề khó ở đây đó là handle cái vụ về model này, ta thấy rất khó khăn để mô hình học đc, nguyên nhân là do việc không cân đối giữa các lớp với nhau. Đề xuất những hướng giải quyết:
- Sau khi train xong với
CrossEntropyLoss, sử dụngfine-tunebằngLovasLoss. - Sử dụng
FocalLossvớiclass weight,SoftDiceLoss, hoặc làJaccardLoss (IoU Loss)
- Sau khi train xong với
-
Sử dụng
Optimađể tìm được bộ tham số khởi tạo chuẩn khi huấn luyện mô hình. -
Thực hiện train trên Colab, chú ý những điều sau:
- Mỗi lần chạy lại train ta sẽ mất hết dữ liệu bên trong
train_metrics.tsvvàval_metrics.tsv. - Mình cần ghi lại giá trị val_loss nhỏ nhất trước đó đã lưu được tại best-save, thiết kế lại load check point và thêm việc truyền tham số vào khi khởi tạo EarlyStopping instance. (Ok, vấn đề đã được giải quyết !)
- Tiếp tục train trên colab !
- Vấn đề hiện tại với model của mình là train hoài mà nó không xuống được nữa, mặc dù nó đang làm khá tốt. Mình nên
cân nhắc việc
FineTunevới cáiREDUCELRONPLATEAUcủa Pytorch để tự động điều chỉnh giá trị learning rate khi mà thấy không ổn.
- Mỗi lần chạy lại train ta sẽ mất hết dữ liệu bên trong
-
Làm cho quá trình train trở nên
deterministic. (Cái này chắc chắn phải để cuối cùng, vì nó cần phải tìm hiểu thêm nhiều thứ lắm mới có thể làm được)
- Model được tải về máy và lưu ở thư mục
FirsModel_2
-
Chạy Testing ở trên
Colabđồng thời chạyCustom datasetcủa mình để xem nó thể hiện như thế nào. So sánh ở 2 tiêu chí: IoU ở tập test như thế nào -
Thể hiện của nó ở tập test và tập custom như thế nào, để so sánh ra bằng hình ảnh:
So sánh trên tập Custom Dataset
| FirstModel | FirstModel_2 |
|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
- Lên Drive tải bản Lần 3 này về, clone thành một bản để backup dữ liệu.
- Sau đó mới chuyển sang mục Lần 4.
- Chạy ở trên local này để đánh giá thử model Lần 3 này như thế nào (Ây da, cái này có vẻ không tốt cho lắm đâu, theo cảm quan của mình thấy được là như vậy, nhưng để chắc chắn hơn thì phải chạy qua toàn bộ ảnh test để coi metric đạt được là bao nhiêu cái đã)
- Test metric của lần 2
- Test metric của lần 3
Vậy là lần 2 tốt hơn lần 3 á !!
Sau khi sửa xong chỗ update bên trong code. Mình cần phải tải cái lần 3 về, lưu thành một bản copy nữa. Sau đó sửa 2 chỗ:
- Sửa trong file config trên Drive thành 17
- Ở local mình dùng thằng
test_torchload.pyđể sửa cáimilestonescủa thằng Scheduler lại thành con 17 luôn. - Bỏ lại lên trên Drive và tiếp tục train xem thử kết quả nó như thế nào
- Fail rồi, mô hình nó vẫn không chịu cập nhật learning rate khi train nữa ...
- Thử sử dụng
LovasLossđể tiếp tục train xem sao ! Nếu không được nữa thì phải chuyển sang hàm mục tiêu mới !!!









































