ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SK AI 경연] 참가 후기
    Code Etc/후기 모음 2023. 8. 5. 07:28
    반응형

    오늘 오후6시면 결과물 제출이 마감된다.

    나는 내가 알고 있는, 할 수 있는 것을 최대한 많이 시도해봤기 때문에 미련은 없다..

    다만 상위권 순위에 있는 사람들이 어떻게 문제를 해결했는지가 너무 궁금하다

    나중에 발표같은 게 있으면 꼭 찾아봐야겠다!

     

    경연을 준비하면서 스스로 노력했던 포인트들을 몇 가지 적어보려고 한다.

    총정리 느낌으로 쭈욱 보면 좋을 것 같다.

     

    이번 경연의 주제는 앞서 말했다시피 "청각장애인을 위한 소리 분류 모델 개발"이다.

    우리가 실생활에서 겪을 수 있는 사고를 유발하는 소리나 생활, 도시 소음 등을 분류하는 모델이다.

     

    나는 경연에 참가하기 전에 사전조사로 구글링을 해봤는데 대부분 인공신경망을 통해 소리의 특성을

    2차원으로 추출하여 이를 학습하는 글이었다. 그래서 나도 별생각없이 이렇게 비슷하게 하면 되겠거니

    했는데 내가 참가한 리그는 CDS리그로 인공 신경망 사용에 제한을 두었다..(여기서부터 막막했음..)

    그래도 베이스라인 코드가 주어졌기 때문에 천천히 따라하며 내가 원하는 대로 수정도 하고 응용도 하면서

    여러 방법을 모색했다.

     

    좋았던 점 및 여러 시도

    이번 경연은 학습데이터만 40GB이고 테스트 데이터가 15GB에 육박하는 나에겐 대규모 데이터 프로젝트였다.

    약 37000개의 train DataSet과 15000개의 test DataSet으로 구성되어 있었다.

    파일은 전부 .wav파일이였고 이를 하나하나 소리 특성 추출 라이브러리에 읽혀서 특성을 추출해내야했는데

    이 과정에서 베이스라인 코드에 37000개를 chunk단위로 나누어서 각 단위 별로 추출이 끝나면 .csv로 내용을 기록하고

    중간에 런타임이 끊기거나 환경문제로 인해 중단되어도 .csv파일을 불러와서 이어서 내용을 추출할 수 있었다.

     

    이 부분에서 나는 앞으로 많이 응용해서 사용할 수 있을거라 느꼈다.

     

    소리 분류 모델을 학습할 때 시도할 수 있는 여러 방법들이 있는데 베이스라인 코드에서 효과가 없었다고

    미리 설명해준 것들이 있는데 EDA나 Data Imbalance를 해결할 overFitting 등 이런 것들을 시도해보았으나

    결과가 좋지 않았다고 베이스라인 코드에 주석으로 담겨있었다.

    내가 시도하려 했던 전략들인데 소용없다니.. 여기서 또 흔들렸다..

     

    남은 방법이 모델 파라미터 튜닝인데 베이스라인 코드에서 XGBoost와 Randomclassifier를 사용했다.

    해당 공식 사이트에서 파라미터를 찾고 튜닝해보았으나 베이스라인 코드의 결과와 크게 차이가 없었다...

     

    다른 방법을 모색하기 위해 소리 데이터를 mfcc를 이용해서 벡터로 출력했다.

    그리고 이 벡터를 SVM모델을 사용해서 실험했으나 validation Set에서 accuracy가 20%가 나와서 바로 접었다 ㅋ...

     

    아무래도 다른 분류기가 필요할 것 같아 boosting방식을 이용하는 분류기 중에서 lightgbm모델이 성능이 좋다는 글을

    발견했다. 비교 대상은 xgboost와 catboost였는데 일각에서는 catboost가 더 좋다는 의견도 있었으나

    multi logloss와 multi error를 계산하기에 lightgbm이 더 쉬웠으므로 이 모델을 택했다.

    아래는 내가 시도한 파라미터 튜닝이다...

    n_estimator 200  =>  150번쯤에서 logloss상승 (0.45 / 1.57) 최종 0.43 1.62
    nest 200 max_depth 4, num_leaves15 => 감소만함(0.48 / 1.60)
    ===> max_depth랑 num_leaves설정하는 것보다 안하는게 낫다
    nest 300, lambda_l2 = 10 => 280번쯤 logloss상승 1.49=>1.5 최종 0.42 1.5
    ===> max_depth랑 num_leaves는 안쓰는게 낫고 l2 정규화는 좋은 옵션이다
    l2정규화 10값은 유지
    maxbin default 255 => 300 =>0.42 1.5
    => max_bin도 안쓰는게 낫다.
    l2정규화 20으로 올려봄 => 0.43 1.491
    l2정규화20 & min_split_gain 0.3 =>0.44 1.49
    l2정규화 30 & min_split_gain 0.3 => 0.44, 1.49
    l2정규화20 & min_split_gain 0.3& min_data_in_leaf=300 => 0.44 1.493
    l2정규화20 & min_split_gain 0.3& min_data_in_leaf=500 => 0.43 1.491
    l2정규화20 & min_split_gain 0.3& min_data_in_leaf=500 & learning_rate=0.05,n est 650> 0.43, 1.47(최고)
    max_depth = 10 n_est 650=> 0.436 1.478
    max_depth = 7 n_est 650=> 0.437 1.483
    max_depth = 10 num_leaves=500 n_est 650=> 0.436 1.477
    max_depth = 10 num_leaves=700 n_est 650=> 0.436 1.477
    max_depth = 10 num_leaves=300 n_est 650=> 0.436 1.477
    max_depth = 10 num_leaves=60 n_est 650=> 0.436 1.477
    rr0.04 nset 800
    cat 0.08 = 1.89
    0.15 => 1.707  
    0.3 => 1.657    
    l2정규화20 & min_split_gain 0.3& min_data_in_leaf=500 & learning_rate=0.05,n est 650> 0.43, 1.47(최고)
    특성 500개 : 0.43 / 1.47
    특성 200개 : 0.47 / 1.56
    특성 400개 : 0.44 1.49 / 0.96 0.3(트레인)
    특성 400개 
    path_smooth = 100 : 0.44 1.49 / 0.96 0.34
    path_smooth = 300 : 0.44 1.49 / 0.95 0.36
    0.45 1.49/0.94 0.4
    feature_fraction 0.8 bagging_fraction 0.8 bagging_freq 10
    extra_trees => 0.52 1.71 / 0.35 1.24
    max_bin = 100 => 0.52 1.71 / 0.34 1.23
    max_bin = 50  => 0.52 1.71 / 0.34 1.23
    max_bin 보류
    bagging = dart => 0.58 1.92 / 0.49 1.68
    learning_rate 0.1, n_est 500 => 0.56 1.81 / 0.43 1.49
    learning_rate 0.3, n_est 500 => 0.52 1.69 / 0.31 1.12

    learning_rate0.04 nest 2000 => 0.54 1.82 / 0.44 1.50

    러닝레이트를 한참 높여도 0.1에 500과 근사치이다.

    learning_rate 0.1, n_est 2000 => 0.51 1.66 / 0.28 1.09 

     ==>과적합이 늘었다 그래도 트레인 셋의 정확도를 수렴하기 위해 학습 횟수를 늘려본다

    learning_rate 0.1, n_est 4000 => 0.49 1.61 / 0.22 0.91

    ==> 이래도 학습 데이터가 수렴하지 않는다..나는 지금 과적합을 초기에 비해 많이 잡은 상태에서 학습 정확도를 높이고싶다

    learning_rate 0.5, n_est 500, lambda_l2 (20 >40) => 0.51 1.69 / 0.29 1.07

    learning_rate 0.5, n_est 500, lambda_l2 40  drop_rate(0.1 > 0.5)=> 0.53 1.73 / 0.33 1.16

    learning_rate 0.5, n_est 500, lambda_l2 40  max_drop = 0 => 0.51 1.66 / 0.23 0.89

    learning_rate 0.5, n_est 500, lambda_l2 40  max_drop 0 uniform_drop = True => 0.51 1.66 /0.22 0.83 
    ==>스킵드랍, 드랍레이트, 유니폼 드랍은 효과 없음, 맥스 드랍은 효과 있음.

    learning_rate 0.3, n_est 500, lambda_l2 40  max_drop 0 => 0.51 1.67 / 0.28 1.04

    learning_rate 0.3, n_est 500 => 0.52 1.69 / 0.31 1.12

    learning_rate 0.3, n_est 500, lambda_l2 (40>20) max_drop 0, path_smooth 300 =>0.50 1.65 / 0.24 0.93

    learning_rate 0.3, n_est 500, lambda_l2 (40>20) max_drop 0, path_smooth 500 =>0.50 1.65 / 0.25 0.95

    learning_rate 0.3, n_est 500, lambda_l2 (40>20) max_drop 0, path_smooth 1000 => 0.51 1.67 / 0.26 1.0

    learning_rate 0.3, n_est (500 > 2000), lambda_l2 (40>20) max_drop 0, path_smooth 500 =>0.48 1.61 / 0.13 0.60

    learning_rate (0.3 > 0.2) , n_est (2000 > 4000), lambda_l2 20 max_drop 0, path_smooth 500 => 0.47 1.60 /0.11 0.55

    이렇게 여러 시도를 했는데 56%의 정확도와 1.6정도의 logloss를 얻었다. 확실히 이는 좋지 않다.

     

    그래서 나는 다른 방법을 생각하다가 데이터 불균형을 해소하기로 마음먹었다.

    공지사항에도 명시되어있듯이 출처가 분명한 외부 데이터는 사용할 수 있었으므로 aihub에서 데이터를 가져왔다.

    전부 가져온 것은 아니고 크기가 작은 class에 해당하는 파일들만 다운로드 받았다.

    이 과정에서 내가 새로 다운받은 파일들에 대해 이름을 정렬하고 .csv파일로 기존에 제공된 데이터와 같은 형식으로 제작하고 기존 데이터프레임과 합치는 등 많은 것을 경험하고 배웠다.

     

    내가 다운받은 데이터도 불균형을 해소하기엔 한계가 있었지만 기존보다 훨씬 불균형이 해소됐다.

    기존에 데이터셋은 작은 데이터는 500개정도인데 많은 데이터는 7000개?정도였다.

    내가 새로 다운받고 기존 데이터와 합친 데이터셋은 최대 1500개 최소 500개 수준으로 이정도면 양호하다.

     

    그리고 모델을 학습시킬 때 class_weight를 balance로 설정하여 가중치를 주었다.

    새로운 데이터 셋으로 모델을 학습시킨 결과....Accuracy가 61%가 나왔고 logloss가 1.3정도 나왔다!

    역대 모델링한 것중에 가장 좋은 성적이였다!! 그리고 여기서 내가 파라미터를 잘 조정하고 모델병합까지 한다면

    accuracy를 60%후반으로 끌어올리고 logloss는 1.1초반대로 내릴 수 있을거란 희망을 품었다!!

     

    중간 과정에서 해당 모델을 test데이터셋 예측결과를 제출했는데 56%의 정확도와 1.56의 logloss를 얻었다..

    내가 만든 모델이 새로 투입한 데이터에 과적합되어있음을 의미했다..

    내 마지막 보루였는데....아쉬었다..오늘이 제출 마감이고 이 결과를 나는 새벽에 얻었으므로

    더이상 어떻게 시도해봐야 할 지 모르겠다.. 내가 모르는건 지식이 부족하기 때문이기에 이 지식을 채워넣을 일만 남았다

     

    마치며

    한 달이라는 시간동안 꽤 많은 시간을 투자했다. 잠도 줄여가면서 모르는 분야를 공부도 하고 구글링을 진짜 열심히 했던거같다. 그래도 원하는 결과를 얻지 못해서 마음은 조금 아프지만 나는 한 달동안 많이 성장했음을 느낀다. 논문을 해석하고 새로운 방법을 도모하고 모델을 만드는 전체 과정을 아우르면서 어떻게 디테일하게 성능을 높일 수 있는지까지 배웠다. 

    아 그리고 코드를 작성하면서 np와 pd, matplot에 대한 기본 지식이 많이 부족함을 깨닫고 바로 udemy에서 기본 강의 결제했다ㅋㅋ...기본기를 더 탄탄하게 갖춘 내가 되기를 바라며...좋은 경험이었고 좋은 대회였다..이제 보내준다..고생했다 내 자신아..!

     

    반응형

    댓글

Designed by Tistory.