상세 컨텐츠

본문 제목

머신러닝과 딥러닝(10)_파이토치

카테고리 없음

by teminam 2023. 6. 14. 16:38

본문

1. 파이토치(Pytorch)

  • 텐서플로우와 함께 머신러닝, 딥러닝에서 가장 널리 사용되는 프레임 워크
  • 초기에는 Torch라는 이름으로 Lua 언어 기반으로 만들어졌으나, 파이썬 기반으로 변경한 것이 Pytorch
  • 뉴욕대학교와 페이스북이 공동으로 개발하였고, 현재 가장 대중적이고 널리 사용함

 

    파이토치(PyTorch)는 딥러닝을 위한 오픈소스 머신 러닝 라이브러리입니다.
    파이토치는 Facebook의 인공지능 연구팀에서 개발되었으며, GPU를 활용한 고성능
    계산과 자동 미분(automatic differentiation)을 통해 신경망 모델을 구축하고
    학습할 수 있는 강력한 도구입니다.

    파이토치의 주요 특징은 다음과 같습니다:

        1. 동적 그래프: 파이토치는 동적 그래프(dynamic graph)를 사용하여 계산
        그래프를 생성합니다. 이는 모델을 구성하고 수정하는 것이 간편하며, 디버깅과
        프로파일링을 용이하게 만들어줍니다.

        2. 쉬운 사용성: 파이토치는 직관적이고 간결한 인터페이스를 제공하여 사용자가
        빠르게 모델을 구현하고 실험할 수 있도록 도와줍니다. 유연한 구성 가능성과
        간단한 API로 인해 파이토치는 많은 개발자들에게 사랑받고 있습니다.

        3. 자동 미분: 파이토치는 자동 미분 기능을 내장하고 있어, 복잡한 신경망
        모델을 쉽게 학습시킬 수 있습니다. 이를 통해 모델의 파라미터에 대한 손실
        함수의 미분을 자동으로 계산하여 경사 하강법(gradient descent) 등의 최적화
        알고리즘을 사용할 수 있습니다.

        4. GPU 지원: 파이토치는 GPU를 효율적으로 활용하여 대규모의 데이터와 복잡한
        모델을 더 빠르게 처리할 수 있습니다. CUDA를 통한 GPU 가속화를 지원하며,
        텐서 연산을 자동으로 GPU로 전달하여 연산 속도를 향상시킵니다.

        5. 다양한 응용 분야: 파이토치는 주로 딥러닝 연구 및 응용 분야에서 사용되며,
        이미지 분류, 객체 감지, 자연어 처리, 음성 처리 등 다양한 분야에서 뛰어난
        성능을 발휘합니다. 또한, PyTorch는 전이 학습(transfer learning)과 같은 고급
        기술을 지원하여 적은 데이터로도 강력한 모델을 구축할 수 있습니다.

    파이토치는 활발한 커뮤니티와 풍부한 생태계를 갖추고 있으며, 다양한 예제와
    튜토리얼, 문서가 제공되어 사용자들이 학습하고 문제를 해결하는 데 도움을
    줍니다.

1-1. 자료구조의 스칼라(Scalar)

  • 하나의 상수를 의미

1-2. 벡터(Vector)

  • 상수가 두 개 이상 나열되었을 경우

1-3. 행렬(Matrix)

  • 2개 이상의 벡터 값을 가지고 만들어진 값으로 행과 열의 개념을 가진 숫자의 나열

1-4. 텐서(Tensor)

  • 다수의 행렬이 모이면 텐서라고 부름
  • 배열이나 행렬과 매우 유사한 특수한 자료구조
  • 파이토치는 텐서를 사용하여 모델의 입력과 출력, 모델의 배개변수들을 처리시 사용됨.
from IPython.display import Image
Image(url='https://miro.medium.com/max/875/1*jRyyMAhS_NZxqyv3EoLCvg.png')

2. 텐서의 변환

3. 파이토치 주요 함수

i = torch.arange(16).reshape(2, 2, 4)
print(i, i.shape)

# 차원을 인덱스로 변경
j = i.transpose(1, 2) # 2, 4, 2
print(j, j.shape)

    주어진 코드에서는 파이토치의 텐서 연산을 사용하여 텐서의 차원을 변경하는 예시가 제시되었습니다. 코드를 한 줄씩 살펴보면서 설명해보겠습니다:

    1. `i = torch.arange(16).reshape(2, 2, 4)`: 0부터 15까지의 숫자로 이루어진 1차원 텐서를 생성한 후, `reshape()` 함수를 사용하여 `(2, 2, 4)` 모양의 3차원 텐서로 변형합니다. 따라서 `i`는 다음과 같은 모양을 갖습니다:
    ```
    tensor([[[ 0,  1,  2,  3],
            [ 4,  5,  6,  7]],

            [[ 8,  9, 10, 11],
            [12, 13, 14, 15]]])
    ```
    `i.shape`를 출력하면 `torch.Size([2, 2, 4])`가 나타납니다. 이는 `i`의 모양을 나타내는 튜플입니다.

    2. `j = i.transpose(1, 2)`: `i`의 차원을 변환하여 `j`를 생성합니다. `transpose()` 함수를 사용하여 차원 1과 차원 2를 서로 바꿈으로써 `i`의 차원을 변경합니다. 따라서 `j`는 다음과 같은 모양을 갖습니다:
    ```
    tensor([[[ 0,  4],
            [ 1,  5],
            [ 2,  6],
            [ 3,  7]],

            [[ 8, 12],
            [ 9, 13],
            [10, 14],
            [11, 15]]])
    ```
    `j.shape`를 출력하면 `torch.Size([2, 4, 2])`가 나타납니다. 이는 `j`의 모양을 나타내는 튜플입니다.

    결과적으로, `i`는 `(2, 2, 4)` 모양의 3차원 텐서이며, `j`는 `(2, 4, 2)` 모양의 3차원 텐서로 변환된 것을 확인할 수 있습니다. `transpose()` 함수를 사용하여 차원을 변경함으로써 텐서의 데이터가 재배열되었습니다.

