본문 바로가기

AI.ML

[AI/ML 스터디] 1주차 - 03. 파이토치기초(~최적화)

텐서

텐서란 넘파이 라이브러리의 ndarray 클래스와 유사한 구조로 배열이나 행렬과 유사한 자료 구조를 말한다. 모델 학습에 특화된 데이터이므로 정확한 데이터 형식을 취해 활용해야한다.


  • 텐서 생성
    • torch.tensor()
      • 입력된 데이터를 복사해 텐서로 변환
    • torch.Tensor()
      • 텐서의 기본형으로 텐서 인스턴스를 생성하는 클래스
      • 값을 입력하지 않는 경우 비어 있는 텐서 생성
    • torch.LongTensor() / torch.FloatTensor() / torch.IntTensor()
      • 데이터 형식이 미리 선언된 클래스
  • 텐서 속성
    • 형태
      • 넘파이 배열에서 사용하는 형태와 유사
      • 텐서의 차원을 의미
    • 자료형
      • 넘파이 배열에서 사용하는 형태와 유사
      • 텐서에 할당된 데이터 형식을 의미
    • 장치
      • 텐서의 GPU 가속 여부 의미
  • 차원 변환
    • reshape
      • 텐서의 차원 변환
  • 자료형 설정
    • torch.*
      • 자료형 설정에 입력되는 인수
    • torch.floatfloat의 차이
      • torch.float는 32비트 부동 소수점 형식 / float는 64비트 부동 소수점
  • 장치 설정
    • 장치 설정을 정확하게 할당하지 않으면 실행 오류나 연산 시간이 오래걸린다는 단점이 있다. 따라서 모델 학습 전, 장치 설정을 확인하는 것을 권장한다.
    • torch.cuda.is_available
      • cuda 사용 여부 확인
    • torch.cuda.Tensor
      • Tensor 클래스의 경우 device 매개변수가 존재하지만, cuda용 클래스가 별도 존재하기 때문에 해당 코드를 이용
    • device 속성
      • cpu, cuda, mps, mkldnn, opengl, opencl, ideep, hip, msnpu, xla 등
  • 장치 변환
    • 기본적으로 CPU 사용 텐서와 GPU 사용 텐서는 상호 간 연산 불가
    • 그러나 cpu 사용 텐서의 경우 넘파이 배열 간 연산이 가능하다.
    • gpu 사용 텐서를 가지고 넘파이 배열 데이터를 활용하려면 장치 변환을 진행해야함.
    • 장치 간 상호 변환은 cuda와 cpu 메서드를 통해 가능
      • cuda 메서드: cpu 장치로 선언된 값을 gpu로 변환
      • cpu 메서드: gup 장치로 선언된 값을 cpu로 변환
      • to 메서드: 파이토치에서 지원하는 모든 장치 간의 텐서 변환 수행
  • 넘파이 배열의 텐서 변환
    • torch.tensor(넘파이 배열)
    • torch.Tensor(넘파이 배열)
    • from_numpy 메서드
  • 텐서의 넘파이 배열 변환
    • 추론된 결과를 후처리하거나 결괏값을 활용할 때 주로 사용
    • 텐서→ 넘파이
      • numpy 메서드
      • detach 메서드: 현재 연산 그래프에서 분리된 새로운 텐서 반환
      • (gpu 장치라면 cpu 장치로 변환한 다음에 넘파이 배열로 변환 해야함)

가설

어떤 사실을 설명하거나 증명하기 위한 가정으로 두 개 이상의 변수의 관계를 검증 가능한 형태로 기술하여 변수 간의 관계를 예측하는 것을 의미한다.


  • 머신러닝에서의 가설
    • 머신러닝에서의 가설 = 통계적 가설 검정
    • 머신러닝에서의 가설 = 독립변수(x)와 종속변수(y)를 가장 잘 매핑시킬 수 있는 기능을 학습하기 위해 사용
    • 독립 변수와 종속 변수 간의 관계를 가장 잘 근사(Approximation) 시키기 위해 사용

    • 단일 가설(h)
      • 입력을 출력에 매핑하고 평가하고 예측하는 데 사용할 수 있는 단일 시스템을 의미
    • 가설 집합(H)
      • 출력에 입력을 매칭하기 위한 가설 공간으로 모든 가설을 의미
    • H(x) = Wx+b
      • H(x) : 가설
      • W: 가중치
      • b: 편향
      • (→ 가설은 회귀 분석과 같은 알고리즘을 통해 최적의 가중치와 평향을 찾는 과정을 진행)
