Quiet Time

■ 3장 목차
  1. 활성화 함수 (active function)
     - 계단함수 
     - 시그모이드 함수
     - Relu 함수
     
  1. 행렬의 내적 문제
  2. 신경망을 파이썬으로 구현 
  3. 손글씨 인식 신경망을 구현 (순전파)

■ 퍼셉트론과 신경망의 차이점? 

퍼셉트론? 원하는 결과를 출력하도록 가중치의 값을 적절히 정하는 작업을 
         사람이 수동으로 해야한다. 
 - 신경망? 가중치 매개변수의 적절한 값ㅇ르 기계가 데이터로 부터 자동으로 학습해서 알아냄

■ 편향을 명시한 퍼셉트론 (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 = -100
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]

■ 출력층에서 사용하는 활성화 함수

  1. 분류 : 소프트 맥스 함수 ( 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


[ 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장 목차
  1. 활성화 함수 (active function)
     - 계단함수 
     - 시그모이드 함수
     - Relu 함수
     
  1. 행렬의 내적 문제
  2. 신경망을 파이썬으로 구현 
  3. 손글씨 인식 신경망을 구현 (순전파)

■ 출력층의 활성화 함수 2가지 ? 

  1. 분류 : 소프트 맥스 함수
 
     질문 예: 데이터가 어느 클래스에 속하는지 확인
          (사진속 인물의 성별 분류)  
  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
xlist(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]

문제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