Kỹ thuật Jedi để giảm mạng tích chập - cắt tỉa

Kỹ thuật Jedi để giảm mạng tích chập - cắt tỉa

Trước mắt bạn một lần nữa là nhiệm vụ phát hiện đồ vật. Ưu tiên là tốc độ hoạt động với độ chính xác chấp nhận được. Bạn lấy kiến ​​trúc YOLOv3 và đào tạo thêm về nó. Độ chính xác (mAp75) lớn hơn 0.95. Nhưng tốc độ chạy vẫn còn thấp. Tệ thật.

Hôm nay chúng ta sẽ bỏ qua lượng tử hóa. Và dưới vết cắt chúng ta sẽ xem xét Cắt tỉa mô hình — cắt bớt các phần dư thừa của mạng để tăng tốc độ suy luận mà không làm giảm độ chính xác. Rõ ràng là cắt ở đâu, bao nhiêu và như thế nào. Hãy tìm hiểu cách thực hiện việc này một cách thủ công và nơi bạn có thể tự động hóa nó. Cuối cùng có một kho lưu trữ trên máy ảnh.

Giới thiệu

Tại nơi làm việc trước đây của tôi, Macroscop ở Perm, tôi có một thói quen - luôn theo dõi thời gian thực hiện các thuật toán. Và luôn kiểm tra thời gian chạy mạng thông qua bộ lọc đầy đủ. Thông thường, công nghệ tiên tiến nhất trong sản xuất không vượt qua được bộ lọc này, điều này đã dẫn tôi đến việc Cắt tỉa.

Cắt tỉa là một chủ đề cũ đã được thảo luận trong bài giảng Stanford vào năm 2017. Ý tưởng chính là giảm kích thước của mạng được đào tạo mà không làm mất độ chính xác bằng cách loại bỏ các nút khác nhau. Nghe có vẻ hay nhưng tôi hiếm khi nghe về công dụng của nó. Có thể là chưa có đủ triển khai, không có bài viết bằng tiếng Nga, hoặc đơn giản là mọi người cho rằng đó là sự cắt xén bí quyết và giữ im lặng.
Nhưng hãy tách nó ra

Một cái nhìn thoáng qua về sinh học

Tôi thích thú khi Deep Learning xem xét các ý tưởng đến từ sinh học. Chúng, giống như sự tiến hóa, có thể được tin cậy (bạn có biết rằng ReLU rất giống với chức năng kích hoạt tế bào thần kinh trong não?)

Quá trình Cắt tỉa mô hình cũng gần gũi với sinh học. Phản ứng của mạng ở đây có thể được so sánh với tính linh hoạt của não. Có một vài ví dụ thú vị trong cuốn sách. Norman Doidge:

  1. Bộ não của người phụ nữ sinh ra chỉ có một nửa đã được lập trình lại để thực hiện các chức năng của nửa còn thiếu.
  2. Anh chàng đã bắn mất phần não chịu trách nhiệm về thị giác. Theo thời gian, các phần khác của não đảm nhận các chức năng này. (chúng tôi không cố gắng lặp lại)

Tương tự như vậy, bạn có thể loại bỏ một số phần chập yếu khỏi mô hình của mình. Biện pháp cuối cùng, những bó còn lại sẽ giúp thay thế những bó đã cắt.

Bạn yêu thích Học chuyển tiếp hay bạn đang học từ đầu?

Tùy chọn số một. Bạn sử dụng Transfer Learning trên Yolov3. Retina, Mask-RCNN hoặc U-Net. Nhưng hầu hết chúng ta không cần nhận dạng 80 lớp đối tượng như trong COCO. Trong thực tế của tôi, mọi thứ chỉ giới hạn ở lớp 1-2. Người ta có thể cho rằng kiến ​​trúc của 80 lớp ở đây là dư thừa. Điều này cho thấy rằng kiến ​​trúc cần phải được làm nhỏ hơn. Hơn nữa, tôi muốn làm điều này mà không làm mất đi số tạ đã được tập luyện trước đó.

Tùy chọn số hai. Có thể bạn có nhiều dữ liệu và tài nguyên máy tính hoặc chỉ cần một kiến ​​trúc siêu tùy chỉnh. Không quan trọng. Nhưng bạn đang học mạng từ đầu. Quy trình thông thường là xem xét cấu trúc dữ liệu, chọn một kiến ​​trúc có sức mạnh vượt trội và loại bỏ những người bỏ đào tạo lại. Tôi thấy có 0.6 học sinh bỏ học, Karl.

Trong cả hai trường hợp, mạng có thể bị giảm. Có động lực. Bây giờ chúng ta cùng tìm hiểu cắt tỉa bao quy đầu là gì nhé

Thuật toán chung

Chúng tôi quyết định rằng chúng tôi có thể loại bỏ các gói. Nó trông khá đơn giản:

Kỹ thuật Jedi để giảm mạng tích chập - cắt tỉa