- 모델
    - 학습이 된 결과
- 예측
    - 모델을 통해 새로운 입력에 대한 결괏값
  • 통계적 가설 검정 사례
    • t- 검정
      • 쌍체 t-검정
        • 동일한 항목 또는 그룹을 두 번 테스트할 때 사용
        • e.g. 동일 집단에 대한 약물 치료 전후 효과 검정, 동일 집단에 대한 학습 방법 전후 효과 검정
      • 비쌍체 t-검정
        • 등분산성을 만족하는 두 개의 독립적인 그룹 간의 평균을 비교할 때 사용
        • e.g. 제약 연구에서 서로 다른 두 개의 독립적인 집단(실험군, 대조군) 간에 유의미한 차이가 있는지 조사, 서울과 인천의 무작위로 선택된 참가자 1000명의 평균 통근 거리 조사
        • 머신러닝의 통계적 가설 적용 시, 비쌍체 t-검정 사용
          • 변수들의 샘플 데이터가 독립항등분포를 따르는데, 이는 비쌍체 t-검정에 적합하기 때문
    • 유의미성 판단
      • 통계량
      • 유의 확률(p-value)
        • 0.05보다 작으면 유의

    *stats.norm.rvs : 특정 평균(loc)과 표준편차(scale)을 따르는 분포에서 데이터를 샘플링하는 함수

손실 함수

단일 샘플의 실젯값과 예측값의 차이가 발생했을 때 오차가 얼마인지 계산하는 함수이다. 인공 신경망의 경우 실젯값과 예측값을 통해 계산된 오찻값을 최소화해 학습 데이터에 대한 가설의 정확도를 높이는 방법으로 학습이 진행되어 각 데이터의 오차를 계산하는데, 이때 손실함수를 사용함. 목적함수, 비용함수라고 부르기도 한다.


  • 제곱 오차
    • 실제값에서 예측값을 뺀 값의 제곱
    • 연속형 변수에 사용되는 손실함수
    • 오차에서는 방향보다 ‘크기’가 더 중요! 그래서 제곱을 취함
      • 평균 제곱 오차(mse)
      • 제곱 오차(se)
      • 오차 제곱합(sse)

 

  • 오차 제곱합
    • 제곱 오차를 모두 더한 값
    • 연속형 변수에 사용되는 손실함수
    • 각 데이터의 오차를 의미하기 때문에 가설 또는 모델 자체가 얼마나 정확히 예측하는 지 알 수 없음
    • 모든 제곱 오차를 더해 하나의 값으로 만들어 가설이나 모델을 평가함

 

  • 평균 제곱 오차
    • 오차 제곱합에서 평균을 취하는 방법
    • 연속형 변수에 사용되는 손실함수
    • 가설의 품질을 측정할 수 있으며, 오차가 0에 가까워질수록 높은 품질을 갖게 된다.
    • 회귀 분석에서 많이 사용되는 손실 함수이다.
      • 평균 제곱근 오차(rmse)
        • 평균 제곱 오차에 루트를 씌운 손실 함수
        • 루트를 통해 평균 제곱 오차에서 발생한 왜곡을 감소시키면, 정밀도를 표현하기에 적합한 형태이다.
        • 오차에 제곱을 적용하여 오차량이 큰 값을 크게 부풀렸기 때문에 왜곡이 발생할 수 있다.최대 신호 대 잡음비를 계산할 때도 사용된다.

  • 교차 엔트로피
    • 실제값의 확률분포와 예측값의 확률분포 차이를 계산
    • 이산형 변수에 사용되는 손실함수 (분류문제)

 

