Học máy công nghiệp: 10 nguyên tắc thiết kế

Học máy công nghiệp: 10 nguyên tắc thiết kế

Ngày nay, các dịch vụ, ứng dụng mới và các chương trình quan trọng khác được tạo ra mỗi ngày giúp tạo ra những điều đáng kinh ngạc: từ phần mềm điều khiển tên lửa SpaceX đến tương tác với ấm đun nước ở phòng bên cạnh thông qua điện thoại thông minh.

Và, đôi khi, mọi lập trình viên mới làm quen, cho dù anh ta là một người khởi nghiệp đam mê hay một Full Stack hay Nhà khoa học dữ liệu bình thường, sớm hay muộn đều nhận ra rằng có những quy tắc nhất định để lập trình và tạo phần mềm giúp đơn giản hóa cuộc sống rất nhiều.

Trong bài viết này, tôi sẽ mô tả ngắn gọn 10 nguyên tắc về cách lập trình machine learning công nghiệp để có thể dễ dàng tích hợp vào ứng dụng/dịch vụ, dựa trên phương pháp Ứng dụng 12 yếu tố. được đề xuất bởi nhóm Heroku. Sáng kiến ​​của tôi là nâng cao nhận thức về kỹ thuật này, kỹ thuật này có thể giúp ích cho nhiều nhà phát triển và những người làm khoa học dữ liệu.

Bài viết này là phần mở đầu cho một loạt bài viết về Machine Learning công nghiệp. Trong đó, tôi sẽ nói thêm về cách thực sự tạo một mô hình và đưa nó vào sản xuất, tạo API cho nó, cũng như các ví dụ từ các khu vực và công ty khác nhau đã tích hợp ML trong hệ thống của họ.

Nguyên tắc 1: Một cơ sở mã

Một số lập trình viên ở giai đoạn đầu, vì lười tìm hiểu nó (hoặc vì lý do nào đó của riêng họ), đã quên Git. Họ hoặc hoàn toàn quên từ, nghĩa là họ ném các tập tin cho nhau trong ổ đĩa/chỉ ném văn bản/gửi bởi chim bồ câu hoặc họ không suy nghĩ kỹ về quy trình làm việc của mình và giao từng tập tin cho chi nhánh riêng của họ, sau đó đến bậc thầy.

Nguyên tắc này nêu rõ: có một cơ sở mã và nhiều triển khai.

Git có thể được sử dụng cả trong sản xuất và nghiên cứu và phát triển (R&D), trong đó nó không được sử dụng thường xuyên.

Ví dụ: trong giai đoạn R&D, bạn có thể để lại các cam kết với các phương pháp và mô hình xử lý dữ liệu khác nhau, để sau đó chọn ra phương pháp và mô hình tốt nhất và dễ dàng tiếp tục làm việc với nó.

Thứ hai, trong quá trình sản xuất, đây là một điều không thể thay thế - bạn sẽ cần phải liên tục xem mã của mình thay đổi như thế nào và biết mô hình nào tạo ra kết quả tốt nhất, mã nào cuối cùng hoạt động và điều gì đã xảy ra khiến mã ngừng hoạt động hoặc bắt đầu tạo ra kết quả không chính xác . Đó là những gì cam kết dành cho!

Bạn cũng có thể tạo một gói dự án của mình, đặt nó, chẳng hạn như trên Gemfury, sau đó chỉ cần nhập các chức năng từ gói đó cho các dự án khác, để không phải viết lại chúng 1000 lần mà còn nhiều hơn thế nữa sau này.

Nguyên tắc 2: Khai báo rõ ràng và tách biệt các phần phụ thuộc

Mỗi dự án có các thư viện khác nhau mà bạn nhập từ bên ngoài để áp dụng chúng ở đâu đó. Cho dù đó là thư viện Python hay thư viện của các ngôn ngữ khác cho nhiều mục đích khác nhau hoặc các công cụ hệ thống - nhiệm vụ của bạn là:

  • Khai báo rõ ràng các phần phụ thuộc, tức là một tệp sẽ chứa tất cả các thư viện, công cụ và phiên bản của chúng được sử dụng trong dự án của bạn và phải được cài đặt (ví dụ: trong Python, điều này có thể được thực hiện bằng cách sử dụng Pipfile hoặc require.txt. A liên kết cho phép hiểu rõ: realpython.com/pipenv-guide)
  • Cô lập các phần phụ thuộc cụ thể cho chương trình của bạn trong quá trình phát triển. Bạn không muốn liên tục thay đổi phiên bản và cài đặt lại, chẳng hạn như Tensorflow?