Việc loại bỏ bất kỳ sự tích chập nào đều gây căng thẳng cho mạng, điều này thường dẫn đến một số lỗi gia tăng. Một mặt, sự gia tăng sai số này là một dấu hiệu cho thấy chúng tôi loại bỏ các cuộn xoắn một cách chính xác như thế nào (ví dụ: mức tăng lớn cho thấy rằng chúng tôi đang làm sai điều gì đó). Nhưng mức tăng nhỏ là khá chấp nhận được và thường bị loại bỏ bằng cách tập luyện bổ sung nhẹ sau đó với LR nhỏ. Thêm một bước đào tạo bổ sung:

Kỹ thuật Jedi để giảm mạng tích chập - cắt tỉa

Bây giờ chúng ta cần tìm hiểu xem khi nào chúng ta muốn dừng vòng lặp Học<->Pruning. Có thể có những lựa chọn kỳ lạ ở đây khi chúng ta cần giảm mạng xuống một kích thước và tốc độ nhất định (ví dụ: đối với thiết bị di động). Tuy nhiên, lựa chọn phổ biến nhất là tiếp tục chu kỳ cho đến khi sai số trở nên cao hơn mức chấp nhận được. Thêm một điều kiện:

Kỹ thuật Jedi để giảm mạng tích chập - cắt tỉa

Vì vậy, thuật toán trở nên rõ ràng. Vẫn còn phải tìm ra cách xác định các kết cấu đã bị xóa.

Tìm kiếm các gói đã xóa

Chúng ta cần loại bỏ một số phức tạp. Lao về phía trước và “bắn” bất kỳ ai là một ý tưởng tồi, mặc dù nó sẽ có tác dụng. Nhưng vì bạn có đầu, bạn có thể suy nghĩ và cố gắng chọn các cấu trúc chập “yếu” để loại bỏ. Có một số lựa chọn:

  1. Thước đo L1 nhỏ nhất hoặc low_magnitude_pruning. Ý tưởng cho rằng các phép cuộn có trọng số nhỏ ít đóng góp vào quyết định cuối cùng
  2. Thước đo L1 nhỏ nhất có tính đến giá trị trung bình và độ lệch chuẩn. Chúng tôi bổ sung bằng đánh giá về bản chất của sự phân phối.
  3. Che giấu các kết cấu và loại trừ những kết cấu ít ảnh hưởng nhất đến độ chính xác cuối cùng. Xác định chính xác hơn các cuộn xoắn không đáng kể, nhưng rất tốn thời gian và tốn tài nguyên.
  4. Những người khác

Mỗi tùy chọn đều có quyền tồn tại và các tính năng triển khai riêng. Ở đây chúng ta xem xét phương án có độ đo L1 nhỏ nhất

Quy trình thủ công cho YOLOv3

Kiến trúc ban đầu chứa các khối còn lại. Nhưng cho dù chúng có tuyệt vời đến đâu đối với mạng sâu thì chúng cũng sẽ cản trở chúng ta phần nào. Khó khăn là bạn không thể xóa các bản đối chiếu có chỉ mục khác nhau trong các lớp này:

Kỹ thuật Jedi để giảm mạng tích chập - cắt tỉa

Do đó, hãy chọn các lớp mà chúng ta có thể tự do xóa các bản đối chiếu:

Kỹ thuật Jedi để giảm mạng tích chập - cắt tỉa

Bây giờ hãy xây dựng một chu trình làm việc:

  1. Đang tải lên kích hoạt
  2. Tính xem cần cắt bao nhiêu
  3. Cắt nó ra
  4. Học 10 kỷ nguyên với LR=1e-4
  5. Kiểm tra

Việc dỡ bỏ các cuộn xoắn rất hữu ích để ước tính xem chúng ta có thể loại bỏ bao nhiêu phần ở một bước nhất định. Ví dụ dỡ tải:

Kỹ thuật Jedi để giảm mạng tích chập - cắt tỉa

Chúng tôi thấy rằng hầu hết mọi nơi đều có 5% tích chập có chỉ tiêu L1 rất thấp và chúng tôi có thể loại bỏ chúng. Ở mỗi bước, việc dỡ tải này được lặp lại và việc đánh giá được thực hiện về lớp nào và số lượng có thể được cắt ra.

Toàn bộ quá trình được hoàn thành theo 4 bước (các con số ở đây và ở mọi nơi đối với RTX 2060 Super):

Bươc map75 Số lượng tham số, triệu Kích thước mạng, mb Từ ban đầu, % Thời gian chạy, ms Tình trạng cắt bao quy đầu
0 0.9656 60 241 100 180 -
1 0.9622 55 218 91 175 5% tổng số
2 0.9625 50 197 83 168 5% tổng số
3 0.9633 39 155 64 155 15% cho các lớp có hơn 400 cuộn xoắn
4 0.9555 31 124 51 146 10% cho các lớp có hơn 100 cuộn xoắn

