반응형

다차원 배열의 계산

신경망을 효율적으로 구현하기 위해서는 넘파이의 다차원 배열을 사용한 계산법을 숙달해야 한다.

따라서 본 포스팅에서는 다차원 배열의 계산을 학습하고자 한다.

 

1. 다차원 배열

다차원 배열도 기본은 '숫자의 집합'이다.

즉, 숫자가 한 줄로 나열된 것(1차원)이나 직사각형의 형태로 나열된 것(2차원), 3차원, ..., N차원으로 나열하는 것을 통틀어 다차원 배열이라고 한다.

주피터 노트북에서 파이썬으로 numpy를 사용해서 다차원 배열을 작성해서 확인해보면 아래와 같다.

배열의 차원 수는 np.ndim() 함수로 확인할 수 있고, 배열의 크기는 인스턴스 변수인 shape로 알 수 있다.

다만, 인스턴스 변수인 shape는 튜플을 반환한다는 사실을 기억해야 한다.

위의 예제로 보면 A는 1차원 배열이고 원소는 4개로 구성되어 있으며 B는 2행 4열로 구성되어 있는 2차원 배열임을 확인할 수 있다.

B의 출력 값을 보면,

[[1 2 3 4]

 [5 6 7 8]]

과 같이 되어 있는데, 배열의 가로 방향([1 2 3 4]와 [5, 6, 7, 8])을 (row)이라 하며, 배열의 세로 방향([1, 5], [2, 6], [3, 7], [4, 8])을 (column)이라 한다. 그리고 이렇게 행과 열로 이루어진 2차원 배열을 행렬(matrix)이라고 부른다.

 

2. 행렬의 내적(행렬 곱)

행렬의 내적을 어떻게 구하는지 아래의 예를 통해 알아보자.

출처: 밑바닥부터 시작하는 딥러닝 p.79

만약 2x2 행렬의 내적을 구하고 싶은 경우 위와 같이 계산하는데,

왼쪽 행렬 A의 행(rows)과 오른쪽 행렬 B의 열(columns)을 원소별로 곱하고 그 값들을 더해서 계산한다.

그리고 그 계산 결과가 새로운 다차원 배열의 원소가 된다.

조금 더 쉽게 말하자면, A의 1행[1 2]와 B의 1열[5, 7]을 곱한 값은 결과 행렬의 1행 1번째 원소(1*5 + 2*7 = 19)가 되고, A의 2행과 B의 1열을 곱한 결과는 2행 1번째 원소(3*5 + 4*7 = 43)가 된다.

위 예시의 계산을 파이썬을 통해 구현해보자.

np.dot()은 넘파이 배열 2개를 인수로 받아 그 내적(곱)을 반환한다.

여기서 한 가지 주의할 것은 np.dot(A, B)와 np.dot(B, A)는 다른 값이 될 수 있다는 점을 기억해야 한다.

그리고 행렬의 곱을 하기 위해서는 A 행렬이 m행 n열의 형태고, B행렬이 i행 j열일 때,

MxN · IxJ 의 형태일 때, '행렬의 형상(shape)'에 주의해야 한다.

N과 I의 값이 같아야만 행렬의 내적을 계산할 수 있다. 이렇게 계산된 결과는 MxJ 형태의 행렬로 만들어진다.

!(앞 행렬의 열 수 == 뒷 행렬의 행 수)

만약, 2x3 행렬과 2x2행렬을 곱하면 에러가 출력된다.

출처: 밑바닥부터 시작하는 딥러닝 p.81

'대응하는 차원의 원소 수를 일치시켜야 한다'는 원칙은 행렬 A가 2차원 행렬이고 행렬 B가 1차원 배열일 때도 동일하게 적용된다.

출처: 밑바닥부터 시작하는 딥러닝 p.81

 

3. 신경망의 내적

그렇다면, 넘파이의 행렬을 써서 신경망을 구현해보자.

간단한 신경망이라 가정하에 편향과 활성화 함수를 생략하고 가중치만 갖도록 할 것이다.

출처: 밑바닥부터 시작하는 딥러닝 p.82

이 구현에서도 X, W, Y의 형상을 주의해서 봐야하는데 특히, X와 W의 대응하는 차원의 원소수가 같아야 한다.

다차원 배열의 내적을 구해주는 np.dot() 함수를 사용하면 쉽게 내적을 계산할 수 있다.

만약 np.dot을 사용하지 않으면 Y의 원소를 모두 따져봐야 하거나 for 문을 사용해서 계산해야 한다.