PyTorch에서 선호하는 텐서 복사 방법
PyTorch에서 텐서의 복사본을 만드는 몇 가지 방법이 있는 것으로 보입니다.
y = tensor.new_tensor(x) #a
y = x.clone().detach() #b
y = torch.empty_like(x).copy_(x) #c
y = torch.tensor(x) #d
b
보다 명백하게 선호됨a
그리고.d
사용자 경고에 따르면 다음 중 하나를 실행하면 표시됩니다.a
또는d
왜 그것이 선호됩니까?퍼포먼스?저는 그것이 덜 읽을 수 있다고 주장합니다.
사용에 대한 모든 이유/반대c
?
TL;DR
사용하다.clone().detach()
(또는 가급적이면).detach().clone()
)
먼저 텐서를 분리한 후 복제하면 계산 경로가 복사되지 않고, 반대로 복사된 후 폐기됩니다.따라서,
.detach().clone()
조금 더 효율적입니다. -- 파이토치 포럼.
그것이 하는 일에 있어서 약간 빠르고 명시적이기 때문입니다.
를 사용하여 파이토치 텐서를 복사하기 위한 다양한 방법의 타이밍을 플롯했습니다.
y = tensor.new_tensor(x) # method a
y = x.clone().detach() # method b
y = torch.empty_like(x).copy_(x) # method c
y = torch.tensor(x) # method d
y = x.detach().clone() # method e
x축은 생성된 텐서의 차원이고, y축은 시간을 나타냅니다.그래프가 선형 척도로 표시됩니다.분명히 보시다시피, 분명히 볼 수 있듯이,tensor()
또는new_tensor()
다른 세 가지 방법에 비해 시간이 더 많이 걸립니다.
참고: 여러 번의 런에서 b, c, e 중에서 모든 방법이 가장 낮은 시간을 가질 수 있다는 것을 알게 되었습니다.a와 d도 마찬가지입니다.그러나 방법 b, c, e는 a 및 d보다 일관되게 타이밍이 낮습니다.
import torch
import perfplot
perfplot.show(
setup=lambda n: torch.randn(n),
kernels=[
lambda a: a.new_tensor(a),
lambda a: a.clone().detach(),
lambda a: torch.empty_like(a).copy_(a),
lambda a: torch.tensor(a),
lambda a: a.detach().clone(),
],
labels=["new_tensor()", "clone().detach()", "empty_like().copy()", "tensor()", "detach().clone()"],
n_range=[2 ** k for k in range(15)],
xlabel="len(a)",
logx=False,
logy=False,
title='Timing comparison for copying a pytorch tensor',
)
Pytorch 문서에 따르면 #a와 #b는 동등합니다.그것은 또한 말합니다.
clone() 및 detach()를 사용하는 동등한 것이 좋습니다.
따라서 텐서를 복사하고 계산 그래프에서 분리하려면 사용해야 합니다.
y = x.clone().detach()
가장 깨끗하고 읽을 수 있는 방법이기 때문입니다.다른 모든 버전에서는 일부 숨겨진 논리가 있으며 계산 그래프와 그라데이션 전파에 무슨 일이 일어나는지도 100% 명확하지 않습니다.
#c와 관련하여: 실제로 수행된 작업에 대해 약간 복잡해 보이고 오버헤드를 유발할 수도 있지만, 저는 그것에 대해 확신할 수 없습니다.
편집 : 댓글로 질문받았으니 그냥 사용하면 어떨까요?.clone()
.
파이토치 문서에서
copy_()와 달리 이 함수는 계산 그래프에 기록됩니다.복제된 텐서로 전파되는 그라데이션은 원래 텐서로 전파됩니다.
그래서 그러는 동안에.clone()
계산 그래프를 유지하고 복제 작업을 기록하는 데이터의 복사본을 반환합니다.언급한 바와 같이 이것은 복제된 텐서에 전파되는 그라데이션으로 이어질 것이며 원래 텐서에도 전파됩니다.이 동작은 오류로 이어질 수 있으며 명확하지 않습니다.이러한 부작용 때문에 텐서는 다음을 통해서만 복제되어야 합니다..clone()
이 동작이 명시적으로 필요한 경우.이러한 부작용을 방지하기 위해.detach()
이 추가되어 복제된 텐서에서 계산 그래프의 연결이 끊어집니다.
수 됩니다..clone().detach()
.
텐서가 복사되었는지 확인하는 한 가지 예:
import torch
def samestorage(x,y):
if x.storage().data_ptr()==y.storage().data_ptr():
print("same storage")
else:
print("different storage")
a = torch.ones((1,2), requires_grad=True)
print(a)
b = a
c = a.data
d = a.detach()
e = a.data.clone()
f = a.clone()
g = a.detach().clone()
i = torch.empty_like(a).copy_(a)
j = torch.tensor(a) # UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).
print("a:",end='');samestorage(a,a)
print("b:",end='');samestorage(a,b)
print("c:",end='');samestorage(a,c)
print("d:",end='');samestorage(a,d)
print("e:",end='');samestorage(a,e)
print("f:",end='');samestorage(a,f)
print("g:",end='');samestorage(a,g)
print("i:",end='');samestorage(a,i)
외부:
tensor([[1., 1.]], requires_grad=True)
a:same storage
b:same storage
c:same storage
d:same storage
e:different storage
f:different storage
g:different storage
i:different storage
j:different storage
다른 저장소가 나타나면 텐서가 복사됩니다.PyTorch에는 거의 100개의 다른 생성자가 있으므로 더 많은 방법을 추가할 수 있습니다.
만내가텐복한사나다것사그입다니용할냥는약면야해서를▁use▁just▁if▁i다것▁would입▁a니▁tensor만▁i사용할약그▁to냥.copy()
은 또한 정보를 가 AD 정보를 는 다음을사용할 입니다.
y = x.clone().detach()
Pytorch '1.1.0'이 #b를 권장하며 #d에 대한 경고를 표시합니다.
언급URL : https://stackoverflow.com/questions/55266154/pytorch-preferred-way-to-copy-a-tensor
'programing' 카테고리의 다른 글
git-upload-pack: 명령을 찾을 수 없음, 원격 Gitrepo 복제 시 (0) | 2023.07.18 |
---|---|
파이썬 스크립트에서 파이썬패스를 설정하려면 어떻게 해야 합니까? (0) | 2023.07.18 |
시리즈물을 필터링하는 방법 (0) | 2023.07.18 |
원격 분기에서 소수의 커밋을 영구적으로 제거하는 방법 (0) | 2023.07.18 |
도커 - 빌드 단계에서 MySQL/MariaDB 루트 암호를 안전하게 설정합니다. (0) | 2023.07.18 |