Làm thế nào để tính toán tác động bộ nhớ mini-batch khi đào tạo mô hình học sâu?


17

Tôi đang cố gắng tính toán dung lượng bộ nhớ cần thiết cho GPU để đào tạo mô hình của mình dựa trên ghi chú này từ Andrej Karphaty: http://cs231n.github.io/convolutional-networks/#computational-considerations

Mạng của tôi có 535.752 kích hoạt19.072.984 tham số (trọng số và độ lệch). Đây là tất cả các giá trị float 32 bit, vì vậy mỗi giá trị chiếm 4 byte trong bộ nhớ.

Hình ảnh đầu vào của tôi là 180x50x1 (chiều rộng x chiều cao x chiều sâu) = 9.000 giá trị float 32. Tôi không sử dụng tính năng tăng cường hình ảnh, vì vậy tôi nghĩ rằng bộ nhớ linh tinh sẽ chỉ liên quan đến kích thước lô nhỏ. Tôi đang sử dụng kích thước lô nhỏ gồm 128 hình ảnh.

Dựa trên khuyến nghị của Andrej, tôi có các kích thước bộ nhớ sau:

Kích hoạt: 532,752 * 4 / (1024 ^ 2) = 2,03 MB

Thông số: 19,072,984 * 4 / (1024 ^ 2) * 3 = 218,27 MB

Linh tinh: 128 * 9.000 * 4 / (1024 ^ 2) = 4,39 MB

Vì vậy, tổng bộ nhớ để đào tạo mạng này sẽ là 224,69 MB .

Tôi đang sử dụng TensorFlow và tôi nghĩ rằng tôi đang thiếu một cái gì đó. Tôi chưa chạy khóa đào tạo, nhưng tôi khá chắc chắn (dựa trên kinh nghiệm trong quá khứ) rằng bộ nhớ đang sử dụng sẽ cao hơn nhiều so với những gì tôi đã tính toán.

Nếu với mỗi hình ảnh trong lô nhỏ, TensorFlow giữ độ dốc của chúng để nó có thể bình thường hóa chúng sau này cho một bước cập nhật trọng số / độ lệch duy nhất, thì tôi nghĩ rằng bộ nhớ nên tính đến một giá trị khác là 535.752 * 128 (độ dốc cho mỗi hình ảnh trong lô nhỏ). Nếu đó là trường hợp, thì tôi cần thêm 260,13 MB để đào tạo mô hình này với 128 hình ảnh / lô nhỏ.

Bạn có thể giúp tôi hiểu các cân nhắc về trí nhớ để đào tạo mô hình học tập sâu của tôi? Những cân nhắc trên có đúng không?


Xin vui lòng xem câu trả lời (đề xuất) của tôi cho câu hỏi của bạn ở đây .
Adam Hendry

Câu trả lời:


5

Tôi nghĩ rằng bạn đang đi đúng hướng.

Có, bạn sẽ cần lưu trữ các dẫn xuất của kích hoạt và của các tham số để truyền bá.

Ngoài ra, sự lựa chọn tối ưu hóa của bạn có thể quan trọng. Bạn đang đào tạo bằng cách sử dụng SGD, hoặc Adam, hoặc Adagrad? Tất cả sẽ có yêu cầu bộ nhớ khác nhau. Ví dụ: bạn sẽ phải lưu trữ bộ đệm kích thước bước cho phương thức dựa trên động lượng, mặc dù đó chỉ là thứ yếu so với các cân nhắc bộ nhớ khác mà bạn đề cập.

Vì vậy, tất cả trong tất cả, bạn dường như đã tính toán các yêu cầu bộ nhớ cho một lần chuyển tiếp. Andrej Karpathy đề cập rằng đường chuyền ngược có thể chiếm tới 3 lần bộ nhớ của đường chuyền về phía trước, vì vậy đây có thể là lý do khiến bạn thấy sự khác biệt như vậy (cuộn xuống 'Nghiên cứu trường hợp' trên trang web để xem ví dụ về VGGNet).