Một tác động tích cực đã được thêm vào bước 2 - kích thước lô 4 phù hợp với bộ nhớ, giúp đẩy nhanh đáng kể quá trình đào tạo bổ sung.
Ở bước 4, quá trình này bị dừng vì ngay cả việc đào tạo bổ sung dài hạn cũng không nâng được mAp75 lên giá trị cũ.
Kết quả là chúng tôi đã cố gắng tăng tốc độ suy luận bằng cách 15%, giảm kích thước xuống 35% và không bị mất chính xác.

Tự động hóa cho các kiến ​​trúc đơn giản hơn

Đối với các kiến ​​trúc mạng đơn giản hơn (không có các khối cộng, nối và khối dư có điều kiện), hoàn toàn có thể tập trung vào việc xử lý tất cả các lớp tích chập và tự động hóa quá trình cắt bỏ các phần tích chập.

Tôi đã triển khai tùy chọn này đây.
Thật đơn giản: bạn chỉ cần một hàm mất mát, một trình tối ưu hóa và các trình tạo hàng loạt:

import pruning
from keras.optimizers import Adam
from keras.utils import Sequence

train_batch_generator = BatchGenerator...
score_batch_generator = BatchGenerator...

opt = Adam(lr=1e-4)
pruner = pruning.Pruner("config.json", "categorical_crossentropy", opt)

pruner.prune(train_batch, valid_batch)

Nếu cần, bạn có thể thay đổi các thông số cấu hình:

{
    "input_model_path": "model.h5",
    "output_model_path": "model_pruned.h5",
    "finetuning_epochs": 10, # the number of epochs for train between pruning steps
    "stop_loss": 0.1, # loss for stopping process
    "pruning_percent_step": 0.05, # part of convs for delete on every pruning step
    "pruning_standart_deviation_part": 0.2 # shift for limit pruning part
}

Ngoài ra, giới hạn dựa trên độ lệch chuẩn được thực hiện. Mục đích là để hạn chế phần bị loại bỏ, ngoại trừ các phần tích chập với số đo L1 đã “đủ”:

Kỹ thuật Jedi để giảm mạng tích chập - cắt tỉa

Do đó, chúng tôi cho phép bạn chỉ xóa các tích chập yếu khỏi các phân phối tương tự như phân phối bên phải và không ảnh hưởng đến việc xóa khỏi các phân phối tương tự như phân phối bên trái:

Kỹ thuật Jedi để giảm mạng tích chập - cắt tỉa

Khi phân phối tiến đến mức bình thường, hệ số pruning_standart_deviation_part có thể được chọn từ:

Kỹ thuật Jedi để giảm mạng tích chập - cắt tỉa
Tôi khuyên bạn nên giả định 2 sigma. Hoặc bạn có thể bỏ qua tính năng này, để lại giá trị < 1.0.

Đầu ra là biểu đồ về kích thước mạng, mức mất mát và thời gian chạy mạng cho toàn bộ quá trình kiểm tra, được chuẩn hóa thành 1.0. Ví dụ: ở đây kích thước mạng đã giảm gần 2 lần mà không giảm chất lượng (mạng tích chập nhỏ có trọng số 100k):

Kỹ thuật Jedi để giảm mạng tích chập - cắt tỉa

Tốc độ chạy có thể dao động bình thường và hầu như không thay đổi. Có một lời giải thích cho việc này:

  1. Số lượng tích chập thay đổi từ thuận tiện (32, 64, 128) sang không thuận tiện nhất cho card màn hình - 27, 51, v.v. Tôi có thể sai ở đây, nhưng rất có thể nó có ảnh hưởng.
  2. Kiến trúc không rộng nhưng nhất quán. Bằng cách giảm chiều rộng, chúng tôi không ảnh hưởng đến chiều sâu. Như vậy, chúng ta giảm tải nhưng không thay đổi tốc độ.

Do đó, sự cải thiện được thể hiện ở việc giảm 20-30% tải CUDA trong quá trình chạy, nhưng không giảm thời gian chạy.

Kết quả

Chúng ta hãy suy ngẫm. Chúng tôi đã xem xét 2 tùy chọn để cắt tỉa - dành cho YOLOv3 (khi bạn phải làm việc bằng tay) và dành cho các mạng có kiến ​​​​trúc đơn giản hơn. Có thể thấy rằng trong cả hai trường hợp đều có thể đạt được việc giảm và tăng tốc kích thước mạng mà không làm giảm độ chính xác. Kết quả:

  • giảm kích thước
  • Chạy tăng tốc
  • Giảm tải CUDA
  • Kết quả là sự thân thiện với môi trường (Chúng tôi tối ưu hóa việc sử dụng tài nguyên máy tính trong tương lai. Ở đâu đó người ta hạnh phúc Greta Thunberg)

Phụ lục

  • Sau bước cắt tỉa, bạn có thể thêm lượng tử hóa (ví dụ: với TensorRT)
  • Tensorflow cung cấp khả năng cho low_magnitude_cắt tỉa. Làm.
  • kho Tôi muốn phát triển và sẽ sẵn lòng giúp đỡ

Nguồn: www.habr.com

Thêm một lời nhận xét