NumPy - np.roll()

olxtar·2022년 8월 18일
0
post-thumbnail
post-custom-banner

Comment :

Udaicty Deep Learning - RNN - Project 3. TV Script Generation, 즉 TV 시트콤 대본 생성 RNN 모델을 만드는 과정에서 np.roll()이란 함수를 보았고 해당 함수를 간단하게 학습 및 정리하려 한다.


상황 :

[+] TV Script Generation에서의 상황은... 훈련이 완료된 모델에 Prime 단어를 하나 입력해서 추후에 예측되는 단어를 쭈루룩, 즉 대본(Script)을 생성하려한다.

모델에 들어갈 입력 Tensor의 사이즈는 (batch_size, seq_length)인데, 훈련이 아닌 실사용에서는 batch_size는 의미가 없으므로 (1, seq_length) 사이즈의 Tensor가 입력 데이터가 된다.

Prime 단어가 jerry: 이고 Padding word가 <Pad>라고 하면, 맨처음 입력으로 쓰일 Tensor는 아래와 같다.

  1. tensor[ <Pad>, <Pad>, ... , <Pad>, jerry:]
    length : =seq_length

RNN의 기본 개념은 이전, 이이전 Timestep의 값들을 기억하여 다음, 다다음 값을 예측하는 것이므로
만약 위의 입력 Tensor를 통해 예측된 단어가 How라면 두번째 입력으로 쓰일 Tensor는 아래와 같아야 할 것이다.

  1. tensor[ <Pad>, <Pad>, ... , jerry:, How]

이렇게 NumPy Array(지금은 Tensor이지만 바로 np.roll에 적용해도 되긴한다!)속 요소를 '굴리는', 즉 특정방향으로 어렸을적 자물쇠 돌리기 or 큐브 돌리기처럼 나란히 이동시키는 것을 NumPy roll로 할 수 있다.



Numpy roll()

참고 : NumPy roll() manual

numpy.roll(a, shift, axis=None)

Roll array elements along a given axis.
Elements that roll beyond the last position are re-introduced at the first.
Array의 요소들을 주어진 axis에 따라 Roll한다.
Array의 사이즈, 즉 범위를 넘는 요소들은 첫번째로 다시 돌아온다

Parameters

  • a : input array
  • shift : int or tuple, 요소들이 이동할 위치 개수(대충 몇칸 움직이는지...) tuple로 주어졌을때에는 axis도 tuple로 받아야하며 두 tuple은 서로 대응하여 aixs tuple의 i번째 축으로 shift tuple의 i번째 값만큼 이동함 / shift는 하나의 int값인데 axis가 tuple로 주어질 경우 axis tuple내 모든 축에서 shift값만큼 이동
  • axis : int or tuple, Axis or axes along which elements are shifted. By default, the array is flattened before shifting

Return

  • Output array, with the same shape as a

글로 보니깐 확 와닿지 않는다, 코드로 한번 봐보자


1D array

x = np.arange(10)
x
>>>

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# x array의 요소들을 뒤로 2칸씩 이동시켜라
np.roll(x,2)
>>>

array([8, 9, 0, 1, 2, 3, 4, 5, 6, 7])

-----------------------------------
# x array의 요소들을 앞으로 2칸씩 이동시켜라
np.roll(x,-2)
>>>

array([2, 3, 4, 5, 6, 7, 8, 9, 0, 1])

[!] (위에 메뉴얼대로) Array의 범위를 넘는 요소들은 다시 첫번째 또는 마지막으로 들어온다


2D Array

x2 = np.reshape(x, (2,5))
x2
>>>

array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
# x2 array의 요소들을 뒤로 1칸씩 이동시켜라
np.roll(x2,1)
>>>

array([[9, 0, 1, 2, 3],
       [4, 5, 6, 7, 8]])

[!] axis, 즉 shift될 축을 따로 지정하지 않았으므로 (위에 메뉴얼대로) 1차원으로 flatten된 array를 1칸씩 이동시킨것과 같다

# x2 array의 요소들을 axis=0, 즉 Row를 잡아 1칸씩 이동시켜라
np.roll(x2, 1, axis=0)
>>>

array([[5, 6, 7, 8, 9],
       [0, 1, 2, 3, 4]])
# 아예 그냥 모든 요소들의 Row위치만 1칸씩 이동시킴
# x2 array의 요소들을 axis=1, 즉 Column을 잡아 1칸씩 이동시켜라
np.roll(x2, 1, axis=1)
>>>

array([[4, 0, 1, 2, 3],
       [9, 5, 6, 7, 8]])
# Column위치만 1칸씩 이동시킴
# x2 array의 요소들을 
# axis=1 기준으로 -1칸
# axis=0 기준으로 1칸 이동시켜라
np.roll(x2, (-1,1), axis=(1,0)
>>>

# 1번 : Column 기준으로 -1칸
array([[1, 2, 3, 4, 0],
		6, 7, 8, 9, 5]])

# 2번 : Row 기준으로 1칸
array([[6, 7, 8, 9, 5],
		1, 2, 3, 4, 0]])

3D Array

x3 = np.arange(1,28).reshape((3,3,3))
x3
>>>
array([[[ 1,  2,  3],
        [ 4,  5,  6],
        [ 7,  8,  9]],

       [[10, 11, 12],
        [13, 14, 15],
        [16, 17, 18]],

       [[19, 20, 21],
        [22, 23, 24],
        [25, 26, 27]]])
# x3 array의 요소들을 axis=0, 즉 depth 기준으로 1칸씩 이동시켜라
np.roll(x3, 1, axis=0)
>>>

array([[[19, 20, 21],
        [22, 23, 24],
        [25, 26, 27]],

       [[ 1,  2,  3],
        [ 4,  5,  6],
        [ 7,  8,  9]],

       [[10, 11, 12],
        [13, 14, 15],
        [16, 17, 18]]])


QUIZ

(3,3,3) 사이즈의 Cube의 (0,0,0)번째 요소만 7이고 나머지는 모두 0이다 \downarrow

cube = np.zeros( (3,3,3) )
cube[0][0][0] = 7
cube
>>>

array([[[7., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]],

       [[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]],

       [[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]]])

이와 같은 3D Array에서 저 7 요소를 (2,2,2), 즉 맨 구석 맨 뒤로 보내려면 어떻게 해야할까?


Solution

np.roll(cube, 2, axis=(0,1,2))
>>>

array([[[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]],

       [[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]],

       [[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 7.]]])

[!] axis는 tuple인데 이동할 칸수, 즉 shift가 1개의 정수값일 경우 모든 axis에 대해서 shift 정수값만큼 이동한다. 즉 (0,0,0)에 있던 7 요소를 (2,2,2)로 이동시킴

profile
예술과 기술
post-custom-banner

0개의 댓글