일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 30 |
- AI
- 컴퓨터
- AI Winter
- p-value
- knn
- 확률
- ANOVA
- 심층학습
- LeetCode
- 퍼셉트론
- 컴퓨터 조립
- 통계
- Stack
- Bayes Theorem
- p 값
- 딥러닝
- 인공지능
- Bayes Rule
- 인공지능 겨울
- 30 Day Challenge
- 편향
- Neural Network
- 분산분석
- 인공신경망
- 조건부 확률
- 베이즈 정리
- Today
- Total
군더더기 없는 기계학습 백과사전
파이썬으로 인공신경망(Neural Network) 구현하기(2) 본문
전편에서 기본적인 단위의 인공신경망을 단순한 파이썬 코드로 구현해봤다. 이제 좀 더 많은 양의 연산을 편리하게 처리하기 위해 행렬 연산 중 하나에 해당하는 점곱(dot product)을 코드에서 사용하는 방법을 보여주고자 한다. 이를 위해선 Numpy 패키지가 필요하다.
전편에서 구현한 인공신경망이다.
입력값 = [2.3, 5.6, 1.2, 2.4]
가중치1 = [3.1, -2.1, 8.7, -9.1]
가중치2 = [4.5, 2.1, -1.7, 3.4]
가중치3 = [2.3, -6.4, 2.1, -6.3]
편향1 = 2
편향2 = 3
편향3 = 1
출력값1 = 입력값[0]*가중치1[0] + 입력값[1]*가중치1[1] + 입력값[2]*가중치1[2] + 입력값[3]*가중치1[3]\
+ 편향1
출력값2 = 입력값[0]*가중치2[0] + 입력값[1]*가중치2[1] + 입력값[2]*가중치2[2] + 입력값[3]*가중치2[3]\
+ 편향2
출력값3 = 입력값[0]*가중치3[0] + 입력값[1]*가중치3[1] + 입력값[2]*가중치3[2] + 입력값[3]*가중치3[3]\
+ 편향3
출력값 = [출력값1, 출력값2, 출력값3]
print(출력값)
입력값과 가중치를 좀 더 간결하게 표현한 리스트로 바꿔보도록 하겠다.
입력값 = [2.3, 5.6, 1.2, 2.4]
가중치 = [[3.1, -2.1, 8.7, -9.1],
[4.5, 2.1, -1.7, 3.4],
[2.3, -6.4, 2.1, -6.3]]
편향 = [2, 3, 1]
코딩을 좀 해본 분들은 본능적으로 앞서 보여준 예시처럼 이걸 출력값을 계산하기 위해서 하나씩 인덱스를 써서 코딩하는 것에 거부감을 느낄 것이다. 만약 이미지에서 픽셀 하나하나가 입력값이고 인공신경망 층 하나당 노드(node)가 최소 5개나 된다면 사람 손으로 일일이 하기엔 거의 불가능에 가까운 작업일 것이다. 만약 Numpy를 쓰지 않는다면 우리는 얼마나 해당 작업을 자동화할 수 있을까? 다음 코드 블록에서는 for 반복문과 zip를 이용해 최대한 자동화한 코드를 다룬다.
여기서 zip 함수는 두 개의 인수(arguments)에 해당되는 리스트들의 원소(element)들을 하나씩 투플(tuple)로 묶어서 리스트를 만들어준다. 1예를 들면 zip([1, 2, 3], [a,b,c])는 [(1, a), (2, b), (3, c)]를 출력한다. zip(가중치, 편향)이라고 출력이 특별히 다를 건 없다. 그저 투플에 '가중치' 리스트의 원소인 리스트와 편향 리스트의 원소가 들어갈 뿐이다. 따라서 해당 함수에서 출력되는 리스트의 첫 번째 원소, 그러니까 zip(가중치, 편향)[0]는 ([3.1, -2.1, 8.7, -9.1], 2)가 될 것이다.
뉴런층출력값= []
for 뉴런가중치, 뉴런편향 in zip(가중치, 편향):
뉴런출력값 = 0
for n_입력값, 가중치 in zip(입력값, 뉴런가중치):
뉴런출력값 += n_입력값*가중치
뉴런출력값 += 편향
뉴런층출력값.append()
print(뉴런층출력값)
위의 코드 블럭은 Numpy가 없는 상태에서 우리가 자동화를 위해 무엇을 할 수 있는지, 그리고 Numpy 없이 읽기 불편한 코드가 몇 줄이나 늘어나고 시간복잡도가 얼마나 늘어나는지 보여주기 위해 만든 것일 뿐이므로 외울 필요는 없다. 다만 첫 번째 코드 블록과 동일한 작업이므로 같은 출력 값이 나와야 한다는 건 이해하도록 하자. 만약 이해가 잘 안 된다면 해당 코드 블록에 들어가 있는 두 개의 zip 함수 출력 값 리스트들을 나열해놓고, 주어진 입력값, 가중치 리스트들을 이용해 for 반복문 순회를 직접 해보는 확인 작업을 해봐라.
이제 Numpy 패키지에서 점곱 기능을 가져와 사용해보도록 하겠다. 일단 행렬 연산에서 점곱은 다음과 같은 작업이라는 알고 있을 것이다.
$$ [1, 2, 3] \cdot [1, 2, 3] = 1 + 4 + 9 $$
파이썬에서는 해당 연산을 다음과 같이 수행한다.
import numpy as np
리스트1 = [1, 2, 3]
리스트2 = [1, 2, 3]
#numpy 없이 수행
출력값 = 리스트1[0]*리스트2[0] + 리스트1[1]*리스트2[1] + 리스트1[2]*리스트2[2]
print(출력값)
#numpy 사용
출력값 = np.dot(리스트1, 리스트2)
print(출력값)
바로 우리에게 주어진 '가중치', '입력값', 그리고 '편향' 리스트에 적용해보도록 하자.
출력값 = np.dot(가중치, 입력값) + 편향
print(출력값)
이렇게 짧은 코드 하나에 우리는 전편에서 마지막으로 본 인공신경망 하나에서 벌어지는 작업을 담아낼 수 있다.
여기서 주의해야할 점은 np.dot()는 첫 번째 인수에 의해 출력 값 인덱스가 정해진다는 것이다. 일단 가중치부터 넣는다면 dot 함수는 3개의 원소를 가진 출력을 내는 것으로 설정될 것이다. 만약 np.dot(입력값, 가중치)를 넣어버리면 4개의 원소를 가진 출력을 내는 것으로 설정되어 '가중치' '입력값' 리스트들의 인덱스가 안 맞아 바로 오류가 나버릴 것이다.
또 한가지 주목할 점은 np.dot()은 Numpy 배열(Numpy array)이라는 파이썬에서 주어지는 리스트와는 좀 다른 성질을 가진 객체가 출력된다는 것이다. 일반적으로 파이썬에서 [1, 2 ,3] + [1, 2, 3] 같은 작업을 실행한다면 우리는 요소별(element-wise) 덧셈인 행렬 덧셈의 결과물인 [1, 4, 6] 대신 [1, 2, 3, 1, 2, 3]이라는 출력 값을 얻을 것이다. 그리고 해당 코드 블록에서 확인했듯이 Numpy 배열과 파이썬 배열이 만난다면 파이썬은 요소별 덧셈인 Numpy 배열 덧셈을 실행한다. 이는 다음 코드로 확인해 볼 수 있다.
np.array([1,2,3]) + [1,2,3]
이에 더해 Numpy 배열 계산은 리스트에 비해 메모리 소모량도 적고 연산 시간도 빠르다는 숨겨진 장점도 존재한다.
이제 Numpy 패키지를 이용해 인공신경망 계산 작업 코드를 굉장히 많이 단순화 할 수 있음을 이해했길 바란다.
[Copyright ⓒ 블로그채널 무단전재 및 재배포 금지]
- 아무리 찾아봐도 다들 엘리먼트라고 부르거나 그냥 영문으로 쓰고 있었다. 통상적으로 집합에 사용되는 단어를 사용하도록 하겠다. [본문으로]
'Machine Learning > 인공신경망' 카테고리의 다른 글
파이썬으로 인공신경망(Neural Network) 구현하기(3) (0) | 2020.05.24 |
---|---|
파이썬으로 인공신경망(Neural Network) 구현하기(1) (1) | 2020.04.21 |