본문 바로가기
정보공유

[정보] 파이썬으로 익히는 딥러닝

by 날고싶은커피향 2018. 3. 27.
반응형

파이썬으로 익히는 딥러닝 관련 자료입니다.

내용 참고 하시기 바랍니다.

 

 

파이썬으로 익히는 딥러닝 from 병호 강

 

 

1. 파이썬으로 익히는 딥러닝 기초 (Deep Learning with Python) 2017. 4. 강병호수석
2.  I. Environment Setup II. Perceptron III. Neural Network IV. Training V. Back Propagation VI. Training Techniques VII. Convolution Neural Network VIII.Deep Learning Contents
 3.  작성자 소개  학력 • 1993년 숭실대학교 인공지능학과 입학 • 2000년 숭실대학교 컴퓨터학부 졸업 (학사)  근무 경력 • 2000년 SKC&C(현, SK주식회사) 입사 • 국내 프로젝트 수행 • 2000년 ~ 2003년 SK Telecom 웹 프로젝트 • 2010년 ~ 2014년 SK Telecom 웹/모바일 프로젝트 • 미국 프로젝트 수행 • 2005년 ~ 2009년 Virgin Mobile USA 프로젝트 • 2009년 ~ 2010년 미국 Mobile Banking 프로젝트 • 중국 프로젝트 수행 • 2015년 ~ 2016년 SKC&C 중국법인 역량개발 총괄 • 베트남 프로젝트 수행 • 2003년 ~ 2004년 베트남 S Telecom 영업시스템 운영  기타 경력 • 회사 사내 강사 (2012년~) • Spring Framework, Java Web Programming 등 다수 • 국가 자격증 문제 출제 위원 (Pilot, 2014년) • 한국소프트웨어기술협회(KOSTA) SW개발자 L4 자격 강병호 수석 medit74@sk.com
 4.  1. Environment Overview 2. Python 3. Anaconda 4. Numpy 5. Matplotlib 6. PyDev 7. Hands-on I. Environment Setup
 5.  1. Environment Overview Python을 이용하여 딥러닝을 구현하기 위한 환경 설정. I. Environment Setup  이 과정의 학습을 위해 필요한 S/W 및 라이브러리 S/W / Lib Description Version 비고 Python 간단하고 배우기 쉬운 프로그래밍 언어 기계학습과 데이터 과학 분야에서 널리 사용 3.6.0 Anaconda에 포함 Anaconda 데이터 분석에 중점을 둔 배포판, 즉 사용자가 설치를 한 번에 수행 할 수 있도록 필요한 라이브러리 등을 하나로 정리해 놓은 것 4.3.1 NumPy 수치 계산용 라이브러리 1.11.3 Anaconda에 포함 Matplotlib 그래프를 그려주는 라이브러리 2.0.0 Anaconda에 포함 PIL Python Image Library 1.1.7 Anaconda에 포함 PyDev Python개발용 eclipse plug-in 5.6.0
 6.  2. Python Python은 간단하고 배우기 쉬운 오픈 소스 프로그래밍 언어 I. Environment Setup  Python이란? • Python은 1990년 귀도 반 로섬(Guido Van Rossum)이 개발한 Interpreter 언어이다. 즉 컴파일 과정이 없다. • 사전적 의미는 고대 신화에 나오는 파르나소스 산의 동굴에 살던 큰 뱀을 의미 • 교육 목적 뿐만 아니라 실무에서도 많이 활용. • http://www.python.org  Python의 특징 • 영어와 유사한 문법으로 프로그램을 작성하는 인간다운 언어 • 문법이 쉬워 빠르게 배울 수 있다. • 코드는 읽기 쉽고 간결하면서도 성능도 뛰어나다. • 개발 속도가 매우 빠르다. “Life is too short, You need python.”  Python 버전 • 현재의 Python은 2.x와 3.x 두 가지 버전이 공존. • 위 두 가지는 서로 호환되지 않음.
7.  3. Anaconda Anaconda는 데이터 분석에 중점을 둔 배포판 I. Environment Setup  Anaconda란? • Python 기반의 Open Data Science Platform • Python 및 Python Library등을 하나로 정리해 둔 배포판. • NumPy와 Matplotlib을 포함해 데이터 분석이 유용한 라이브러리 가 포함. • http://www.continuum.io  Anaconda Package 주요 List • Python 3.6의 경우 453개 패키지를 지원한다. Name Version Summary In Installer djanggo 1.10.5 빠른 웹 개발을 위한 프레임워크 flask 0.12 Micro Web Framework Yes jupyter 1.0.0 Python 개발 도구 Yes matplotlib 2.0.0 그래프를 그려주는 라이브러리 Yes numpy 1.11.3 수치 계산용 라이브러리 Yes pandas 0.19.2 강력한 데이터 구조 분석 도구 Yes python 3.6.0 Python 프로그래밍 언어 Yes scipy 0.18.1 Python 과학 라이브러리 Yes
 8.  4. NumPy 딥러닝 구현 시 배열과 행렬 계산이 많은데 NumPy의 배열 클래스 numpy.array에는 이를 위한 method가 많이 있다. I. Environment Setup  NumPy 라이브러리 import 하기  NumPy 배열 생성하기 • 1차원 배열 (벡터) 생성하기 • 2차원 배열 (행렬) 생성하기  NumPy 배열 원소 접근하기  NumPy 배열 연산하기 • NumPy 배열 산술 연산 import numpy as np x1 = np.array([1.0, 2.0, 3.0]) y1 = np.array([5.0, 10.0, 15.0]) x2 = np.array([[1.0, 2.0],[ 3.0, 4.0]]) y2 = np.array([[5.0,10.0],[15.0,20.0]]) print(x1[0]) print(x2[1][0]) print(x1 + y1) print(x1 - y1) print(x2 + y2) print(x2 * y2)  NumPy 배열 Broadcast 연산
9.  5. Matplotlib 딥러닝 구현 시 데이터 시각화를 위해 그래프를 그려주는 matplotlib를 사용한다. I. Environment Setup  matplotlib 라이브러리 import  그래프 그리기  이미지 표시하기 import matplotlib.pyplot as plt #image 모듈에서 imread 함수만 import 함. from matplotlib.image import imread # 데이터준비 x = np.arange(0, 6, 0.1) #0에서 6까지 0.1 간격으로 배열생성 y1 = np.sin(x) y2 = np.cos(x) # 그래프 그리기 plt.plot(x, y1, label="sin") plt.plot(x, y2, linestyle="--", label="cos") plt.xlabel("x") plt.ylabel("y") plt.title("sin & cos") plt.legend() plt.show() img = imread("../resources/Scream.jpg") plt.imshow(img) plt.show()
 10.  6. PyDev Eclipse에서 Python 개발 환경을 구축하기 위한 Plug-in I. Environment Setup  PyDev란? • Eclipse에서 실행되는 Python 개발환경 • Python, Jython, IronPython 개발을 위해서 사용 • http://www.pydev.org/  PyDev 버전 • PyDev5.6.0은 Java 8과 Eclipse 4.6 (Neon)을 필요로 한다.  Eclipse PyDev 설치 • Eclipse Marketplace에서 PyDev로 검색 후 설치 • Eclipse Preferences > PyDev > Interpreters > Python Interpreters 에서 Quick Auto-Config를 통한 Python 인터프 리터 라이브러리 연결  Eclipse 일반설정 • Eclipse Preferences > General > Workspace에서 Text file encoding을 UTF-8로 설정 • Eclipse Preferences > General > Appearance > Colors and Fonts에서 Text Font를 Consolas 9 사이즈로 설정
11.  7. Hands-on #1 - Anaconda 설치하기 I. Environment Setup  Anaconda 설치 • http://www.continuum.io 에서 사용하고 있는 OS에 맞추어 Anaconda 다운로드 후 설치  설치 후 버전 확인 • 윈도우 명령 프롬프트 실행하여 확인 C:>python --version Python 3.6.0 :: Anaconda 4.3.1 (64-bit)
 12.  #2 - PyDev 설치하기 I. Environment Setup  사전조건 • Java Platform (JDK) 8 이상 설치 • Eclipse Neon 이상 설치  PyDev 설치 • Eclipse Marketplace에서 PyDev로 검색 후 설치 • Eclipse Preferences > PyDev > Interpreters > Python Interpreters 에서 Quick Auto-Config를 통한 Python 인터프리 터 라이브러리 연결  Eclipse 일반설정 • Eclipse Preferences > General > Workspace에서 Text file encoding을 UTF-8로 설정 • Eclipse Preferences > General > Appearance > Colors and Fonts에서 Text Font를 Consolas 9 사이즈로 설정 7. Hands-on
 13.  7. Hands-on #3 – Python Project 생성 I. Environment Setup  PyDev Project 생성 • Wizard를 통한 PyDev Project 생성 • Grammar Version을 3.6으로 선택  PyDev Package 생성 • EnvironmentSetup 패키지 생성 • resources 폴더 생성 및 image file 복사 (여기선 Scream.jpg)
 14.  7. Hands-on #4 - Python 이해하기 - 자료형 I. Environment Setup  mydatatype.py # Number print(123) print(1.23) print(1 + 2j) #복소수 print(0o34) #8진수 print(0xFF) #16진수 # String print('Hello') print("What's your name?") print('"My name is Tiger" he said') print("Life is too short.nYou need python.") print("I've been to %d countries." % 15) print("%s is the best country in %d" % ("Swiss", 15)) # list type list1 = ['my','python','list'] print(list1, type(list1)) list1.append('added') print(list1) # tuple type (the tuples cannot be changed unlike lists) tuple1 = ('my','python','tuple') print(tuple1, type(tuple1)) tuple2 = 'this','is','tuple','type','too' print(tuple2, type(tuple2)) # dictionary type (Each key is separated from its value by a colon (:)) dict1 = {'company':'SKC&C','location':'Seongnam'} print(dict1, type(dict1)) dict1['company'] = 'SK' dict1['slogan'] = 'Creative ICT Factory' print(dict1, type(dict1)) • 실행 결과 확인 123 1.23 (1+2j) 28 255 Hello What's your name? "My name is Tiger" he said Life is too short. You need python. I've been to 15 countries. Swiss is the best country in 15 ['my', 'python', 'list'] <class 'list'> ['my', 'python', 'list', 'added'] ('my', 'python', 'tuple') <class 'tuple'> ('this', 'is', 'tuple', 'type', 'too') <class 'tuple'> {'company': 'SKC&C', 'location': 'Seongnam'} <class 'dict'> {'company': 'SK', 'location': 'Seongnam', 'slogan': 'Creative ICT Factory'} <class 'dict'> {1, 3, 5} <class 'set'> {'l', 'H', 'o', 'e'} <class 'set'> # set type set1 = set([1,1,3,3,5,5]) print(set1, type(set1)) set2 = set("Hello") print(set2, type(set2))
 15.  7. Hands-on #5 - Python 이해하기 - 제어문 I. Environment Setup  myflowcontrol.py import time localtime = time.localtime(time.time()) localhour = localtime.tm_hour print(localtime, type(localtime)) print(localtime.tm_hour, type(localtime.tm_hour)) #if statement print("n-- if statement --") greeting = "" if(localhour >= 6 and localhour < 11): greeting = "Good Morning" elif(localhour >= 11 and localhour < 17): greeting = "Good Afternoon" elif(localhour >= 17 and localhour <22): greeting = "Good Evening" else: greeting = "Hello" print(greeting, type(greeting)) #while statement print("n-- while statement --") count = 0 while(count < 9): print ('The count is: ', count, type(count)) count = count + 1 #for statement print("n-- for statement --") fruits = ['banana','apple','mango'] for item in fruits: print (item, type(item)) for idx in range(len(fruits)): print (idx, "-", fruits[idx]) • 실행 결과 확인 time.struct_time(tm_year=2017, tm_mon=4, tm_mday=7, tm_hour=10, tm_min=48, tm_sec=33, tm_wday=4, tm_yday=97, tm_isdst=0) <class 'time.struct_time'> 10 <class 'int'> -- if statement -- Good Morning <class 'str'> -- while statement -- The count is: 0 <class 'int'> The count is: 1 <class 'int'> The count is: 2 <class 'int'> The count is: 3 <class 'int'> The count is: 4 <class 'int'> The count is: 5 <class 'int'> The count is: 6 <class 'int'> The count is: 7 <class 'int'> The count is: 8 <class 'int'> -- for statement -- banana <class 'str'> apple <class 'str'> mango <class 'str'> 0 - banana 1 - apple 2 - mango
 16.  7. Hands-on #6 - Python 이해하기 - 함수 I. Environment Setup  myfunction.py def sayHello(name): greeting = "Hello " + name + "." return greeting def noReturn(): print("This function doesn't have return.") def keywordArgs(name, age): print("Hello! I'm", name + ",", age, "years old.") def defaultArgs(name, age, nationality="korean"): print("Hello! I'm", name + ",", age, "years old. I'm a", nationality) def variableLengthArgs(sentence, *args): for idx in range(len(args)): if (idx == 0): sentence = sentence + " " + args[idx] elif (idx <= len(args)-2): sentence = sentence + ", " + args[idx] else: sentence = sentence + " and " + args[idx] + "." print(sentence) def returnTuples(): cust1 = "Cass" cust2 = "Singha" return cust1, cust2 if __name__ == "__main__": print(sayHello('Singha')) noReturn() keywordArgs(age="44", name="Singha") defaultArgs("Cass", "23") variableLengthArgs("My hobbies are", "soccer", "horse riding", "travelling") variableLengthArgs("I've been to", "China", "Vietnam", "U.S.A", "India") customers = returnTuples() (cust1, cust2) = returnTuples() print(customers, type(customers)) print(cust1, type(cust1)) • 실행 결과 확인 Hello Singha. This function doesn't have return. Hello! I'm Singha, 44 years old. Hello! I'm Cass, 23 years old. I'm a korean My hobbies are soccer, horse riding and travelling. I've been to China, Vietnam, U.S.A and India. ('Cass', 'Singha') <class 'tuple'> Cass <class 'str'>
 17.  7. Hands-on #7 - Python 이해하기 – 내장함수 I. Environment Setup  mybuiltin.py print(abs(-1.2)) print(bool(1)) print(chr(97)) print(dict(one=1, two=2, three=3)) print(float("3.14")) print(int('100')) print(len('python')) print(list('python')) print(max([1,2,3])) print(min([1,2,3])) print(open("mydatatype.py","rb").name) print(pow(2,3)) print(list(range(0,100,10))) print(round(1.2345, 2)) print(sorted([3,1,2])) print(str(3.14)) print(sum([1,2,3])) print(tuple('python')) print(type("python")) func = lambda a, b: 3*a+2*b print(func(1,2)) • 실행 결과 확인 1.2 True a {'one': 1, 'two': 2, 'three': 3} 3.14 100 6 ['p', 'y', 't', 'h', 'o', 'n'] 3 1 mydatatype.py 8 [0, 10, 20, 30, 40, 50, 60, 70, 80, 90] 1.23 [1, 2, 3] 3.14 6 ('p', 'y', 't', 'h', 'o', 'n') <class 'str'> 7
 18.  7. Hands-on #8 - Python 이해하기 – 표준라이브러리 I. Environment Setup  mystandardlib.py import sys import os import pickle import time import calendar import random # sys - Path 경로 print(sys.path) # os- Directory print(os.pardir) print(os.getcwd()) • 실행 결과 확인 ['C:workspaceMyPythonDeepLearningEnvironmentSetup', … 결과 생략 …] .. C:workspaceMyPythonDeepLearningEnvironmentSetup {'company': 'SK', 'location': 'Seongnam', 'slogan': 'Creative ICT Factory'} 1491537539.9740002 time.struct_time(tm_year=2017, tm_mon=4, tm_mday=7, tm_hour=12, tm_min=58, tm_sec=59, … 결과 생략 … 2017.04.07 12:58:59 April 2017 Mo Tu We Th Fr Sa Su … 결과 생략 … # pickle - 객체의 형태를 유지하면서 파일에 저장하고 불러올수 있게 하는 객체 f = open("../resources/pickletest.txt","wb") data = {'company':'SK','location':'Seongnam','slogan':'Creative ICT Factory'} pickle.dump(data,f) f.close f = open("../resources/pickletest.txt", "rb") data = pickle.load(f) print(data) # time - Date and time print(time.time()) print(time.localtime(time.time())) print(time.strftime('%Y.%m.%d %X', time.localtime(time.time()))) # calendar localtime = time.localtime(time.time()) print(calendar.prmonth(localtime.tm_year, localtime.tm_mon)) # random print(random.random()) print(random.randint(1,100)) data = [1,2,3,4,5] random.shuffle(data) print(data)
 19.  7. Hands-on #9 - Python 이해하기 – 파일처리 I. Environment Setup  myfile.py ''' 파일열기 open(filename, mode) r-read w-write a-append b-binary ''' f = open("../resources/newfile.txt","w") for idx in range(1, 6): data = "%d번째 줄입니다.n" % idx f.write(data) f.close() f = open("../resources/newfile.txt","r") data = f.read() print(data) f.close() ''' with문을 이용해서 파일열기 with block을 벗어나면 파일객체는 자동 Close ''' with open("../resources/newfile.txt","r") as f: f.read() print(data) • 실행 결과 확인 1번째 줄입니다. 2번째 줄입니다. 3번째 줄입니다. 4번째 줄입니다. 5번째 줄입니다. 1번째 줄입니다. 2번째 줄입니다. 3번째 줄입니다. 4번째 줄입니다. 5번째 줄입니다.
