-
Harmonizers Transformer 'process_data.py' 코드 분석CS/논문 리뷰 2024. 4. 17. 23:14
메인 코드 :
위 코드가 process_data --dataset CMD 등의 명령어를 실행했을 때 제일 처음 실행되는 코드이다.
1. 크게 데이터셋을 파싱하는 파트와,
2. 데이터셋의 batch를 저장하는 부분으로 나뉜다.
데이터를 파싱하는 부분에서는 CMD_parser_features.py를 호출해서 진행한다.
이 코드부터 살펴보도록 하자.
1. xml파일로부터 데이터 파싱
CMD_parser_features.py는 위 코드로부터 시작한다.
save_feature()함수를 살펴보자.
일단 dataset에 저장된 데이터들을 불러와서, output파일에 파싱한 형태를 저장하는것 같다.
files라는 객체에 데이터셋에 있는 xml 형식의 데이터들이 저장된다.
이 파일들을 순회하면서, 각 곡별로, 또 그 곡 안에있는 12키별로 데이터의 파싱을 진행한다.
파싱은 parse_CMD_features라는 메서드를 통해 진행하고, 이는 input_list라는 객체에 담긴다.
이 저장한 객체를 최종적으로 features.{}.{}.npy라는 형식으로 output파일에 저장한다.
이제 parse_CMD_features라는메서드가 무슨일을 하는 친구인지 알아보면 되겠다.
코드가 매우 긴데, 결론적으로 쭉 살펴보니 악보형식의 xml파일에서 각 음표별 길이, 피치등과 코드의 종류등을 파싱해서 npy형식으로 저장해주는 형식이다. 이정도만 알아도 충분할 것 같고, 자세한 내부 구조는 알지 않아도 될 것 같아 넘어가겠다.
코드의 결과 : output파일에 저장되는 npy확장자의 파일
2. 데이터셋의 batch를 저장
데이터셋을 batch로 나누고 저장하는 코드는,
split_sets_CMD와
save_batches_CMD 총 메서드를 실행시켜 진행된다.
split_sets_CMD의 코드부터 살펴보자.
split_sets_CMD
코드의 앞부분부터 차근차근 뜯어보겠다.
일단 datapath로 직전 코드에서 파싱되어 저장된 파일이 있는 output파일을 지정한다.
그리고 그 아래부분이 정말 특이하다.
pieces에는 각 곡별로, 여러 키별로 변환되어있는, 그래서 총 12개의 파일이 저장되어있는 파일이다.
그런데 이 길이가 12보다 짧으면, test_list에 저장해서 validation과 test셋으로 사용한다.
이게 무슨 소린가 싶어 테스트로 지정되어있는 노래 파일들을 들어가보았는데, 이빨이 빠지듯 키가 하나씩 비어있었다.
그러니까 12키의 온전한 데이터를 갖고있지 않은 데이터들은 val과 test케이스로 뺀 것이다..
뺀 것중에 홀수 인덱스는 테스트, 짝수는 validation 으로 사용한다.
그 뒤 각 케이스별 데이터를 저장할 path를 exp 하위 경로의 raw폴더로 지정한다.
뒤의 코드는 그냥 생성된 폴더에 나누어준 데이터셋을 넣는것 밖에 없다.
이제 save_batches_CMD 메서드를 살표보자.
save_batches_CMD
마찬가지로 위 부분부터 살펴보겠다.
parent path로 exp폴더를 지정하고,
orig path로 dataset 폴더를 지정해준다.
아래 for문을 살펴보면, data path로 아까 저장한 raw폴더를 지정해주고,
save path로 batch폴더를 지정해준다.
catages에는 음악들의 리스트가 들어가고,
catag에는 각각의 음악이 들어간다.(정상적이라면 키별로 12개의 파일이 저장되어있을것임)
piece에는 키별로 저장되어있는 npy파일이 할당되어, features라는 변수에 그 파일의 정보가 load되어 들어간다.
그 뒤 mesures를 순회하는 for 문을 통해 음악에서 한 번 사용되는 모든 코드를 chord_list 변수에 append해준다.
get_roll_CMD라는 메서드를 그 뒤에 실행하는데, 이 코드를 알아야겠다.
get_roll_CMD 파일을 살펴보면,
결국 데이터셋을 분석해서 note_roll, chord_roll, key_roll, beat_roll, onset_roll, onset_roll_xml, note_ind_onset을 리턴한다. 중간의 많은 양의 과정을 거치지만, 세부적인 내용은 알 필요가 없을 것 같다.
features에 저장된 데이터의 형식은 대충 다음과 같다.
notes :
[74, {'key': {'root': 7, 'mode': 'major'}, 'pitch_abs': {'pc': 11, 'octave': 4, 'num': 71}, 'downbeat': 1, 'beat': 1, 'measure_num': 12, 'time_position': 24.75}]
measure:
[[0, {'chord': [{'kind': 'none', 'root': 'none', 'degrees': 'none', 'time': 'none'}], 'beat': [{'time': 0.0, 'index': 0}, {'time': 0.5, 'index': 1}, {'time': 1.0, 'index': 2}, {'time': 1.5, 'index': 3}], 'measure_num': 0, 'time_position': 0.0}]
다시 돌아와보면,
복잡해 보이지만, 결국은 get_roll_CMD로 받아온
note_roll, chord_roll, key_roll, beat_roll, onset_roll, onset_roll_xml, note_ind_onset
정보들을 정리하는 것이다.
이 메서드의 마지막을 보면 in1_,in2_,in_3등을 리턴하므로 해당 변수를 주의깊게 살펴보자.
일단 in1_에 inp, 즉 note_roll을 저장하고,
in2_에 이 정보를 roll to note한 정보를 저장한다.
in3_에는 note to chord한 정보를 저장한다.
shape x: (128, 89)
shape n: (128, 34)
shape m: (34, 16)
shape c: (34, 14)
shape y: (16, 72)assert in1_.shape[0] == in2_.shape[0]assert in2_.shape[1] == in4_.shape[0]assert in3_.shape[1] == out1_.shape[0]'CS > 논문 리뷰' 카테고리의 다른 글
Harmonizers Transformer 논문 코드 재현 (0) 2024.04.14 Translating Melody to Chord: Structuredand Flexible Harmonization ofMelody With Transformer (0) 2024.04.11 Transformer-Based Seq2Seq Model for Chord Progression Generation (0) 2024.04.10