일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- 단순회귀 분석
- 데이터분석
- 팀스파르타
- 데이터분석가
- 히스토그램 그리기
- %in%
- 여러 데이터 검색
- loop 문
- difftime
- Sum
- 상관관계
- 불순도제거
- 총과 카드만들기
- 순위출력
- max
- 막대그래프
- merge
- 그래프시각화
- 빅데이터
- 그래프 생성 문법
- Intersect
- 정보획득량
- sql
- sqld
- Dense_Rank
- 회귀분석
- 빅데이터분석
- 회귀분석 알고리즘
- if문 작성법
- count
- Today
- Total
ch0nny_log
[빅데이터분석] 딥러닝_9. 2층 신경망 구현하기2 (오차 역전파로 2층 신경망 학습시키기) 본문
[빅데이터분석] 딥러닝_9. 2층 신경망 구현하기2 (오차 역전파로 2층 신경망 학습시키기)
chonny 2024. 10. 11. 16:109. 렐루 함수의 계산 그래프
신경망에서 활성화 함수가 왜 필요한지?
이미지, 음성, 텍스트 입력 데이터의 중요한 부분을 파악하기 위해서 입니다.
1. 고양이 이미지 | 배경은 중요하지 않고 고양이의 귀나 입이 중요하다라는 것을 활성화 함수가 신호를 보내줌으로서 파악 |
2. 강아지 음성 | 강아지 음성의 배경에 들리는 차소리는 중요하지 않고 강아지 소리자체가 강아지 소리를 인식하는데 있어서 중요하다는 것을 인식 |
3. 텍스트 데이터 | 내가 던진 질문 데이터에서 핵심적인 단어가 무엇인지를 파악 |
렐루 함수 ?
입력신호가 0보다 큰 값이 입력이 되면 그 값을 그대로 출력하고
0보다 작은 값이 입력이 되면 0을 출력하는 함수
렐루 함수는 순전파일 때 x 가 0보다 큰값이 입력되었으면 역전파일 때 상류에서 흘러왔던 기울기가 그대로 흘러가고 순전파일 때 x 가 0 보다 작거나 같은 값이 입력되었으면 역전파일 때는 0 이 기울기로 흘러갑니다. 그래서 렐루 계층을 구현할 때는 순전파일때 어떤 값이 흘러갔는지를 기억하는 코드가 있어야합니다. 그래야 역전파때 흘러갈 데이터를 결정할 수 있습니다.
실습1. 렐루 계층 파이썬으로 구현하기
1. 렐루 계층을 만들기 위해 알아야할 파이썬 문법 첫번째 copy 모듈 배우기
a = [ 1, 2, 3 ] b = a # a 가 가리키고 있는 곳을 b 도 가리키겠다. print(b) a[1] = 6 # a 리스트의 1번째 요소를 6으로 변경합니다 print(a) # [1, 6, 3] print(b) # [ 1, 2, 3] 이 나올까요 ? 아니면 [ 1, 6, 3 ] 이 나올까요 ?
지금 b는 a와 같은 곳을 바라보고 있는 것이므로 똑같이 [ 1, 6, 3 ] 이 출력됩니다. 그런데 만약 b 를 위한 [ 1, 2, 3 ] 을 만들고 싶다면 copy 를 이용해야합니다.
from copy import copy a = [ 1, 2, 3 ] b = a.copy() # copy 를 했기 때문에 b 는 별도의 객체가 됩니다. a[1] = 6 print(a) print(b)
위의 파이썬 문법을 알아야하는 이유는 신경망에서 역전파 할 때 순전파 일때 흘러갔던 그 입력값을 기억하기 위해서 입니다. 순전파때 신호를 보냈으면 역전파할때도 기울기를 보내고 순전파때 신호를 안보냈으면 역전파할때도 신호를 안보낼려고 copy 가 필요합니다.
2. x [ x <= 0 ]의 의미?
렐루는 순전파일때 신호를 보냈다는 유무를 기억하고 있어야기 떄문에 이 문법이 필요합니다ㅣ
import numpy as np x = np.array([ [ 1, -0.5 ] , [ -2, 3 ] ] ) print(x) mask = (x<=0) mask out = x.copy() out[mask] = 0 # True 인 자리에 0 을 할당합니다. print(out)
순전파일 때 0 또는 마이너스값이 있었던 자리는 역전파일 때 0 으로 기울기가 흘러가야 하므로 위와 같이 코드를 작성해야합니다.
3. 책 166페이지에 나오는 Relu 클래스를 생성하시오 !
class Relu: def __init__(self): self.mask = None def forward(self, x ): self.mask = ( x <= 0 ) # 입력 행렬 x 에서 0보다 작거나 같은 자리에 True 할당 out = x.copy() # 입력 행렬 x를 copy 해서 out 변수에 할당 out[self.mask] = 0 # out 행렬의 True 자리에 0 을 할당 return out def backward(self, dout): dout[ self.mask ] = 0 # 순전파일때 신호가 안보낸자리가 self.mask 에 True 로 dx = dout # 기억되고 있어서 그 자리에 0 을 할당합니다. return dx
4. 위의 relu 클래스를 객체화 시켜서 아래의 x 데이터를 흘려보내고 순전파 결과를 출력하시오 !import numpy as np x = np.array([ [ 1.0, -0.5 ], [ -2.0, 3.0 ] ] ) 답: relu = Relu() x = np.array([ [ 1.0, -0.5 ], [ -2.0, 3.0 ] ] ) relu.forward(x) array([[1., 0.], [0., 3.]])
5. 텐써 플로우에서 렐루함수가 어떻게 사용되는지 확인하시오 !model.add( Dense( 100, activation='relu') )
문제1. 위의 렐루 계층의 역전파 함수도 실행해보시오 ! dout 행렬은 다음과 같이 생성하시오
dout = np.array([ [ 7.0, 8.5 ], [ 3.0, 9.0 ] ] ) 답: relu = Relu() x = np.array([ [ 1.0, -0.5 ], [ -2.0, 3.0 ] ] ) dout = np.array([ [ 7.0, 8.5 ], [ 3.0, 9.0 ] ] ) # 오차 행렬 relu.forward(x) relu.backward(dout) array([[7., 0.], [0., 9.]])
10. 시그모이드 계층 구하기
시그모이드 함수 ?
입력값을 받아서 0 ~ 1 사이의 실수를 출력하는 함수
시그모이드 함수 역전파 첫번째 그림
시그모이드 함수 역전파 두번째 그림
실습1. 시그모이드 계층을 파이썬으로 구현하시오
class Sigmoid: def __init__(self): self.out = None def forward( self, x ) : out = 1 / ( 1 + np.exp(-x) ) self.out = out # 역전파 할 때 사용하려고 담아둡니다. return out def backward( self, dout ): dx = dout * self.out * ( 1 - self.out )
실습2. 위의 시그모이드 클래스를 객체화 시켜서 아래의 입력값을 흘려보내고 순전파와 역전파를 각각 구현하시오
import numpy as np class Sigmoid: def __init__(self): self.out = None # forward에서 나온 결과를 저장 def forward(self, x): self.out = 1 / (1 + np.exp(-x)) # Sigmoid 함수 계산 return self.out def backward(self, dout): dx = dout * self.out * (1 - self.out) # Sigmoid의 미분 계산 return dx # 예제 실행 x = np.array([24, 32, 1]) dout = np.array([24, 32, 1]) sigmoid = Sigmoid() # 순전파 out = sigmoid.forward(x) print("Forward:", out) # 역전파 dx = sigmoid.backward(dout) print("Backward:", dx)
▣ 5.11 Affine 계층 구현하기 p173
Affine (어파인) ? 신경망의 순전파 때 수행하는 행렬의 내적을 기하학에서는
어파인(Affine) 변환이라고 합니다.
그래서 신경망에서 입력값과 가중치의 내적의 합에 바이어스를 더하는 층을
Affine 계층이라고 부르면서 구현합니다.
그림 3-15
그림 5-24 어파인 계층의 계산 그래프
가중치가 처음에는 수지얼굴 같지 않다고 점점 학습되면서 수지 얼굴을 닮아갑니다. 어파인 계층이 하는일이 바로 수지 사진에서 수지 얼굴을 특징을 잡아내는 역할을 합니다.
■ 그림 5-24 어파인 계층의 계산 그래프의 순전파
■ 그림 5-25 어파인 계층의 계산 그래프의 역전파
실습1. 책 175 페이지에 나오는 Affine 계층 클래스를 생성하시오 ! 순전파 부분
class Affine: def __init__( self, W, b ): self.W = W # 가중치 행렬 self.b = b # 바이어스 행렬 self.x = None # 입력값 저장할 변수 self.dW = None # 역전파할 때 계산된 가중치의 기울기를 담을 변수 self.db = None # 역전파팔 때 계산된 바이어스의 기울기를 담을 변수 def foward( self, x ): # 순전파 함수 self.x = x # 입력값을 self.x 에 할당합니다. out = np.dot( x , self.W ) + self.b # 입력값과 가중치를 내적하고 바이어스를 더함 return out
실습2. 위의 설계도로 어파인 객체를 만들고 아래의 데이터를 순전파 시키시오 !
x = np.array( [ [ 3, 1 ] ] ) # 수지사진 W = np.array( [ [ 1, 3, 5 ], [ 2, 4, 6 ] ] ) # 가중치 행렬 b = np.array([ [ 1, 1, 1 ] ] ) affine1 = Affine(W,b) result = affine1.forward(x) print(result)
실습3. Affine 계층의 역전파 함수도 같이 구현하시오 !class Affine: def __init__( self, W, b ): self.W = W # 가중치 행렬 self.b = b # 바이어스 행렬 self.x = None # 입력값 저장할 변수 self.dW = None # 역전파할 때 계산된 가중치의 기울기를 담을 변수 self.db = None # 역전파팔 때 계산된 바이어스의 기울기를 담을 변수 def forward( self, x ): # 순전파 함수 self.x = x # 입력값을 self.x 에 할당합니다. out = np.dot( 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 ) # 바이어스 행렬의 기울기 return dx
왜 바이어스 행렬의 역전파 코드는 np.sum을 사용했는가?
순전파일때 바이어스 행렬은 ( 1, 1, 1 ) 로 1x3 행렬이었습니다. 그래서 역전파일 때도 1x3 행렬로 역전파 되어야합니다.
np.sum( dout, axis=0 ) 로 구현해서 열끼리 다 더해서 1x3 행렬로 만들어준것입니다.
실습1. backward 까지 구현한 Affine 클래스를 객체화 시켜서 아래의 데이터로 순전파와 역전파를 수행하시오 !
x = np.array([ [ 2, 3 ] ]) # 수지 사진 1장 W = np.array([ [ 1, 3, 5 ], [ 2, 4, 6 ] ] ) # 수지사진의 특징을 살린 케리커쳐 b = np.array([ [ 1, 1, 1 ] ] ) # 1을 더해서 사진을 더 진하게 해줌 dout = np.array( [ [ 2, 2, 1 ] ] ) # 수지 사진 한장에 대한 오차 affine1 = Affine( W, b ) a = affine1.forward(x) b = affine1.backward(dout) print(a) print(b)
배치용 Affine 계층 구현하기 p174
지금까지 구현한 Affine 계층은 '수지 사진' 한장만 입력했습니다.
그런데 배치 처리란 수지 사진을 100장씩 넣어서 학습 시키는 것을 배치 처리라고 합니다. 컴퓨터는 여러개의 사진을 한번에 학습 할 수 있습니다. 배치처리를 해야 신경망 학습 속도가 빨라집니다.
수지 사진 100장을 3층 신경망에 입력하는 그림입니다.
첫번째 은닉층의 뉴런의 수는 50개, 두번째 은닉층의 뉴런수는 30개이고 마지막 출력층의 뉴런수는 2개입니다. 수지와 은우를 분류하는 신경망이어서 출력층의 뉴런수가 2개인것입니다.
실습1. 앞에서 만들었던 Affine 클래스를 객체화 시켜서 아래의 수지 사진 100장을 입력하시오 !
입력층 ----> 은닉1층 ---> 결과
x = np.random.randn( 100, 28*28 ) # 수지 사진 100장 W = np.random.randn( 28*28 , 50 ) # 은닉1층의 뉴런수 50개 b = np.random.randn( 1, 50 ) # 은닉 1층의 뉴런수에 맞춰서 50개 affine1 = Affine( W, b ) result = affine1.forward(x) print( result.shape)
5. 13 소프트 맥스 함수 with 오차함수 계층 만들기
■ 수지와 설현 사진을 분류하는 신경망
설현 수지
수지사진 -----> 은닉층 ---> 출력층 ----> [ 0.2, 0.8 ] --> np.argmax --> 1
↑
소프트맥스함수
■ 수지와 설현과 은우를 분류하는 신경망
설현 수지 은우
수지사진 -----> 은닉층 ---> 출력층 ----> [ 0.2, 0.7 ,0.1 ] --> np.argmax --> 1
↑
소프트맥스함수
실습1. 패션 mnist 신경망의 예측결과에 확률도 같이 출력되게 합니다.
확률이 나오게 하는 부분 설명
https://cafe.daum.net/oracleoracle/SpOP/184
import tkinter as tk import numpy as np from tensorflow.keras.models import load_model from PIL import Image, ImageTk # 모델 불러오기 model_path = 'c:\\data\\fashion_model3.h5' fashion_model = load_model(model_path) # 이미지 전처리 (필요에 따라 작성) def predict_image(image_array): # 모델로 예측 results = fashion_model.predict(image_array) predicted_class = np.argmax(results) predicted_probability = results[0][predicted_class] # 클래스 이름 매핑 (필요에 따라 target_dict 작성) target_dict = { 0: "T-shirt/top", 1: "Trouser", 2: "Pullover", 3: "Dress", 4: "Coat", 5: "Sandal", 6: "Shirt", 7: "Sneaker", 8: "Bag", 9: "Ankle boot" } predicted_label = target_dict.get(predicted_class, "Unknown") return predicted_label, predicted_probability # GUI 설정 def upload_and_predict(): # 이미지 선택 및 처리 (사용자가 업로드한 이미지를 전처리해서 array로 변환) # 예측 호출 label, probability = predict_image(image_array) # 예측된 클래스와 확률을 GUI에 출력 result_label.config(text=f"Predicted Label: {label}") probability_label.config(text=f"Probability: {probability:.4f}") # GUI 디자인 root = tk.Tk() root.title("Fashion MNIST Classifier") # 업로드 버튼과 결과 출력 upload_button = tk.Button(root, text="Upload Image", command=upload_and_predict) upload_button.pack() result_label = tk.Label(root, text="Predicted Label: ") result_label.pack() probability_label = tk.Label(root, text="Probability: ") probability_label.pack() # GUI 실행 root.mainloop()
'빅데이터 분석(with 아이티윌) > deep learning' 카테고리의 다른 글
[빅데이터분석] 딥러닝_13. 코렙에서 정상 이파리와 질병 이파리 분류 신경망 만들기 (0) | 2024.10.17 |
---|---|
[빅데이터분석] 딥러닝_11. CNN 층 (1) | 2024.10.15 |
[빅데이터분석] 딥러닝_8. 2층 신경망 구현하기(오차 역전파로 2층 신경망 학습시키기) (0) | 2024.10.10 |
[빅데이터분석] 딥러닝_7. 미니배치/수치미분/사진인식(mnist) (0) | 2024.10.10 |
[빅데이터분석] 딥러닝_6. 2층 신경망 구현하기 (1) | 2024.10.07 |