20.  7. Hands-on #10 - Python 이해하기 – import modules I. Environment Setup  mymodule.py ''' import (패키지이름).모듈이름 from (패키지이름).모듈이름 import 모듈함수 ''' import EnvironmentSetup.myfunction as mf from EnvironmentSetup.myfunction import noReturn print("-- mymodule.py --") print(mf.sayHello("Tiger")) noReturn() • 실행 결과 확인 -- mymodule.py -- Hello Tiger. This function doesn't have return.
 21.  7. Hands-on #11 - Python 이해하기 – 클래스 I. Environment Setup  mymodule.py class Calculator: def __init__(self, first, second): self.first = first self.second = second def plus(self): return self.first + self.second def minus(self): return self.first - self.second def multiply(self): return self.first * self.second def divide(self): return self.first / self.second c = Calculator(3, 4) print(c.plus(), c.minus(), c.multiply(), c.divide()) • 실행 결과 확인 7 -1 12 0.75
 22.  7. Hands-on #11 - NumPy 이해하기 – create array I. Environment Setup  mynumpyarray.py import numpy as np ''' ndarray creation numpy.arange([start,]stop,[step,]dtype=None) ndarray.ndim : number of dimensions ndarray.shape : the size of the array in each dimension ndarray.size : total number of elements ndarray.dtype : the type of the elements ''' a = np.arange(15).reshape(3,5) print(a, type(a)) print(a.ndim) print(a.shape) print(a.size) print(a.dtype.name, a.dtype.itemsize) a = np.arange(-5, 5, 0.5) print(a) ''' ndarray creation create an array from a regular python list ''' a1 = np.array([1.0, 2.0, 3.0]) a2 = np.array([[1.0, 2.0],[ 3.0, 4.0]]) print(a1, type(a1)) print(a2, type(a2)) print(a1.ndim, a1.shape, a1.size, a1.dtype) print(a2.ndim, a2.shape, a2.size, a2.dtype) • 실행 결과 확인 [[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14]] <class 'numpy.ndarray'> 2 (3, 5) 15 int32 4 [-5. -4.5 -4. -3.5 -3. -2.5 -2. -1.5 -1. -0.5 0. 0.5 1. 1.5 2. 2.5 3. 3.5 4. 4.5] [ 1. 2. 3.] <class 'numpy.ndarray'> [[ 1. 2.] [ 3. 4.]] <class 'numpy.ndarray'> 1 (3,) 3 float64 2 (2, 2) 4 float64
 23.  7. Hands-on #12 - NumPy 이해하기 – operate array I. Environment Setup  mynumpyoperation.py import numpy as np x1 = np.array([1.0, 2.0, 3.0]) y1 = np.array([5.0, 10.0, 15.0]) x2 = np.array([[1.0, 2.0],[ 3.0, 4.0]]) y2 = np.array([[5.0,10.0],[15.0,20.0]]) z1 = np.array([-1.0, -2.0]) z2 = np.array([[5.0],[10.0],[15.0]]) ''' ndarray basic operation ''' print(x1 + y1) print(x1 - y1) print(x1 * y1) print(x1 / y1) print(x2 + y2) print(x2 * y2) ''' ndarray broadcast ''' print(x2 + z1) print(x2 * z1) print(x1 + z2) print(x1**2) print(x1>=2) ''' shape manipulation ''' print(x2.flatten()) print(x2.reshape(2,2)) • 실행 결과 확인 [ 6. 12. 18.] [ -4. -8. -12.] [ 5. 20. 45.] [ 0.2 0.2 0.2] [[ 6. 12.] [ 18. 24.]] [[ 5. 20.] [ 45. 80.]] [[ 0. 0.] [ 2. 2.]] [[-1. -4.] [-3. -8.]] [[ 6. 7. 8.] [ 11. 12. 13.] [ 16. 17. 18.]] [ 1. 4. 9.] [False True True] [ 1. 2. 3. 4.] [[ 1. 2.] [ 3. 4.]]
 24.  7. Hands-on #13 - NumPy 이해하기 – indexing, slicing and iterating I. Environment Setup  mynumpyoperation.py import numpy as np a = np.arange(10)**2 print(a) print(a[2]) print(a[3:5]) a[0:6:2] = -a[0:6:2] #from start to position 6 very element print(a) print(a[::-1]) #reversed a for i in a: print(i+1) a = np.arange(1,21,1).reshape(4,5) print(a) print(a[2,3]) print(a[0:4,1]) print(a[1,]) print(a[-1,]) • 실행 결과 확인 [ 0 1 4 9 16 25 36 49 64 81] 4 [ 9 16] [ 0 1 -4 9 -16 25 36 49 64 81] [ 81 64 49 36 25 -16 9 -4 1 0] 1 2 -3 10 -15 26 37 50 65 82 [[ 1 2 3 4 5] [ 6 7 8 9 10] [11 12 13 14 15] [16 17 18 19 20]] 14 [ 2 7 12 17] [ 6 7 8 9 10] [16 17 18 19 20]
 25.  7. Hands-on #14 - NumPy 이해하기 – universal functions I. Environment Setup  mynumpyuniversal.py import numpy as np a = np.arange(0, 6, 1) print(a) print(np.sin(a)) print(np.cos(a)) print(np.tanh(a)) print(np.exp(a)) a = np.arange(0.01, 1, 0.05) print(np.log(a)) a1 = np.array([2,3,4]) a2 = np.array([1,5,2]) print(np.maximum(a1,a2)) print(np.minimum(a1,a2)) print(np.sum(a1)) print(np.random.choice(100,5)) #0~100사이 중 5개 선택 print(np.random.rand(2,3)) # (2,3) Shape의 Random 값 리턴 print(np.random.rand(2,3)) # (2,3) Shape 표준정규분포로 초기화 ''' numpy.argmax() : Returns the indices of the maximum values ''' a = np.array([6,2,3,1,4,5]) print(a) print(np.argmax(a), a[np.argmax(a)]) a = np.array([[0.1,0.8,0.2],[0.3,0.2,0.5],[0.9,0.5,0.3]]) print(np.argmax(a, axis=1)) • 실행 결과 확인 [0 1 2 3 4 5] [ 0. 0.84147098 0.90929743 0.14112001 - 0.7568025 -0.95892427] [ 1. 0.54030231 -0.41614684 -0.9899925 - 0.65364362 0.28366219] [ 0. 0.76159416 0.96402758 0.99505475 0.9993293 0.9999092 ] [ 1. 2.71828183 7.3890561 20.08553692 54.59815003 148.4131591 ] [-4.60517019 -2.81341072 -2.20727491 -1.83258146 - 1.56064775 -1.34707365 -1.17118298 -1.02165125 -0.89159812 -0.77652879 - 0.67334455 -0.5798185 -0.49429632 -0.41551544 -0.34249031 -0.27443685 - 0.21072103 -0.15082289 -0.09431068 -0.04082199] [2 5 4] [1 3 2] 9 [69 37 83 51 61] [[ 0.94980072 0.36666774 0.02717995] [ 0.05536549 0.6011632 0.78340661]] [[ 0.62427247 0.09579107 0.16240299] [ 0.69994835 0.14973522 0.53502239]] [6 2 3 1 4 5] 0 6 [1 2 0]
 26.  7. Hands-on #15 - matplotlib 이해하기 I. Environment Setup  mymatplotlib.py import numpy as np import matplotlib.pyplot as plt import matplotlib.image as image # 데이터준비 x = np.arange(0, 6, 0.1) y1 = np.sin(x) y2 = np.cos(x) print(x) print(y1) print(y2) # 그래프 그리기 plt.plot(x, y1, label="sin") plt.plot(x, y2, linestyle="--", label="cos") plt.xlabel("x") plt.ylabel("y") plt.title("sin & cos") plt.legend() plt.show() # 이미지 표시하기 img = image.imread("../resources/Scream.jpg") plt.imshow(img) plt.show()
 27.  1. 최초의 인공신경망 2. 단층 퍼셉트론 3. 논리 회로 4. Bias 5. 단층 퍼셉트론의 한계 6. 다층 퍼셉트론 7. Hands-on II. Perceptron
 28.  1. 최초의 인공신경망 II. Perceptron 1943년 워렌 맥컬록(McCulloch)과 월터 피츠(Pitts)는 생물학적 신경망 이론을 단순화 해서 최초로 인공신경망 이론을 제시.  인공신경망(ANN, Artificial Neural Network) 최초의 인공신경망은 생물학적 신경망을 단순화 해서 논리, 산술, 기호 연산을 구현할 수 있게 하였는데 이것을 TLU (Threshold Logic Unit, 한계 논리 단위)라고 정의했다. 헵의 학습 (Hebb’s Learning)  생물학적 신경망에서 뉴런 사이에서 신호전달 시 반 복적 또는 지속적으로 신호가 자극됨. 이 결과로 뉴런 A에서 뉴런 B로 가는 경로인 시냅스 연결이 강화된다.  Hebb은 이것이 신경 레벨의 일종의 학습/기억의 과정 이라고 보고 인공신경망에 가중치 개념으로 도입했다.  이것이 헵의 규칙 또는 헵의 학습이라 한다. 𝒙 𝟏 𝒙 𝟐 Σ 𝜃 = 2 𝒚 McCulloch-Pitts 논문에 표현된 TLU  인공신경망 TLU를 AND 논리 연산에 적용한 예 입력 x1 입력 x2 출력 y 0 0 0 0 1 0 1 0 0 1 1 1 만약 𝜃=1이면 OR 연산이 적용된 TLU가 된다.
29.  2. 단층 퍼셉트론 (SLP, Single-Layer Perceptron) 로센블래트는 사람의 시각 인지 과정에 영감을 얻어 퍼셉트론 이론으로 인공적인 시각 인지 과정을 구현하는 데 적용했다.  단층 퍼셉트론 (Single-Layer Perceptron) McCulloch-Pitts TLU 이론 + Hebb의 가중치 이론으로 입력층과 출력층만으로 구성  활성화 함수 (Activation Function)  일정크기(Threshold 𝜃)이상의 신호가 올 경우 값을 전달  계단함수 대신 Sigmoid 함수나 tanh함수 또는 ReLU함수 를 사용할 수도 있다.  AND / OR Perception 예  AND : 𝑦 = 0.6𝑥1 + 0.6𝑥2 이고 𝜃 = 1  OR : 𝑦 = 1.2𝑥1 + 1.2𝑥2 이고 𝜃 = 1  적당한 가중치를 알아내는 학습이 필요함. Widrow-Hoff Learning Rule  Widrow-Hoff Learning Rule (Delta Rule) 단층 신경망에서 적당한 가중치를 알아내기 위해 출력 층의 출력 값의 오차에 비례해 가중치를 조절하는 것.  델타 규칙은 신경망의 오차가 충분히 들어들 때 까지 학 습 데이터를 반복해서 재 학습해야 한다.  델타 규칙은 후에 역전파의 기본이론이 된다.  1960년 스탠포드대 Bernard Widrow교수는 Perceptron과 유사한 ADALINE (Adaptive Linear Neuron) 단층 신경망 모델 과 위드로-호프 학습규칙(Widrow-Hoff Learning Rule)을 공개 II. Perceptron
 30.  3. 논리회로 Perceptron으로 AND, NAND, OR 논리 회로를 구조의 변경 없이 표현할 수 있다. 다른 것은 가중치와 임계 값 뿐이다.  입력이 2개인 Perceptron II. Perceptron 𝒚 = 𝟎 (𝒘 𝟏 𝒙 𝟏 + 𝒘 𝟐 𝒙 𝟐 ≤ 𝜽) 𝟏 (𝒘 𝟏 𝒙 𝟏 + 𝒘 𝟐 𝒙 𝟐 > 𝜽) 𝒙 𝟏 𝒙 𝟐 Σ 𝜃 𝒚 𝒘 𝟏 𝒘 𝟐  논리회로 진리표 (Truth-table) 입력 출력 (𝒚) 𝒙 𝟏 𝒙 𝟐 AND NAND OR 0 0 0 1 0 1 0 0 1 1 0 1 0 1 1 1 1 1 0 1 𝒘 𝟏 𝒘 𝟐 𝜽 AND 0.5 0.5 0.7 NAND -0.5 -0.5 -0.7 OR 0.5 0.5 0.2 • 가중치와 임계 값을 조정하면 논리회로를 표현할 수 있음. 기계 학습  위 예제에서 가중치와 임계 값은 사람이 임의로 지정하였음.  기계학습은 이 값을 정하는 작업을 컴퓨터가 자동으로 하도록 하는 것.  즉, 신경망에서 학습이란 컴퓨터가 가중치를 정하는 것이며, 사람은 망의 구조(모델)을 고민하고 학습 데이터를 주는 일 을 하는 것이다.
