https://inuplace.tistory.com/460?category=912534
위 구현의 확실한 이해를 위한 개인복습문서입니다.
다른 사람들의 가독성은 신경쓰지 않았습니다.
<파이썬 모듈 불러오기>
먼저 모듈은 당연히 불러와야한다. numpy 배열은 각 데이터 정보를 표현하는데 사용할 것이므로 필요하고, csv는 csv파일로부터 데이터를 불러올 것이므로 필요하다. time함수는 randomize함수를 정의할 때 시드값을 시간마다 다르게 부여하기 위해서 사용된다. 랜덤 시드값을 1234로 먼저 주고, randomize함수를 사용하면 시드값이 현재 시간을 기반으로 다르게 부여되도록 한다.
<하이퍼 파라미터 정의>
하이퍼파라미터는 추후 가중치 값들을 랜덤난수배열 생성을 통해 정의할 때 정규분포의 평균값과 표준편차값으로 활용된다. 학습률은 뭐 걍 학습률이다.
<메인 실험함수>
그냥 데이터를 불러오고 모델 초기화한 다음 학습이랑 테스트 수행시키는 함수이다. 아래에 정의할 함수를 순서대로 실행할 뿐이다. 이것의 의미라 하면 에폭카운트랑 미니배치사이즈, 레포트 주기값을 받아 각 함수에 배분시키는 정도이다. 그냥 전체적인 프로세스를 좀더 간단하게 하기위한 함수라고할 수 있겠다.
<데이터 불러오는 함수>
abalone.csv로부터 값을 받아 이를 배열에 저장한다. 한 행씩 row에 받아서 저장하는 형태이기 때문에 csv를 다 돌고나서 rows에는 csv파일에 존재하는 모든 행들이 하나씩 저장되어 있을 것이다. (2차원리스트) 참고로 next는 하나 건너뛰는 함수로 csv파일 첫행에 존재하는 컬럼이 저장된 행 하나를 스킵해준다. 참고로 데이터 내부엔 결과값(Rings, 종속변수)도 함께 저장되어 있다.
data, input_cnt, output_cnt를 정의한다. input_cnt는 입력데이터 개수인데, 우리는 성별정보에 대해 원 핫 벡터 방식을 사용할 것이므로 총 10개(총 8개인데, 성별3 + 나머지7해서 10)가 필요하다. output_cnt는 rings개수만 구하면 되므로 1을 저장한다. data에는 입력데이터(독립변수)와 결과데이터(종속변수)가 우선 함께 저장될 것이다. 따라서 rows에 존재하는 행의 갯수를 len함수를 통해 찾고, 우선 0으로 구성된 numpy 배열을 생성한다. 그리고 row를 받아오면서 원 핫 벡터처리와 함께 data에 rows의 row에 저장된 데이터들을 넣어준다.
<모델 초기화 함수>
사용할 모델의 weight와 bias를 정의한다. weight는 입력데이터 하나하나에 대해 결과데이터 수만큼 필요하므로, (독립변수개수x종속변수개수)의 numpy 배열이 필요하다. 기존에 정의해놓은 하이퍼 파라미터를 사용해 정규분포의 랜덤변수 기반 (10x1) 크기의 numpy배열을 생성한다. 해당값들이 초기 가중치이다. bias는 결과데이터마다만 필요하므로, 종속변수개수만큼만 필요하다. 초기값으로는 0을 사용했다. 1크기의 0을 가지는 numpy배열을 생성한다.
<학습 및 테스트 수행 함수>
epoch_count, mb_size, report를 받아 학습을 시행한다. 미니배치사이즈를 기반으로 전체 배치를 몇으로 나눠야 할지 step_count에 저장한다. 그리고 아래에서 정의할 get_test_data를 사용해 data변수에 저장해놓은 데이터 중 test에 사용할 데이터를 받아온다. (전체 데이터를 모두 학습에 사용하면 테스트할 데이터가 없어진다. 따라서 데이터를 나눠서 학습전용데이터와 테스트전용데이터로 나눈다. 물론 나누는 기준은 row이다. column별로 나누면 변수들이 쪼개져서 아예 쓸수가 없을 것이다.)
그 후 에폭(학습 데이터 기반 한 사이클)개수만큼 배치에 대해 학습을 진행한다. get_train_data를 통해 현 미니배치에 해당하는 학습데이터를 얻고, 미니배치별로 나눠서 학습을 진행(run_train)한다. 한 미니배치 학습이 끝날때마다 해당 학습에서 도출된 손실함수값과 정확도를 리스트에 저장해놓고 보고가 필요할시(보고주기가 돌아올시) 현 학습에 대한 평균손실함수값과 평균정확도를 리턴한다.
모든 에폭이 종료되면 미리 얻어놨던 테스트 데이터(test_x, test_y)를 기반으로 최종 테스트를 진행하고 결과를 출력한다.
<학습 및 평가 데이터 획득함수>
arrange_data함수는 미니배치 사이즈를 기반으로 전체 배치를 수행하기 위해선 총 몇번 미니배치학습을 진행해야 하는지를 구하고 리턴한다. 뿐만 아니라 전역변수 'shuffle_map'을 사용한다. 셔플맵은 데이터 행크기의 0부터 행개수까지의 값을 하나씩 가지는 numpy배열이다. 참고로 학습데이터는 전체데이터의 80%이므로 이를 기반으로 step_count를 결정한다. test_begin_idx함수는 이러한 학습데이터와 테스트 데이터의 구분 기준점을 명시한 변수이다. step_count * mb_size로 결정한다.
get_test_data는 위에서 구한 셔플맵과 테스트비긴인덱스를 기반으로 테스트 데이터를 가져온다. 현재데이터 그대로에서 데이터를 뽑아오면 특정순서로 나열되어 있을 우려가 있으므로, 셔플맵을 통해 fanxy_indexing하여 랜덤하게 가져온다. 해당 데이터를 슬라이싱을 통해 독립변수 파트와 종속변수파트로 나누어 리턴한다. (test_x와 test_y로 받을 것)
get_train_data는 get_test_data와 마찬가지로 셔플맵을 통해 현재의 미니배치(nth파라미터로 받아옴)에 해당하는 데이터를 받아오고 슬라이싱으로 파트를 나누어 리턴한다. 단, nth==0이면 현 에폭에서 첫번째 미니배치라는 뜻이므로 학습데이터부분의 셔플맵을 섞어준다. 이렇게 하는 이유는 매 에폭마다 다른 순서의 데이터를 넣어주어 학습의 다양성을 추구하기 위해서이다.
<단층 퍼셉트론에 대한 순전파 함수>
forward_neuralnet은 가중치와 편향값을 기반으로 입력데이터 x에 대해 순전파를 수행한다. 그냥 행렬곱을 하고 편향을 더해준 값이다. x에는 run_train을 통해 train_x가 전달될 것이므로 미니배치사이즈x10 크기 numpy행렬이 전달될 것이다. weight는 10x1 이므로 결과적으로 미니배치사이즈x1의 output이 나온다.
forward_postproc은 손실함수(평균제곱오차)값을 찾아준다. 추후 편미분에 활용하기 위해 단순차이값도 함께 리턴한다.
<단층 퍼셉트론에 대한 역전파 함수>
backprop_postproc은 1(dL/dL)과 단순차이값을 파라미터로 받는다. 단순차이값를 기반으로 해당 사이즈(미니배치사이즈x1)를 가지며 '1/크기(미니배치사이즈*1)' 값들을 가지는 numpy배열을 생성한다. 그리고 단순차이값에 2를 곱한다. 이는 자세히 보면 미분의 체인룰을 나타낸다. 너무 복잡하게 들어갈 것 없이 합성미분의 앞부분을 나타낸다 정도로 받아들여도 괜찮다.(내부적으로는 더 많은 체인룰이 있어서 코드를 이렇게 짠거 같긴한데, 나는 이해만 하고 넘겼다.)
그 후 해당값을 활용해서 backprop_neuralnet에서 가중치와 편향을 최적화해준다.
<학습실행함수 및 평가실행함수>
지금까지 익힌 함수를 적절히 사용하는 정도라 설명할 건 없음.
이정도면 다음장으로 넘어가도 되겠지
또 이해안되면 다시 복습해야겠다
'🛠 기타 > Data & AI' 카테고리의 다른 글
규제 선형모델 Ridge와 Lasso 개념 이해 (0) | 2020.07.23 |
---|---|
[scikit-learn 라이브러리] LinearRegression (선형회귀) (0) | 2020.07.23 |
IMDB Dataset을 활용한 나이브베이즈 예제 (0) | 2020.07.22 |
자주 사용되는 numpy.random 함수들 (0) | 2020.07.22 |
[scikit-learn 라이브러리] KNN 분류기 옵션 (0) | 2020.07.22 |