Transpose
Transpose(전치)의 linear algebra에서의 정의는 다음과 같음.
Given an m x n matrix A,
the transpose of A is the n x m matrix,
denoted by AT whose columns are formed from the corresponding rows of A.
간단하게 말하면 행과 열을 바꾸는 처리이다.
Tensor의 경우
rank가 2 보다 클 수 있으며 해당 rank의 수만큼 축이 있다.
때문에
Tensor에서의 transpose는 여러 축들 중 2개를 서로의 위치를 바꾸는 것이라고 보면 된다.
주의할 것은
- numpy와 pytorch의 경우, aixs(축)만 변경된 것이지, 여전히 같은 데이터 (the same underlying data)를 공유하는 방식이므로
- transpose 처리로 얻은 tensor인스턴스에서 데이터를 변경할 경우, 원래의 tensor인스턴스에서도 데이터가 변경된다.
- tensorflow에서는 tensor가 immutable이라, 데이터를 변경을 하면 다른 tensor가 생성하는 것에 해당하므로 조금 다름.
다음 예를 참고할 것.
numpy
a = np.random.rand(2, 3)
t1 = np.transpose(a)
t2 = a.T
print(a.shape) # (2,3)
print(t1.shape) # (3,2)
print(t2.shape) # (3,2)
t2[0,1] = 77
print(a[1,0]) # 77.0
print(t1[0,1]) # 77.0
print(t2[0,1]) # 77.0
pytorch
a_torch = torch.rand(2, 3)
t1_torch = torch.transpose(a_torch, 0, 1) #axis-0 (행) 과 axis-1 (열)을 교체.
t2_torch = a_torch.T
print(a_torch.shape) #torch.Size([2,3])
print(t1_torch.shape) #torch.Size([3,2])
print(t2_torch.shape) #torch.Size([3,2])
t2_torch[0,1] = 77
print(a_torch[1,0]) # tensor(77.)
print(t1_torch[0,1]) # tensor(77.)
print(t2_torch[0,1]) # tensor(77.)
- transpose 를 수행하면, 기존의 contiguous tensor 는 더이상 contiguous 이 아님: is_contiguous() 메서드(tensor인스턴스에서 지원)로 확인 가능.
- storage() 를 이용하여 실제 저장된 underlying 1-D array 에서의 순서를 확인가능함.
tensorflow
a_tf = tf.random.normal([2, 3])
t1_tf = tf.transpose(a_tf)
t2_tf = tf.transpose(a_tf, perm=[1, 0]) # T 지원안함.
print(a_tf.shape, a_tf.dtype)
print(t1_tf.shape, t1_tf.dtype)
print(t2_tf.shape, t2_tf.dtype)
indices = tf.constant([[0, 1]]) # (2, 2) 위치를 변경하고자 함
updates = tf.constant([77], dtype=tf.float32) # 해당 위치에 넣고 싶은 값
t2_tf = tf.tensor_scatter_nd_update(t2_tf, indices, updates)
print(a_tf[1,0])
print(t1_tf[0,1])
print(t2_tf[0,1])
Permute (순열, 축의 위치를 변경)
Tensor의 축들의 순서를 임의로 바꾸는 데 사용됨.
transpose가 한번에 2개의 축의 위치를 바꾸는 것과 달리,
임의의 수의 축들을 임의의 순서로 자유롭게 변경할 수 있음.
참고로, numpy, tensorflow에서는 transpose
를 통해 permute를 구현하고 있음.
numpy
a = np.random.rand(2, 3, 4)
t1 = np.transpose(a, (0, 2, 1)) # 기존의 axis 0,1,2 순서를 axis 0,2,1 순서로 변경.
print(a.shape) # (2,3,4)
print(t1.shape) # (2,4,3)
t1[0,1,2] = 77
print(a[0,2,1]) # 77.0
print(t1[0,1,2]) # 77.0
pytorch
a_torch = torch.rand(2, 3, 4)
t1_torch = torch.permute(a_torch, (0, 2, 1)) # numpy의 transpose와 사용방법이 유사.
print(a_torch.shape) # torch.Size([2, 3, 4])
print(t1_torch.shape) # torch.Size([2, 4, 3])
t1_torch[0,1,2] = 77
print(a_torch[0,2,1]) # tensor(77.)
print(t1_torch[0,1,2]) # tensor(77.)
- permute의 경우도 역시 contiguous가 깨지게 됨.
tensorflow
a_tf = tf.random.normal([2, 3, 4])
t1_tf = tf.transpose(a_tf, perm=[0, 2, 1]) #perm 이라는 키워드로 변경될 축의 순서를 기재.
print(a_tf.shape) # (2, 3, 4)
print(t1_tf.shape) # (2, 4, 3)
https://gist.github.com/dsaint31x/4b703b26775a826c978cb3d65cf607c8
'Python' 카테고리의 다른 글
[ML] where: numpy 의 idx찾기 (2) | 2024.03.19 |
---|---|
[DL] Tensor: Indexing <Simple, Slicing, Fancy, Boolean Mask> (0) | 2024.03.18 |
[DL] Tensor 객체의 attributes: ndim, shape, dtype (0) | 2024.03.15 |
[DL] Tensor: dtype 변경(casting) 및 shape 변경. (0) | 2024.03.15 |
[DL] Tensor 간의 변환: NumPy, PyTorch, TensorFlow (0) | 2024.03.15 |