2 điểm bởi GN⁺ 2024-07-02 | 1 bình luận | Chia sẻ qua WhatsApp
  • Con người khá kém trong việc quản lý spaghetti code
  • Trong các dự án nghiên cứu, thường phải viết chương trình để trích xuất thông tin từ dữ liệu thô
  • Dữ liệu không tuân theo đặc tả rõ ràng
  • Ví dụ:
    • Nhận diện doanh nghiệp và lãnh đạo trong các bài báo
    • Gắn nhãn các hợp đồng mua sắm công theo loại dịch vụ
    • Nhận diện mã chương trình trong tin nhắn giữa các kỹ sư

Phát hiện mã chương trình trong tin nhắn

  • Giải quyết bài toán phát hiện liệu một tin nhắn có đang tham chiếu đến mã chương trình trong quá trình review code hay không
  • Ví dụ tin nhắn:
    • LGTM with render_ipa_alloc()
    • If the FTPSACK flag is set, then use a prespecified value
    • AFAICT there is nothing else to check (unless you can think of something)
    • Actually, debug_error() doesn’t return NULL, so we should use IS_ERROR() here
    • This fails to build on aarch64 even though it works without issue on amd64
    • I’ve added if (err) goto cleanup; but the code still leaks

Ý tưởng về quy tắc quyết định

  • Cách tiếp cận dùng các quy tắc đơn giản để phân biệt mã chương trình với tiếng Anh thông thường
  • Quy tắc:
    1. Từ nào theo sau bởi dấu ngoặc đơn thì là mã
    2. Từ viết hoa toàn bộ là mã
    3. Từ không phải tiếng Anh là mã
  • Ưu và nhược điểm của từng quy tắc:
    • Quy tắc 1: đơn giản nhưng bỏ sót các trường hợp dương tính hiển nhiên
    • Quy tắc 2: phân loại nhầm các từ viết tắt in hoa thành mã chương trình
    • Quy tắc 3: phân loại nhầm các thuật ngữ kỹ thuật thành mã chương trình

Thuật toán viết tay

  • Đánh giá rằng một thuật toán đơn giản có thể hoạt động đủ tốt
  • Xác định một tin nhắn có chứa mã hay không theo hai bước:
    1. Tiền xử lý: chuyển tin nhắn thành một chuỗi token
    2. Suy luận: áp dụng các quy tắc lên chuỗi token để xác định có chứa mã hay không
  • Ví dụ triển khai bằng Python:
    from dataclasses import dataclass  
    
    Token = str  
    
    @dataclass  
    class State:  
        previous_was_identifier: bool = False  
        previous_was_open_paren: bool = False  
        previous_previous_was_identifier: bool = False  
        seen_code: bool = False  
    
    def contains_code(tokens: Iterable[Token]) -> bool:  
        state = State()  
        for token in tokens:  
            state = process(state, token)  
        return state.seen_code  
    
    def process(state: State, token: Token) -> State:  
        if state.seen_code:  
            return state  
        if (token == "close_paren" and state.previous_was_open_paren and state.previous_previous_was_identifier):  
            state.seen_code = True  
            return state  
        state.previous_previous_was_identifier = state.previous_was_identifier  
        state.previous_was_identifier = token in ("all_caps_identifier", "underscore_identifier", "misc_identifier")  
        state.previous_was_open_paren = token == "open_paren"  
        return state  
    

Sự trợ giúp của mạng nơ-ron

  • Có thể mã hóa contains_codeprocess dưới dạng một RNN như một máy trạng thái
  • Có thể dùng RNN để tìm ra một thuật toán tốt hơn

Ý tưởng tổng quát

  • RNN xấp xỉ xác suất có điều kiện
  • Tính một vector trạng thái cho mỗi token
  • Phân loại tin nhắn dựa trên trạng thái cuối cùng

Mã Python nhìn từ góc độ toán học

  • Giải thích cách RNN mã hóa quy tắc 1
  • Biểu diễn mỗi token bằng một vector nhị phân
  • Tính trạng thái ẩn để áp dụng quy tắc

Huấn luyện mạng

  • Thay hàm kích hoạt thành ReLU để huấn luyện RNN
  • Có thể huấn luyện bằng PyTorch

