딥러닝 3장. 신경망
딥러닝2017. 7. 26. 10:51
■ 3장 목차
- 활성화 함수 (active function)
- 계단함수
- 시그모이드 함수
- Relu 함수
- 행렬의 내적 문제
- 신경망을 파이썬으로 구현
- 손글씨 인식 신경망을 구현 (순전파)
■ 퍼셉트론과 신경망의 차이점?
퍼셉트론? 원하는 결과를 출력하도록 가중치의 값을 적절히 정하는 작업을
사람이 수동으로 해야한다.
- 신경망? 가중치 매개변수의 적절한 값ㅇ르 기계가 데이터로 부터 자동으로 학습해서 알아냄
■ 편향을 명시한 퍼셉트론 (p65)
단층 퍼셉트론 : 계단 함수 (선형함수) ---> 0 또는 1 의 값을 출력
다층 퍼셉트론 : 시그모이드 or Relu (비선형 함수) --> 0 ~ 1 사이의 실수
예 : 0.731, 0.880
def step_function(x):
y = x > 0
return y.astype(np.int)
x_data = np.array([-1,0,1])
print(step_function(x_data))
문제36. 위의 step_function 함수를 이용해서 계단함수 그래프를 그리시오
def step_function(x):
y = x > 0
return y.astype(np.int)
x = np.arange(-5.0,5.0,0.1)
y = step_function(x)
plt.plot(x,y)
plt.show()
문제37 위의 step_function 함수를 이용해서 계단함수 그래프를 반대로 그리시오
def step_function(x):
y = x > 0
return -y.astype(np.int)
x = np.arange(-5.0,5.0,0.1)
y = step_function(x)
plt.plot(x,y)
plt.show()
문제38. (점심시간 문제 )
x0, x1, x2 = -1, 0, 0
w0, w1, w2 = .3, .4, .1
일 때 ㄱ
를 코드로 나타내 보아라 !
x = np.array([x0,x1,x2])
w = np.array([w0,w1,w2])
a = np.sum(x*w)
def step(x):
y = x > 0
return y.astype(np.int)
print(step(a))
■ 시그모이드 함수
계단함수 (단층 퍼셉트론) vs 시그모이드 함수(다층 퍼셉트론)
이 둘의 차이점과 공통점?
차이점 ? 계단함수는 숫자 1과 0만 출력한느데
시그모이드 함수는 0과 1사이의 실수를 출력한다.
f(가중의 합) = 0.8834
공통점 ? 둘다 0과 1사이의 데이터만 출력하는것이 공통점이다.
1
시그모이드 함수식 = -------------
1 + exp(-x)
↓
e(자연상수)^-x
h(1,0) = 0.731 , h(2.0) = 0.880
문제39. 진짜로 시그 모이드 함수를 생성해보자
def sigmoid(x):
return 1 / (1+np.exp(-x))
x = np.array([1.0,2.0])
print(sigmoid(x))
문제40. 시그모이드 함수를 그래프로 그리시오 !
def sigmoid(x):
return 1 / (1+np.exp(-x))
x = np.arange(-8.0,8.0,0.1)
y = sigmoid(-x)
plt.plot(x,y)
plt.show()
문제41. 시그모이드 반대록 ㄱㄱ
def sigmoid(x):
return 1 / (1+np.exp(x))
x = np.arange(-8.0,8.0,0.1)
y = sigmoid(x)
plt.plot(x,y)
plt.show()
둘다 나타내봐라 계단이랑 시그모이드
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid(x):
return 1/(1+np.exp(-x))
plt.figure(figsize=(6,4))
x1 = np.arange(-6.0,6.0,0.1)
y1 = step_function(x1)
plt.plot(x1,y1,linestyle='--')
y = sigmoid(x1)
plt.plot(x1, y)
plt.show()
■ ReLu 함수 (Rectified Linear Unit)
정류된
ReLu는 입력이 0을 넘으면 그 입력을 그대로 출력하고
0 이하이면 0을 출력하는 함수
x (x > 0)
h(x) = [
0 (x<= 0)
학습이 잘 되어서 현업에서 주로 사용하는 함수
문제43. ReLu 함수를 생성하시오 !
def relu(x):
return np.maximum(0,x)
print (relu(-2))
print (relu(0.3))
문제44. Relu 함수를 그래프로 그리시오
def relu(x):
return np.maximum(0, x)
x = np.arange(-15.0,15.0,0.1)
y= relu(x)
plt.figure(figsize=(10,10))
plt.plot(x,y)
plt.show()
■ 3.2 행렬의 내적 (p77 다차원 배열계산)
문제45. 아래의 행렬 곱 (행렬내적) 을 파이썬으로 구현하시오 !
1 2 3 5 6
[ ] * [ 7 8 ] = ?
4 5 6 9 10
2 x 3 * 3 x 2 = 2 x 2
a=np.array([[1,2,3],[4,5,6]])
b=np.array([[5,6],[7,8],[9,10]])
print(np.dot(a,b))
[[ 46 52]
[109 124]]
문제46. 아래의 행렬곱을 파이썬으로 구현하시오!
5 6 1
( 7 8 ) * ( ) = ?
9 10 2
a=np.array([[5,6],[7,8],[9,10]])
b=np.array([[1],[2]])
print(np.dot(a,b))
[[17]
[23]
[29]]
■ 신경망 내적
문제47. 아래 그림을 numpy 로 구현하시오
x = np.array([1,2])
y = np.array([[1,3,5],[2,4,6]])
b = np.array([7,8,9])
print(np.dot(x,y)+b)
문제48. 위의 문제에서 구한 입력신호의 가중의 합인 y 값이
활성함수인 sigmoid 함수를 통과하면 어떤 값으로 출력되는지
z 값을 확인하시오.
x = np.array([1,2])
y = np.array([[1,3,5],[2,4,6]])
b = np.array([7,8,9])
print(np.dot(x,y)+b)
문제49. 아래의 신경망 그림을 파이썬으로 구현하시오
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
x = np.array([4.5, 6.2])
w = np.array([[0.1, 0.3], [0.2, 0.4]])
b = np.array([0.7, 0.8])
l1 = sigmoid(np.dot(x, w)+b)
w = np.array([[0.5, 0.7], [0.6, 0.8]])
l2 = sigmoid(np.dot(l1, w)+b)
w = np.array([[0.1, 0.3], [0.2, 0.4]])
l3 = np.dot(l1, w)+b
print(l3)
[ 0.98967405 1.47095426]
■ 출력층에서 사용하는 활성화 함수
- 분류 : 소프트 맥스 함수 ( 0 ~ 1 사이의 숫자로 출력되는 함수 )
1.2 0.46
[ 0.9 ] ---> 소프트맥스 --->[ 0.34 ]
0.4 0.20
p96.
y0 = 0(확률 = 0.2 : 20%)
필기체 2 ---> 신경망 y1 = 1(확률 = 0.1 : 10%)
y2 =2(확률 = 0.46 : 46%)
:
y9 = 9(확률 = 0.01 : 1 %)
2.회귀 : 항등함수 ( 입력값을 그대로 출력하는 함수 )
문제50. 소프트맥스 함수를 파이썬으로 구현하시오 !
def softmax(a):
c = np.max(a)
exp_a = np.exp(a - c)
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y
c = np.max(a)
exp_a = np.exp(a - c)
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y
[ 0.01821127 0.24519181 0.73659691] <- 확률 벡터
" 인공 신경망의 출력값으로 확률 벡터를 얻고 싶을때 사용한다."
문제51. 입력값을 그대로 출력하는 항등 함수를 파이썬으로 구현하시오
def identity_function(x):
return x
문제52. 책 88 페이지에 나오는 3층 신경망을 파이썬으로 구현하시오 !
(오늘의 마지막 문제)
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
x= np.array([1.0, .5])
W1 = np.array([[.1, .3, .5], [.2, .4, .6]])
W2 = np.array([[.1, .4],[.2, .5] ,[.3, .6]])
W3 = np.array([[.1, .3],[.2,.4]])
b1 = np.array([.1,.2,.3])
b2 = np.array([.1,.2])
b3= np.array([.1,.2])
l1 = sigmoid(np.dot(x,W1)+b1)
print(l1)
l2 = sigmoid(np.dot(l1,W2)+b2)
print(l2)
l3 = np.dot(l2,W3)+b3
print(l3)
test
import numpy as np
import matplotlib.pyplot as plt
# A = np.array([[1,1,-1],[4,0,2],[1,0,0]])
# B = np.array([[2,-1],[3,-2],[0,1]])
#
# print(np.dot(A,B))
#
# A = np.matrix([[1,1,-1],[4,0,2],[1,0,0]])
# B = np.matrix([[2,-1],[3,-2],[0,1]])
#
# print(A*B)
def softmax(a):
c = np.max(a)
exp_a = np.exp(a - c)
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y
x0, x1, x2 = .2, .7, .9
w11, w12, w13 = 2, 4, 3
w21, w22, w23 = 2, 3, 5
w31, w32, w33 = 2, 4, 4
b1, b2, b3 = -3, 4, 9
x = np.array([x0,x1,x2])
w1 = np.array([[w11, w21, w31],[w12, w22, w32],[w13, w23, w33]])
b = np.array([b1,b2,b3])
result = softmax(np.dot(x,w1)+b)
print(result)
x = np.arange(-1.,1.,0.001)
plt.plot(x , result[1])
plt.show()
■ 3장 목차
- 활성화 함수 (active function)
- 계단함수
- 시그모이드 함수
- Relu 함수
- 행렬의 내적 문제
- 신경망을 파이썬으로 구현
- 손글씨 인식 신경망을 구현 (순전파)
■ 출력층의 활성화 함수 2가지 ?
- 분류 : 소프트 맥스 함수
질문 예: 데이터가 어느 클래스에 속하는지 확인
(사진속 인물의 성별 분류)
2.회귀 : 항등 함수
질문 예 : 입력 데이터에서 연속적인 수치를 예측하는 문제
( 사진 속 인물의 몸무게를 예측하는 문제)
" 소프트 맥스 함수는 a의 원소의 대소 관계가 y의 원소의
대소 관계로 그대로 이어지기 때문에 출력이 가장 큰 뉴런의 위치는 변하지 않는다.
결과적으로 지수 함수 계산에 드는 자원 낭비를 줄이고자 출력층의 소프트 맥스 함수는
생략하는 것이 일반적이다. "
학습 ----------------------> 추론(테스트) --> 해야할 진짜 일
↓ ↓
소프트 맥스 함수 사용 o 소프트 맥스 함수 사용 x
■ 손글씨 숫자 인식 (p 96)
- mnist ? 손글씨 숫자 이미지 집합 데이터 셋
0 ~ 9 까지의 숫자 이미지로 구성되어있고
훈련 이미지가 60000 장, 시험 이미지가 10000 장이 준비됨
- 28 x 28 크기의 회색조 이미지 (총 784개의 픽셀)
- 각 픽셀은 0 ~ 255 까지의 값을 취한다. 숫자가 커질수록 픽셀이 진해짐
- 각 이미지에는 숫자 7,2,1 과 같은 이미지가 레이블되어 있다.
# coding: utf-8
import sys, os
sys.path.append(os.pardir) # 부모 디렉터리의 파일을 가져올 수 있도록 설정
import numpy as np
from mnist import load_mnist
from PIL import Image
def img_show(img):
pil_img = Image.fromarray(np.uint8(img))
pil_img.show()
테스트데이터, 테스트데이터라벨
↓ ↓
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)
↑ ↑
훈련 데이터, 훈련데이터 라벨
# 설명 : flatten = True 라는 것은 립력이미지를 평탄하게 1차원 배열로 변환하라
# normalize : 입력 이미지의 픽셀 값을 0 ~ 1 사이로 할지 아니면 원래 값인 0 ~ 255 로 할지
결정하는 함수
# 0 ~ 255 범위의 각 픽셀의 값을 0.0 ~ 1.0 사이 범위로 변환능ㄹ 하는데 이렇게 특정 범위로
# 변환 처리하는 것을 ?
# "정규화" 라고 한다
#신경망의 입력 데이터에 특정 변환을 가하는 것을
# "전처리" 라고 한다.
img = x_train[0]
label = t_train[0]
print(label) # 5
print(img.shape) # (784,)
img = img.reshape(28, 28) # 형상을 원래 이미지의 크기로 변형
print(img.shape) # (28, 28)
img_show(img)
문제53. x_train 의 0 번째 요소의 필기체 숫자를 5였다. 그렇다면 x_train 의 1번재 요소의 필기체 숫자는 무엇인지 확인하시오
7
• mnist파라미터 설명
a. flatten
i. true : 입력이미지를 평탄하게 1차원 배열로 변환하는 것 (학습시킬때는 변환해야함)
ii. false : 입력이미지를 평탄하게 1차원 배열로 변환하지 않는것 (이미지를 표시해야 함)
b. normalize
i. true : 픽셀의 값을 0~1 사이로 변환한다. (전처리 작업)
ii. false : 픽셀의 값을 0~255 사이로 그대로 둔다.
c. one_hot_label
§ 0~9의 숫자가 라벨로 저장되어 있음 [0,0,0,0,0,0,0,1,0,0] --> 7을 의미한다.
i. true : 원-핫 인코딩 (one-hot encoding) 형태로 저장한다.
false : 레이블을 원-핫 인코딩 형태로 저장안한다.
# coding: utf-8
import sys, os
sys.path.append(os.pardir) # 부모 디렉터리의 파일을 가져올 수 있도록 설정
import numpy as np
import pickle
# (p98) mmist 데이터셋을 읽어올 때 인터넷이 연결되어 있는 상태에서 가져와야하는데 이때 시간이 걸린다.
# 가져온 이미지를 로컬에 저장할 때 pickle 파일로 생성이 되고 로컬에 저장되어 있으면 순식간에 읽을 수 있기 때문에 임포트 해야함
from dataset.mnist import load_mnist
from common.functions import sigmoid, softmax
def get_data():
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
#(학습데이터, 학습라벨), (테스트데이터, 테스트라벨)
# 60000장 , 10000장
return x_test, t_test
#테스트 데이터만 return. 학습할 필요 x
#훈련시킬려는 목적 x
def init_network():
with open("C:\\sample_weight.pkl", 'rb') as f:
# (훈련되어있는 매개변수, 가중치) 가지고 추론
network = pickle.load(f)
return network
# sample_weight.pkl 파일안에 학습된 가중치, 바이어스가 다 계산되어서 들어있음
# 신경망 어떻게 구현해서 학습한것인지 확인(추정)
# 이 최종결과가 sample어쩌구 저 파일에 있다
# 그니까 여기 안엔 학습코드 x. 학습된거 가지고 추론하는거임
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
# [0.05, 0.05, 0.7, 0.01 ...]
# 2
## 2가 맞는지 확인
x, t = get_data()
# 테스트 데이터(x), 테스트 라벨(t)
# t에는 숫자가 들어있을 것(원핫인코딩x)
network = init_network()
##파이썬 함수의 4가지 특징
#1. 변수에 할당할 수 있다
#2. 다른 함수 내에서 정의될 수 있다
#3. 함수의 매개변수로 함수가 전달될 수 있다
#4. 함수의 반환값이 될 수 있다
accuracy_cnt = 0 #정확도를 출력해주기 위한 변수
for i in range(len(x)):
y = predict(network, x[i])
# x 784개...
# y가 [0.05, 0.05, 0.7, 0.01 ..]
p= np.argmax(y) # 확률이 가장 높은 원소의 인덱스를 얻는다. #2
if p == t[i]: # t: 타겟(숫자있음.. 원핫인코딩안했으니깐...)
accuracy_cnt += 1
print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
문제56. 위의 코드를 수정해서
■ 배치처리 (p102)
이미지를 한장씩 처리하는게 아니라 여러장르 한번에 처리
이미지를 한장씩 처리함
이미지는 50페이지씩 처리함
추론(테스트)를 배치 단위로 진행하면 결과를 훨씬 빠르게 얻을 수 있다.
- 배치로 돌리는 코드를 이해하기 위한 사전 파이썬 코드의 이해
list( range(0, 10) ) <--- 이 결과를 프린트하면 ?
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
문제57. [0, 3, 6, 9]로 결과를 출력하려면 ?
print(list(range(0,10,3)))
문제58. 아래의 리스트를 만들고
[0, 3, 6, 9] 이중의 최대 값을 출력하라 인덱스도
x= list(range(0,10,3))
print(max(x))
print(x.index(max(x)))
문제59. numpy를 이용해서 아래의 리스트에 최대값의 인덱스를 출력하시오 !
import numpy as np
x= list(range(0,10,3))
print(np.argmax(x))
문제60. 아래의 행렬 배열을 생성하고 각 행의 최대값을 갖는 인덱스가
출력되게 하시오
0.1 0.8 0.1 1
0.3 0.1 0.6 2
0.2 0.5 0.3 1
0.8 0.1 0.1 0
import numpy as np
a = np.array([[ 0.1, 0.8 , 0.1 ],
[ 0.3 , 0.1 , 0.6 ],
[ 0.2 ,0.5, 0.3 ],
[ 0.8, 0.1 , 0.1 ] ])
for i in range(len(a)):
print(np.argmax(a[i]))
for i in range(a.shape[0]):
print(np.argmax(a[i])
print(np.argmax(a, axis = 1))
axis = 0 : 열
axis = 1 : 행
print(a.shape[0])
for i in range(a.shape[0]):
print(np.argmax(a[i]))
print(np.argmax(a, axis = 0))
[3 0 1]
문제61. 아래의 2개의 리스트를 만들고 서로 같은 자리에 같은 숫자가 몇개가 있는지 출력하시오 !
[2,1,3,5,1,4,2,1,1,0]
[2,1,3,4,5,4,2,1,1,2]
결과 : 7
a = [2,1,3,5,1,4,2,1,1,0]
j = 0
b= [2,1,3,4,5,4,2,1,1,2]
for i inrange(len(a)):
if (a[i] == b[i]):
j+=1
print(j)
a = [2,1,3,5,1,4,2,1,1,0]
b= [2,1,3,4,5,4,2,1,1,2]
a= np.array(a)
b= np.array(b)
print(np.sum(a==b))
문제62. 아래의 리스트를 x라는 변수에 담고 앞에 5개의 숫자만 출력하시오
[1,2,3,4,5,6,7,8,9,10]
결과 : [1,2,3,4,5]
답 :
a=[1,2,3,4,5,6,7,8,9,10]
print(a[0:5]
print(a[0:5]
문제63. 100장의 이미지를 한번에 입력츠엥 넣어서 정확도를
추론하는 신경망 코드를 수행하시오 !
# coding: utf-8
import sys, os
sys.path.append(os.pardir) # 부모 디렉터리의 파일을 가져올 수 있도록
import numpy as np
import pickle
from dataset.mnist import load_mnist
from common.functions import sigmoid, softmax
def get_data():
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
return x_test, t_test
def init_network():
with open("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
x, t = get_data()
network = init_network()
batch_size = 1 # 배치 크기
accuracy_cnt = 0
for i in range(0, len(x), batch_size):
x_batch = x[i:i+batch_size]
y_batch = predict(network, x_batch)
p = np.argmax(y_batch, axis=1)
accuracy_cnt += np.sum(p == t[i:i+batch_size])
print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
문제64. batch_size를 1로 했을 때와 batch_size를 100으로 했을 떄
수행속도의 차이가 있는지 확인하시오 ! (정확도와 수행속도)
100개씩
0.046002864837646484
Accuracy:0.9352
1개씩
0.7430424690246582
Accuracy:0.9352
문제65. 훈련 데이터 (6만개)로 batch_size 1 로 했을 때와
batch_size 100으로 했을때의 정확도와 수행속도차이를 비교하시오 (오늘의 마지막 문제 )
100 개씩
0.239013671875
Accuracy:0.9357666666666666
1개씩
4.204240560531616
Accuracy:0.9357666666666666
4장을 미리 읽으세요
'딥러닝' 카테고리의 다른 글
딥러닝 5장 . (0) | 2017.07.26 |
---|---|
딥러닝 4장. 신경망 학습 (0) | 2017.07.26 |
딥러닝 2장. 퍼셉트론 (0) | 2017.07.26 |
딥러닝 1장. Numpy, matplotlib 사용법 (0) | 2017.07.26 |