PyTorch의 clone(), detach() 및 확장 상세 정보
Torch는 속도를 높이기 위해 벡터나 행렬의 값이 같은 메모리를 가리키는데 이것은 Matlab와 다르다.오래된 tensor를 저장하려면 인용이 아닌 새로운 저장 주소를 열어야 합니다. clone () 으로 깊이 복사할 수 있습니다.
우선 clone () 작업 후의 데이터 형식 정의 변화를 출력합니다.
(1). 단순 인쇄 유형
import torch
a = torch.tensor(1.0, requires_grad=True)
b = a.clone()
c = a.detach()
a.data *= 3
b += 1
print(a) # tensor(3., requires_grad=True)
print(b)
print(c)
'''
:
tensor(3., requires_grad=True)
tensor(2., grad_fn=<AddBackward0>)
tensor(3.) # detach() a
'''
grad_fn=detach () 작업 후의tensor는 원시tensor와 데이터 메모리를 공유합니다. 원시tensor가 계산도에서 수치가 역방향으로 전파되는 등 업데이트가 발생하면detach () 의tensor 값도 변경됩니다.
주의:pytorch에서 우리는 id가 같은지 아닌지를 직접 사용해서 텐서가 메모리를 공유하는지 판단하지 마십시오. 이것은 충분한 조건입니다. 왜냐하면 밑바닥에서 데이터 메모리를 공유할 수도 있지만 여전히 새로운 텐서, 예를 들어 detach () 입니다. 만약에 우리가 직접 id를 인쇄하면 다음과 같은 상황이 발생할 수 있습니다.
import torch as t
a = t.tensor([1.0,2.0], requires_grad=True)
b = a.detach()
#c[:] = a.detach()
print(id(a))
print(id(b))
#140568935450520
140570337203616
분명히 직접 출력된 id는 같지 않다. 우리는 간단한 값을 부여한 후에 데이터의 변화를 관찰하여 판단할 수 있다.(2). clone () 의 사다리 회전
detach () 함수는 완전히 같은tensor를 되돌려줍니다. 낡은 tensor와 메모리를 공유하고 계산도에서 벗어나 사다리 계산에 연루되지 않습니다.
반면에 clone은 중간 변수를 충당하면 사다리를 원량에 전달하여 중첩되지만 그 자체는grad를 저장하지 않습니다. 즉, 값은 None입니다.
import torch
a = torch.tensor(1.0, requires_grad=True)
a_ = a.clone()
y = a**2
z = a ** 2+a_ * 3
y.backward()
print(a.grad) # 2
z.backward()
print(a_.grad) # None. variable, grad
print(a.grad)
'''
:
tensor(2.)
None
tensor(7.) # 2*2+3=7
'''
torch를 사용합니다.clone () 에서 얻은 새로운tensor와 원래의 데이터는 더 이상 메모리를 공유하지 않지만 계산도에 남아 있습니다. clone 작업은 데이터 메모리를 공유하지 않는 동시에 사다리 전달과 중첩을 지원하기 때문에 신경 네트워크의 어떤 단원이 중복적으로 사용해야 하는 장면에 자주 사용됩니다.보통 원tensor의requires_grad=True:
import torch
torch.manual_seed(0)
x= torch.tensor([1., 2.], requires_grad=True)
clone_x = x.clone()
detach_x = x.detach()
clone_detach_x = x.clone().detach()
f = torch.nn.Linear(2, 1)
y = f(x)
y.backward()
print(x.grad)
print(clone_x.requires_grad)
print(clone_x.grad)
print(detach_x.requires_grad)
print(clone_detach_x.requires_grad)
'''
:
tensor([-0.0053, 0.3793])
True
None
False
False
'''
또 다른 특이한 것은 원본 장량의 require_grad=False, clone 후 장량 require_grad=True, 이때 장량 회전 현상이 존재하지 않으며,clone 후의 장량 구도를 얻을 수 있습니다.다음과 같습니다.
import torch
a = torch.tensor(1.0)
a_ = a.clone()
a_.requires_grad_() #require_grad=True
y = a_ ** 2
y.backward()
print(a.grad) # None
print(a_.grad)
'''
:
None
tensor(2.)
'''
양자의 차이를 이해한 후에 우리는 항상 다른 함수와 조합하여 사용하여 데이터 복사 후의 기타 수요를 실현한다.예를 들어 우리는view () 함수를 자주 사용하여tensor에 대해reshape 작업을 한다.되돌아오는 새 Tensor와 원본 Tensor는 서로 다른size가 있을 수 있지만 데이터를 공유하는 것입니다. 즉, 그 중 하나가 바뀌고 다른 것도 따라서 바뀝니다.
주의해야 할 것은view가 되돌아오는 Tensor와 원본 Tensor는 데이터를 공유하지만 여전히 새로운 Tensor입니다. (Tensor는 데이터를 포함하는 것 외에 다른 속성이 있기 때문입니다.) 양자 id(메모리 주소)는 일치하지 않습니다.
x = torch.rand(2, 2)
y = x.view(4)
x += 1
print(x)
print(y) # 1
view () 는 단지 이 장량에 대한 관찰 각도를 바꾸었을 뿐 내부 데이터는 변하지 않았다.이때 진정한 새로운 복사본(즉 데이터 메모리를 공유하지 않음)으로 돌아가려면 어떻게 해야 합니까?Pytorch는 reshape () 를 제공하여 모양을 바꿀 수 있지만, 이 함수는 복사본으로 되돌아오는 것을 보장할 수 없기 때문에 사용을 추천하지 않습니다.먼저 clone으로 사본을 만들고 view를 사용하는 것을 추천합니다.여기 참조
x = torch.rand(2, 2)
x_cp = x.clone().view(4)
x += 1
print(id(x))
print(id(x_cp))
print(x)
print(x_cp)
'''
140568935036464
140568935035816
tensor([[0.4963, 0.7682],
[0.1320, 0.3074]])
tensor([[1.4963, 1.7682, 1.1320, 1.3074]])
'''
또한 clone () 을 사용하면 계산도에 기록됩니다. 즉, 사다리가 복사본으로 전송될 때도 원본 Tensor로 전송됩니다전편에서 총결이 있다 .요약:
제자리 작업(in-place, such as resize_/resize_as_/set_/transpose_)위에서 두 가지를 실행하면 오류나 경고를 일으킬 수 있습니다.
y = x + y 같은 연산은 메모리를 새로 열고 y를 새 메모리로 가리킨다.우리는 Python이 가지고 있는 id 함수를 사용하여 검증할 수 있습니다. 만약 두 개의 실례의 ID가 같다면, 그것들이 대응하는 메모리 주소가 같습니다.
PyTorch의 clone (), detach () 및 확장에 대한 자세한 내용은 여기 소개되어 있습니다. 더 많은 PyTorch의 clone (), detach () 및 확장에 관한 내용은 이전의 글을 검색하거나 아래의 관련 글을 계속 훑어보시기 바랍니다. 앞으로 많은 응원 부탁드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정확도에서 스케일링의 영향데이터셋 스케일링은 데이터 전처리의 주요 단계 중 하나이며, 데이터 변수의 범위를 줄이기 위해 수행됩니다. 이미지와 관련하여 가능한 최소-최대 값 범위는 항상 0-255이며, 이는 255가 최대값임을 의미합니다. 따...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.