31.  4. Bias Bias (편향)을 도입하여 임계 값을 치환하면 같은 결과를 낼 수 있다. (𝜽를 −𝒃로 대체)  입력이 2개인 Perceptron (Bias의 도입) II. Perceptron 𝒚 = 𝟎 (𝒃 + 𝒘 𝟏 𝒙 𝟏 + 𝒘 𝟐 𝒙 𝟐 ≤ 𝟎) 𝟏 (𝒃 + 𝒘 𝟏 𝒙 𝟏 + 𝒘 𝟐 𝒙 𝟐 > 𝟎) 𝒙 𝟏 𝒙 𝟐 Σ 𝒚 𝒘 𝟏 𝒘 𝟐 𝒃  Bias (편향) • 가중치 (𝒘 𝟏, 𝒘 𝟐)는 각 입력 신호가 결과에 주는 영향력을 조절하는 매개변수이고, Bias는 뉴런(Node)이 얼마나 쉽 게 활성화(여기에서는 결과를 1로 출력)하느냐를 조정하는 매개변수 임. • Bias의 사전적 의미로는 ‘한쪽으로 치우쳐 균형을 깬다’라는 의미를 담고 있다.
32.  단층 퍼셉트론은 비선형 영역 문제을 분리할 수가 없다.  Perceptron 이론의 한계 발견 • Perceptron은 학습이 진행될수록 선형 분리(linear boundary)를 업데이트하면서 학습 • 하지만, 간단한 XOR문제에는 적용할 수 없는 한계가 발견  인공지능의 1차 겨울을 초래 5. 단층 퍼셉트론의 한계 II. Perceptron 입력 출력 (𝒚) 𝒙 𝟏 𝒙 𝟐 XOR 0 0 0 1 0 1 0 1 1 1 1 0
 33.  6. 다층 퍼셉트론 (MLP, Multi-Layer Perceptron) XOR 문제는 단층 퍼셉트론에서는 해결할 수 없는데, 입력층과 출력층 사이에 은닉층 수를 하나만 더하면 쉽게 해결할 수 있다.  2층 Perceptron을 이용한 XOR 판별식 𝒙 𝟏 𝒙 𝟐 Σ|𝜃=1 𝒚 Σ|𝜃=1 Σ|𝜃=1 입력 x1 입력 x2 은닉층 뉴런#1 은닉층 뉴런#2 y 0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 1 1 1 1 0 𝑤1 = −1.2 𝑤2 = 1.2 𝑤1 = 1.2 𝑤2 = 0.6 𝑤2 = 1.2 𝑤1 = 0.6 [ 은닉층 뉴런#1은 AND연산, 은닉층 뉴런#2는 OR연산, 출력층은 XOR연산이 된다. ] 은닉층뉴런#1 은닉층뉴런#2  은닉층 (Hidden Layer)  Hidden Layer을 추가하면 선형분리 불가능 (linearly inseparable) 문제를 풀 수 있다.  하지만, 다층 퍼셉트론 발견 상시에는 다층 퍼 셉트론을 학습시킬 수학적 모델이 없었다.  은닉층의 개수가 늘어나면 더욱 복잡한 문제를 풀 수 있으나 컴퓨터 계산량이 늘어난다.  Hidden Layer의 역할  앞 단계에서 받은 데이터(신호)를 필터링해서 좀 더 구체화 한 후 다음 단계 층으로 전달  각 은닉층마다 몇 개의 뉴런(노드)이 최적인지 는 문제에 따라 다르다.  신경망 층에 따라 Decision Boundary는 더 정확 해 진다. [ 2차원 평면에 분포된 데이터 세트를 은닉층 개수에 따라 분리 비교 ] II. Perceptron
 34.  7. Hands-on #1 – 단층 퍼셉트론  myperceptron.py • AND, NAND, OR Perceptron 구현하고, 특히 OR Perceptron 구현 시는 Bias를 활용해 본다. • 구현된 함수는 가중치와 임계 값을 제외한 다른 코드는 똑같음을 확인한다. II. Perceptron import numpy as np def andPerceptron(x1, x2): w1, w2, theta = 0.5, 0.5, 0.7 netInput = x1*w1 + x2*w2 if netInput <= theta: return 0 elif netInput > theta: return 1 def nandPerceptron(x1, x2): w1, w2, theta = -0.5, -0.5, -0.7 netInput = x1*w1 + x2*w2 if netInput <= theta: return 0 elif netInput > theta: return 1 def orPerceptron(x1, x2): w1, w2, bias = 0.5, 0.5, -0.2 netInput = x1*w1 + x2*w2 + bias if netInput <= 0: return 0 else: return 1 inputData = np.array([[0,0],[0,1],[1,0],[1,1]]) print("---And Perceptron---") for xs1 in inputData: print(str(xs1) + " ==> " + str(andPerceptron(xs1[0], xs1[1]))) print("---Nand Perceptron---") for xs2 in inputData: print(str(xs2) + " ==> " + str(nandPerceptron(xs2[0], xs2[1]))) print("---Or Perceptron---") for xs3 in inputData: print(str(xs3) + " ==> " + str(orPerceptron(xs3[0], xs3[1])))  실행 결과 확인 ---And Perceptron--- [0 0] ==> 0 [0 1] ==> 0 [1 0] ==> 0 [1 1] ==> 1 ---Nand Perceptron--- [0 0] ==> 1 [0 1] ==> 1 [1 0] ==> 1 [1 1] ==> 0 ---Or Perceptron--- [0 0] ==> 0 [0 1] ==> 1 [1 0] ==> 1 [1 1] ==> 1
 35.  7. Hands-on #2 – 다층 퍼셉트론  myperceptron.py • 단층 Perceptron을 쌓아서 다층 Perceptron을 생성해 본다. II. Perceptron … 코드 생략 … def xorPerceptron(x1, x2): s1 = nandPerceptron(x1, x2) s2 = orPerceptron(x1, x2) y = andPerceptron(s1, s2) return y … 코드 생략 … print("---Xor Perceptron---") for xs4 in inputData: print(str(xs4) + " ==> " + str(xorPerceptron(xs4[0], xs4[1]))) ---Xor Perceptron--- [0 0] ==> 0 [0 1] ==> 1 [1 0] ==> 1 [1 1] ==> 0  실행 결과 확인
36.  1. Neural Network 2. Activation Function 3. Matrix Inner Product 4. Feed Forward 5. Output Layer 6. MNIST Example 7. Hands-on III. Neural Network
 37.  1. Neural Network III. Neural Network 신경망은 입력층, 은닉층, 출력층으로 구성되어 있다.  딥러닝이란? 인간의 신경망(Neural Network) 이론을 이용한 인공 신경망 (ANN, Artificial Neural Network)의 일종으로, 계층 구조 (Layer Structure)로 구성하면서 입력층(Input Layer)과 출력층(Output Layer) 사이에 하나 이상의 은닉층(Hidden Layer)을 가지고 있는 심층 신경망(DNN, Deep Neural Network) 이다. Hidden Layer 수  Deep Learning의 깊이는 Hidden Layer 개수에 하나를 더하면 된다.  굳이 구별하면 2~3개 층의 신경망을 Shallow (Non-deep) Learning, 10개 이상이면 Very Deep Learning이라 한다.  Deep Learning의 신경망 계층 수를 늘리면 연산에 필요한 복잡도가 제곱 크기로 늘어난다.
38.  인공신경망(ANN)은 인간의 뇌 구조를 모방하여 모델링 한 수학적 모델이다.  신경세포 (Neuron, 뉴런) Neuron의 입력은 다수이고 출력은 하나이며, 여러 신경세포로부터 전달되어 온 신호들은 합산되어 출력된다. 합산된 값이 설정 값(역치, Threshold) 이상이면 출력 신호가 생기고 이하이면 출력 신호가 없다. 생물 신경망 인공 신경망 세포체 (Cell Body) 노드 (Node) 수상돌기 (Dendrites) 입력 (Input) 축삭 (Axon) 출력 (Output)  연결 : Synapse vs. weight 다수의 Neuron이 연결되어 의미 있는 작업을 하듯, 인공신경망의 경우도 노드들을 연결시켜 Layer를 만들고 연결 강 도는 가중치로 처리된다. 생물 신경망 인공 신경망 Synapse 가중치 (Weight) 1. Neural Network III. Neural Network
 39.  tanh 함수 (Hyperbolic Tangent Function, 쌍곡 탄젠트 함수) Sigmoid 함수 ReLU 함수 (Rectified Linear Unit Function)  활성화 함수 (Activation Function)  Synapse는 전달된 전기 신호가 최소한의 자극 값을 초과하면 활성화되어 다음 뉴런으로 전기신호를 전달한다.  활성화 함수는 이것을 모방하여 값이 작을 때는 출력 값을 작은 값으로 막고, 일정한 값을 초과하면 출력 값이 급격히 커지는 함수를 이용한다.  신경망에서 Node는 전달받은 데이터를 가중치를 고려해 합산하고, 그 값을 활성화 함수를 적용해 다음 층에 전달한다. 뇌 신경망에는 시냅스가 있는데 인공 신경망에서는 이런 방식을 모방한 활성화 함수를 이용한다.  은닉층에서 자주 이용되는 활성화 함수 𝑦 = tanh(𝑥) 𝑦 = 1 1 + 𝑒−𝑥 𝑦 = 0 𝑖𝑓, 𝑥 < 0 𝑦 = 𝑥 (𝑖𝑓, 𝑥 ≥ 0) • 예전에는 활성화 함수로 tanh함수나 Sigmoid함수를 자주 사용했으나 최근에는 ReLU 함수를 사용  ReLU 함수는 상대적으로 학습 속도가 빠르고 학습이 잘 됨.  Parametric ReLU 함수 • ReLU함수는 0보다 작은 값에서 경사가 0이다. • 그래서 이 부분에 작은 경사 값을 준 Parametric ReLU함수도 자주 이용된다. 2. Activation Function III. Neural Network
 40.  Python으로 활성화 함수를 구현해보자 2. Activation Function III. Neural Network  계단 함수 (Step Function)  시그모이드 함수 (Sigmoid Function) • 계산 결과는 항상 0과 1 사이에 있게 된다 • E는 자연상수로 2.7182…의 값을 갖는 실수  ReLU 함수 (Rectified Linear Unit Function) 비선형 함수  계단 함수나 시그모이드 함수처럼 값이 하나의 직선으로 나오지 않는 함수를 비선 형함수라 함.  선형 함수의 예 : 𝑓 𝑥 = 𝑎𝑥 + 𝑏  신경망에서 활성화 함수로 비선형 함수를 사용해야 함.  선형 함수를 사용하면 신경망을 깊게 하는 의미가 없어짐. def stepFunction(x): y = [] # Empty List for value in x: if value > 0: y.append(1) else: y.append(0) return np.array(y) def sigmoidFunction(x): return 1/(1+np.exp(-x)) def reluFunction(x): return np.maximum(0, x) 𝒚 = 𝟏 (𝒙 > 𝟎) 𝟎 (𝒙 ≤ 𝟎) 𝒚 = 𝟏 𝟏 + 𝒆−𝒙 𝒚 = 𝒙 (𝒙 > 𝟎) 𝟎 (𝒙 ≤ 𝟎)
41.  벡터와 행렬은 인경신경망을 이해하기 위한 기초 수학이다. 【 벡터 】 【 행렬과 벡터의 연산 】  행렬과 벡터의 곱셈(내적)은 일정한 규칙에 따라 계산하 며 행렬과 벡터의 크기에 따라 그 결과가 달라진다.  벡터는 방향과 크기의 의미를 모두 포함하는 수학으로 스칼라 값들을 순서대로 가진다.  선형대수학에서 n-차원 벡터  n개의 원소를 갖는 벡터로 열 벡터(Column Vector) 로 표현  열 벡터는 행 벡터(Row Vector)로 전치해서 표현하 기도 함  행렬은 원소들이 놓여지는 행과 열을 가진다.  2 x 3 행렬의 예  행 또는 열의 크기가 1이고, 다른 열 또는 행의 크기 가 1이 아닐 때, 그 행렬은 벡터로 볼 수 있다. 【 행렬 】 3. Matrix Inner Product III. Neural Network
 42.  Python으로 행렬을 생성하고 내적을 계산해 보자 3. Matrix Inner Product III. Neural Network  numpy.ndarray를 이용한 다차원 배열 생성  행렬의 내적 • NumPy의 dot()함수를 이용하여 내적을 쉽게 계산한다 • 행렬의 곱에서는 대응하는 차원의 원소 소의 일치 시켜야 한다. npArr1 = np.array([[1,2],[3,4]]) # 2x2 행렬 (2차원배열) npArr2 = np.array([[5,6],[7,8]]) # 2x2 행렬 (2차원배열) npArr3 = np.array([[1,2,3],[4,5,6]]) # 2x3 행렬 (2차원배열) npArr4 = np.array([[5,6],[7,8],[9,10]]) # 3x2 행렬 (2차원배열) npArr5 = np.array([1,2]) # 2x1 벡터 (1차원 배열) npResult1 = np.dot(npArr1, npArr2) # matrix inner product (2x2 행렬) npResult2 = np.dot(npArr3, npArr4) # matrix inner product (2x2 행렬) npResult3 = np.dot(npArr4, npArr3) # matrix inner product (3x3 행렬) npResult4 = np.dot(npArr4, npArr5) # matrix inner product (3x1 벡터) 𝟏 𝟐 𝟑 𝟒 𝟓 𝟔 𝟕 𝟖 = 𝟏𝟗 𝟐𝟐 𝟒𝟑 𝟓𝟎 𝟏 𝟐 𝟑 𝟒 𝟓 𝟔 𝟓 𝟔 𝟕 𝟖 𝟗 𝟏𝟎 = 𝟒𝟔 𝟓𝟐 𝟏𝟎𝟗 𝟏𝟐𝟒 𝟓 𝟔 𝟕 𝟖 𝟗 𝟏𝟎 𝟏 𝟐 𝟑 𝟒 𝟓 𝟔 = 𝟐𝟗 𝟒𝟎 𝟓𝟏 𝟑𝟗 𝟓𝟒 𝟔𝟗 𝟒𝟗 𝟔𝟖 𝟖𝟕 𝟓 𝟔 𝟕 𝟖 𝟗 𝟏𝟎 𝟏 𝟐 = 𝟏𝟕 𝟐𝟑 𝟐𝟗
