관리 메뉴

개발자의 스터디 노트

텐서의 인덱싱, 슬라이싱, 연결 본문

파이썬/파이토치 자연어처리

텐서의 인덱싱, 슬라이싱, 연결

박개발씨 2022. 2. 8. 23:27
row_indices = torch.arange(2).long()
col_indices = torch.LongTensor([0,1])
describe(x[row_indices, col_indices])

타입: torch.LongTensor
크기: torch.Size([2])
값: 
tensor([0, 4])

1. 텐서의 속성을 볼 수 있는 함수를 선언합니다.

## 헬퍼함수 describe(x)를 정의
def describe(x):
    print("타입: {}".format(x.type()))
    print("크기: {}".format(x.shape))
    print("값: \n{}".format(x))

 

2. 텐서를 생성하여 값을 공유하는 텐서 x를 만들어 봅시다.

import torch
x = torch.arange(6).view(2,3)
describe(x)

타입: torch.LongTensor
크기: torch.Size([2, 3])
값: 
tensor([[0, 1, 2],
        [3, 4, 5]])

 

 

3. 텐서 슬라이싱

describe(x[:1, :2])

타입: torch.LongTensor
크기: torch.Size([1, 2])
값: 
tensor([[0, 1]])
describe(x[0,1])

타입: torch.LongTensor
크기: torch.Size([])
값: 
1

 

 

4. 복잡한 인덱싱 연속적이지 않은 텐서 인덱스 참조하기

indices = torch.LongTensor([0,2])
describe(indices)
describe(torch.index_select(x, dim=1, index=indices))

타입: torch.LongTensor
크기: torch.Size([2])
값: 
tensor([0, 2])
타입: torch.LongTensor
크기: torch.Size([2, 2])
값: 
tensor([[0, 2],
        [3, 5]])
indices = torch.LongTensor([0,0])
describe(torch.index_select(x, dim=0, index=indices))

타입: torch.LongTensor
크기: torch.Size([2, 3])
값: 
tensor([[0, 1, 2],
        [0, 1, 2]])
row_indices = torch.arange(2).long()
col_indices = torch.LongTensor([0,1])
describe(x[row_indices, col_indices])

타입: torch.LongTensor
크기: torch.Size([2])
값: 
tensor([0, 4])

https://runebook.dev/ko/docs/pytorch/generated/torch.index_select

 

PyTorch - torch.index_select - 반환 인덱스 새로운 텐서 input 크기에 따라 텐서가 dim 의 항목을 사용하여

반환 인덱스 새로운 텐서 input 크기에 따라 텐서가 dim 의 항목을 사용하여 index A는 LongTensor 을 . 반환 된 텐서는 원래 텐서 ( input ) 와 동일한 수의 차원을 갖습니다 . dim 번째 차원의 길이와 동일

runebook.dev

 

5. 텐서 연결

import torch
x = torch.arange(6).view(2,3)
describe(x)

타입: torch.LongTensor
크기: torch.Size([2, 3])
값: 
tensor([[0, 1, 2],
        [3, 4, 5]])
        
        

describe(torch.cat([x,x],dim=0))

타입: torch.LongTensor
크기: torch.Size([4, 3])
값: 
tensor([[0, 1, 2],
        [3, 4, 5],
        [0, 1, 2],
        [3, 4, 5]])



describe(torch.cat([x,x],dim=1))

타입: torch.LongTensor
크기: torch.Size([2, 6])
값: 
tensor([[0, 1, 2, 0, 1, 2],
        [3, 4, 5, 3, 4, 5]])


describe(torch.stack([x,x]))

타입: torch.LongTensor
크기: torch.Size([2, 2, 3])
값: 
tensor([[[0, 1, 2],
         [3, 4, 5]],

        [[0, 1, 2],
         [3, 4, 5]]])

 

6. 텐서의 선형대수 계산: 행렬 곱셈

## 텐서의 선형대수 계산: 행렬 곱셈
import torch
x1 = torch.arange(6, dtype=float).view(2,3)
describe(x1)

