문제 발견

Pytorch sort 함수 구현중 복사가 안되는 문제가 발생함

x = torch.randn(10, 2)

for i in range(len(x)):
    x[i][1] = i

for i in range(len(x)):
    for j in range(i, len(x)):
        if x[i][0] > x[j][0]:
            temp = x[i]
            x[i] = x[j]
            x[j] = temp

단순한 sort함수지만 temp에 x[i]값을 넣은 후 x[i]값이 변경될 때 temp 값도 같이 변경되는 현상 발생

처음엔 pytorch의 문제인줄 알고 접근했지만 디버깅 할 수록 주소값의 문제라고 판단하게 되었음

하지만 해결하지 못해 대안으로 수정한 코드는

temp = torch.tensor(x[i])

새로운 tensor를 만들어주는 것, 하지만 근본적인 해결이되지 않았기에 좀더 찾아봤다.

문제 원인

문제 원인은 파이썬의 객체방식이였다.

파이썬은 모든것이 객체로 구성돼이 있다.

또한 주소값을 가지고 있고 생성한 temp 변수의 주소값이 공유된 것이였다.

이를 참조라고 부른다.

파이썬 공식문서에서 복사에 대한 설명[1]

Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other. This module provides generic shallow and deep copy operations.

파이썬에서 대입문은 객체를 복사하지 않고, 대상과 객체 사이에 바인딩을 만듭니다.가변(mutable) 컬렉션 또는 가변(mutable) 항목들을 포함한 컬렉션의 경우때로 컬렉션을 변경하지 않고 사본을 변경하기 위해 복사가 필요합니다. 이 모듈은 일반적인 얕은 복사와 깊은 복사 연산을 제공합니다

대입문을 통해 복사한 경우 실제 객체가 변수에 들어가는 것이 아닌 참조하고 있기 때문에 변수가 주소값으로 연결돼 있다.

여기서 얕은 복사와 깊은 복사가 나오는데 얕은 복사란 참조, 주소값을 복사한 경우를 의미한다.

여기서 mutable, immutable이란 개념이 나오는데 쉽게말해 list와 dictionary같은 객체를 mutable이라 하며, int, float같은 객체를 immutable이라 한다.

얕은 복사와 깊은 복사에 차이점은 immutable 객체는 해당 없으며, mutable 객체에만 해당된다.

얕은 복사는 ‘=’연산자, [:] 슬라이싱을 통한 복사, copy 메서드, copy.copy() 함수

깊은 복사는 copy.deepcopy를 통해 할 수 있다.

얕은 복사는 주소값만 가졌다면, 깊은 복사는 새로운 객체가 만들어집니다. 물론 주소값도 새로 생겨납니다.

torch.clone()

Pytorch에서는 clone() 메소드를 통해 텐서를 깊은 복사 할 수 있다.