파이토치 tensor를 numpy array나 list로 바꾸기
파이썬 파이토치에서 tensor 자료형을 넘파이 배열 또는 리스트 자료형으로
변환하는 방법에 대하여 케이스별로 정리해보도록 하겠습니다.
1. 기본 텐서의 경우 : numpy() / tolist()
먼저, grad 정보가 없고 gpu에 선언되지 않은 가장 기본적인 텐서의 경우입니다.
아래와 같은 예시의 tensor를 형변환해보도록 하겠습니다.
data1 = torch.randn(3, 2)
data1
# 출력 결과
tensor([[-0.2370, -1.4314],
[-0.7539, 0.5552],
[-1.1405, -0.4047]])
넘파이 배열 자료형으로 바꾸려면 tensor.numpy() 형태로 지정해주시면 됩니다.
data1.numpy()
# 출력 결과
array([[-0.23703063, -1.4314126 ],
[-0.7539355 , 0.5551915 ],
[-1.140489 , -0.40470666]], dtype=float32)
반면, 리스트 자료형으로 변환하려면 tensor.tolist() 형태로 작성해주시면 됩니다.
data1.tolist()
# 출력 결과
[[-0.23703062534332275, -1.4314125776290894],
[-0.7539355158805847, 0.5551915168762207],
[-1.1404889822006226, -0.4047066569328308]]
2. grad 정보가 포함된 경우 numpy array로 변환 : detach().numpy()
만일, 모델의 output으로 반환된 텐서 내에 autograd 기능이 포함되어 있어
grad 정보가 같이 저장된 경우 리스트 변환시에는 위 예시처럼 tolist()를 바로 적용할 수 있지만
넘파이 배열로 바꾸려면 detach() 메소드로 grad 정보 제거 후 numpy()를 적용해야 합니다.
예시로 다음과 같이 grad 정보가 저장된 텐서를 가정해보겠습니다.
data2
# 출력 결과
tensor([[0.3311, 1.1163],
[0.4816, 0.4099],
[0.5949, 0.3613]], grad_fn=<AddmmBackward0>)
numpy()를 바로 적용 시도할 경우에는 아래와 같은 오류 메시지가 출력됩니다.
data2.numpy()
# RuntimeError: Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.
따라서, 넘파이 배열 변환 시에는 tensor.detach().numpy() 형태로 작성해주셔야 합니다.
data2.detach().numpy()
# 출력 결과
array([[0.33107007, 1.116349 ],
[0.4816136 , 0.4098794 ],
[0.5949428 , 0.36126232]], dtype=float32)
3. gpu에 선언된 텐서의 경우 numpy array로 변환 : cpu().numpy()
만일, gpu에 올라가있는 tensor라면 넘파이 배열 자료형 변환 시
cpu() 메소드를 통하여 cpu로 옮긴 뒤, numpy() 메소드를 적용해주셔야 합니다.
(단, 리스트 변환 시에는 마찬가지로 tolist()만 사용해주셔도 무방합니다.)
아래와 같이 cuda에 선언된 예시 텐서를 np.array로 바꿔보겠습니다.
data3 = torch.rand(3, 2).cuda()
data3
# 출력 결과
tensor([[0.7657, 0.5605],
[0.3344, 0.0708],
[0.1097, 0.8183]], device='cuda:0')
만일, 그냥 numpy()를 바로 시도할 경우 아래와 같이 오류가 발생합니다.
data3.numpy()
# TypeError: can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.
여기서는 tensor.cpu().numpy() 형태로 넘파이 배열 자료형 변환을 완료하였습니다.
data3.cpu().numpy()
# 출력 결과
array([[0.7657117 , 0.5605019 ],
[0.3344291 , 0.07077938],
[0.10965961, 0.81833345]], dtype=float32)
참고로, 만일 gpu에 올라가 있고 grad 정보도 포함되어 있는 경우라면
detach()와 cpu()를 모두 적용해주셔야 넘파이 배열로의 형변환을 완료할 수 있습니다.
(여기서도 리스트로 변환 시에는 tolist()만 단독 적용이 가능합니다.)
data4
# 출력 결과
tensor([[-0.4238, -0.4075],
[ 0.2597, -0.2759],
[-0.0784, -1.2160]], device='cuda:0', grad_fn=<AddmmBackward0>)
### 넘파이 배열로 자료형 변환 ###
data4.detach().cpu().numpy()
# 출력 결과
array([[-0.42379946, -0.40748018],
[ 0.25967413, -0.2758565 ],
[-0.07839801, -1.2159803 ]], dtype=float32)
### 리스트로 자료형 변환 ###
data4.tolist()
# 출력 결과
[[-0.42379945516586304, -0.4074801802635193],
[0.2596741318702698, -0.27585649490356445],
[-0.07839801162481308, -1.2159802913665771]]
'Python > Pytorch' 카테고리의 다른 글
[Pytorch] 파이토치 과적합 방지(Early Stopping) 구현 방법 정리 (0) | 2022.09.08 |
---|---|
[Pytorch] 파이토치 허브(torch.hub) 사용법 (0) | 2022.07.28 |
[Pytorch] 파이썬 Contrastive Learning 구현 예제(feat. SimCLR) (2) | 2022.07.20 |