최적화

목적 함수의 결과값의 최적화하는 변수를 찾는 알고리즘을 의미한다. 머신러닝은 손실 함수를 활용해 최적의 해법이나 변수를 찾는 것이 목표이다.

최적화 알고리즘은 실젯값과 예측값의 차이를 계산해 오차를 최소로 줄일 수 있는 가중치와 편향을 계산한다.

최적의 가중치와 편향을 갖는 가설은 오찻값이 0에 가까운 함수가 된다. (=도함수의 변화량이 0에 가깝다.) 따라서 가중치와 오차에 대한 그래프의 극값이 가설을 가장 잘 표현하는 가중치와 오차가 된다.

수학적인 측면에서, 가중치와 오차의 그래프에서 기울기가 0에 가까워질 때 최적의 가중치를 갖는 것을 알 수 있다. 그러나 가중치와 오차 그래프를 가지고 1. 어느 방향으로 이동해야하는지? 2. 얼마나 이동해야하는지?를 알 수 없기 때문에 우리는 최적화 알고리즘 중 하나인 경사 하강법을 사용하는 것이다.


  • 경사 하강법
    • 함수의 기울기가 낮은 곳으로 계속 이동시켜 극값에 도달할 때 까지 반복하는 알고리즘
    • 함수의 기울기가 가장 낮은 곳에 도달한다면 최적의 해를 갖게 되기에, 함수의 기울기가 낮은 곳으로 계속 이동시키는 것임.
    • 기울기가 0을 갖게 되는 가중치를 찾을 때까지 반복하기 때문에 어느 지점에서 시작하더라도 극값을 찾을 수 있게 연산이 진행된다.
    • 밑의 공식에서 a를 곱해 가중치 결과를 조정하는데, 이 값은 기울기가 한 번에 이동하는 간격을 조정한다

    • 가중치 갱신 방법
      • 가설과 손실 함수
      • 가중치 갱신 방법(편미분 진행)
  • 학습률(learning rate)
    • 가중치를 갱신할 때 a를 곱해 가중치 결과를 조정하는데, 머신러닝에서는 이 a 값을 학습률이라고한다.
    • 임의의 값으로 설정한다.
    • 학습률에 따라 다음 가중치의 변화향이 결정되며, 이에 따라 최적의 해를 찾기 위한 반복 횟수가 결정된다.
    • 적절하지 않은 학습률을 선택할 경우, 1. 너무 많은 반복 필요 2. 최적의 해를 못 찾는 문제점이 있다.
  • 최적화 문제
    • 초깃값이나 학습률을 너무 낮거나 높게 잡으면 최적의 가중치를 찾는 데 시간이 오래 걸리거나, 그래프가 발산하여 아예 값을 찾지 못하는 문제점이 발생한다.
      • 기울기가 0이 되는 지점인 극값은 최댓값, 최솟값, 극댓값, 극솟값으로 구분이 가능하다.
      • 이때, 초기 가중치나 학습률을 설정할때 시작점이 적절하지 않거나 학습률이 너무 낮으면, 최솟값이 아닌 극솟값에서 가중치가 결정될 수 있다. 혹은 안장점(안장처럼 생긴 그래프로 방향에 따라 최댓값이 바뀌어 보이는 그래프)이 존재하는 함수에서도 적절한 가중치를 찾을 수 없다.
    • 최적화 알고리즘은 경사 하강법처럼 목적 함수가 최적의 값을 찾아갈 수 있도록 최적화되게끔 하는 알고리즘이다. 따라서 어떤 최적화 알고리즘을 사용하느냐에 따라 모델의 정확도가 달라진다.
      • 경사 하강법
      • 모멘텀
      • Adagrad
      • Adam
  • 단순 선형 회귀: 넘파이
    • 데이터 선언 완료 후, 하이퍼파라미터로 사용되는 가중치, 편향, 학습률에 대한 초깃값을 선언해야한다.
    • 에폭
      • 인공 신경망에서 순전파와 역전파 과정 등의 모델 연산을 전체 데이터세트가 1회 통과하는 것을 의미한다.
      • 각 에폭은 모델이 데이터를 학습하고 가중치를 갱신하는 단계를 나타내며, 여러 에폭을 반복해 모델을 학습시킨다.
        • 순전파: 입력 데이터를 기반으로 신경망을 따라 입력층부터 출력층까지 차례대로 변수를 계산하고 추론한 결과를 의미한다
        • 과소적합: 에폭값이 너무 적을 경우에 학습이 제대로 되지 않은 현상
        • 과대적합: 에폭값이 너무 많을 경우
    • 배치
      • 가설이나 모델의 가중치를 갱신할 때 사용하는 데이터의 크기
      • x와 y변수 쌍으로 이루어진 행 데이터를 나눠서 계산하지 않고 전체 데이터를 한번에 연산하는 경우
      • gpu나 cpu의 상황에 따라 배치 크기 줄여서(=데이터를 나눠서) 반복 학습 시키기도함.

