.
This commit is contained in:
80
spec.md
80
spec.md
@@ -7,69 +7,47 @@
|
||||
- data_dir
|
||||
- train_data_count = 100
|
||||
- validate_data_count = 20
|
||||
- margin = 0.1
|
||||
- margin = 0.5
|
||||
- validate_iterations = 5
|
||||
|
||||
## 학습 모델
|
||||
- **추천:** PyTorch 기반의 **Deep MLP** (Dropout 및 Weight Decay 필수 적용)
|
||||
- **과적합 방지 전략:**
|
||||
- **Dropout (0.3 ~ 0.5):** 학습 시 뉴런을 의도적으로 꺼서 특정 데이터 암기를 방지한다.
|
||||
- **L2 Regularization (Weight Decay):** 가중치가 비정상적으로 커지는 것을 막는다.
|
||||
- **Output Mapping:** 최종 출력에 `Sigmoid`를 걸고 (y * 11) + 1을 적용해 [1, 12] 범위를 강제한다.
|
||||
|
||||
## 학습 과정
|
||||
1. `{data_dir}/tja`의 tja를 파싱한다.
|
||||
- `{script_dir}/parse.ts`를 사용한다.
|
||||
2. `oni`와 `edit` course를 factorize한다.
|
||||
- `{script_dir}/factorize.ts`를 사용하며, `{working_dir}/features.json`에 저장한다. 이 때, songno와 난이도(oni | edit)을 같이 저장하여야한다.
|
||||
- `{working_dir}/features.json`이 이미 존재하면 이 과정은 생략한다.
|
||||
3. factorized된 데이터를 `train_data_count` 만큼 랜덤으로 가져온다.
|
||||
4. train data로 학습을 진행한다.
|
||||
- 예측 값이 [1, 12]에 없으면 완전히 잘못 트레이닝 된 것이다.
|
||||
- `{data_dir}/measure.csv`로 오차 확인
|
||||
- course가 `edit`이면 measure.json에서는 `ura`이므로 적절히 매칭한다.
|
||||
- Train error를 계속 로깅한다.
|
||||
- Train error가 `margin`보다 클 경우 이 과정(4번)을 다시 진행한다.
|
||||
- 최대 10번만 진행한다.
|
||||
5. validate_data_count 만큼 랜덤으로 validate data를 가져온 후 validate data로 각각의 measure, 예측한 measure, 오차를 `validate_result_{n}.csv`로 저장한다.
|
||||
- `validate_result_{n}.csv`에는 `songno`, `difficulty`, `measure`, `predicted_measure`, `error`을 작성한다. (중요)
|
||||
- `n`에는 몇번째 iteration인지 적는다.
|
||||
6. 만약 validate한 데이터 중 오차가 `margin`보다 큰 것이 있다면 3~5과정을 다시 반복한다.
|
||||
7. 모델 파일을 저장한다.
|
||||
1. `{data_dir}/tja`의 tja를 파싱한다. (`{script_dir}/parse.ts`)
|
||||
2. `oni`와 `edit` course를 factorize하여 `{working_dir}/factors.json`에 저장한다.
|
||||
- 이미 존재하면 생략하되, Factor 로직 수정 시 삭제 후 재실행한다.
|
||||
3. 데이터 표준화(Standardization)를 위한 스케일링 파라미터를 계산하고 `{working_dir}/scaler.json`에 저장한다.
|
||||
4. **학습 단계:** 전체 데이터 중 `train_data_count`만큼 데이터를 랜덤하게 추출하여 학습을 진행한다.
|
||||
- `edit` 코스는 `ura`와 매칭하여 오차를 계산한다.
|
||||
- 모델이 충분히 수렴할 때까지 학습을 수행하며, 기존 모델 존재 시 가중치를 로드하여 업데이트한다.
|
||||
5. **검증 단계:** 학습이 완료된 모델을 대상으로 아래 과정을 수행한다.
|
||||
- `validate_data_count`만큼의 데이터를 랜덤하게 추출하여 오차를 계산하고 `validate_result_{n}.csv`에 저장한다.
|
||||
- 이 과정을 `validate_iterations` 횟수만큼 반복한다.
|
||||
- **재시도 조건:** 검증 루프 도중 단 한 번이라도 Mean Absolute Error(MAE)가 `margin`보다 크다면, 즉시 검증을 중단하고 4번(학습 단계)으로 돌아가 데이터를 새로 샘플링하여 재학습한다.
|
||||
6. **성공 및 종료:** 모든 `validate_iterations` 회차에서 MAE가 `margin` 이하일 경우에만 학습 성공으로 간주하고 최종 모델 파일을 저장한다.
|
||||
|
||||
### 유의 사항
|
||||
- 모든 출력되는 데이터는 working_dir에 저장한다.
|
||||
- 이미 working_dir에 모델이 존재하면 모델을 삭제하지 않고 업데이트하는 식으로 학습한다.
|
||||
- 애플 실리콘 cpu를 사용할 경우 적극적으로 gpu를 사용할 수 있도록 한다.
|
||||
- 모든 데이터는 `working_dir`에 저장한다.
|
||||
- Apple Silicon 환경에서 `mps` 디바이스를 할당하여 GPU 가속을 사용한다.
|
||||
|
||||
# 예측
|
||||
## CLi
|
||||
- cli로 예측 데이터를 뽑을 수 있는 쉘 스크립트를 작성한다.
|
||||
- argument
|
||||
- working_dir
|
||||
- tja
|
||||
- difficulty: oni | edit
|
||||
## CLI
|
||||
- argument: `working_dir`, `tja`, `difficulty` (oni | edit)
|
||||
|
||||
## 예측 과정
|
||||
- `working_dir`에 있는 model로 예측을 진행한다.
|
||||
- `tja` argument에 tja파일이 존재한다.
|
||||
- `difficulty`로 예측을 진행할 난이도를 선택한다.
|
||||
- 로드된 모델과 학습 시 사용했던 스케일링 파라미터(Mean, Std)를 동일하게 적용하여 예측을 진행한다.
|
||||
|
||||
# Factor
|
||||
## 종류
|
||||
- physical_density: 곡의 전반적인 및 순간적인 타격 밀도 (Global NPS, Peak NPS)
|
||||
- stamina_requirement: 긴 연타 구간과 휴식 구간의 비율을 통한 체력 소모량
|
||||
- pattern_complexity: 색상 전환 및 손 배치 전환(Hand-switching)의 복잡도
|
||||
- rhythmic_complexity: 엇박, 다양한 음표 단위 사용 등으로 인한 리듬의 난해함
|
||||
- reading_gimmick: BPM 변화, 스크롤 속도(SV) 변동 등 시각적 요소 및 기믹
|
||||
|
||||
## 가중치 (하이퍼 파라미터)
|
||||
`script/factor.json`에 `Record<factor 이름, 가중치>`를 기록한다.
|
||||
- average_density: 평균 밀도
|
||||
- peak_density: 최고 초당 밀도
|
||||
- max_combo: 노트의 수
|
||||
|
||||
# Scripts
|
||||
## `script/parse.ts`
|
||||
- `parseTja` 함수
|
||||
- tja를 string으로 받는다.
|
||||
- `Partial<Record<'oni' | 'edit', Course>> | null`을 반환한다.
|
||||
- null이 반환되면 에러가 나온 것이므로 무시한다.
|
||||
## `script/factorize.ts`
|
||||
- `factorize` 함수
|
||||
- course를 input으로 받는다.
|
||||
- factor들을 반환한다.
|
||||
- `Factor` namespace
|
||||
- 각 factor을 반환하는 함수의 namespace이다.
|
||||
- `factorize` 함수는 `Factor` namespace에서 함수들을 호출하여 factor들을 반환한다.
|
||||
- `parse.ts`: TJA 문자열을 `Course` 객체로 변환.
|
||||
- `factorize.ts`: `Course`를 입력받아 확장된 `Factor` 세트를 반환.
|
||||
Reference in New Issue
Block a user