4. GPU 사용하기

  • 코랩에서 device 변경하는 방법
    • 상단 메뉴 -> 런타임 -> 런타임 유형변경 -> 하드웨어 가속기를 GPU로 변경 -> 저장 -> 다시 시작 및 모두실행

    위의 코드는 파이토치를 사용하여 텐서(Tensor)를 조작하는 예시입니다. 코드를
    한 줄씩 살펴보겠습니다:

    1. `tensor = tensor.reshape(4, 3)`: `tensor` 변수의 형태를 `(4, 3)`으로
    변경합니다. 이는 원래 텐서의 요소들을 4개의 행과 3개의 열로 재구성하는
    작업입니다. 텐서의 모양을 변경하기 위해 `reshape()` 함수를 사용합니다.

    2. `tensor = tensor.int()`: `tensor`의 데이터 타입을 정수형(integer)으로
    변환합니다. 이는 텐서의 요소들을 정수로 변환하는 작업입니다. `int()` 함수를
    사용하여 변환합니다.

    3. `if torch.cuda.is_available():`: 현재 시스템에서 CUDA를 사용할 수 있는지
    확인하는 조건문입니다. CUDA는 NVIDIA의 GPU를 활용한 연산 가속을 제공하는
    도구입니다.

    4. `print('GPU를 사용할 수 있음')`: CUDA를 사용할 수 있다면 'GPU를 사용할
    수 있음'을 출력합니다. 이는 CUDA를 사용하여 GPU 가속 연산을 수행할 수
    있는지 여부를 확인하는 메시지입니다.

    5. `tensor = tensor.to('cuda')`: CUDA를 사용할 수 있다면, `tensor`를 GPU
    메모리로 이동시킵니다. 이를 통해 GPU에서 텐서 연산을 수행할 수 있습니다.
    `'cuda'`는 CUDA 디바이스를 의미하며, `.to()` 메소드를 사용하여 텐서를 특정
    디바이스로 이동시킵니다.

    6. `print(f'shape: {tensor.shape}')`: `tensor`의 모양(shape)을 출력합니다.
    `shape` 속성은 텐서의 차원을 나타내는 튜플입니다.

    7. `print(f'type: {tensor.dtype}')`: `tensor`의 데이터 타입을 출력합니다.
    `dtype` 속성은 텐서의 요소들의 데이터 타입을 나타냅니다.

    8. `print(f'device: {tensor.device}')`: `tensor`가 현재 저장된 디바이스를
    출력합니다. `device` 속성은 텐서가 저장된 디바이스를 나타냅니다. 앞서
    CUDA를 사용했다면, 'cuda'로 출력될 것입니다.

    이 코드는 주어진 텐서의 모양과 데이터 타입을 변경한 후, GPU를 사용할 수
    있다면 해당 텐서를 GPU로 이동시키는 예시입니다.

 

5. 텐서의 인덱싱과 슬라이싱

    주어진 텐서는 다음과 같습니다:

    ```
    tensor([[ 1,  2,  3,  4],
            [ 5,  6,  7,  8],
            [ 9, 10, 11, 12]])
    ```

    이제 각각의 코드와 그에 대한 설명을 살펴보겠습니다:

    1. `print(a[1])`: 인덱스 1의 행을 출력합니다. 따라서 결과는 `[5, 6, 7, 8]
    `입니다. 행 인덱스는 0부터 시작하며, 인덱스 1은 두 번째 행을 나타냅니다.

    2. `print(a[0, -1])`: 첫 번째 행의 마지막 열의 값을 출력합니다. 따라서
    결과는 `4`입니다. 열 인덱스는 0부터 시작하며, `-1`은 마지막 열을 나타냅니다.

    3. `print(a[1:-1])`: 두 번째 행부터 마지막 행 직전까지의 모든 행을
    출력합니다. 따라서 결과는 다음과 같습니다:
    ```
    tensor([[ 5,  6,  7,  8],
            [ 9, 10, 11, 12]])
    ```
    두 번째 행부터 마지막 행 직전까지의 행이 선택되었습니다.

    4. `print(a[:2, 2:])`: 처음부터 두 번째 행까지의 모든 행과, 세 번째 열부터
    마지막 열까지의 모든 열을 출력합니다. 따라서 결과는 다음과 같습니다:
    ```
    tensor([[ 3,  4],
            [ 7,  8]])
    ```
    처음부터 두 번째 행까지의 행과, 세 번째 열부터 마지막 열까지의 열이
    선택되었습니다.

    이렇게 주어진 텐서에서 인덱싱과 슬라이싱을 사용하여 특정 원소, 행, 열, 또는
    부분 텐서를 선택할 수 있습니다.