타입: torch.DoubleTensor
크기: torch.Size([2, 3])
값: 
tensor([[0., 1., 2.],
        [3., 4., 5.]], dtype=torch.float64)



x2 = torch.ones(3,2, dtype=float)
x2[:, 1] +=1
describe(x2)

타입: torch.DoubleTensor
크기: torch.Size([3, 2])
값: 
tensor([[1., 2.],
        [1., 2.],
        [1., 2.]], dtype=torch.float64)



describe(torch.mm(x1,x2))

타입: torch.DoubleTensor
크기: torch.Size([2, 2])
값: 
tensor([[ 3.,  6.],
        [12., 24.]], dtype=torch.float64)

 

7. 텐서와 계산 그래프

7.1 그레이디언트(기울기) 연산을 할 수 있는 텐서 만들기

import torch
x = torch.ones(2,2, requires_grad=True)
describe(x)
print(x.grad is None)

타입: torch.FloatTensor
크기: torch.Size([2, 2])
값: 
tensor([[1., 1.],
        [1., 1.]], requires_grad=True)
True

 

7.2 y를 구하는 함수 선언

y = (x+2) * (x+5) +3
describe(y)
print(x.grad is None)

타입: torch.FloatTensor
크기: torch.Size([2, 2])
값: 
tensor([[21., 21.],
        [21., 21.]], grad_fn=<AddBackward0>)
True

 

 

7.3 x로 부터 y를 구한 뒤 그에 따를 기울기 계산

z = y.mean()
describe(z)
z.backward()
print(x.grad is None)

타입: torch.FloatTensor
크기: torch.Size([])
값: 
21.0
False

 

 

8. CUDA 텐서

8.1 CUDA 사용 여부 확인

import torch
print(torch.cuda.is_available())

True

 

8.2 장치와 무관한 텐서 초기화(바람직한 방법)

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(device)

cuda
x = torch.rand(3,3).to(device)
describe(x)

타입: torch.cuda.FloatTensor
크기: torch.Size([3, 3])
값: 
tensor([[0.8199, 0.9851, 0.5542],
        [0.6472, 0.8845, 0.2886],
        [0.1834, 0.8518, 0.4399]], device='cuda:0')

 

8.3 CUDA텐서와 CPU 텐서 더하기

 - 서로 다른 장치에 선언된 텐서는 연산을 할 수 없습니다.

## cuda 텐서와 cpu 텐서 더하기
y = torch.rand(3,3)
x + y


---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-63-1d09b3220b13> in <module>
      1 ## cuda 텐서와 cpu 텐서 더하기
      2 y = torch.rand(3,3)
----> 3 x + y

RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu!

 

8.4 같은 장치의 텐서 연산

cpu_device = torch.device("cpu")
y = y.to(cpu_device)
x = x.to(cpu_device)
x + y

tensor([[1.5859, 1.7247, 0.7105],
        [0.7811, 1.6266, 0.6977],
        [0.7569, 1.5020, 1.3939]])

 

 

* CUDA,CPU 장치에 따른 텐서 정리

 - GPU로 데이터를 넣고 꺼내는 작업은 비용이 많이 듭니다. 병렬 계산은 일반적으로 GPU에서 수행하고 최종 결과만 CPU로 전송하는 방식으로 이루어집니다. 이렇게 하면 GPU를 최대로 활용할 수 있습니다.

 

* CUDA 장치가 여럿(GPU 장치가 여럿일 경우) 프로그램 실행할 때 다음처럼 CUDA_VISIBLE_DEVICES 환경변수를 사용할 수 있습니다.

CUDA_VISIBLE_DEVICES=0,1,2,3 python main.py

 

'파이썬 > 파이토치 자연어처리' 카테고리의 다른 글

지도학습 훈련 순서  (0) 2022.02.12
신경망의 기본 구성 요소  (0) 2022.02.10
텐서의 연산  (0) 2022.02.08
텐서를 만들어 봅시다.  (0) 2022.02.08
샘플과 타깃의 인코딩  (0) 2022.02.08