본문 바로가기

Data_Analysis_Track_33/Python

Python_Deeplearning_pytorch_01(tensor 다루기)

pip install  torch  torchvision  torchaudio : pytorch 설치

 

Tensor 생성

  • 파이토치에서 데이터를 저장하는 자료구조
  • ndarray와 성격, 사용법이 유사하다.

 

원하는 형태(shape) 텐서 생성

  • torch.tensor(자료구조 \[, dtype\])
        - 지정한 dtype(Data type)에 맞는 Tensor객체를 생성해서 반환한다.

 

특정 타입의 Tensor를 직접 생성

  • torch.tensor()로 생성하면서 dtype을 지정하면 아래 타입의 Tensor객체가 생성된다.
  • 원하는 Type의 Tensor클래스를 이용해 직접 생성해도 된다.
  • torch.FloatTensor(자료구조)
        - float32 타입 텐서 생성
  • torch.LongTensor(자료구조)
        - int64 타입 텐서생성
  • 그외
        - BoolTensor(bool), CharTensor(int8), ShortTensor(int16), IntTensor(int32), DoubleTensor(float64)

 

tensor 상태 조회

  • tensor.shape, tensor.size([축번호])
        -  tensor의 shape조회
  • tensor.dtype, tensor.type()
        - tensor 원소들의 데이터타입 조회
        - dtype은 data type을 type()은 tensor 객체의 클래스 타입을 반환한다.
  • tensor.ndim, tensor.dim()  : tensor 차원
  • tensor.numel(): 전체 원소 개수

 

torch import 및 version 확인

import torch

torch.__version__

 

tensor 생성 및 정보 확인

a = torch.tensor([[1,2],[3,4]], dtype=torch.float32)

print("shape:", a.shape, a.size()) # 전체 shape
print("축별 크기:", a.shape[0], a.size(0)) # 축별 size
print("type:", a.type(), a.dtype)
print('차원크기:', a.dim(), a.ndim)
print('원소개수:', a.numel())
print("device:", a.device)

 

range를 활용한 torch 생성 : 0~9까지의 자연수를 생성한다.

torch.tensor(range(10))

 

tensor type 설정

#Float, Double(32, 64bit 실수)/Int, Long(32, 64 bit 정수) type Tensor
b = torch.FloatTensor([1,3,7])  #float32
print(b.dtype)
c = torch.IntTensor([10,20,30]) # int64
print(c.dtype)
d = torch.DoubleTensor([1, 2, 3]) #torch.tensor([], dtype=torch.float64)
print(d.dtype)
e = torch.LongTensor([10, 20, 30, 40]) # torch.tensor([], dtype=torch.int64)
print(e.dtype)

 

특정 값으로 구성된 Tensor 생성

  • torch.zeros(*size), zeros_like(텐서): 0으로 구성된 tensor 생성
  • torch.ones(*size), ones_like(텐서): 1로 구성된 tensor생성
  • torch.full(*size, fill_value), full_like(텐서, fill_value): 지정한 값으로 구성된 tensor생성

 

zeros, ones, full

torch.zeros(3,2,3)  # 3 X 2 X 3 3차원 
torch.ones(2,3) # 2 X 3 2차원
torch.full((3,2), fill_value=100) # 3 X 2 2차원. 100으로 구성

 

a = torch.tensor([[1, 2],[3,4]]) # 2 x 2
print(a.shape)
b = torch.zeros_like(a)  # a와 동일한 shape의 tensor를 생성. 
b = torch.ones_like(a)
b = torch.full_like(a, 20)
b.shape
b

 

동일한 간격으로 떨어진 값들로 구성된 배열생성

  • torch.arange(start=0, end, step=1)
  • torch.linspace(start, end, steps,) : steps - 원소개수

 

arange를 활용한 동일한 간격으로 떨어진 값들의 배열 생성

torch.arange(10) # 0 ~ 10-1
torch.arange(0, 1, 0.1)  # 0 ~ 1, 증감: 0.1
torch.arange(10, 1, -1)  # 10 ~ 1+1 : 증감: -1

 

linspace를 활용한 동일한 간격으로 떨어진 값들의 배열 생성

torch.linspace(0, 10, 5)  # 0 ~ 10, 등분한값 5개
torch.linspace(0, 1, 11)  # 0 ~ 1, 등분한값 10개

 

빈 tensor 생성

  • torch.empty(*size)

 

empty

torch.empty(3,2)

 

난수를 이용한 생성

  • torch.rand(*size): 0 ~ 1사이 실수로 구성된 배열을 생성. 각 값은 균등분포를 따른다.
  • torch.randn(*size): 표준정규분포(평균:0, 표준편차:1)를 따르는 실수로 구성된 배열 생성
  • torch.randint(low=0, high, size): 지정한 범위의 정수로 구성된 배열 생성
  • torch.randperm(n): 0 ~ n-1 사이의 정수를 랜덤하게 섞은 값을 원소로 가지는 배열 생성

 