4

@StatsSorceress TL; DR:

Tôi đang trải qua hoạt động này để xem liệu tôi có thể tự tính toán bộ nhớ cần thiết không:

Kích hoạt: 532,752 * 2 * 4 / (1024 ^ 2) = 4,06 MB

Thông số: 19,072,984 * 4 / (1024 ^ 2) * 3 = 218,27 MB

Linh tinh: 128 * 9.000 * 4 / (1024 ^ 2) = 4,39 MB

Tổng bộ nhớ: (4.06 * 128 ) + 218,27 + 4,39 = 742,34 MB

( Ai đó làm ơn sửa tôi về điều này nếu tôi sai. FYI, bạn đã nhân số linh tinh lên 128, vì vậy đó là lý do tại sao tôi không nhân nó với 128 ở trên )


Tôi sẽ chỉ cho bạn bài viết nàyvideo tương ứng . Họ đã giúp tôi hiểu những gì đang diễn ra tốt hơn rất nhiều.

LƯU Ý: Bộ nhớ cần thiết để sử dụng mạng để dự đoán ít hơn nhiều so với yêu cầu đào tạo vì hai lý do:

  • Khi dự đoán, chúng tôi chỉ gửi một hình ảnh chuyển tiếp qua mạng chứ không gửi ngược (vì vậy chúng tôi không nhân bộ nhớ X 3; xem bên dưới)
  • Có một dự đoán cho mỗi hình ảnh (vì vậy chúng tôi không cần nhân bộ nhớ cần thiết cho một hình ảnh với kích thước lô vì chúng tôi không sử dụng các lô trong dự đoán).

Quá trình (Bộ nhớ để đào tạo)

  1. Tính toán bộ nhớ cần thiết để đào tạo trên một hình ảnh
  2. Nhân số này với số lượng hình ảnh trong lô của bạn

( NHỚ: Mini-trạm trộn nói chúng ta hãy tập hợp con của dữ liệu của chúng tôi, tính toán gradient và các lỗi cho mỗi hình ảnh trong bộ trang bị, sau đó trung bình này và bước về phía trước theo hướng tỷ lệ trung bình Đối với convnets, trọng lượng và những thành kiến được chia sẻ, nhưng. số lượng kích hoạt được nhân đôi theo số lượng hình ảnh trong lô. ).

BƯỚC 1: Bộ nhớ cho 1 Hình ảnh

Để đào tạo một hình ảnh, bạn phải dành bộ nhớ cho:

  • Thông số mẫu:

    Các trọng số và độ lệch ở mỗi lớp, độ dốc và các biến động lượng của chúng (nếu Adam, Adagrad, RMSProp, v.v., tối ưu hóa được sử dụng)

    Để tính gần đúng bộ nhớ cho việc này, hãy tính toán bộ nhớ cần thiết để lưu trữ trọng số và độ lệch và nhân số đó với 3 (tức là "bằng 3" bởi vì chúng tôi nói rằng lượng bộ nhớ cần thiết để lưu trữ trọng số và độ lệch là (khoảng) bằng cần thiết cho độ dốc và cho các biến động lượng)

    THIẾT BỊ:

    Kết luận:

    trọng số (n) = độ sâu (n) * (kernel_creen * kernel_height) * độ sâu (n-1)

    sai lệch (n) = độ sâu (n)

    Các lớp được kết nối đầy đủ (dày đặc):

    trọng số (n) = đầu ra (n) * đầu vào (n)

    sai lệch (n) = đầu ra (n)

Trong đó n là lớp hiện tại và n-1 là lớp trước và đầu ra là số lượng đầu ra từ lớp FC và đầu vào là số lượng đầu vào của lớp FC (nếu lớp trước không phải là lớp được kết nối đầy đủ, số lượng đầu vào bằng với kích thước của lớp đó được làm phẳng).

