2 คะแนน โดย GN⁺ 2024-07-02 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • มนุษย์จัดการสปาเกตตีโค้ดได้ไม่เก่ง
  • ในโปรเจ็กต์วิจัย มักต้องเขียนโปรแกรมเพื่อดึงข้อมูลจากข้อมูลดิบ
  • ข้อมูลไม่ได้เป็นไปตามสเปกที่ชัดเจน
  • ตัวอย่าง:
    • ระบุบริษัทและผู้บริหารจากบทความข่าว
    • ติดป้ายกำกับสัญญาจัดซื้อจัดจ้างภาครัฐตามประเภทบริการ
    • ระบุโค้ดโปรแกรมจากข้อความระหว่างวิศวกร

การตรวจจับโค้ดโปรแกรมในข้อความ

  • แก้ปัญหาการตรวจจับว่าข้อความอ้างถึงโค้ดโปรแกรมหรือไม่ระหว่างการรีวิวโค้ด
  • ตัวอย่างข้อความ:
    • 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

ไอเดียของกฎตัดสินใจ

  • แนวทางที่ใช้กฎง่าย ๆ เพื่อแยกโค้ดโปรแกรมออกจากภาษาอังกฤษทั่วไป
  • กฎ:
    1. คำที่ตามด้วยวงเล็บคือโค้ด
    2. คำที่เป็นตัวพิมพ์ใหญ่ทั้งหมดคือโค้ด
    3. คำที่ไม่ใช่ภาษาอังกฤษคือโค้ด
  • ข้อดีข้อเสียของแต่ละกฎ:
    • กฎ 1: เรียบง่าย แต่พลาดกรณีบวกที่ชัดเจน
    • กฎ 2: จัดประเภทตัวย่อพิมพ์ใหญ่ผิดเป็นโค้ดโปรแกรม
    • กฎ 3: จัดประเภทคำศัพท์ทางวิศวกรรมผิดเป็นโค้ดโปรแกรม

อัลกอริทึมที่เขียนด้วยมือ

  • ตัดสินว่าอัลกอริทึมง่าย ๆ อาจทำงานได้ดีพอ
  • ตัดสินสองขั้นตอนว่าข้อความมีโค้ดหรือไม่:
    1. การเตรียมข้อมูลล่วงหน้า: แปลงข้อความเป็นลำดับของโทเค็น
    2. การอนุมาน: ใช้กฎกับลำดับโทเค็นเพื่อตัดสินว่ามีโค้ดหรือไม่
  • ตัวอย่างการเขียนด้วย 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  
    

ความช่วยเหลือจากโครงข่ายประสาท

  • สามารถเข้ารหัส contains_code และ process ในฐานะ state machine ให้เป็น RNN ได้
  • ใช้ RNN เพื่อค้นหาอัลกอริทึมที่ดีกว่าได้

แนวคิดทั่วไป

  • RNN ใช้ประมาณความน่าจะเป็นแบบมีเงื่อนไข
  • คำนวณเวกเตอร์สถานะสำหรับแต่ละโทเค็น
  • จัดประเภทข้อความจากสถานะสุดท้าย

โค้ด Python ในมุมมองทางคณิตศาสตร์

  • อธิบายว่า RNN เข้ารหัสกฎข้อ 1 อย่างไร
  • แทนแต่ละโทเค็นด้วยเวกเตอร์ไบนารี
  • คำนวณ hidden state เพื่อใช้กฎ

การฝึกโครงข่าย

  • เปลี่ยน activation function เป็น ReLU เพื่อฝึก RNN
  • สามารถฝึกได้ด้วย PyTorch

สถาปัตยกรรมที่มีการติดตั้งใช้งานมีประสิทธิภาพกว่า

  • ใช้สถาปัตยกรรมที่มีใน PyTorch เช่น Elman RNN
  • Elman RNN ใช้อินพุตจากทั้งเลเยอร์ก่อนหน้าและเลเยอร์ปัจจุบันในแต่ละ hidden layer

สถาปัตยกรรมที่มีกราเดียนต์เสถียรกว่า

  • ข้อความที่ยาวทำให้กราเดียนต์เข้าใกล้ 0 จนเกิดปัญหา
  • สถาปัตยกรรมอย่าง GRU หรือ LSTM อาจให้ประสิทธิภาพที่ดีกว่า

วินัยที่ยึดข้อมูลเป็นศูนย์กลาง

  • RNN จัดการสปาเกตตีโค้ดได้ดีกว่า
  • บังคับใช้วินัยแบบยึดข้อมูลเป็นศูนย์กลางเพื่อทำให้ปัญหาชัดเจนขึ้น

