이 시리즈는 R로 딥러닝을 구현하고 설명하는 것에 목표를 둔 글입니다. 이전 글에서 내용이 이어집니다.

행렬의 연산

이제 벡터의 연산에 이어 행렬의 연산에 대해 알아보겠습니다. 행렬의 연산의 경우 행렬과 오브젝트 간 연산 행렬과 행렬 간 연산 두 가지 경우가 있습니다.

행렬과 오브젝트 간에 연산

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
a <- matrix(data = 1:6, nrow = 2, ncol = 3, byrow = FALSE)
b <- c(1, 2)
c <- c(1, 2, 3)

> a
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
> b
[1] 1 2
> c
[1] 1 2 3
> a*2
     [,1] [,2] [,3]
[1,]    2    6   10
[2,]    4    8   12
> a*b
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    4    8   12
> a*c
     [,1] [,2] [,3]
[1,]    1    9   10
[2,]    4    4   18

행렬의 연산 역시 벡터의 원소별 연산과 같은 방식으로 이루어집니다. 기본적으로 행렬과 단일 오브젝트와 연산은 행렬의 모든 원소에 대응하여 연산이 이루어 집니다. 예를 들면 1에서 6까지의 원소를 가진 2행 3열의 행렬 a에 2를 곱하게 되면 행렬의 모든 원소에 대해 2를 곱한 결과를 얻을 수 있습니다. 예시에서는 곱하기 연산만 했지만 다른 사칙연산의 경우도 마찬가지로 작동합니다.

그렇다면 원소가 여러개인 벡터와 행렬 간 연산 역시 원소별로 연산이 이루어집니다. 단 행렬의 원소 개수 보다 작은 원소의 개수를 가진 벡터의 경우 R에서는 재활용 규칙이 사용됩니다. 예를 들면 a 행렬에 1,2라는 두 개의 원소를 지닌 벡터 b를 곱할 경우 열 방향(1행1열, 2행 1열, 1행 2열… 순서)으로 원소를 곱해나갑니다. 벡터의 원소 개수가 3개여도 같은 방식으로 연산이 진행됩니다.

그러나 벡터의 원소 개수가 행렬의 원소 개수의 약수가 아닌 경우 이 예시에서는 6개의 원소이므로 1,2,3,6이 아닌 개수의 벡터일 경우는 재활용 규칙을 사용되는 과정에서 전체 원소를 반복해서 사용하지 못하게 되고 연산에서 어디까지 반복된 것인지 알기 어렵게 됩니다. 이에 따라 행렬과 벡터 간 연산을 할때에는 반드시 벡터의 원소 개수를 행렬의 원소 개수의 약수인 수로 맞추어 연산을 해야합니다.

행렬과 행렬 간 연산

 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
28
29
a <- matrix(data = 1:6, nrow = 2, ncol = 3, byrow = TRUE)
b <- matrix(data = 1:6, nrow = 3, ncol = 2, byrow = FALSE)
c <- matrix(data = 1:6, nrow = 2, ncol = 3, byrow = FALSE)

> a
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
> b
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6
> c
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
>
> a*c
     [,1] [,2] [,3]
[1,]    1    6   15
[2,]    8   20   36
> a%*%b
     [,1] [,2]
[1,]   14   32
[2,]   32   77

> a%*%c
Error in a %*% c : non-conformable arguments

행렬과 행렬의 연산에는 두 행렬의 크기가 같은 경우와 다른 경우 2가지가 있습니다. 행렬의 크기가 같은 경우는 앞서 행렬과 벡터 간 연산과 마찬가지로 두 행렬의 원소가 서로 일대일로 대응하여 곱셈을 비롯한 사칙연산이 이루어집니다. 그러나 행렬의 크기가 서로 다를 경우에는 수학에서 정의하는 행렬의 곱셈 연산만 가능합니다.

수학에서 배웠던 것처럼 m행 n열의 행렬과 n행 p열의 행렬같이 두 행렬 중 앞 행렬의 열과 뒷 행렬의 행의 수가 같은 값일 때만 서로 크기가 다른 행렬의 곱셈이 성립하게 됩니다. 만약, 서로 크기가 완전히 다른 행렬의 연산을 할 경우에는 non-conformable arguments 라는 에러 메시지가 출력됩니다. R에서 서로 다른 크기의 행렬 곱셈은 일반적인 연산자가 아닌 %*% 연산자를 통해 연산이 이루어집니다.