Kiến trúc có cách triển khai hiệu quả hơn

  • Sử dụng các kiến trúc có sẵn trong PyTorch như Elman RNN
  • Elman RNN sử dụng mỗi lớp ẩn với cả lớp trước đó và lớp hiện tại làm đầu vào

Kiến trúc có gradient ổn định hơn

  • Với các tin nhắn dài, gradient tiến gần về 0 và gây ra vấn đề
  • Các kiến trúc như GRU hoặc LSTM có thể cho hiệu năng tốt hơn

Kỷ luật lấy dữ liệu làm trung tâm

  • RNN xử lý spaghetti code tốt hơn
  • Ép buộc kỷ luật lấy dữ liệu làm trung tâm để làm rõ bài toán

Ý kiến của GN⁺

  • Bài viết này giải thích rất tốt cách dùng RNN để giải quyết các bài toán phức tạp
  • Dùng RNN giúp việc bảo trì mã dễ dàng hơn
  • Có thể triển khai hiệu quả bằng các công cụ như PyTorch
  • Cần cân nhắc các kiến trúc như GRU hoặc LSTM
  • Cách tiếp cận lấy dữ liệu làm trung tâm hữu ích cho việc giải quyết vấn đề

1 bình luận

 
GN⁺ 2024-07-02
Ý kiến trên Hacker News
  • Bài viết này không đề cập nhiều đến kiểm thử hay dữ liệu huấn luyện

    • Lý do mọi người nghĩ rằng mã có thể được hiểu là vì đã không chính thức chứng minh được các thuộc tính khái quát
    • Với mạng nơ-ron, vấn đề là không thể biết nó sẽ khái quát hóa thế nào với đầu vào mới
    • Nếu có thể định nghĩa tốt các thuộc tính, ta có thể viết kiểm thử dựa trên thuộc tính để tạo ra nhiều dữ liệu kiểm thử
    • Đây không phải là chứng minh, nhưng có thể là điểm khởi đầu
    • Việc phụ thuộc vào spaghetti code hay mạng nơ-ron có thể khá giống nhau
    • Thay vì huấn luyện mạng nơ-ron, có thể viết kiểm thử dựa trên thuộc tính
    • Dù vậy tôi vẫn có lẽ sẽ tin mã hơn, vì có thể debug được
  • Bài viết này khá thú vị nếu đọc như một cách xây dựng mạng nơ-ron để thực hiện công việc thực tế

    • Tác giả xử lý bài toán khó là phân tích cú pháp đầu vào tùy ý
    • Để giải quyết điều này, tác giả đề xuất mạng nơ-ron, nhưng nó vẫn khó hiểu
    • Mã có thể hiểu được có lẽ vẫn tốt hơn mã khó đọc
  • Có định lý xấp xỉ phổ quát (Universal Approximation Theorem) dành cho mạng nơ-ron

    • Nhưng không có định lý nào nói rằng có thể học được những phép xấp xỉ như vậy
  • Bài viết này đề cập đến các khái niệm toán học sâu về RNN, nhưng đưa ra những ý tưởng thú vị

    • Cách tiếp cận xử lý chuỗi đầu vào theo từng ký tự rất mạnh mẽ
    • Viết logic vào/ra mỏng, còn lại để thuật toán xử lý
  • Có ý kiến thắc mắc liệu RNN đã bị Transformer thay thế hoàn toàn hay chưa

  • Genetic Programming đáng để tìm hiểu

    • Không cần toán học, và tối ưu bằng cách tái tổ hợp chương trình dưới dạng AST
    • Có thể chọn thứ cần tối ưu (ví dụ: tốc độ, độ dài chương trình, giảm thiểu cấu trúc phức tạp, v.v.)
  • Bài viết này xem RNN như một trải nghiệm học tập và so sánh với RNN của PyTorch

    • Có câu hỏi vì sao phải thêm ba lớp ẩn vào mạng
  • RNN có thể thực hiện tính toán tùy ý, nhưng không thực tế

    • Bài viết này nói về cách học một máy trạng thái, còn việc học ý nghĩa thực sự của Python là khó
  • Có ý kiến cho rằng mạng nơ-ron sẽ ngày càng trông giống mã hơn

    • Cách biến mô hình kiểu MOE thành gọi hàm sẽ là bước đột phá lớn tiếp theo