43.   신경망 계산을 행렬 내적 식으로 표현 NumPy 행렬을 이용해서 신경망의 계산을 수행한다. 3. Matrix Inner Product III. Neural Network 𝒙 𝟏 𝒙 𝟐 1 𝒚 𝟐 𝒚 𝟏 𝒚 𝟑 2 3 4 5 6 𝒙 𝟏 𝒙 𝟐 𝟏 𝟑 𝟓 𝟐 𝟒 𝟔 = 𝒚 𝟏 𝒚 𝟐 𝒚 𝟑  코드 구현 예 preNodes = np.array([1,2]) # 신경망의 이전계층의 노드 값 weight = np.array([[1,3,5],[2,4,6]]) # 가중치 netInput = np.dot(preNodes, weight) # 노드값과 가중치의 연산 print(netInput) [ 5 11 17] • 실행 결과 확인
44.  신경망에서 정보의 흐름은 입력층  은닉층  출력증으로 진행되는데 이렇게 정보가 전방으로 전달되는 인공신경망을 피드포 워드 신경망 (FNN, Feedforward Neural Network)라고 한다.  Feedforward Neural Network  Input Layer (입력층)  입력 데이터를 받아들인다.  입력층의 노드(뉴런) 수는 입력 데이터의 특성 개수와 일치 한다.  Hidden Layer (은닉층)  은닉층의 뉴런 수와 은닉층의 개수는 신경망 설계자의 직관과 경험에 의존  은닉층의 뉴런 수가 너무 많으면 Overfitting이 발생, 너무 적으면 충 분히 표현하지 못함.  은닉충의 개수가 너무 많으면 비효율적 (예, 은닉층 수를 2배로 늘리 면 컴퓨팅 시간은 400% 증가하지만 정확성은 10%로 증가함)  Output Layer (출력층)  해결하고자 하는 문제의 성격 (예, 필기체 숫자를 인식한다면 0에서 9 까지 10개 노드로 선정) 학습이란?  Feedforward 신경망에서 원하는 결과를 얻기 위해 뉴런 사이의 적당한 가중치 를 알아내는 것 4. Feed Forward III. Neural Network
 45.  4. Feed Forward III. Neural Network Python으로 3층 신경망을 구현해 보자  3층 신경망의 구성 예 Layer Node 수 Node Shape Weight Shape Bias shape 계산 식 입력층 2 2차원 Vector 2x3 Matrix 3차원 Vector 은닉층 (1st) = 활성화함수((입력층x가중치1) + 편향1) 은닉층 (1st) 3 3차원 Vector 3x2 Matrix 2차원 Vector 은닉층 (2nd) = 활성화함수((은닉층 (1st) x가중치2) + 편향2) 은닉층 (2nd) 2 2차원 Vector 2x2 Matrix 2차원 Vector 출력층 = 활성화함수((은닉층 (2nd) x가중치3) + 편향3) 출력층 2 2차원 Vector 𝒙 𝟏 𝒙 𝟐 𝒛 𝟐 (𝟏) 𝒛 𝟏 (𝟏) 𝒛 𝟑 (𝟏) 𝒛 𝟏 (𝟐) 𝒛 𝟐 (𝟐) 𝒚 𝟏 𝒚 𝟐 𝟏 𝟏 𝟏 w b W1 = np.array([[0.1, 0.3, 0.5],[0.2, 0.4, 0.6]]) # 가중치1 : 2x3 shape W2 = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])# 가중치2 : 3x2 shape W3 = np.array([[0.1, 0.3], [0.2, 0.4]]) # 가중치3 : 2x2 shape b1 = np.array([0.7, 0.8, 0.9]) # Bias1 : 3차원 Vector b2 = np.array([0.7, 0.8]) # Bias2 : 2차원 Vector b3 = np.array([0.7, 0.8]) # Bias3 : 2차원 Vector ia = np.array([4.5, 6.2]) # 첫번째 은닉층의 계산 z1 = sigmoidFunction(np.dot(ia, W1) + b1) print("1st 은닉층 값 : " + str(z1)) # 두번째 은닉층의 계산 z2 = sigmoidFunction(np.dot(z1, W2) + b2) print("2nd 은닉층 값 : " + str(z2)) # 출력층의 계산 y = identityFunction(np.dot(z2, W3) + b3)
 46.  신경망은 분류(Classification)와 회귀(Regression)에 모두 이용할 수 있으며, 목적에 맞게 출력층을 설계 해야 한다. 5. Output Layer III. Neural Network  출력층의 활성화 함수 • 회귀 문제를 해결할 때  항등 함수 (identity function) 이용 • 분류 문제를 해결할 때  소프트맥스 함수 (softmax function) 이용  항등 함수 (identity function) • 입력을 그대로 출력, 즉 입력과 출력이 같다.  분류 문제에서 출력층의 Node 수 정하기 • 분류하고 싶은 클래스 수로 설정 • 예를 들어 숫자 0에서 9까지 하나로 분류하고 싶으면 출력층의 Node를 10개로 설정
47.   Softmax 함수  출력 층에서의 Activation Function으로 자주 사용  인공신경망의 출력 값으로 확률 벡터를 얻고 싶을 때 사용 (출력 값의 해석을 용이하기 한다.)  분류문제에서 학습단계에 사용된 Softmax 함수는 추론 시에 생각하는 경우가 많다. (출력 값이 큰 Node는 변하지 않음으로...) 분류 문제를 풀기 위해서 출력 층에서는 출력 값으로 확률벡터를 얻는 softmax 함수를 자주 사용한다.  Softmax 함수는 각 output node의 출력을 0~1로 제한  output node의 출력을 모두 합한 값은 항상 1  Softmax function의 수식  Softmax 함수 원리 𝒆 𝒚𝒊 : 지수함수 (exponential function) 5. Output Layer III. Neural Network
 48.   Python으로 구현하기 • 지수 함수 계산 결과가 매우 크면 overflow가 발생할 수 있다. • 이를 해결하기 위해 Softmax 함수 구현 시 입력 값 중 최대값을 찾아 빼주면 올바르게 계산할 수 있다. Python으로 Softmax함수를 구현해 보자 5. Output Layer III. Neural Network def softmaxFunction(x): expX = np.exp(x) # 지수 함수 (exponential function) sumExpX = np.sum(expX) # 지수 함수 결과의 합 return expX / sumExpX a = np.array([2.3, -0.9, 3.6]) y4 = softmaxFunction(a) print(y4, np.sum(y4)) def softmaxFunction(x): expX = np.exp(x) # 지수 함수 (exponential function) sumExpX = np.sum(expX) # 지수 함수 결과의 합 return expX / sumExpX a = np.array([900, 1000, 1000]) y4 = softmaxFunction(a) print(y4, np.sum(y4)) • 실행 결과 확인 RuntimeWarning: overflow encountered in exp [ nan nan nan] nan def softmaxFunction(x): expX = np.exp(x - np.max(x)) # Overflow 대비를 위해 원소 중 최대값을 각 입력 신호에서 빼서 예방한다. sumExpX = np.sum(expX) # 지수 함수 결과의 합 return expX / sumExpX a = np.array([900, 1000, 1000]) y4 = softmaxFunction(a) print(y4, np.sum(y4))
 49.  MNIST Data Set은 Handwritten Digit Image 집합이다. 6. MNIST Example III. Neural Network  MNIST(Mixed National Institute of Standards and Technology) 란? • 기계학습 분야에서 사용되는 손글씨 숫자 이미지 데이터 셋 • 실험용 데이터로 자주 사용된다. • 0부터 9까지 숫자 이미지로 구성되어 있다 • 각 이미지가 실제 의미하는 숫자가 Label되어 있다. • 훈련 이미지가 6만장, 시험 이미지가 1만장으로 준비되어 있다. • 각 숫자는 가로, 세로 각각 28 픽셀 크기의 흑백 이미지이다 • https://en.wikipedia.org/wiki/MNIST_database  기계학습 알고리즘에 사용된 예
50.  MINST를 위한 신경망 설계 및 추론 과정 6. MNIST Example III. Neural Network  MNIST를 위한 신경망 설계 • 입력층 : 784개 (이미지 크기가 28x28 픽셀임으로) • 출력층 : 10개 (0에서 9로 분류함으로) • 첫번째 은닉층 : 50개 (임의의 수) • 두번째 은닉층 : 100개 (임의의 수)  MNIST Example 준비 • 훈련데이터(6만장), 검증데이터(1만장) 다운로드  데이터 정규화 : 0~255의 픽셀 값을 0.0~1.0으로 변환  데이터 평탄화 : 28x28 배열을 784 배열로 평탄화  레이블 one-hot encoding : 정답을 뜻하는 원소만 1이고 나머지는 0으로 표기법 예) [0,0,1,0,0,0,0,0,0,0] 는 2를 나타냄 • 가중치, 편향 값 설정 𝒙 𝟏 𝒙 𝟐 𝒛 𝟓𝟎 (𝟏) 𝒛 𝟏 (𝟏) 𝒛 𝟏𝟎𝟎 (𝟐) 𝒛 𝟏 (𝟐) 𝒛 𝟐 (𝟐) 𝒚 𝟏 𝒚 𝟏𝟎 𝟏 𝟏 𝟏 w b 𝒙 𝟕𝟖𝟒 … … … … X W1 W2 W3  Y 784 784 x 50 50 x 100 100 x 10 10 일치 일치 일치 일치 • 신경망 각 층의 배열 형상 추이 (Bias와 Activation Function은 생략)
51.  MINST를 위해 설계된 신경망을 구현하기 6. MNIST Example III. Neural Network  Python으로 구현하기 import numpy as np import pickle from Common.mnist import load_mnist from Common.functions import sigmoid, softmax def getData(): (trainImg, trainLbl),(testImg, testLbl) = load_mnist(normalize=True, flatten=True, one_hot_label=False) print(trainImg.shape) # (60000, 784) print(trainLbl.shape) # (60000,) print(testImg.shape) # (10000, 784) print(testLbl.shape) # (10000,) return (trainImg, trainLbl),(testImg, testLbl) def initNetwork(): with open("../resources/sample_weight.pkl","rb") as f: network = pickle.load(f) return network def predict(network,x): W1, W2, W3 = network['W1'], network['W2'], network['W3'] b1, b2, b3 = network['b1'], network['b2'], network['b3'] a1 = np.dot(x, W1) + b1 z1 = sigmoid(a1) a2 = np.dot(z1, W2) + b2 z2 = sigmoid(a2) a3 = np.dot(z2, W3) + b3 y = softmax(a3) return y ''' load dataset and initialize weight & bias ''' (trainImg, trainLbl),(testImg, testLbl) = getData() network = initNetwork(); ''' show first element ''' firstImg = trainImg[0].reshape(28,28) firstLbl = trainLbl[0] print(firstLbl) # 5 plt.imshow(firstImg,cmap='gray',interpolation='nearest') plt.show() ''' predict ''' accuracyCnt = 0 print(len(trainImg)) # 60000 for idx in range(len(trainImg)): y = predict(network, trainImg[idx]) p = np.argmax(y) if p == trainLbl[idx]: accuracyCnt += 1 print(accuracyCnt) print("Accuracy:" + str(accuracyCnt / len(trainImg)))
 52.  MINST 배치 처리를 통한 빠른 연산 수행 6. MNIST Example III. Neural Network  이미지 여러 장을 한꺼번에 처리 하기 • 100장을 한꺼번에 처리하는 경우의 형상  입력층은 100 x 784  첫번째 은닉층은 100 x 50  두번째 은닉층은 100 x 100  출력층은 100 x 10 • 배치 처리의 장점  수치 계산 라이브러리 대부분이 큰 배열을 효율적으로 처리하는 데 최적화 되어 있음.  데이터 I/O 횟수를 줄여, CPU, GPU가 계산에 집중  Python으로 구현하기 𝒙 𝟏 𝒙 𝟐 𝒛 𝟓𝟎 (𝟏) 𝒛 𝟏 (𝟏) 𝒛 𝟏𝟎𝟎 (𝟐) 𝒛 𝟏 (𝟐) 𝒛 𝟐 (𝟐) 𝒚 𝟏 𝒚 𝟏𝟎 𝟏 𝟏 𝟏 𝒙 𝟕𝟖𝟒 … … … … X W1 W2 W3  Y 100 x 784 784 x 50 50 x 100 100 x 10 100 x 10 일치 일치 일치 일치 • 신경망 각 층의 배열 형상 추이 (Bias와 Activation Function은 생략) 100x784 100x50 100x100 ''' predict ''' batchSize = 100 accuracyCnt = 0 print(len(trainImg)) # 60000 for idx in range(0, len(trainImg), batchSize): y = predict(network, trainImg[idx:idx+batchSize]) p = np.argmax(y, axis=1) accuracyCnt += np.sum(p == trainLbl[idx:idx+batchSize]) print(accuracyCnt) print("Accuracy:" + str(accuracyCnt / len(trainImg)))
 53.  7. Hands-on III. Neural Network  myactivation.py • 계단 함수, Sigmoid 함수, ReLU 함수를 구현해보고 시각화해 본다. import numpy as np import matplotlib.pyplot as plt def stepFunction(x): y = [] # Empty List for value in x: if value > 0: y.append(1) else: y.append(0) return np.array(y) def sigmoidFunction(x): return 1/(1+np.exp(-x)) def reluFunction(x): return np.maximum(0, x) x = np.arange(-5, 5, 0.01) y1 = stepFunction(x) y2 = sigmoidFunction(x) y3 = reluFunction(x) plt.plot(x, y1, label="Step Function" ,linestyle="-") plt.plot(x, y2, label="Sigmoid Function",linestyle="--") plt.xlabel("x") plt.ylabel("y") plt.title("Step & Sigmoid") plt.legend() plt.show() plt.plot(x, y3, label="ReLU Function" ,linestyle="-.") plt.xlabel("x") plt.ylabel("y") plt.title("ReLU Function") plt.legend() plt.show() #1 – Activation Function 구현하기