난수 이용 (rand, randn, randint, randperm)

# torch.manual_seed(1004)  # seed 설정
torch.rand(100, 3)#.shape
torch.randn(30, 5).shape
torch.randint(1, 10, (3,30)).shape
torch.randperm(5) # 0, 1, 2, 3, 4

 

randperm을 이용한 데이터 섞기

a = torch.arange(100, 109)
print(a)
# index를 섞어서 데이터를 섞는다.(shuffle)
idx = torch.randperm(9)
print(a[idx])
print(idx)

 

tensor를 상수로 변환

  • tensor객체.item()
        - Scalar(상수) tensor를 python 상수로 변환

 

변환

# tensor.item() -> torch.Tensor객체를 파이썬 상수로 변환.
a = torch.tensor(10)
print(a, a.dtype, a.type())
print(a.item())  # 파이썬 정수로 변환.

 

원소가 하나인 배열 변환

b = torch.tensor([20])
print(b)
print(b.item()) #원소가 하나인 배열 변환 가능

 

원소 여러개 배열 변환

c = torch.tensor([1, 10, 100])
print(c, c.shape)
# print(c.item()) #원소가 여러개일 경우 Exception발생

 

d = torch.tensor([10], device='cuda') # device="cuda" -> VRAM(GPU의 RAM)에 저장.
# VRAM에 저장된 값도 추출가능
print(d)
print(d.item())

ndarray 호환

  • ndarray를 tensor로 생성
        - torch.tensor(ndarray)
        - torch.from_numpy(ndarray)
  • tensor를 ndarray로 변환
        - tensor.numpy()
        - tensor가 gpu에 있을 경우 cpu로 옮긴 뒤 변환해야 한다.

 

import

import numpy as np
import torch

 

ndarray -> tensor

# ndarray -> tensor
arr = np.arange(1,10)

torch.tensor(arr)
torch.from_numpy(arr)

 

tensor  ->  ndarray

# tensor -> ndarray
t = torch.randn(3,3)
print(t)
b = t.numpy()
print(type(b))
b

 

device = cuda 경우

t2 = torch.randn(2,2, device="cuda")
t2

 

# VRAM에 있는 Tensor객체는 ndarray로 변환이 안됨.
# VRAM의 Tensor를 RAM(CPU)로 이동시킨뒤에 변환.
# t2.numpy() 
t2.to("cpu").numpy()

 

Tensor gpu/cpu 메모리로 옮기기

  • pytorch는 데이터셋인 tensor를 cpu메모리와 gpu 메모리로 서로 옮길 수 있다.
        - 데이터에 대한 연산처리를 어디서 하느냐에 따라 메모리를 선택한다.
        - 장치는 문자열로 설정한다.
            - CPU 사용: "cpu"
            - nvida GPU: "cuda"
            - Apple m1: "mps"
                - pytorch 1.12 부터 지원
  • 옮기기
        - tensor 생성시 `device` 파라미터를 이용해 설정
        - `tensor.to(device)`를 이용해 설정
  • 현재 실행환경에서 어떤 장비를 사용할 수 있는지 확인
        - nvidia gpu 사용가능확인
            - `torch.cuda.is_available()` - nvida gpu 사용가능 여부
            - `torch.backends.mps.is_available()` - M1 사용가능 여부

 

cuda.is_available()

# device = 'cuda' if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_available() else 'cpu'
device = 'cuda' if torch.cuda.is_available() else 'cpu'
device

 

device 확인

t = torch.tensor([1, 2, 3], dtype=torch.float32, device=device)
print(t.device)
t

# t2 = t.to("cpu")
# t2

원소 조회및 변경 - indexing/slicing

  • 대부분 Numpy 와 동일
        - slicing에서 step을 음수로 지정할 수 없다.

 

배열 t 생성

t = torch.randint(-10, 10, (100, ))
t.shape
t

 

indexing, fancy indexing

t[0] # indexing
t[0], t[[1, 5, -1]] # 여러개 조회 -> fancy indexing

 

reverse

t[:5]
t[10:15]
t[90:]
t[3:30:3]
# t[10:1:-2]  #에러
t[1:10:2].flip(dims=(0,)) #reverse

 

boolean index

# boolean index
t[t > 0] # 0보다 큰 값들만 조회

 

변경

# 변경
t[0] = 100
t

 

2차원 배열 t 생성

t = torch.arange(1, 10).reshape(3,3) # 2차원 : 2방향의 index
t

 

2차원 배열 indexing

# t[ 0축, 1축]
t[0, 2]
t[1, 2]

 

t[[1,0], [2,2]]  #(1,2), (0,2)
# t[[첫번째값, 두번째값]-0축, [첫번째값, 두번째값]-1축]