⇒ 실습 결론: 초깃값의 설정은 학습에 큰영향을 미친다. 적절하지 않는 초깃값을 할당 했을 때 하이퍼파라미터 튜닝을 진행하며, 하이퍼파라미터 튜닝을 통해 원활한 학습을 진행할 수 있다.

  • 단순 선형 회귀: 파이토치
    • 파이토치 사용 위한 2가지 포함
      • torch
      • torch.optim : 최적화 함수가 포함된 모듈
    • 파이토치를 사용하기 때문에 ndarray 형식이 아닌, FloatTensor 형식으로 값을 할당해준다.
    • 학습 데이터를 선언했다면, 하이퍼파라미터를 초기화한다.
    • tensor.zeros
      • 0의 값을 갖는 텐서 생성 메소드
    • requires_grad
      • 모든 텐서에 대한 연산을 추적하며 역전파 메서드를 호출해 기울기를 계산하고 저장(파이토치에서 지원하는 자동 미분 기능의 사용 여부)
    • 예제에서 사용한 최적화 함수: 확률적 경사 하강법
      • 모든 데이터에 대해 연산을 진행하지 않고, 일부 데이터만 계산하여 빠르게 최적화된 값을 찾는 방식
      • 미니 배치의 형태이지. 전체 데이터를 n등분하여 학습을 진행하기 때문!
      • 확률적 경사 하강법의 클래스는 최적화하려는 변수와 학습률로 최적화를 적용함. 최적화 하려는 변수는 역전파 과정을 통해 기울기(변화도)를 갱신하려는 텐서 변수를 입력하고, 학습률은 0보다 큰 값을 할당한다.
      • 매게변수에 최적화하려는 변수(가중치, 편향)과 학습률을 입력한다.
    • optimizer.zero_grad 메서드: potimizer변수의 포함시킨 매개변수들의 기울기를 0으로 초기화하여 중복 연산을 방지함
    • cost.backward 메서드: 역전파 수행하여 기울기를 새로 계산해서 넣음
    • optimizer.step 메서드: 최적화 함수의 계산 결과 반영
  • 신경망 패키지를 활용하여 모델 구성
    • torch.nn에 포함되어 있음: from torch import nn
    • 네트워크를 정의하거나 자동 미분, 계층 등을 정의할 수 있는 모듈이 포함되어 있음
    • 먼저 선언한 후 실행부를 짠다
    • 신경망 패키지의 경우 weight와 bias 변수를 사용하지 않으므로 학습 결과 출력 시 모델 매게 변수model.parameters()를 출력한다. 모델 매개별수로 model 변수에서 계산중인 가중치와 편향을 확인할 수 있다는 차이점이 존재한다.
    • ⇒ 실습 결론: 앞으로의 모델은 이 신경망 패키지를 통해 구현한다.