Bằng cách này, các nhà phát triển sẽ tham gia nhóm của bạn trong tương lai sẽ có thể nhanh chóng làm quen với các thư viện và phiên bản của họ được sử dụng trong dự án của bạn, đồng thời bạn cũng sẽ có cơ hội quản lý các phiên bản và thư viện được cài đặt cho một dự án cụ thể. dự án, điều này sẽ giúp bạn tránh được tình trạng không tương thích giữa các thư viện hoặc phiên bản của chúng.

Ứng dụng của bạn cũng không nên dựa vào các công cụ hệ thống có thể được cài đặt trên một hệ điều hành cụ thể. Những công cụ này cũng phải được khai báo trong bảng kê khai phụ thuộc. Điều này là cần thiết để tránh các tình huống trong đó phiên bản của các công cụ (cũng như tính khả dụng của chúng) không khớp với các công cụ hệ thống của một hệ điều hành cụ thể.

Vì vậy, ngay cả khi Curl có thể được sử dụng trên hầu hết các máy tính, bạn vẫn nên khai báo nó trong phần phụ thuộc, vì khi di chuyển sang nền tảng khác, nó có thể không có ở đó hoặc phiên bản sẽ không phải là phiên bản bạn cần ban đầu.

Ví dụ: require.txt của bạn có thể trông như thế này:

# Model Building Requirements
numpy>=1.18.1,<1.19.0
pandas>=0.25.3,<0.26.0
scikit-learn>=0.22.1,<0.23.0
joblib>=0.14.1,<0.15.0

# testing requirements
pytest>=5.3.2,<6.0.0

# packaging
setuptools>=41.4.0,<42.0.0
wheel>=0.33.6,<0.34.0

# fetching datasets
kaggle>=1.5.6,<1.6.0

Nguyên tắc 3: Cấu hình

Nhiều người đã nghe câu chuyện về nhiều nhà phát triển vô tình tải mã lên GitHub lên kho lưu trữ công khai có mật khẩu và các khóa khác từ AWS, sáng hôm sau thức dậy với khoản nợ 6000 USD, thậm chí 50000 USD.

Học máy công nghiệp: 10 nguyên tắc thiết kế

Tất nhiên, những trường hợp này là cực đoan, nhưng rất có ý nghĩa. Nếu bạn lưu trữ thông tin xác thực hoặc dữ liệu khác cần thiết cho việc định cấu hình bên trong mã thì bạn đang mắc lỗi và tôi nghĩ không cần phải giải thích tại sao.

Một giải pháp thay thế cho việc này là lưu trữ cấu hình trong các biến môi trường. Bạn có thể đọc thêm về các biến môi trường đây.

Ví dụ về dữ liệu thường được lưu trữ trong các biến môi trường:

  • Tên miền
  • URL API/URI
  • Khóa công khai và khóa riêng
  • Danh bạ (thư, điện thoại, v.v.)

Bằng cách này, bạn không phải thay đổi mã liên tục nếu các biến cấu hình của bạn thay đổi. Điều này sẽ giúp bạn tiết kiệm thời gian, công sức và tiền bạc.

Ví dụ: nếu bạn sử dụng API Kaggle để tiến hành kiểm tra (ví dụ: tải xuống phần mềm và chạy mô hình thông qua phần mềm đó để kiểm tra khi chạy mô hình đó có hoạt động tốt không), thì các khóa riêng tư từ Kaggle, chẳng hạn như KAGGLE_USERNAME và KAGGLE_KEY, phải là được lưu trữ trong các biến môi trường.

Nguyên tắc 4: Dịch vụ của bên thứ ba

Ý tưởng ở đây là tạo ra chương trình theo cách không có sự khác biệt giữa tài nguyên cục bộ và bên thứ ba về mặt mã. Ví dụ: bạn có thể kết nối cả MySQL cục bộ và bên thứ ba. Điều tương tự cũng xảy ra với các API khác nhau như Google Maps hoặc Twitter API.

Để vô hiệu hóa dịch vụ của bên thứ ba hoặc kết nối dịch vụ khác, bạn chỉ cần thay đổi các khóa trong cấu hình trong các biến môi trường mà tôi đã nói ở đoạn trên.

Vì vậy, ví dụ: thay vì chỉ định đường dẫn đến các tệp có tập dữ liệu bên trong mã mỗi lần, tốt hơn là bạn nên sử dụng thư viện pathlib và khai báo đường dẫn đến tập dữ liệu trong config.py, để cho dù bạn sử dụng dịch vụ nào (ví dụ: ví dụ: CircleCI), chương trình có thể tìm ra đường dẫn đến các tập dữ liệu có tính đến cấu trúc của hệ thống tệp mới trong dịch vụ mới.

Nguyên tắc 5. Xây dựng, phát hành, chạy

