[PyTorch] 파이토치 기초

imacusirius·2021년 11월 21일
0

파이토치

파이토치는 오픈소스이고, 커뮤니티가 주도하는 딥러닝 프레임워크다. 테이프 기반 자동 미분 방식을 구현한다. (bit.ly/2Jrntq1) 이 방식은 계산 그래프를 동적으로 정의하고 실행할 수 있다. 디버깅이 아주 편리하고, 복잡한 모델을 손쉽게 만들 수 있다!

다양한 딥러닝용 패키지를 제공하는 최적화된 텐서 조작 라이브러리로, 핵심은 텐서다! 텐서란 다차원 데이터를 담은 수학 객체로, 0차 텐서는 하나의 숫자 또는 스칼라이고, 1차 텐서는 숫자 배열 또는 벡터, 2차 텐서는 벡터의 배열 또는 행렬이다.

텐서는 n차원 스칼라 배열로 일반화할 수 있다!

여기서 앞으로 공부할 내용...

  • 텐서 만들기
  • 텐서로 연산하기
  • 텐서로 인덱싱, 슬라이싱, 연결하기
  • 텐서로 그레이디언트 계산하기
  • GPU와 함께 CUDA 텐서 사용하기

파이토치 설치

설치 과정은 다른 블로그를 참고하여 진행했다.
Anaconda Prompt에 명령어를 입력하는 방식이고, https://pytorch.org/ 요기서 명령어를 긁어 왔다.

텐서 만들기

헬퍼 함수 describe(x)를 정의한다. describe는 텐서 타입, 차원, 값과 같은 텐서의 속성을 출력한다.

파이토치에서는 torch 패키지를 사용해 다양한 방법으로 텐서를 만들 수 있다.

차원을 지정해 텐서를 랜덤하게 초기화

// 책이랑 코드가 다르다. 아래 코드를 안 넣어서 그런가.... 책에는 없음...!!

  • torch.manual_seed()는 random seed를 고정하기 위한 함수이다! 난수가 매번 바뀌면 결과 값에 영향을 미치므로 고정시키는 것

[0,1) 범위의 균등 분포에서 샘플링한 값으로 랜덤하게 초기화한 텐서 생성

또는

표준 정규 분포에서 텐서 생성

동일한 스칼라 값으로 채운 텐서 생성

내장함수로 0(zeros) 또는 1(ones)로 채운 텐서를 만들거나, fill_() 메서드를 사용해 특정 값으로 채울 수도 있다.
밑줄 문자가 있는 파이토치 인-플레이스 메서드는 텐서 값을 바꾸는 연산을 의미한다. 즉, 아래 코드처럼 새로운 객체를 생성하지 않고 현재의 값을 변경한다.

파이썬 리스트를 사용해 텐서 생성


값은 리스트로 전달하거나 넘파이 배열로 전달할 수 있다. 또한 언제든 파이토치 텐서를 넘파이 배열로 바꿀 수도 있다.

넘파이 배열을 사용하면 텐서 타입이 기본 FloatTensor가 아니라 DoubleTensor가 된다. → 랜덤한 넘파이 배열의 기본 데이터 타입이 float64라서

넘파이로 텐서 생성하고 초기화


넘파이 배열과 파이토치 텐서 사이를 변환하는 것은 넘파이 포맷의 수치 데이터를 사용하는 레거시(legacy) 라이브러리를 사용할 때 중요하다.

텐서의 타입과 크기

텐서에는 타입과 크기가 있다.

torch.Tensor 생성자를 사용할 때 기본 텐서 타입은 torch.FloatTensor다. 텐서 타입은 초기화할 때 지정하거나 이후 타입 캐스팅 메서드를 사용해 다른 타입(float, long, double 등)으로 바꿀 수 있다.

초기화할 때 타입을 지정하는 방법은 두 가지다. FloatTensor, LongTensor과 같은 특정 텐서 타입의 생성자를 직접 호출하거나 torch.tensor() 메서드와 dtype 매개변수를 사용하는 것이다.

텐서 연산

