GN⁺: 내 Python 코드는 신경망
(blog.gabornyeki.com)- 인간은 스파게티 코드 관리에 서툴음
- 연구 프로젝트에서 원시 데이터에서 정보를 추출하는 프로그램을 작성하는 경우가 많음
- 데이터는 명확한 사양을 따르지 않음
- 예시:
- 뉴스 기사에서 기업과 임원을 식별
- 공공 조달 계약을 서비스 종류별로 라벨링
- 엔지니어 간의 메시지에서 프로그램 코드를 식별
메시지에서 프로그램 코드 감지
- 코드 리뷰 중 메시지가 프로그램 코드를 참조하는지 감지하는 문제를 해결
- 예시 메시지:
- 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: 엔지니어링 용어를 프로그램 코드로 잘못 분류함
손으로 작성한 알고리듬
- 간단한 알고리듬이 충분히 잘 작동할 수 있다고 판단
- 두 단계로 메시지가 코드를 포함하는지 결정:
- 전처리: 메시지를 토큰 시퀀스로 변환
- 추론: 토큰 시퀀스에 규칙을 적용하여 코드 포함 여부 결정
- 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
를 RNN으로 인코딩 가능 - RNN을 사용하여 더 나은 알고리듬을 찾을 수 있음
일반적인 아이디어
- RNN은 조건부 확률을 근사함
- 각 토큰에 대해 상태 벡터를 계산
- 최종 상태를 기반으로 메시지를 분류
수학으로 본 Python 코드
- RNN이 규칙 1을 인코딩하는 방법을 설명
- 각 토큰을 이진 벡터로 표현
- 숨겨진 상태를 계산하여 규칙을 적용
네트워크 훈련
- RNN을 훈련시키기 위해 활성화 함수를 ReLU로 변경
- PyTorch를 사용하여 훈련 가능
더 효율적인 구현을 가진 아키텍처
- Elman RNN과 같은 PyTorch에서 제공하는 아키텍처 사용
- Elman RNN은 각 숨겨진 레이어가 이전 레이어와 현재 레이어를 모두 입력으로 사용
더 안정적인 그래디언트를 가진 아키텍처
- 긴 메시지는 그래디언트가 0에 가까워져서 문제 발생
- GRU나 LSTM과 같은 아키텍처가 더 나은 성능을 보일 수 있음
데이터 중심의 규율
- RNN은 스파게티 코드를 더 잘 처리함
- 데이터 중심의 규율을 강제하여 문제를 명확히 함
GN⁺의 의견
- 이 기사는 RNN을 사용하여 복잡한 문제를 해결하는 방법을 잘 설명함
- RNN을 사용하면 코드 유지보수가 용이해짐
- PyTorch와 같은 도구를 사용하여 효율적인 구현 가능
- GRU나 LSTM과 같은 아키텍처를 고려할 필요 있음
- 데이터 중심의 접근 방식이 문제 해결에 유용함
Hacker News 의견
-
이 글은 테스트나 훈련 데이터에 대해 많이 다루지 않음
- 코드가 이해된다고 생각하는 이유는 일반화된 속성을 비공식적으로 증명했기 때문임
- 신경망의 경우, 새로운 입력에 대해 어떻게 일반화될지 알 수 없다는 점이 문제임
- 속성을 잘 정의할 수 있다면, 속성 기반 테스트를 작성하여 많은 테스트 데이터를 생성할 수 있음
- 이는 증명은 아니지만 시작점이 될 수 있음
- 스파게티 코드나 신경망에 의존하는 것은 비슷할 수 있음
- 신경망을 훈련시키는 대신 속성 기반 테스트를 작성할 수 있음
- 여전히 코드를 더 신뢰할 것 같음, 디버깅이 가능하기 때문임
-
이 글은 실용적인 작업을 수행하기 위한 신경망 구축 방법으로 읽으면 흥미로움
- 저자는 임의의 입력을 구문 분석하는 어려운 문제를 다룸
- 이를 해결하기 위해 신경망을 제안하지만, 이는 여전히 이해하기 어려움
- 읽기 어려운 코드보다는 이해할 수 있는 코드가 더 나을 수 있음
-
신경망에 대한 보편적 근사 정리(Universal Approximation Theorem)가 존재함
- 그러나 이러한 근사치를 학습할 수 있다는 정리는 없음
-
이 글은 RNN에 대한 깊은 수학적 개념을 다루지만, 흥미로운 아이디어를 제공함
- 입력 문자열을 문자 단위로 처리하는 접근법이 강력함
- 얇은 입출력 로직을 작성하고 나머지는 알고리즘이 처리함
-
RNN이 트랜스포머에 완전히 대체되었는지 궁금해하는 의견이 있음
-
유전 프로그래밍(Genetic Programming)을 살펴볼 가치가 있음
- 수학이 필요 없고, 프로그램을 AST로 재조합하여 최적화함
- 최적화할 항목을 선택할 수 있음 (예: 속도, 프로그램 길이, 복잡한 구조 최소화 등)
-
이 글은 RNN을 학습 경험으로 다루며, PyTorch의 RNN과 비교함
- 네트워크에 세 개의 숨겨진 레이어를 추가해야 하는 이유를 질문함
-
RNN은 임의의 계산을 수행할 수 있지만, 실용적이지 않음
- 이 글은 상태 기계를 학습하는 방법을 다루며, Python의 실제 의미를 학습하는 것은 어려움
-
신경망이 점점 코드처럼 보일 것이라는 의견이 있음
- MOE 스타일 모델을 함수 호출로 변환하는 방법이 다음 큰 혁신이 될 것임