ความเห็นของ GN⁺

  • บทความนี้อธิบายได้ดีว่าการใช้ RNN เพื่อแก้ปัญหาที่ซับซ้อนทำได้อย่างไร
  • การใช้ RNN ช่วยให้บำรุงรักษาโค้ดได้ง่ายขึ้น
  • สามารถทำ implementation ที่มีประสิทธิภาพได้ด้วยเครื่องมืออย่าง PyTorch
  • ควรพิจารณาสถาปัตยกรรมอย่าง GRU หรือ LSTM
  • แนวทางแบบยึดข้อมูลเป็นศูนย์กลางมีประโยชน์ต่อการแก้ปัญหา

1 ความคิดเห็น

 
GN⁺ 2024-07-02
ความคิดเห็นจาก Hacker News
  • บทความนี้ไม่ได้พูดถึงการทดสอบหรือข้อมูลฝึกมากนัก

    • เหตุผลที่คิดว่าเข้าใจโค้ดได้ ก็เพราะได้พิสูจน์คุณสมบัติที่ทำให้ใช้งานทั่วไปได้แบบไม่เป็นทางการ
    • ปัญหาของโครงข่ายประสาทคือเราไม่รู้ว่ามันจะทำการสรุปเหมารวมกับอินพุตใหม่อย่างไร
    • ถ้ากำหนดคุณสมบัติได้ดี ก็สามารถเขียนการทดสอบแบบ property-based เพื่อสร้างข้อมูลทดสอบจำนวนมากได้
    • นี่ไม่ใช่การพิสูจน์ แต่ก็อาจเป็นจุดเริ่มต้นได้
    • การพึ่งพา spaghetti code หรือโครงข่ายประสาทอาจคล้ายกัน
    • แทนที่จะฝึกโครงข่ายประสาท ก็อาจเขียนการทดสอบแบบ property-based ได้
    • ถึงอย่างนั้นก็น่าจะยังเชื่อถือโค้ดมากกว่า เพราะดีบักได้
  • ถ้าอ่านบทความนี้ในฐานะวิธีสร้างโครงข่ายประสาทเพื่อทำงานเชิงปฏิบัติ ก็ถือว่าน่าสนใจ

    • ผู้เขียนกำลังจัดการกับปัญหาที่ยาก คือการแยกวิเคราะห์อินพุตตามอำเภอใจ
    • เขาเสนอให้ใช้โครงข่ายประสาทเพื่อแก้ปัญหานี้ แต่ก็ยังเข้าใจได้ยากอยู่ดี
    • โค้ดที่เข้าใจได้อาจดีกว่าโค้ดที่อ่านยาก
  • มีทฤษฎีบทการประมาณค่าแบบสากล (Universal Approximation Theorem) สำหรับโครงข่ายประสาท

    • แต่ไม่มีทฤษฎีบทที่บอกว่าเราสามารถเรียนรู้การประมาณค่าเหล่านี้ได้
  • บทความนี้พูดถึงแนวคิดคณิตศาสตร์เชิงลึกเกี่ยวกับ RNN แต่ก็มีไอเดียที่น่าสนใจ

    • แนวทางที่ประมวลผลสตริงอินพุตทีละตัวอักษรนั้นทรงพลัง
    • เขียนลอจิกอินพุต/เอาต์พุตแบบบาง ๆ แล้วให้อัลกอริทึมจัดการที่เหลือ
  • มีความเห็นที่สงสัยว่า RNN ถูกแทนที่โดยทรานส์ฟอร์เมอร์อย่างสมบูรณ์แล้วหรือยัง

  • การลองศึกษาการเขียนโปรแกรมเชิงพันธุกรรม (Genetic Programming) อาจคุ้มค่า

    • ไม่ต้องใช้คณิตศาสตร์ และเพิ่มประสิทธิภาพด้วยการนำโปรแกรมมาจัดองค์ประกอบใหม่ในรูป AST
    • สามารถเลือกได้ว่าจะเพิ่มประสิทธิภาพด้านไหน (เช่น ความเร็ว, ความยาวของโปรแกรม, การลดโครงสร้างที่ซับซ้อน เป็นต้น)
  • บทความนี้มอง RNN เป็นประสบการณ์การเรียนรู้ และนำไปเทียบกับ RNN ของ PyTorch

    • มีคำถามว่าทำไมต้องเพิ่ม hidden layer สามชั้นให้กับเครือข่าย
  • RNN สามารถทำการคำนวณตามอำเภอใจได้ แต่ไม่ค่อยใช้งานได้จริง

    • บทความนี้ว่าด้วยวิธีเรียนรู้ state machine แต่การเรียนรู้ความหมายจริงของ Python นั้นยาก
  • มีความเห็นว่าโครงข่ายประสาทจะค่อย ๆ ดูเหมือนโค้ดมากขึ้น

    • วิธีแปลงโมเดลสไตล์ MOE ให้เป็นการเรียกใช้ฟังก์ชันจะเป็นนวัตกรรมใหญ่ถัดไป