54.  7. Hands-on III. Neural Network  myinnerproduct.py • numpy.ndarray 를 이용하여 배열을 생성하고 내적을 계산한다. • 신경망에 적용해 본다. import numpy as np npArr1 = np.array([[1,2],[3,4]]) # 2x2 행렬 (2차원배열) npArr2 = np.array([[5,6],[7,8]]) # 2x2 행렬 (2차원배열) npArr3 = np.array([[1,2,3],[4,5,6]]) # 2x3 행렬 (2차원배열) npArr4 = np.array([[5,6],[7,8],[9,10]]) # 3x2 행렬 (2차원배열) npArr5 = np.array([1,2]) # 2x1 벡터 (1차원배열) npResult1 = np.dot(npArr1, npArr2) # matrix inner product (2x2 행렬) npResult2 = np.dot(npArr3, npArr4) # matrix inner product (2x2 행렬) npResult3 = np.dot(npArr4, npArr3) # matrix inner product (3x3 행렬) npResult4 = np.dot(npArr4, npArr5) # matrix inner product (3x1 벡터) print(npResult1) print(npResult2) print(npResult3) print(npResult4) preNodes = np.array([1,2]) # 신경망의 이전계층의 노드 값 weight = np.array([[1,3,5],[2,4,6]]) # 가중치 netInput = np.dot(preNodes, weight) # 노드값과 가중치의 연산 print(netInput) 𝒙 𝟏 𝒙 𝟐 1 𝒚 𝟐 𝒚 𝟏 𝒚 𝟑 2 3 4 5 6 #2 – Matrix Inner Product 계산해보기
55.  #3 – 3층 신경망 구현해보기 7. Hands-on III. Neural Network  myfeedforward.py • 3층 신경망을 구성하고 신경망 계산 결과를 확인한다. import numpy as np def initNeuralNetwork(): neuralNetwork = {} # Python Dictonary 자료형 neuralNetwork['W1'] = np.array([[0.1, 0.3, 0.5],[0.2, 0.4, 0.6]]) neuralNetwork['W2'] = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]]) neuralNetwork['W3'] = np.array([[0.1, 0.3], [0.2, 0.4]]) neuralNetwork['b1'] = np.array([0.7, 0.8, 0.9]) neuralNetwork['b2'] = np.array([0.7, 0.8]) neuralNetwork['b3'] = np.array([0.7, 0.8]) return neuralNetwork def sigmoidFunction(x): return 1/(1+np.exp(-x)) def identityFunction(x): return x def feedForward(neuralNetwork, ia): # 신경망 초기값을 가져온다. W1, W2, W3 = neuralNetwork['W1'], neuralNetwork['W2'], neuralNetwork['W3'] b1, b2, b3 = neuralNetwork['b1'], neuralNetwork['b2'], neuralNetwork['b3'] # 첫번째 은닉층의 계산 z1 = sigmoidFunction(np.dot(ia, W1) + b1) print("1st 은닉층 값 : " + str(z1)) # 두번째 은닉층의 계산 z2 = sigmoidFunction(np.dot(z1, W2) + b2) print("2nd 은닉층 값 : " + str(z2)) # 출력층의 계산 y = identityFunction(np.dot(z2, W3) + b3) return y neuralNetwork = initNeuralNetwork() ia = np.array([4.5, 6.2]) print("입력층 값 : " + str(ia)) oa = feedForward(neuralNetwork, ia) print("출력층 값 : " + str(oa)) 𝒙 𝟏 𝒙 𝟐 𝒛 𝟐 (𝟏) 𝒛 𝟏 (𝟏) 𝒛 𝟑 (𝟏) 𝒛 𝟏 (𝟐) 𝒛 𝟐 (𝟐) 𝒚 𝟏 𝒚 𝟐 𝟏 𝟏 𝟏 w b  실행 결과 확인 입력층 값 : [ 4.5 6.2] 1st 은닉층 값 : [ 0.91606157 0.99033948 0.9989626 ] 2nd 은닉층 값 : [ 0.78403932 0.90559276] 출력층 값 : [ 0.95952248 1.3974489 ]
 56.  #4 – Softmax 함수 구현보기 7. Hands-on III. Neural Network  myactivation.py • Softmax 함수를 추가 구현하고 실행해 본다. … 코드 생략 … ''' Softmax함수 구현 입력파라미터 numpy.ndarray 출력파라미터 numpy.ndarray ''' def softmaxFunction(x): expX = np.exp(x - np.max(x)) # Overflow 대비를 위해 원소 중 최대값을 각 입력 신호에서 빼서 예방한다. sumExpX = np.sum(expX) # 지수 함수 결과의 합 return expX / sumExpX … 코드 생략 … a = np.array([2.3, -0.9, 3.6]) y4 = softmaxFunction(a) print(y4, np.sum(y4)) a = np.array([900, 1000, 1000]) y4 = softmaxFunction(a) print(y4, np.sum(y4)) • 실행 결과 확인 [ 0.21231157 0.00865429 0.77903414] 1.0 [ 1.86003799e-44 5.00000000e-01 5.00000000e-01] 1.0
 57.  #5 – MNIST 실습해보기 7. Hands-on III. Neural Network  mymnist.py • 제공되는 파일을 이용하여 MNIST 를 위한 신경망을 구축해 본다. • 제공되는 파일 : Common/mnist.py, Common/functions.py, resources/sample_weight.pkl • 전체 소스코드 : MNIST Example – Python으로 구현하기 참조 • 실행 결과 확인 (60000, 784) (60000,) (10000, 784) (10000,) 5 60000 56146 Accuracy:0.9357666666666666  올바르게 분류한 비율이 93.57%
 58.  #6 – MNIST 실습해보기 (배치처리) 7. Hands-on III. Neural Network  mymnist.py • 100장의 이미지를 한꺼번에 처리하여 효율적으로 처리해 본다. • 실행 결과 확인 (60000, 784) (60000,) (10000, 784) (10000,) 5 60000 56146 Accuracy:0.9357666666666666  계산 속도를 체감 비교해 본다. … 코드 생략 … ''' predict ''' batchSize = 100 accuracyCnt = 0 print(len(trainImg)) # 60000 for idx in range(0, len(trainImg), batchSize): y = predict(network, trainImg[idx:idx+batchSize]) p = np.argmax(y, axis=1) accuracyCnt += np.sum(p == trainLbl[idx:idx+batchSize]) print(accuracyCnt) print("Accuracy:" + str(accuracyCnt / len(trainImg)))
 59.  1. Neural Network Training 2. Cost Function 3. Numerical Differentiation 4. Gradient Descent Method 5. MNIST Example 6. Hands-on IV. Training
 60.  학습이란 신경망에서 원하는 결과를 얻기 위해 뉴런 사이의 적당한 가중치를 알아내는 것. 즉 가중치를 최적화 하는 것이다.  신경망에서 지도학습 a. 훈련 데이터 (Training Set) 준비 : 입력 데이터와 출력 데이터 b. 신경망에 데이터 훈련 : 출력층 값을 확인 c. 지도학습 데이터와 차이 (오차) 계산 d. 오차가 최대한 작도록 가중치를 최적화  가중치를 어떻게 최적화 할까요?  Gradient Method(경사하강법)를 이용한다.  Gradient Method에서 경사는 어떻게 계산하나요?  수치 미분을 사용해 구할 수 있으나 계산 시간이 매우 오래 걸린다. 따라서 기울기를 효율적으로 계산하는 Back Propagation(역전파)를 이용한다.  심층 신경망(Deep Neural Network)에서 더 정밀하게 최적화하는 방법은 무엇인가요?  Dropout 알고리즘을 이용한다.  심층 신경망(Deep Neural Network)에서도 학습이 잘 되게 하려면?  Pre-Training(사전학습)을 이용한다. 1. Neural Network Training IV. Training  오차를 어떻게 측정하나요?  Cost Function(비용함수)을 이용한다.