Nhiều người trong ngành Khoa học dữ liệu thấy việc cải thiện kỹ năng viết phần mềm của họ là rất hữu ích. Nếu chúng ta muốn chương trình của mình ít gặp sự cố nhất có thể và hoạt động mà không gặp lỗi trong thời gian dài nhất có thể, chúng ta cần chia quá trình phát hành phiên bản mới thành 3 giai đoạn:

  1. Sân khấu tổ hợp. Bạn chuyển đổi mã trần của mình với các tài nguyên riêng lẻ thành một gói được gọi là chứa tất cả mã và dữ liệu cần thiết. Gói này được gọi là một hội đồng.
  2. Sân khấu phát hành — ở đây chúng ta kết nối cấu hình của mình với hợp ngữ, nếu không có cấu hình này chúng ta sẽ không thể phát hành chương trình của mình. Bây giờ đây là một bản phát hành hoàn toàn sẵn sàng để ra mắt.
  3. Tiếp theo là sân khấu sự hoàn thành. Ở đây chúng tôi phát hành ứng dụng bằng cách chạy các quy trình cần thiết từ bản phát hành của chúng tôi.

Hệ thống phát hành các phiên bản mới của mô hình hoặc toàn bộ quy trình như vậy cho phép bạn phân tách vai trò giữa quản trị viên và nhà phát triển, cho phép bạn theo dõi các phiên bản và ngăn chặn các điểm dừng chương trình không mong muốn.

Đối với tác vụ phát hành, nhiều dịch vụ khác nhau đã được tạo trong đó bạn có thể viết các quy trình để tự chạy trong tệp .yml (ví dụ: trong CircleCI, đây là config.yml để hỗ trợ chính quy trình đó). Wheely rất giỏi trong việc tạo ra các gói cho dự án.

Bạn có thể tạo các gói với các phiên bản khác nhau của mô hình học máy của mình, sau đó đóng gói chúng và tham khảo các gói cần thiết cũng như phiên bản của chúng để sử dụng các chức năng bạn đã viết từ đó. Điều này sẽ giúp bạn tạo API cho mô hình của mình và gói của bạn có thể được lưu trữ trên Gemfury chẳng hạn.

Nguyên tắc 6. Chạy mô hình của bạn dưới dạng một hoặc nhiều quy trình

Hơn nữa, các quy trình không nên có dữ liệu được chia sẻ. Nghĩa là, các quy trình phải tồn tại riêng biệt và tất cả các loại dữ liệu phải tồn tại riêng biệt, chẳng hạn như trên các dịch vụ của bên thứ ba như MySQL hoặc các dịch vụ khác, tùy thuộc vào những gì bạn cần.

Nghĩa là, việc lưu trữ dữ liệu bên trong hệ thống tệp quy trình chắc chắn là không đáng, nếu không, điều này có thể dẫn đến việc xóa dữ liệu này trong lần phát hành/thay đổi cấu hình tiếp theo hoặc chuyển hệ thống mà chương trình chạy trên đó.

Nhưng có một ngoại lệ: đối với các dự án học máy, bạn có thể lưu trữ bộ đệm của các thư viện để không cài đặt lại chúng mỗi khi bạn khởi chạy phiên bản mới, nếu không có thư viện bổ sung hoặc bất kỳ thay đổi nào được thực hiện đối với phiên bản của chúng. Bằng cách này, bạn sẽ giảm được thời gian cần thiết để triển khai mô hình của mình trong ngành.

Để chạy mô hình dưới dạng một số quy trình, bạn có thể tạo tệp .yml trong đó bạn chỉ định các quy trình cần thiết và trình tự của chúng.

Nguyên tắc 7: Khả năng tái chế

Các tiến trình chạy trong ứng dụng mô hình của bạn phải dễ dàng bắt đầu và dừng lại. Do đó, điều này sẽ cho phép bạn nhanh chóng triển khai các thay đổi mã, thay đổi cấu hình, mở rộng quy mô nhanh chóng và linh hoạt, đồng thời ngăn chặn các sự cố có thể xảy ra của phiên bản đang hoạt động.

Nghĩa là, quy trình của bạn với mô hình sẽ:

  • Giảm thiểu thời gian khởi động. Lý tưởng nhất là thời gian khởi động (từ thời điểm lệnh khởi động được đưa ra cho đến khi quá trình đi vào hoạt động) không quá vài giây. Bộ nhớ đệm thư viện, được mô tả ở trên, là một kỹ thuật giúp giảm thời gian khởi động.
  • Kết thúc một cách chính xác. Nghĩa là, việc nghe trên cổng dịch vụ thực sự bị tạm dừng và các yêu cầu mới được gửi tới cổng này sẽ không được xử lý. Ở đây, bạn cần phải thiết lập giao tiếp tốt với các kỹ sư DevOps hoặc tự mình hiểu cách thức hoạt động của nó (tất nhiên là tốt nhất là sau này, nhưng giao tiếp phải luôn được duy trì trong bất kỳ dự án nào!)