텐서 생성 후, 일반적 프로그래밍 언어처럼 +, -, *, / 연산자를 사용해 연산을 수행할 수 있다. 또한 아래 코드처럼 연산자 대신에 .add() 같은 함수를 사용할 수도 있다.

텐서의 특정 차원에 적용할 수 있는 연산도 있다. 아래처럼 2D 텐서는 행을 차원 0, 열을 차원 1로 표현한다.

// 책에서는 FloatTensor로 나오는데 나는 왜 LongTensor이지?
// arange(n)는 0부터 n-1까지 순차적으로... ()를 생성한다! 공부하자!


// dim의 의미에 대해서 찾아보자.
// matlab에서는 sum(a, dim)이 차원 dim 에 따라 합을 반환한다는 의미라고 한다.
// dim이나 axis에 대해 알려면 행렬을 알아야 한다. 교육과정에서 왜 빠진 걸까...!!!!!!!!!!!!!

dim이 0이라면 col을 기준으로 연산하고, 1이라면 row를 기준으로 연산한다.

인덱싱, 슬라이싱, 연결


넘파이를 사용한 적이 있다면 위와 같은 인덱싱과 슬라이싱 구조가 익숙하겠지만 나는 아니다!!! ㅠㅠ

복잡한 인덱싱과 슬라이싱!

텐서에서 연속적이지 않은 위치를 참조할 때 유용하다.

여기서 인덱스가 LongTensor 인 점에 주목해야 한다! 파이토치 함수를 사용할 때 필수 조건이다.

텐서 연결... with 내장 함수로 차원 지정

선형 대수 연산

행렬 곱셈(mm), 역행렬(inverse, pinverse), 대각합(trace) 등이 있다.


// 책에 적힌 예제대로 하면 또 이런 오류가 뜬다. 진짜 짱난다. github에 올라온 코드를 보면 다르다. 아니 왜??
// 중간에 In [32]는 내가 추가한 건데, float로 바꿔 줘도 안 됐다. 분명히 안 됐었는디 아래는 왜 되는 거지? 열밧네..


아무튼 되신다. 자세한 건 파이토치수학문서를 참고하자.

텐서와 계산 그래프

파이토치 tensor 클래스는 텐서 그 자체인 데이터와 대수 연산, 인덱싱, 크기 변경과 같은 다양한 연산을 캡슐화한다. 텐서의 require_grad 불리언 매개변수를 True로 지정하면 그레이디언트 기반 학습에 필요한 손실 함수와 텐서의 그레이디언트를 기록하는 부가 연산을 활성화한다.

그레이디언트 연산


아니이거전자책올해발행된거아니냐고요대체나한테왜이러는데ㅠㅠ짱나지만github가서코드보고수정수정...참을인참을인참을인
// 수정수정!! 내가 오타 내서 그런 거였다!!

// 아래는 책 보고 수정한 코드

requires_grad = True로 텐서를 생성하면 파이토치는 그레이디언트 계산에 사용하는 부가 정보를 관리한다.
1. 파이토치가 정방향 계산의 값을 기록한다.
2. 계산이 끝나면 스칼라 값 하나를 사용해 역방향 계산을 수행한다.
3. 역방향 계산은 손실 함수의 평가 결과로 얻은 텐서에서 backward() 메서드를 호출해 시작한다.
4. 역방향 계산은 정방향 계산에 참여한 텐서 객체에 대한 그레이디언트 값을 계산한다.

일반적으로 그레이디언트는 함수 입력에 대한 함수 출력의 기울기를 나타내는 값이다. 계산 그래프에서 그레이디언트는 모델의 파라미터마다 존재하고, 오류 신호에 대한 파라미터의 기여로 생각할 수 있다.

파이토치에서 계산 그래프에 있는 노드에 대한 그레이디언트를 .grad 속성으로 참조할 수 있다! 옵티마이저는 .grad 속성을 사용해 파라미터 값을 업데이트한다.

쿠다는 내 노트북이 힘드니까 다음 번에 추가하겠음...

0개의 댓글