GHI CHÚ: Chỉ riêng bộ nhớ cho các trọng số và độ lệch, cộng với bộ nhớ cho các kích hoạt cho một hình ảnh (xem bên dưới), là tổng dung lượng bộ nhớ bạn cần để dự đoán (không bao gồm một số chi phí cho bộ nhớ để kết hợp và một số thứ khác).

  • Kích hoạt (đây là "Blobs" trong Caffe):

(Tôi đang sử dụng thuật ngữ một cách lỏng lẻo ở đây, chịu đựng với tôi)

Mỗi tích chập trong một lớp chập tạo ra kích hoạt " số pixel trong ảnh " (nghĩa là bạn chuyển một hình ảnh qua một tích chập duy nhất, bạn nhận được một bản đồ tính năng duy nhất bao gồm các kích hoạt " m ", trong đó " m " là số pixel từ hình ảnh / đầu vào).

Đối với các lớp được kết nối đầy đủ, số lượng kích hoạt bạn tạo ra bằng với kích thước đầu ra của bạn.

Kết luận:

kích hoạt (n) = image_creen * image_height * image_num_channels

Các lớp được kết nối đầy đủ (dày đặc):

kích hoạt (n) = đầu ra (n)

Lưu ý rằng đầu vào của bạn thực sự chỉ là một hình ảnh ở đầu mạng. Sau khi kết luận, nó biến thành một thứ khác (bản đồ đặc trưng). Vì vậy, thực sự thay thế "image_creen", "image_height" và "image_num_channels" bằng "input_creen", "input_height" và "layer_depth" để chính xác hơn. (Nó chỉ dễ dàng hơn đối với tôi khi nghĩ về khái niệm này về mặt hình ảnh.)

Vì chúng tôi cũng cần lưu trữ lỗi cho các kích hoạt ở mỗi lớp (được sử dụng trong đường chuyền ngược), chúng tôi nhân số lần kích hoạt lên 2 để có tổng số thực thể chúng tôi cần để dành chỗ trong không gian lưu trữ. Số lượng kích hoạt tăng theo số lượng hình ảnh trong lô, vì vậy bạn nhân số này với kích thước lô.

BƯỚC 2: Bộ nhớ để đào tạo hàng loạt

Tổng số lượng trọng lượng và độ lệch (lần 3) và số lần kích hoạt (gấp 2 lần kích thước lô). Nhân số này với 4 và bạn nhận được số byte cần thiết để huấn luyện lô. Bạn có thể chia cho 1024 ^ 2 để có câu trả lời bằng GB.


Tại sao bạn nói "chúng tôi không sử dụng các đợt trong dự đoán"? Nếu người dùng cần đưa ra dự đoán về số lượng lớn hình ảnh, thì việc sử dụng các lô trong dự đoán có thể có ý nghĩa.
dùng3731622

1

Ngoài ra, tôi nghĩ rằng bạn có thể sử dụng bất kỳ thư viện hồ sơ nào để phân tích bộ nhớ và mức sử dụng CPU theo chương trình của bạn. Có nhiều thư viện python có thể cung cấp cho bạn ảnh chụp nhanh về việc sử dụng bộ nhớ và CPU theo luồng hoặc quy trình cụ thể ở khoảng thời gian mili giây.

Bạn có thể chạy một phần chương trình bạn muốn theo dõi trong một quy trình phụ khác bằng cách sử dụng popen và theo dõi việc sử dụng bộ nhớ và CPU của nó bằng cách sử dụng PID.

psutil tôi thấy tốt cho công việc như vậy. Mặc dù có nhiều người khác.

Hy vọng điều này có thể giúp cho bạn.


3
Cảm ơn câu trả lời, @Anwar. Tôi đang tìm kiếm một tính toán phân tích hơn là một quan sát thực nghiệm.
barbolo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.