Nguyên tắc 8: Triển khai/Tích hợp liên tục

Nhiều công ty sử dụng sự tách biệt giữa nhóm phát triển và triển khai ứng dụng (cung cấp ứng dụng cho người dùng cuối). Điều này có thể làm chậm đáng kể quá trình phát triển phần mềm và tiến bộ trong việc cải thiện nó. Nó cũng làm hỏng văn hóa DevOps, nơi mà sự phát triển và tích hợp, nói một cách đại khái, là sự kết hợp với nhau.

Do đó, nguyên tắc này nêu rõ rằng môi trường phát triển của bạn phải càng gần với môi trường sản xuất của bạn càng tốt.

Điều này sẽ cho phép:

  1. Giảm thời gian phát hành hàng chục lần
  2. Giảm số lượng lỗi do mã không tương thích.
  3. Điều này cũng làm giảm khối lượng công việc của nhân viên vì các nhà phát triển và những người triển khai ứng dụng hiện là một nhóm.

Các công cụ cho phép bạn làm việc với điều này là CircleCI, Travis CI, GitLab CI và các công cụ khác.

Bạn có thể nhanh chóng thực hiện các bổ sung cho mô hình, cập nhật và khởi chạy nó ngay lập tức, đồng thời, trong trường hợp có lỗi, sẽ rất dễ dàng quay lại phiên bản đang hoạt động rất nhanh để người dùng cuối thậm chí không nhận thấy. Điều này có thể được thực hiện đặc biệt dễ dàng và nhanh chóng nếu bạn có bài kiểm tra tốt.

Giảm thiểu sự khác biệt!!!

Nguyên tắc 9. Nhật ký của bạn

Nhật ký (hoặc “Nhật ký”) là các sự kiện, thường được ghi ở định dạng văn bản, xảy ra trong ứng dụng (luồng sự kiện). Một ví dụ đơn giản: "2020-02-02 - cấp hệ thống - tên quy trình." Chúng được thiết kế để nhà phát triển có thể thấy rõ điều gì đang xảy ra khi chương trình đang chạy. Anh ta nhìn thấy tiến trình của các quy trình và hiểu liệu nó có đúng như dự định của chính nhà phát triển hay không.

Nguyên tắc này nêu rõ rằng bạn không nên lưu trữ nhật ký bên trong hệ thống tệp của mình - ví dụ: bạn chỉ nên “xuất” chúng ra màn hình, thực hiện việc này trên đầu ra tiêu chuẩn của hệ thống. Và bằng cách này, có thể theo dõi dòng chảy trong thiết bị đầu cuối trong quá trình phát triển.

Điều này có nghĩa là không cần phải lưu nhật ký? Dĩ nhiên là không. Ứng dụng của bạn không nên làm điều này—hãy để nó cho các dịch vụ của bên thứ ba. Ứng dụng của bạn chỉ có thể chuyển tiếp nhật ký đến một tệp hoặc thiết bị đầu cuối cụ thể để xem trong thời gian thực hoặc chuyển tiếp nhật ký đó tới hệ thống lưu trữ dữ liệu cho mục đích chung (chẳng hạn như Hadoop). Bản thân ứng dụng của bạn không nên lưu trữ hoặc tương tác với nhật ký.

Nguyên tắc 10. Kiểm tra!

Đối với machine learning công nghiệp, giai đoạn này cực kỳ quan trọng vì bạn cần hiểu rằng mô hình hoạt động chính xác và tạo ra những gì bạn mong muốn.

Các thử nghiệm có thể được tạo bằng pytest và được thử nghiệm bằng tập dữ liệu nhỏ nếu bạn có nhiệm vụ hồi quy/phân loại.

Đừng quên đặt cùng một hạt giống cho các mô hình học sâu để chúng không liên tục tạo ra các kết quả khác nhau.

Đây là phần mô tả ngắn gọn về 10 nguyên tắc và tất nhiên rất khó để sử dụng chúng nếu không thử và xem chúng hoạt động như thế nào, vì vậy bài viết này chỉ là phần mở đầu cho một loạt bài viết thú vị trong đó tôi sẽ tiết lộ cách tạo ra mô hình học máy công nghiệp, cách tích hợp chúng vào hệ thống và cách những nguyên tắc này có thể giúp cuộc sống của tất cả chúng ta trở nên dễ dàng hơn.

Tôi cũng sẽ cố gắng sử dụng những nguyên tắc thú vị mà bất kỳ ai cũng có thể để lại trong phần bình luận nếu họ muốn.

Nguồn: www.habr.com

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