61.  학습 데이터에 너무 지나치게 맞추다 보면 일반화 성능이 떨어지는 모델을 얻게 되는 현상을 과적합(Overfitting)이라고 한다.  Under Fitting 적정 수준의 학습을 하지 못하여 실제 성능이 떨어지는 경우  Normal Fitting (Generalized Fitting) 적정 수준의 학습으로 실제 적정한 일반화 수준을 나타냄. 기계 학습이 지향하는 수준.  Over Fitting 학습 데이터에 성능이 좋지만 실제 데이터에 관해 성능이 떨어짐. 특히 조심해야 함. 1. Neural Network Training IV. Training
 62.  비용함수란 신경망 학습에서 학습 데이터에 대한 오차를 측정하는 척도이다.  평균제곱오차 (mean squared error, MSE) 2. Cost Function IV. Training 𝑬 = 𝟏 𝟐 (𝒚 𝒌 − 𝒕 𝒌) 𝟐 𝒌 • 𝒚 𝒌 : 신경망의 출력 (신경망이 추정한 값) • 𝒕 𝒌 : 정답 레이블 • 𝒌 : 데이터의 차원 수 (MNIST에서는 0에서 9의 10개)  파이썬으로 구현 및 사용 import numpy as np def meanSquaredError(y, t): return 0.5*np.sum((y-t)**2) t = np.array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0]) # label = 5 y = np.array([0.1, 0.03, 0.05, 0.2, 0.9, 0.0, 0.1, 0.2, 0.12, 0.03]) # 5라고 추정 # 정답일 경우 MSE, CEE의 값은 적다. print("-- 정답인 경우 --") print("MSE :", meanSquaredError(y, t)) y = np.array([0.1, 0.03, 0.05, 0.2, 0.0, 0.1, 0.2, 0.12, 0.03, 0.9]) # 9라고 추정 # 오류일 경우 MSE, CEE의 값은 적다. print("-- 오류인 경우 --") print("MSE :", meanSquaredError(y, t))
 63.  교차엔트로피오차 함수는 활성함수로 Sigmoid함수나 Softmax함수를 채택한 신경망과 함께 사용되는 경우가 많다.  교차 엔트로피 오차 (cross entropy error, CEE) 2. Cost Function IV. Training 𝑬 = − 𝒕 𝒌 𝐥𝐨𝐠 𝒚 𝒌 𝒌 • 𝒚 𝒌 : 신경망의 출력 (0에서 1사이어야 한다) • 𝒕 𝒌 : 정답 레이블 (정답이 아닌 나머지는 𝑡 𝑘 가 0임으로 곱해도 0이 된다. • log : 밑이 e인 자연로그 (log 𝑒 𝒚 𝒌)  파이썬으로 구현 및 사용 자연로그 e의 그래프 (𝒚 = 𝐥𝐨𝐠 𝒙) • 𝒙가 1일 때 𝒚는 0이 된다. • 𝒙가 0에 가까워질수록 𝒚값은 점점 작아진다 • 𝒙가 0이면 𝒚는 –inf가 된다. (무한대) import numpy as np def crossEntropyError(y, t): delta = 1e-7 #아주 작은 값 (y가 0인 경우 -inf 값을 예방) return -np.sum(t*np.log(y+delta)) t = np.array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0]) # label = 5 y = np.array([0.1, 0.03, 0.05, 0.2, 0.9, 0.0, 0.1, 0.2, 0.12, 0.03]) # 정답일 경우 MSE, CEE의 값은 적다. print("-- 정답인 경우 --") print("CEE :", crossEntropyError(y, t)) y = np.array([0.1, 0.03, 0.05, 0.2, 0.0, 0.1, 0.2, 0.12, 0.03, 0.9]) # 오류일 경우 MSE, CEE의 값은 적다. print("-- 오류인 경우 --") print("CEE :", crossEntropyError(y, t))
 64.  Mini-batch학습이란 훈련 데이터로부터 일부만 골라서 학습을 수행하는 방식이다.  Mini-batch학습 2. Cost Function IV. Training • 가중치를 조절하기 위한 비용함수의 계산은 모든 훈련데이터를 1회 마치고 비용 함수의 합을 구해야 한다. • 하지만 데이터가 많은 경우 (MNIST는 6만개) 손실함수 이렇게 구하는 건 비 현실적이다. • 이를 개선하기 위해 신경망 학습에서 훈련 데이터의 일부만 골라 학습하는 방법을 미니배치 학습이라고 한다. (즉, 표본을 뽑아 학습한다.)  파이썬으로 구현 (MNIST 예제) ''' predict - MiniBatch Target Setting - Predict (추론 수행) - Cost Function (비용함수계산) ''' miniBatchSize = 10 print(len(trainImg), "개 중에 ", miniBatchSize, "를 미니배치 학습.") miniBatchMask = np.random.choice(len(trainImg), miniBatchSize) trainImgBatch = trainImg[miniBatchMask] trainLblBatch = trainLbl[miniBatchMask] print("Random Choice 된 정답 레이블", trainLblBatch) y = predict(network, trainImgBatch) print("신경망 출력 결과 (10-배치크기, 10-분류크기) Shapen", y) p = np.argmax(y, axis=1) print("최대값으로 추정한 결과", p) print(crossEntropyError(y, trainLblBatch)) • 실행 결과 확인 60000 개 중에 10 를 미니배치 학습. Random Choice 된 정답 레이블 [4 5 1 8 1 2 2 7 7 4] 신경망 출력 결과 (10-배치크기, 10-분류크기) Shape [[ 1.41822547e-05 2.35181437e-06 1.51875982e-04 3.35034133e-06 … 결과 생략 … 최대값으로 추정한 결과 [4 5 1 8 1 2 2 7 7 4] 0.12456381321 • 비용함수인 crossEntropyError 함수의 구현도 배치 처리가 가능하게 변경되어야 함. (코드 생략)
65.  미분(Differentiation)은 특정 순간의 변화량이다.  연속적이고 매끄러운 함수 (미분 가능한 함수)에서 특정 지점의 접선의 기울기는 그 점에서의 미분 값과 같다  점 Q가 점 P로 움직일 경우 직선 PQ의 기울기는 점 P 에서의 접선의 기울기와 같다. 3. Numerical Differentiation IV. Training  미분 수식 𝒅𝒇(𝒙) 𝒅𝒙 = lim ℎ→𝟎 𝒇 𝒙 + 𝒉 − 𝒇(𝒙) 𝒉 • 𝒅𝒇(𝒙) 𝒅𝒙 : 미분, 즉 𝒙에 대한 𝒇(𝒙)의 변화량 • 𝒉 : 시간 • 𝒍𝒊𝒎 𝒉→𝟎 : 시간이 0에 가까워짐. 미분 가능하지 않는 경우
66.  수치 미분(Numerical Differentiation)은 근사치를 이용해서 계산하는 방법이다. 3. Numerical Differentiation IV. Training  수치 미분 • 시간을 나타내는 h에 가급적 낮은 값을 넣어야 하는데 너무 작은 값 (예, 0.00….1) 을 넣으면 컴퓨터 계산에 문제가 발생한다. . • 시간 h는 무한의 0으로 좁히는 것은 불가능 하다. • 따라서 근사치를 이용하여 계산한다. (h는 0.0001이 가장 좋다)  파이썬으로 구현  수치 미분의 예 • 𝐲 = 𝟎, 𝟎𝟏𝒙 𝟐 + 𝟎. 𝟏𝒙 의 수치 미분 def numericalDiff(f, x): h = 1e-4 # 0.0001 return (f(x+h)-f(x-h))/(2*h) def numericalDiff(f, x): h = 1e-4 # 0.0001 return (f(x+h)-f(x-h))/(2*h) def sampleFunc1(x): return 0.01*x**2 + 0.1*x x = np.arange(0, 20, 0.1) y = sampleFunc1(x) plt.xlabel("x") plt.ylabel("f(x)") plt.plot(x, y) plt.show() print(numericalDiff(sampleFunc1, 5)) print(numericalDiff(sampleFunc1, 10)) • 실행 결과 확인 0.1999999999990898 0.2999999999986347 • 수치 미분이 아닌 진정한 미분은 각각 0.2와 0.3이다. • 수치 미분으로 계산하더라도 값의 차는 거의 없다. 𝐲 = 𝟎, 𝟎𝟏𝒙 𝟐 + 𝟎. 𝟏𝒙
67.  변수가 2개 이상인 함수를 미분할 때 미분 대상 변수 외에 나머지 변수를 상수처럼 고정시켜 미분하는 것을 편미분이라 한다. 3. Numerical Differentiation IV. Training  편 미분의 예 • 𝒇 𝒙 𝟎, 𝒙 𝟏 = 𝒙 𝟎 𝟐 + 𝒙 𝟏 𝟐 인 경우 𝝏𝒇 𝝏𝒙 𝟎 나 𝝏𝒇 𝝏𝒙 𝟏 처럼 쓴다.  𝒙 𝟎 = 𝟑, 𝒙 𝟏 = 𝟒 일 때, 편미분 𝝏𝒇 𝝏𝒙 𝟎 을 구한다.  𝒙 𝟎 = 𝟑, 𝒙 𝟏 = 𝟒 일 때, 편미분 𝝏𝒇 𝝏𝒙 𝟏 을 구한다. def numericalDiff(f, x): h = 1e-4 # 0.0001 return (f(x+h)-f(x-h))/(2*h) def sampleFunc2(x): return x**2 + 4**2 print(numericalDiff(sampleFunc2, 3.0)) def numericalDiff(f, x): h = 1e-4 # 0.0001 return (f(x+h)-f(x-h))/(2*h) def sampleFunc3(x): return 3**2 + x**2 print(numericalDiff(sampleFunc3, 4.0))
 68.  모든 변수의 편미분을 벡터로 정리한 것을 기울기(Gradient)라고 한다. 4. Gradient Descent Method IV. Training  기울기의 예 • 𝒇 𝒙 𝟎, 𝒙 𝟏 = 𝒙 𝟎 𝟐 + 𝒙 𝟏 𝟐 인 경우 기울기는 ( 𝝏𝒇 𝝏𝒙 𝟎 , 𝝏𝒇 𝝏𝒙 𝟏 )이다.  𝒇 𝒙 𝟎, 𝒙 𝟏 = 𝒙 𝟎 𝟐 + 𝒙 𝟏 𝟐 인 함수의 기울기 구하기 (변수 0,0 일 때 최소값 0을 가지는 함수) def numeiralGradient(f, x): h = 1e-4 # 0.0001 grad = np.zeros_like(x) #x와 형상이 같은 배열을 생성 for idx in range(x.size): tmpVal = x[idx] x[idx] = tmpVal + h print(idx, x) fxh1 = f(x) x[idx] = tmpVal - h print(idx, x) fxh2 = f(x) grad[idx] = (fxh1 - fxh2) / (2*h) x[idx] = tmpVal # 원래 값 복원 return grad # f(x0, x1) = x0**2 + x1**2인 함수 def sampleFunc4(x): return x[0]**2 + x[1]**2 print(numeiralGradient(sampleFunc4, np.array([3.0, 4.0]))) print(numeiralGradient(sampleFunc4, np.array([0.0, 2.0]))) print(numeiralGradient(sampleFunc4, np.array([3.0, 0.0]))) • 실행 결과 확인 0 [ 3.0001 4. ] 0 [ 2.9999 4. ] 1 [ 3. 4.0001] 1 [ 3. 3.9999] [ 6. 8.] 0 [ 1.00000000e-04 2.00000000e+00] 0 [ -1.00000000e-04 2.00000000e+00] 1 [ 0. 2.0001] 1 [ 0. 1.9999] [ 0. 4.] 0 [ 3.0001 0. ] 0 [ 2.9999 0. ] 1 [ 3.00000000e+00 1.00000000e-04] 1 [ 3.00000000e+00 - 1.00000000e-04] [ 6. 0.] • 점 (3,4)에서의 기울기는 (6,8) • 점 (0,2)에서의 기울기는 (0,4) • 점 (3,0)에서의 기울기는 (6,0) 이 예제에서 최솟값은 𝒙 𝟎, 𝒙 𝟏가 0,0 일 때 함수 f는 0 값을 가진다. 하지만, 신경망에서는 함수의 최소값(최소 오차)을 가지기 위해서 변수 x (가중치) 가 얼마 인지 알 수 없음으로 “기울기의 반대 방 향으로 갈수록 최솟값이 가까워짐” 것을 이용하여 x를 조정한다.
69.  Gradient Descent Method의 최솟값을 계산하는 알고리즘을 이용해 신경망의 연결가중치를 최적화한다.  Gradient Descent Method 란? 수치 계산에서 함수의 최솟값을 계산할 때 사용되는 가장 보편적인 알고리즘 a. 먼저 변수의 초기값을 선정 b. 변수 값에 해당하는 함수의 경사도 계산 c. 변수를 경사 방향으로 움직여 다음 숫자값으로 설정 a~c를 반복하며 함수의 최솟값이 되는 변수값으로 근접해 나간다.  Gradient Descent Method를 신경망에 적용  비용함수를 계산하는 부분에서 훈련 데이터가 늘어날수록 시간이 많이 걸림. 𝒙𝒊 = 𝒙𝒊 − ℰ 𝝏𝒇 𝝏𝒙 경사 하강법 신경망 변수 𝒙 각 연결의 Weight 함수 𝒇 비용함수(손실함수) 함수의 경사 𝝏𝒇 𝝏𝒙 가중치 매개변수에 대한 비용함수의 기울기 움직임의 정도 ℰ 학습률 (미리 적정한 값으로 정해야 함) 2차원에서의 Gradient Descent Method (Parameter가 하나인 경우) Parameter가 두 개인 경우 4. Gradient Descent Method IV. Training
 70.  𝒇 𝒙 𝟎, 𝒙 𝟏 = 𝒙 𝟎 𝟐 + 𝒙 𝟏 𝟐 의 최솟값을 구하기 위해 Gradient(기울기)에 학습률을 이용하여 반복학습 해 본다. (x 값을 조정) 4. Gradient Descent Method IV. Training  파이썬으로 구현 import numpy as np import matplotlib.pyplot as plt from Common.gradient_2d import numerical_gradient ''' f = x[0]**2 + x[1]**2 initX = 초기값 (-3,4) 초기값에서 함수에 대한 기울기 (편미분에 의한 계산)를 구한 후 기울기 값과 학습률을 이용해서 x값을 이동 위를 stepNum(100번) 반복 ''‘ def gradientDescent(f, initX, learningRate, stepNum=100): x = initX xHistory = [] for i in range(stepNum): xHistory.append(x.copy()) grad = numerical_gradient(f,x) x -= learningRate*grad if(i == stepNum-1): print(x) return x, np.array(xHistory) def sampleFunction(x): return x[0]**2 + x[1]**2 # 적정학습률 initX = np.array([-3.0,4.0]) learningRate = 0.1 x, xHistory = gradientDescent(sampleFunction, initX, learningRate) # 학습률이 큰 경우 initX = np.array([-3.0,4.0]) learningRate = 2 x, xHistory = gradientDescent(sampleFunction, initX, learningRate) # 학습률이 작은 경우 initX = np.array([-3.0,4.0]) learningRate = 0.001 x, xHistory = gradientDescent(sampleFunction, initX, learningRate) • 실행 결과 확인 (100회 반복 후 x 값의 조정된 모습) [ -6.11110793e-10 8.14814391e-10] [ -1.35262250e+12 2.26052540e+12] [-2.45570041 3.27426722] Hyper parameter • 학습에 의한 가중치 조정과는 다르게 학습률 같이 사람이 직 접 설정하는 매개변수
71.  신경망에서의 기울기는 가중치에 대한 비용 함수(손실 함수)의 기울기이다. 4. Gradient Descent Method IV. Training  예) 2x3 형상의 가중치 W, 손실 함수 L인 신경망의 기울기는 아래와 같다. • 가중치 𝑾의 형상과 기울기 𝝏𝑳 𝝏𝑾 의 형상이 같다. 𝑾 = 𝒘 𝟏𝟏 𝒘 𝟐𝟏 𝒘 𝟑𝟏 𝒘 𝟏𝟐 𝒘 𝟐𝟐 𝒘 𝟑𝟐 𝝏𝑳 𝝏𝑾 = 𝝏𝑳 𝝏𝒘 𝟏𝟏 𝝏𝑳 𝝏𝒘 𝟐𝟏 𝝏𝑳 𝝏𝒘 𝟑𝟏 𝝏𝑳 𝝏𝒘 𝟏𝟐 𝝏𝑳 𝝏𝒘 𝟐𝟐 𝝏𝑳 𝝏𝒘 𝟑𝟐  입력층 2개, 출력층 3개, 은닉층이 없는 신경망에서 기울기를 구현해보자 𝒙 𝟏 𝒙 𝟐 𝒚 𝟐 𝒚 𝟏 𝒚 𝟑w import numpy as np from Common.functions import softmax, cross_entropy_error from Common.gradient import numerical_gradient class SimpleNet: def __init__(self): self.W = np.random.randn(2,3) # 정규분포로 가중치 초기화 def predict(self, x): z = np.dot(x, self.W) y = softmax(z) return y def loss(self, x, t): y = self.predict(x) loss = cross_entropy_error(y, t) return loss simpleNet = SimpleNet() x = np.array([0.6, 0.9]) t = np.array([0, 0, 1]) def f(w): #w는 dummy return simpleNet.loss(x, t) ''' numerical_gradient(f,x)에서 f는 손실함수, x는 손실함수 f의 인수 즉, simpleNet.W[0,0], [0,1], [0,2], [1,0], [1,1], [1,2] 의 값으로 손실함수를 편미분한 결과 (Gradient) ''' gradient = numerical_gradient(f, simpleNet.W) print("gradient:n", gradient) • 실행 결과 확인 gradient: [[ 0.14511488 0.08426216 -0.22937704] [ 0.21767231 0.12639324 -0.34406556]] “기울기의 반대 방향으로 갈수록 최솟값이 가까워짐”  가중치 값을 기울기 반대로 조정하면 손실(오차)이 적어짐
72.  신경망의 지도학습에서 가중치를 갱신 값을 계산하는 방법(Gradient Descent Method)은 3가지가 있다.  Gradient Descent Method의 종류 종류 계산방법 (Batch) Gradient Descent • 모든 데이터를 학습하고 오차를 이용하여 가중치 갱신 값을 계산한 다음 갱신 • 단점 : 학습 데이터가 많으면 가중치 갱신 값 평균 계산 시 계산량 많음. SGD 대비 학습이 오래 걸림. • 단점 : 가중치 𝒙의 초기 설정에 따라 Global minimum 값이 아닌 local minimum 값을 수렴할 수 있다. Stochastic Gradient Descent (확률적 경사 하강법) • 하나의 학습 데이터마다 오차를 계산해서 신경망의 가중치를 바로 조절. 빠르다. • 단점 : 한 개의 학습 데이터마다 매번 가중치를 갱신함으로 신경망의 성능이 들쑥날쑥 변함. • 단점 : 최적의 학습률을 구하기 위해 일일이 튜닝하고 수렴조건을 조정해야 함 Mini-Batch Stochastic Gradient Descent • 훈련데이터에서 소량의 데이터를 적당히 선택해 학습 후 갱신 처리를 수행 • 장점 : 위 두 가지 경사 하강법의 단점을 보완하고 장점을 취함. • 장점 : GPU 기반의 효율적인 병렬 컴퓨팅이 가능해 진다. epoch • 전체 학습 데이터를 한 번씩 모두 학습 시킨 횟수 • 학습 시킨 데이터도 재 학습 시키면 신 경망이 개선 4. Gradient Descent Method IV. Training
 73.  import numpy as np import Common.functions as cf from Common.gradient import numerical_gradient class MyTwoLayerNet: def __init__(self, inputSize, hiddenSize, outputSize, weightInitStd = 0.01): self.params = {} self.params['W1'] = weightInitStd * np.random.randn(inputSize, hiddenSize) self.params['W2'] = weightInitStd * np.random.randn(hiddenSize, outputSize) self.params['b1'] = np.zeros(hiddenSize) self.params['b2'] = np.zeros(outputSize) def predict(self, x): W1 = self.params['W1'] W2 = self.params['W2'] b1 = self.params['b1'] b2 = self.params['b2'] z = cf.sigmoid(np.dot(x, W1) + b1) y = cf.softmax(np.dot(z, W2) + b2) return y def loss(self, x, t): y = self.predict(x) return cf.cross_entropy_error(y, t) def accuracy(self, x, t): y = self.predict(x) y = np.argmax(y, axis=1) t = np.argmax(t, axis=1) accuracy = np.sum(y == t) / float(x.shape[0]) return accuracy MNIST에 사용될 2층 신경망을 클래스로 구현해 본다.  2층 신경망 클래스를 생성 5. MNIST Example IV. Training 𝒙 𝟏 𝒙 𝟐 𝒛 𝟓𝟎 (𝟏) 𝒛 𝟏 (𝟏) 𝒚 𝟏 𝒚 𝟏𝟎 𝟏 𝟏 w b 𝒙 𝟕𝟖𝟒 … … … X W1 W2  Y 784 784 x 50 50 x 10 10 일치 일치 일치 ''' Gradient 구하기 (수치 미분을 이용) ''' def numericalGradient(self, x, t): lossW = lambda W : self.loss(x, t) grads = {} grads['W1'] = numerical_gradient(lossW, self.params['W1']) grads['W2'] = numerical_gradient(lossW, self.params['W2']) grads['b1'] = numerical_gradient(lossW, self.params['b1']) grads['b2'] = numerical_gradient(lossW, self.params['b2']) return grads
 74.  import numpy as np import matplotlib.pyplot as plt from Common.mnist import load_mnist from Training.mytwolayernet import MyTwoLayerNet (trainImg, trainLbl),(testImg, testLbl) = load_mnist(one_hot_label=True) network = MyTwoLayerNet(784, 50, 10) # hyper parameters itersNum = 1000 # 반복횟수 trainSize = trainImg.shape[0] # 60000 batchSize = 100 # mini-bach 크기 learningRate = 0.1 # 학습률 # 누적기록 trainLossList = [] print("-- Start Learning -- ") for i in range(itersNum): # mini-batch 획득 miniBatchMask = np.random.choice(trainSize, batchSize) trainImgBatch = trainImg[miniBatchMask] trainLblBatch = trainLbl[miniBatchMask] # Gradient 계산 grad = network.numericalGradient(trainImgBatch, trainLblBatch) # 가중치, 편향 갱신 for key in ('W1', 'W2', 'b1', 'b2'): network.params[key] -= learningRate*grad[key] # 비용함수(오차)의 변화 기록 loss = network.loss(trainImgBatch, trainLblBatch) trainLossList.append(loss) print("iteration", i, ":", loss) print("-- End Learning -- ") 2층 신경망을 클래스를 이용해서 MNIST 판별을 위한 mini-batch 학습을 진행한다.  Mini-batch 크기 : 100, 학습반복 : 1000회, 학습률 : 0.1로 학습을 진행해 본다. 5. MNIST Example IV. Training
 75.  6. Hands-on  mycostfunction.py • Mean Squared Error와 Cross Entropy Error 비용함수를 구현해 본다. import numpy as np def meanSquaredError(y, t): return 0.5*np.sum((y-t)**2) def crossEntropyError(y, t): delta = 1e-7 #아주 작은 값 (y가 0인 경우 -inf 값을 예방) return -np.sum(t*np.log(y+delta)) t = np.array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0]) # label = 5 y = np.array([0.1, 0.03, 0.05, 0.2, 0.9, 0.0, 0.1, 0.2, 0.12, 0.03]) # 5라고 추정 # 정답일 경우 MSE, CEE의 값은 적다. print("-- 정답인 경우 --") print("MSE :", meanSquaredError(y, t)) print("CEE :", crossEntropyError(y, t)) y = np.array([0.1, 0.03, 0.05, 0.2, 0.0, 0.1, 0.2, 0.12, 0.03, 0.9]) # 9라고 추정 # 오류일 경우 MSE, CEE의 값은 적다. print("-- 오류인 경우 --") print("MSE :", meanSquaredError(y, t)) print("CEE :", crossEntropyError(y, t)) #1 – Cost Function 이해하기 • 실행 결과 확인 -- 정답인 경우 -- MSE : 0.06435 CEE : 0.105360404547 -- 오류인 경우 -- MSE : 0.96435 CEE : 16.118095651 IV. Training
 76.  6. Hands-on  mymnist.py • Cross Entropy Error 비용함수를 구현하여 MNIST에 적용해 본다. … 코드 생략 … def crossEntropyError(y, t): # 1차원 배열인 경우 2차원 배열로 변경 if y.ndim == 1: t = t.reshape(1, t.size) y = y.reshape(1, y.size) miniBatchSize = y.shape[0] ''' y[np.arange(miniBatchSize), t] 은 정답 레이블에 해당되는 신경망의 출력을 추출 예) 만약 배치사이즈가 10개라면 아래와 같이 10개의 신경망 추출에 대한 출력값을 추출 y[0,2], y[1,7], y[2,0], y[3,9],...y[9.5] ''' return -np.sum(t*np.log(y[np.arange(miniBatchSize), t])) / miniBatchSize … 코드 생략 … miniBatchSize = 10 print(len(trainImg), "개 중에 ", miniBatchSize, "를 미니배치 학습한다.") miniBatchMask = np.random.choice(len(trainImg), miniBatchSize) trainImgBatch = trainImg[miniBatchMask] trainLblBatch = trainLbl[miniBatchMask] print("Random Choice 된 정답 레이블", trainLblBatch) y = predict(network, trainImgBatch) print("신경망 출력 결과 (10-배치크기, 10-분류크기) Shapen", y) p = np.argmax(y, axis=1) print("최대값으로 추정한 결과", p) print(crossEntropyError(y, trainLblBatch)) #2 – Cost Function을 MNIST에 적용하기 (미니배치를 이용해 MNIST 신경망 출력결과를 확인하고 비용함수 결과를 계산) IV. Training • 실행 결과 확인 60000 개 중에 10 를 미니배치 학습. Random Choice 된 정답 레이블 [4 5 1 8 1 2 2 7 7 4] 신경망 출력 결과 (10-배치크기, 10-분류크기) Shape [[ 1.41822547e-05 2.35181437e-06 1.51875982e-04 3.35034133e-06 … 결과 생략 … 최대값으로 추정한 결과 [4 5 1 8 1 2 2 7 7 4] 0.12456381321
 77.  6. Hands-on  mydifferentiation.py • 수치미분과 편미분을 구현해 본다. import numpy as np import matplotlib.pyplot as plt def numericalDiff(f, x): h = 1e-4 # 0.0001 return (f(x+h)-f(x-h))/(2*h) def sampleFunc1(x): return 0.01*x**2 + 0.1*x ''' f(x) = x[0]**2 + x[1]**2 x[0] = 3, x[1] = 4일 때 편미분 구하기 위한 함수 ''' def sampleFunc2(x): return x**2 + 4**2 def sampleFunc3(x): return 3**2 + x**2 x = np.arange(0, 20, 0.1) y = sampleFunc1(x) plt.xlabel("x") plt.ylabel("f(x)") plt.plot(x, y) plt.show() print(numericalDiff(sampleFunc1, 5)) print(numericalDiff(sampleFunc1, 10)) print(numericalDiff(sampleFunc2, 3.0)) print(numericalDiff(sampleFunc3, 4.0)) #3 – 미분이해하기 (수치미분, 편미분) • 실행 결과 확인 0.1999999999990898 0.2999999999986347 6.00000000000378 7.999999999999119 IV. Training
 78.  6. Hands-on  mydifferentiation.py • 𝒇 𝒙 𝟎, 𝒙 𝟏 = 𝒙 𝟎 𝟐 + 𝒙 𝟏 𝟐 함수의 기울기를 계산을 구현하고 테스트한다. … 코드 생략 … def numeiralGradient(f, x): h = 1e-4 # 0.0001 grad = np.zeros_like(x) #x와 형상이 같은 배열을 생성 for idx in range(x.size): tmpVal = x[idx] x[idx] = tmpVal + h print(idx, x) fxh1 = f(x) x[idx] = tmpVal - h print(idx, x) fxh2 = f(x) grad[idx] = (fxh1 - fxh2) / (2*h) x[idx] = tmpVal # 원래 값 복원 return grad ''' f(x0, x1) = x0**2 + x1**2인 함수 ''' def sampleFunc4(x): return x[0]**2 + x[1]**2 … 코드 생략 … print(numeiralGradient(sampleFunc4, np.array([3.0, 4.0]))) print(numeiralGradient(sampleFunc4, np.array([0.0, 2.0]))) print(numeiralGradient(sampleFunc4, np.array([3.0, 0.0]))) #4 – Gradient (기울기) 계산하기 • 실행 결과 확인 0 [ 3.0001 4. ] 0 [ 2.9999 4. ] 1 [ 3. 4.0001] 1 [ 3. 3.9999] [ 6. 8.] 0 [ 1.00000000e-04 2.00000000e+00] 0 [ -1.00000000e-04 2.00000000e+00] 1 [ 0. 2.0001] 1 [ 0. 1.9999] [ 0. 4.] 0 [ 3.0001 0. ] 0 [ 2.9999 0. ] 1 [ 3.00000000e+00 1.00000000e-04] 1 [ 3.00000000e+00 -1.00000000e-04] [ 6. 0.] IV. Training
 79.  6. Hands-on  mylearningrate.py • 𝒇 𝒙 𝟎, 𝒙 𝟏 = 𝒙 𝟎 𝟐 + 𝒙 𝟏 𝟐 함수의 기울기를 계산 후 기울기 값과 학습률을 이용해서 x 값을 조정한다. #5 – Gradient (기울기)와 학습률을 이용하여 반복 학습하면서 최솟값 찾아가기 IV. Training import numpy as np import matplotlib.pyplot as plt from Common.gradient_2d import numerical_gradient ''' f = x[0]**2 + x[1]**2 initX = 초기값 (-3,4) 초기값에서 함수에 대한 기울기 (편미분에 의한 계산)를 구한 후 기울기 값과 학습률을 이용해서 x값을 이동 위를 stepNum(100번) 반복 ''‘ def gradientDescent(f, initX, learningRate, stepNum=100): x = initX xHistory = [] for i in range(stepNum): xHistory.append(x.copy()) grad = numerical_gradient(f,x) x -= learningRate*grad if(i == stepNum-1): print(x) return x, np.array(xHistory) def sampleFunction(x): return x[0]**2 + x[1]**2 # 적정학습률 initX = np.array([-3.0,4.0]) learningRate = 0.1 x, xHistory = gradientDescent(sampleFunction, initX, learningRate) # 학습률이 큰 경우 initX = np.array([-3.0,4.0]) learningRate = 2 x, xHistory = gradientDescent(sampleFunction, initX, learningRate) # 학습률이 작은 경우 initX = np.array([-3.0,4.0]) learningRate = 0.001 x, xHistory = gradientDescent(sampleFunction, initX, learningRate) # 그래프로 표현 plt.plot([-5,5],[0,0],'--b') plt.plot([0,0],[-5,5],'--b') plt.plot(xHistory[:,0],xHistory[:,1],'o') plt.xlim(-3.5, 3.5) plt.ylim(-4.5, 4.5) plt.xlabel("X0") plt.ylabel("X1") plt.show() • 실행 결과 확인 (100회 반복 후 x 값의 조정된 모습) [ -6.11110793e-10 8.14814391e-10] [ -1.35262250e+12 2.26052540e+12] [-2.45570041 3.27426722]
 80.  6. Hands-on  mysimplenet.py • 입력층 𝟐개, 출력층 𝟑개, 은닉층이 없는 신경망에서 임의의 가중치로 오차와 기울기를 구현한다. import numpy as np from Common.functions import softmax, cross_entropy_error from Common.gradient import numerical_gradient class SimpleNet: def __init__(self): self.W = np.random.randn(2,3) # 정규분포로 가중치 초기화 def predict(self, x): z = np.dot(x, self.W) y = softmax(z) return y def loss(self, x, t): y = self.predict(x) loss = cross_entropy_error(y, t) return loss simpleNet = SimpleNet() x = np.array([0.6, 0.9]) t = np.array([0, 0, 1]) print("input values:", x) print("initialized weight:n", simpleNet.W) print("labeled values:", t) print("neuralnet output:", simpleNet.predict(x)) print("cost(loss) :", simpleNet.loss(x, t)) #6 – 신경망에서 Gradient (기울기) 계산하기 • 실행 결과 확인 input values: [ 0.6 0.9] initialized weight: [[-0.06407468 -0.71326724 -1.33225821] [ 1.57714681 -0.91908203 -0.69465475]] labeled values: [0 0 1] neuralnet output: [ 0.88330389 0.06327864 0.05341747] cost(loss) : 2.92961749969 gradient: [[ 0.52998234 0.03796718 -0.56794952] [ 0.79497351 0.05695077 -0.85192428]] IV. Training def f(w): #w는 dummy return simpleNet.loss(x, t) ''' numerical_gradient(f,x)에서 f는 손실함수, x는 손실함수 f의 인수 즉, simpleNet.W[0,0], [0,1], [0,2], [1,0], [1,1], [1,2] 의 값으로 손실함수를 편미분한 결과 (Gradient) ''' gradient = numerical_gradient(f, simpleNet.W) print("gradient:n", gradient)
 81.  6. Hands-on  mytwolayernet.py #7 – MNIST를 위한 2층 신경망 만들기 IV. Training import numpy as np import Common.functions as cf from Common.gradient import numerical_gradient class MyTwoLayerNet: def __init__(self, inputSize, hiddenSize, outputSize, weightInitStd = 0.01): self.params = {} self.params['W1'] = weightInitStd * np.random.randn(inputSize, hiddenSize) self.params['W2'] = weightInitStd * np.random.randn(hiddenSize, outputSize) self.params['b1'] = np.zeros(hiddenSize) self.params['b2'] = np.zeros(outputSize) def predict(self, x): W1 = self.params['W1'] W2 = self.params['W2'] b1 = self.params['b1'] b2 = self.params['b2'] z = cf.sigmoid(np.dot(x, W1) + b1) y = cf.softmax(np.dot(z, W2) + b2) return y def loss(self, x, t): y = self.predict(x) return cf.cross_entropy_error(y, t) def accuracy(self, x, t): y = self.predict(x) y = np.argmax(y, axis=1) t = np.argmax(t, axis=1) accuracy = np.sum(y == t) / float(x.shape[0]) return accuracy ''' Gradient 구하기 (수치 미분을 이용) ''' def numericalGradient(self, x, t): lossW = lambda W : self.loss(x, t) grads = {} grads['W1'] = numerical_gradient(lossW, self.params['W1']) grads['W2'] = numerical_gradient(lossW, self.params['W2']) grads['b1'] = numerical_gradient(lossW, self.params['b1']) grads['b2'] = numerical_gradient(lossW, self.params['b2']) return grads
 82.  6. Hands-on  mymnistlearning.py #8 – MNIST 신경망 학습하기 IV. Training import numpy as np import matplotlib.pyplot as plt from Common.mnist import load_mnist from Training.mytwolayernet import MyTwoLayerNet (trainImg, trainLbl),(testImg, testLbl) = load_mnist(one_hot_label=True) network = MyTwoLayerNet(784, 50, 10) # hyper parameters itersNum = 1000 # 반복횟수 trainSize = trainImg.shape[0] # 60000 batchSize = 100 # mini-bach 크기 learningRate = 0.1 # 학습률 # 누적기록 trainLossList = [] print("-- Start Learning -- ") for i in range(itersNum): # mini-batch 획득 miniBatchMask = np.random.choice(trainSize, batchSize) trainImgBatch = trainImg[miniBatchMask] trainLblBatch = trainLbl[miniBatchMask] # Gradient 계산 grad = network.numericalGradient(trainImgBatch, trainLblBatch) # 가중치, 편향 갱신 for key in ('W1', 'W2', 'b1', 'b2'): network.params[key] -= learningRate*grad[key] # 비용함수(오차)의 변화 기록 loss = network.loss(trainImgBatch, trainLblBatch) trainLossList.append(loss) print("iteration", i, ":", loss) print("-- End Learning -- ") “신경망 학습을 위해 기울기를 수치미분을 통해서 구하면 계산 시간이 오래 걸린다. “ # 그래프 그리기 x = np.arange(len(trainLossList)) plt.plot(x, trainLossList, label="loss") plt.xlabel("iteration") plt.ylabel("loss") plt.show() • 실행 결과 확인 -- Start Learning -- iteration 0 : 2.29192863536 iteration 1 : 2.29489284268 iteration 2 : 2.28903658939 … 결과 생략 … iteration 997 : 0.489302945227 iteration 998 : 0.454912045635 iteration 999 : 0.494802915552 -- End Learning --
83.  1. Back Propagation Algorithm 2. Computational Graph 3. 계층별 구현 4. MNIST Examples 5. 역전파의 문제 6. Hands-on V. Back Propagation
 84.  예측된 결과와 실제값의 차이인 에러의 역전파를 통해 가중치를 구한다. (Backward propagation of errors)  역 전파 알고리즘 (Back propagation algorithm) • Deep Learning의 대표적인 지도학습 알고리즘. • 역 전파 : 역방향으로 오차를 전파 • Back propagation 알고리즘은 Gradient descent rule과 결합되어 인공신경망 학습 알고리즘으로 많이 이용된다. • 학습된 출력 값과 실제 값과의 차이인 오차를 계산하여 Feedforward 반대인 역방향으로 전파(Propagation) 한다. • 전파된 오차를 이용하여 가중치를 조정한다. • 출력층의 오차 : 지도학습 데이터의 정답과 출력층의 출력값의 차이 • 은닉층의 오차 : 출력층의 오차가 가중치를 고려하여 역방향으로 전달 • 델타(𝜹)규칙 : 어떤 입력 노드가 출력 노드 의 오차에 기여했다면, 두 노드의 연결 가중 치는 오차에 비례해 조절한다. • 델타(𝜹) : 델타는 활성함수의 도함수 (derivatives)를 이용해 계산됨. 즉, 델타를 이용해 가중치를 조절(compute gradient)하고 앞 은닉 노드들의 델타를 계 산함. • 비용함수(cost function) : 오차를 계산하는 함수로 Cross Entropy 함수가 많이 사용  대부분의 딥러닝 오픈 프레임워크에는 역 전파 알고리즘이 구현되어 있음. 1. Back Propagation Algorithm V. Back Propagation
 85.  Computational Graph (계산 그래프)란 계산 과정을 그래프로 나타낸 것이다.  Computational Graph 사과 2개, 귤 3개를 사는데 사과는 1개 100원, 귤은 150원이고 소비세는 10%일 때 지불 금액은 얼마인가? 2. Computational Graph V. Back Propagation x + x x 2 100 3 150 200 450 650 1.1 715 • Computational Graph에서 계산을 왼쪽에서 오른쪽으로 진행하는 것을 순전파 (forward propagation)이라고 한다. • 계산 그래프에서 종착점에서 출발점으로 계산하는 것을 역전파(backward propagation)이라고 한다.  Computational Graph 의 장점 • 국소적 계산 : 전체에서 어떻게 진행되는 상관없이 자신과 관계된 정보만으로 계산 (예, 가운데 + Node의 경우 여러 식품을 구매하더라도 해당 노드는 더하는 계산만 하면 됨. • 중간 계산 결과를 모두 보관할 수 있다. • 역전파를 통해 ‘미분’을 효율적으로 계산할 수 있다.  사과 가격, 귤 가격, 사과 개수, 귤 개수, 소비세에 대한 지불 금액의 미분을 계산할 수 있다.
86.  Computational Graph의 역전파 계산시는 미분을 계산하여 앞쪽 노드로 전파한다.  Backward Propagation의 계산 절차 예) 𝑦 = 𝑓(𝑥) 의 역전파 2. Computational Graph V. Back Propagation f x E 𝝏𝒚 𝝏𝒙 E • 역전파의 계산 절차는 신호 E에 노드의 편미분 𝝏𝒚 𝝏𝒙 을 곱한 후 다음 노드로 전달하는 것 • 𝑦 = 𝑥2 인 경우, 𝝏𝒚 𝝏𝒙 = 2𝑥 가 된다. y
 87.  Chain Rule(연쇄법칙)이란 합성 함수의 미분의 성질이며, 합성 함수의 미분은 합성함수를 구성하는 각 함수의 미분의 곱이다.  합성 함수의 예 ( 𝒛 = (𝒙 + 𝒚) 𝟐 ) 순전파 계산 • 𝑧 = 𝑡2 • 𝑡 = 𝑥 + 𝑦 V. Back Propagation + **2 x y t z • 𝝏𝒛 𝝏𝒛 𝝏𝒛 𝝏𝒕 𝝏𝒕 𝝏𝒙 = 𝝏𝒛 𝝏𝒕 𝝏𝒕 𝝏𝒙 = 𝝏𝒛 𝝏𝒙 즉, x에 대한 z의 미분, 즉 역전파는 연쇄법칙의 원리와 같다. 𝝏𝒛 𝝏𝒛 = 𝟏 𝝏𝒛 𝝏𝒛 𝝏𝒛 𝝏𝒕 역전파 계산 • 𝝏𝒛 𝝏𝒙 = 𝝏𝒛 𝝏𝒛 𝝏𝒛 𝝏𝒕 • 𝝏𝒛 𝝏𝒕 = 𝟐𝒕 이고 𝝏𝒛 𝝏𝒛 = 𝟏 임으로 𝝏𝒛 𝝏𝒙 = 𝟐𝒕 ∗ 𝟏 = 𝟐 𝒙 + 𝒚 가 된다. 2. Computational Graph
 88.  덧셈노드와 곱셈노드의 역전파를 예를 통해서 확인해 본다.  덧셈 노드 ( 𝒛 = 𝒙 + 𝒚 ) V. Back Propagation • 𝝏𝒛 𝝏𝒙 = 𝟏 이고 𝝏𝒛 𝝏𝒚 = 𝟏 이다 + x y z 𝝏𝑳 𝝏𝒛 𝜕𝐿 𝜕𝑧 은 상류에서 전해진 미분 값 + 10 5 15 𝟏. 𝟑 역전파 계산 • 만약 상류에서 1.3이 흘러오면 다음 노드 로 1.3을 전달한다.  곱셈 노드 ( 𝒛 = 𝒙𝒚 ) • 𝝏𝒛 𝝏𝒙 = 𝒚 이고 𝝏𝒛 𝝏𝒚 = 𝒙 이다 + x y z 𝝏𝑳 𝝏𝒛 𝜕𝐿 𝜕𝑧 은 상류에서 전해진 미분 값 + 10 5 50 𝟏. 𝟑 역전파 계산 • 만약 상류에서 1.3이 흘러오면 한 군데는 6.5 (1.3x5) 다른 하나는 13 (1.3x10)을 보 낸다. • 곱셈 역 전파 계산 시 순방향 입력 신호 값이 필요함. 2. Computational Graph
 89.  사과 귤 쇼핑의 역전파를 계산해 보자  순전파 V. Back Propagation 사과 2개, 귤 3개를 사는데 사과는 1개 100원, 귤은 150원이고 소비세는 10%일 때 지불 금액은 얼마인가? x + x x 2 100 3 150 200 450 650 1.1 715  역전파 x + x x 110 2.2 165 3.3 1.1 1.1 1.1 650 1 2. Computational Graph
 90.  사과 귤 쇼핑의 계산 그래프와 순전파/역전파를 파이썬으로 구현해보자  덧셈 노드와 곱셈 노드의 구현 V. Back Propagation class AddLayer: def forward(self, x, y): return x+y def backward(self, difOut): dx = difOut dy = difOut return dx, dy class MulLayer: # 순전파시 입력값 유지 def forward(self, x, y): self.x = x self.y = y return x*y def backward(self, difOut): dx = difOut*self.y dy = difOut*self.x return dx, dy  순전파/역전파 활용 applePrice = 100 orangePrice = 150 appleCnt = 2 orangeCnt = 3 tax = 1.1 calAppleLayer = MulLayer() calOrangeLayer = MulLayer() calSumLayer = AddLayer() calTaxLayer = MulLayer() # forward Propagation calApple = calAppleLayer.forward(applePrice, appleCnt) calOrange = calOrangeLayer.forward(orangePrice, orangeCnt) calSum = calSumLayer.forward(calApple, calOrange) calTax = calTaxLayer.forward(calSum, tax) print(calApple, calOrange, calSum, calTax) # backward Propagation difOut = 1 difCalSum, difCalTax = calTaxLayer.backward(difOut) difCalApple, difCalOrange = calSumLayer.backward(difCalSum) difApplePrice, difAppleCnt = calAppleLayer.backward(difCalApple) difOrangePrice, difOrangeCnt = calOrangeLayer.backward(difCalOrange) print(difOut, difCalSum, difCalTax, difCalApple, difCalOrange) print(difApplePrice, difAppleCnt, difOrangePrice, difOrangeCnt) • 실행 결과 확인 200 450 650 715.0000000000001 1 1.1 650 1.1 1.1 2.2 110.00000000000001 3.3000000000000003 165.0 2. Computational Graph
 91.  • forward propagation • backward propagation ReLU 계층을 Computational Graph를 이용해 구현해 보자. (backward 계산과정은 생략)  ReLU (활성화 함수) V. Back Propagation3. 계층별 구현 𝒚 = 𝒙 (𝒙 > 𝟎) 𝟎 (𝒙 ≤ 𝟎) 𝝏𝒚 𝝏𝒙 = 𝟏 (𝒙 > 𝟎) 𝟎 (𝒙 ≤ 𝟎) ReLU 𝒙 𝒚 𝝏𝑳 𝝏𝒙 𝝏𝑳 𝝏𝒙 ReLU 𝒙 𝒚 𝝏𝑳 𝝏𝒙 𝟎 [ 𝒙 > 𝟎 인 경우] [ 𝒙 ≤ 𝟎인 경우]  ReLU 구현 코드 class Relu: def __init__(self): self.mask = None def forward(self, x): self.mask = (x <= 0) out = x.copy() out[self.mask] = 0 return out def backward(self, dout): dout[self.mask] = 0 dx = dout return dx • Test ReLU : input [[ 1.1 -0.2] [-1.5 2.7]] ReLU : forward [[ 1.1 0. ] [ 0. 2.7]] ReLU : dif. out [[ 1. 1.] [ 1. 1.]] ReLU : backward [[ 1. 0.] [ 0. 1.]]
 92.  • forward propagation • backward propagation Sigmoid 계층을 Computational Graph를 이용해 구현해 보자. (backward 계산과정은 생략)  ReLU (활성화 함수) V. Back Propagation3. 계층별 구현 𝒚 = 𝟏 𝟏 + 𝒆−𝒙 𝝏𝒚 𝝏𝒙 = 𝒚(𝟏 − 𝒚) Sigmoid 𝒙 𝒚 𝝏𝑳 𝝏𝒙 𝝏𝑳 𝝏𝒙 𝒚(𝟏 − 𝒚)  Sigmoid 구현 코드 class Sigmoid: def __init__(self): self.out = None def forward(self, x): out = sigmoid(x) self.out = out return out def backward(self, dout): dx = dout * (1.0 - self.out) * self.out return dx • Test Sigmoid : input [[ 1.1 -0.2] [-1.5 2.7]] Sigmoid : forward [[ 0.75026011 0.450166 ] [ 0.18242552 0.93702664]] Sigmoid : dif. out [[ 1. 1.] [ 1. 1.]] Sigmoid : backward [[ 0.18736988 0.24751657] [ 0.14914645 0.05900771]]
 93.  • forward propagation Affine 계층을 Computational Graph를 이용해 구현해 보자. (backward 계산과정은 생략)  신경망 순전파시 수행하는 행렬의 내적을 Affine 변환이라고 한다. V. Back Propagation3. 계층별 구현 dot 𝑿 𝒀  Affine 구현 코드 class Affine: def __init__(self, W, b): self.W = W self.b = b self.x = None self.original_x_shape = None # 가중치와 편향 매개변수의 미분 self.dW = None self.db = None def forward(self, x): # 텐서 대응 self.original_x_shape = x.shape x = x.reshape(x.shape[0], -1) self.x = x out = np.dot(self.x, self.W) + self.b return out def backward(self, dout): dx = np.dot(dout, self.W.T) self.dW = np.dot(self.x.T, dout) self.db = np.sum(dout, axis=0) dx = dx.reshape(*self.original_x_shape) return dx 𝝏𝑳 𝝏𝒀 + • backward propagation 𝑾 𝑿 ∙ 𝑾 𝑩 dot + 𝝏𝑳 𝝏𝒀 𝝏𝑳 𝝏𝑩 = 𝝏𝑳 𝝏𝒀 의 첫 번째 축(axis=0)의 합 𝝏𝑳 𝝏𝑾 = 𝑿 𝑻 ∙ 𝝏𝑳 𝝏𝒀 𝝏𝑳 𝝏𝑿 = 𝝏𝑳 𝝏𝒀 ∙ 𝑾 𝑻 𝑾 𝑻 는 𝑾의 전치 행렬이다. 𝑾 = 1 2 3 4 5 6 이면 𝑾 𝑻 = 1 4 2 5 3 6 이다
94.  • 간소화된 Softmax-with-Loss 의 계산 그래프 Softmax-with-Loss 계층을 Computational Graph를 이용해 구현해 보자. (backward 계산과정은 생략)  Softmax 함수와 Cross Entropy 함수를 같이 구현 V. Back Propagation3. 계층별 구현 𝒂 𝟏  Softmax-with-Loss 구현 코드 class SoftmaxWithLoss: def __init__(self): self.loss = None # 손실함수 self.y = None # softmax의 출력 self.t = None # 정답 레이블(원-핫 인코딩 형태) def forward(self, x, t): self.t = t self.y = softmax(x) self.loss = cross_entropy_error(self.y, self.t) return self.loss def backward(self, dout=1): batch_size = self.t.shape[0] if self.t.size == self.y.size: dx = (self.y - self.t) / batch_size else: dx = self.y.copy() dx[np.arange(batch_size), self.t] -= 1 dx = dx / batch_size return dx 𝒚 𝟏 − 𝒕 𝟏 3개 분류로 가정 𝒂 𝟏, 𝒂 𝟐, 𝒂 𝟑 는 Softmax 계층의 입력 𝒚 𝟏, 𝒚 𝟐, 𝒚 𝟑 는 Softmax 계층의 출력 (정규화, 합계가 1) 𝒕 𝟏, 𝒕 𝟐, 𝒕 𝟑 는 정답 레이블 𝑳 은 비용함수 값 (손실) 𝒚 𝟏 − 𝒕 𝟏, 𝒚 𝟐 − 𝒕 𝟐, 𝒚 𝟑 − 𝒕 𝟑는 역전파 값 (즉, 오차가 역전파 된다.) Softmax Cross Entropy Error 𝒂 𝟐 𝒚 𝟐 − 𝒕 𝟐 𝒂 𝟑 𝒚 𝟑 − 𝒕 𝟑 𝒂 𝟏 𝒂 𝟐 𝒂 𝟑 𝑳 𝟏 𝒕 𝟏 𝒕 𝟐 𝒕 𝟑 출력층 고려사항 • Softmax 계층은 학습 시에는 활용하지만 추론 시에는 활용하지 않는다. • 회귀 목적의 신경망에서는 항등함수의 손실함수로 평균제곱오차를 활용한다.
95.  class MyTwoLayerNet: def __init__(self, inputSize, hiddenSize, outputSize, weightInitStd = 0.01): self.params = {} self.params['W1'] = weightInitStd * np.random.randn(inputSize, hiddenSize) self.params['W2'] = weightInitStd * np.random.randn(hiddenSize, outputSize) self.params['b1'] = np.zeros(hiddenSize) self.params['b2'] = np.zeros(outputSize) # 계층생성 self.layers = OrderedDict() self.layers['Affine1'] = cl.Affine(self.params['W1'], self.params['b1']) self.layers['Relu1'] = cl.Relu() self.layers['Affine2'] = cl.Affine(self.params['W2'], self.params['b2']) self.lastLayer = cl.SoftmaxWithLoss() def predict(self, x): for layer in self.layers.values(): x = layer.forward(x) return x def loss(self, x, t): y = self.predict(x) return self.lastLayer.forward(y, t) def accuracy(self, x, t): y = self.predict(x) y = np.argmax(y, axis=1) t = np.argmax(t, axis=1) accuracy = np.sum(y == t) / float(x.shape[0]) return accuracy MNIST에 사용될 2층 신경망을 클래스를 변경해 본다.  2층 신경망 클래스를 생성 4. MNIST Example 𝒙 𝟏 𝒙 𝟐 𝒛 𝟓𝟎 (𝟏) 𝒛 𝟏 (𝟏) 𝒚 𝟏 𝒚 𝟏𝟎 𝟏 𝟏 w b 𝒙 𝟕𝟖𝟒 … … … ''' Gradient 구하기 (역전파를이용) ''' def gradient(self, x, t): # 순전파 self.loss(x,t) # 이후 역전파 dout = 1 dout = self.lastLayer.backward(dout) layers = list(self.layers.values()) layers.reverse() for layer in layers: dout = layer.backward(dout) grads = {} grads['W1'] = self.layers['Affine1'].dW grads['b1'] = self.layers['Affine1'].db grads['W2'] = self.layers['Affine2'].dW grads['b2'] = self.layers['Affine2'].db return grads V. Back Propagation
 96.  (trainImg, trainLbl),(testImg, testLbl) = load_mnist(one_hot_label=True) network = MyTwoLayerNet(784, 50, 10) # hyper parameters itersNum = 1000 # 반복횟수 trainSize = trainImg.shape[0] # 60000 batchSize = 100 # mini-bach 크기 learningRate = 0.1 # 학습률 # 누적기록 trainLossList = [] print("-- Start Learning -- ") for i in range(itersNum): # mini-batch 획득 miniBatchMask = np.random.choice(trainSize, batchSize) trainImgBatch = trainImg[miniBatchMask] trainLblBatch = trainLbl[miniBatchMask] # Gradient 계산 grad = network.gradient(trainImgBatch, trainLblBatch) # 가중치, 편향 갱신 for key in ('W1', 'W2', 'b1', 'b2'): network.params[key] -= learningRate*grad[key] # 비용함수(오차)의 변화 기록 loss = network.loss(trainImgBatch, trainLblBatch) trainLossList.append(loss) print("iteration", i, ":", loss) print("-- End Learning -- ") 2층 신경망을 클래스를 이용해서 MNIST 판별을 위한 mini-batch 학습을 진행한다.  Mini-batch 크기 : 100, 학습반복 : 1000회, 학습률 : 0.1로 학습을 진행해 본다. 4. MNIST Example V. Back Propagation
 

반응형

loading