close_btn
조회 수 81 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print Files
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print Files

ToBig's_11th_W05_Neural_Network_실습

Assignment_01 : 주석달기

11기 김대웅



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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
import numpy as np
# 행렬 X에 가중치 벡터 W를 내적해 Hidden layer H 생성
# <=> H = w_1 * x_1 + w_2 * x_2 + ... + w_d * x_d
def linear(X, W):
    H = np.dot(X, W)
    return H
# activation function : 시그모이드 함수
def sigmoid(H):
    p = 1 / (1 + np.exp(-H))
    return p
# 입력 Feature는 1 X 2 행렬
= np.array([12])
#가중치 행렬 W는 1 X 2 행렬
= np.array([23])
# 입력 Feature x_i에 각각 가중치 w_i를 곱하여 Hidden layer H 계산 (1 * 1)
# H값이 양수일 경우. Sigmoid는 1에 가까운 값
= linear(X, W)
print(H)
# H에 activation function : sigmoid
= sigmoid(H)
print(p)
'''
8
0.9996646498695336
'''
# H값이 음수일 경우, Sigmoid는 0에 가까운 값
= np.array([-4-3])
= linear(X, W)
print(H)
= sigmoid(H)
print(p)
'''
-10
4.5397868702434395e-05
'''
# Iris 자료 load
from sklearn.datasets import load_iris
data = load_iris()
= data["data"]
= data["target"]
len(x)
#150
# X (150, 4)
x[:10]
'''
array([[5.1, 3.5, 1.4, 0.2],
       [4.9, 3. , 1.4, 0.2],
       [4.7, 3.2, 1.3, 0.2],
       [4.6, 3.1, 1.5, 0.2],
       [5. , 3.6, 1.4, 0.2],
       [5.4, 3.9, 1.7, 0.4],
       [4.6, 3.4, 1.4, 0.3],
       [5. , 3.4, 1.5, 0.2],
       [4.4, 2.9, 1.4, 0.2],
       [4.9, 3.1, 1.5, 0.1]])
'''
# y (150, )
y
'''
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
'''
class Softmax:
    def __init__(self):
        # Parameter 저장할 Dict
        self.params = {}
        # 임의 가중치 행렬 W (4 x 3) (Hidden layer의 Node 수 : 3개)
        self.params['W'= 0.0001 * np.random.randn(43)
        # Bias 항으로 초기값 1을 부여함. 
        # WX가 (150 X 3) 행렬이므로 각 bias의 개수는 hidden layer의 Node 수(3)와 동일 
        self.params['b'= np.ones(3)
    
    def forward(self, X):
        # parameter dict에서 Weight와 Bias를 가져와 local variable W와 b에 할당
        W = self.params['W']
        b = self.params['b']
        # Hidden layer = Weight * Features  + Bias // H = XW + b
        # H : (150, 3)
        h = np.dot(X, W) + b
        # Softmax probability 계산을 위해 지수함수 변환 : exp(H)
        # A : (150, 3)
        a = np.exp(h)
        # stable_a = np.exp(h - np.max(h, axis = 1).reshape(-1,1))
        # 각각의 probability.
        # P : (150, 3)
        p = a/np.sum(a, axis = 1, keepdims=True)
        # cf. keepdims = True : a의 원래 형태 유지. (열벡터)
        return p
    
    # Softmax-with-loss Node
    def loss(self, X, T):
        # 예측확률 p를 계산
        p = self.forward(X)
        # 전체 자료 길이 n 
        n = T.shape[0]
        
        # Cross Entropy 오차의 계산 
    
        # Error = -log(정답 label의 Softmax probability)의 총 합계
        # log내에 들어가는 확률값이 1에 가까울수록 -log변환의 값은 작다.
        # 즉 정답레이블에 대해 정답으로 예측할 확률이 클수록(1에 가까울수록)
        # -log(Softmax probability)는 0에 가깝기 때문에 이렇게 설정
        
        log_likelihood = 0
        log_likelihood -= np.log(p[np.arange(n), T]).sum()
        # loss를 Sample Size N으로 나눔 (개별 자료에 대한 loss를 나타내기 위해)
        Loss = log_likelihood / n
        return Loss
    
    def accuracy(self, X, T):
        p = self.forward(X) # Softmax prob : P (150, 3)
        # predict (150, 1) : 분류 결과 : 가장 큰 확률값을 가지는 index
        predict = np.argmax(p, axis = 1#예측 결과 index 1darray 로 출력 
        
        # 정분류율(Accuracy) = 1 - (오분류율)
        return 1 - np.count_nonzero(predict - T)/len(T)
        
    def gradient(self, X, T, learning_rate = 0.0001):
        # Softmax prob 계산 p에 할당
        p = self.forward(X)
        # Softmax-Loss Node의 입력값(H) 각각의 Loss에 대한 Gradient
        # (H : 150, 3)
        # (P : 150, 3)
        # dp (150, 3) : derivate of Loss w.r.t. h_i ( i = 1, 2, ... , 150 )
        dp = p.copy()
        dp[np.arange(len(T)), T] -= 1
        
        # Softmax-loss의 입력단 : h_1, h_2, h_3 각각의 Gradient를 구합니다.
        # 이 때 각 자료에 대해서 Gradient값이 구해지며, update를 위해선 150개 자료의 각 Gradient의 평균값을 사용합니다.
        # 각 Gradient의 평균값을 구하기 위해 batch size로 나눠줍니다(뒤에서 총합을 내어 mean이 됨)
        # cf. 여기서는 전체 자료를 사용하기 때문에 batch size = 150. SGD의 mini bath의 경우 mini batch size로 나누어줌
        
        dp /= len(T)
        
        #목적함수에 대한 가중치 미분값을 담을 zero array 생성
        grads = {}
        
        #목적함수에 대한 가중치 미분값 합 구하기
        # {partial L} over {partial W} = [X^T]product dot[{partial L} over {partial H}]
        # X : (150, 4), dp : (150, 3)
        # grads["W"] : (4, 3)
        #     row : input feature 4
        #     col : Softmax-loss node input 3
        
        grads['W'= np.dot(X.T, dp)
        # {partial L} over {partial b} = 1 * [{partial L} over {partial H} = dp]
        # grads["b"] : (1, 3)
        grads['b'= np.sum(dp, axis = 0)
        #p-t 대신 dp 사용 가능
        
        # parameter update 
        self.params['W'-= learning_rate * grads['W']
        self.params['b'-= learning_rate * grads['b']
softmax = Softmax()
for i in range(1000000000):
    softmax.gradient(x, y)
    
    if i % 1000 == 0:
        print(i, "번째 학습중입니다.")
        print("Accuracy : ", softmax.accuracy(x, y))
        print("Loss :     ", softmax.loss(x, y))
        print(softmax.params['W'])
'''
0 번째 학습중입니다.
Accuracy :  0.33333333333333337
Loss :      1.0987191201522015
[[ 4.71958896e-05  4.22167250e-05 -2.19067037e-04]
 [-2.01014883e-04 -4.52424608e-05 -9.59231972e-05]
 [ 1.26014621e-04  1.63714011e-04  1.26605259e-04]
 [ 1.20505533e-04 -1.07729572e-05  3.49531937e-05]]
.
.
.
1697000 번째 학습중입니다.
Accuracy :  0.9866666666666667
Loss :      0.10198757944890943
[[ 1.05691333  0.81684877 -1.87389175]
 [ 2.41294916 -0.10832469 -2.30496665]
 [-3.28752422 -0.19953339  3.48747395]
 [-1.54129193 -1.46582057  3.00725719]]
'''
 

cs



ToBig's_11th_W05_Neural_Network_실습

Assignment_02 : 2layer MLP 구현

11기 김대웅

다운로드.png

1. Model.py

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import numpy as np
 
class TwoLayerNet():
    """
    2 Layer Network를 만드려고 합니다.
    해당 네트워크는 다음과 같은 구조를 따릅니다.
    input - Linear - ReLU - Linear - Softmax
    Softmax 결과는 입력 N개의 데이터에 대해 각 클래스에 대한 확률입니다.
    """
 
    def __init__(self, input_size, hidden_size, output_size, std=1e-4):
         """
         네트워크에 필요한 가중치들을 initialization합니다.
         해당 가중치들은 self.params 라는 Dictionary에 담아둡니다.
         input_size: 데이터의 변수 개수 - D
         hidden_size: 히든 층의 H 개수 - H
         output_size: 클래스 개수 - C
         """
        # 여기에 가중치들을 init 하세요
         self.params = {}
         self.params["W1"= std * np.random.randn(input_size, hidden_size)
         self.params["b1"= np.ones(hidden_size)
         self.params["W2"= std * np.random.randn(hidden_size, output_size)
         self.params["b2"= np.ones(output_size)
 
    def forward(self, X, y=None):
        """
        X: input 데이터 (N, D)
        y: 레이블 (N,)
        Linear - ReLU - Linear - Softmax - CrossEntropy Loss
        이 코드에서는,
        y가 주어지지 않으면 Softmax 결과 p와 Activation 결과 a를 return합니다.
        그 이유는 p와 a 모두 backward에서 미분할때 사용하기 때문입니다.
        y가 주어지면 CrossEntropy Error를 return합니다.
        """
 
        W1, b1 = self.params["W1"], self.params["b1"]
        W2, b2 = self.params["W2"], self.params["b2"]
        N, D = X.shape
 
        # 여기서 p를 구하는 작업을 수행하세요.
        # Linear layer 1 
        h1 = np.dot(X, W1) + b1 # h1 : (N, H) / b1이 broadcasting되어 더해짐
        # ReLU
        a = np.maximum(0, h1) # a : (N, H)
        # Linear layer 2
        h2 = np.dot(a, W2) + b2 # h2 : (N, C) / b2가 broadcasting되어 더해짐
        
        # centering to avoid inf # scores : (N, C)
        scores = np.exp(h2 - np.max(h2, axis = 1).reshape(-11))
        
        # Softmax
        # p : (N, C)
        p = scores / np.sum(scores, axis=1, keepdims=True)
        
        if y is None:
            return p, a
 
        # 여기서 Loss를 구하는 작업을 수행하세요.
        n = X.shape[0]
        
        log_likelihood = 0
        # Cross entropy : 음의 로그우도의 기대값
        log_likelihood -= np.log(p[np.arange(n), y]).sum()
        # N개의 자료에 대한 오차의 합계이므로
        # 이를 하나의 자료에 대한 오차로 표현하기 위해 N으로 나눔
        Loss = log_likelihood / n
 
        return Loss
 
 
    def backward(self, X, y, learning_rate=1e-5):
        """
        X: input 데이터 (N, D)
        y: 레이블 (N,)
        grads에는 Loss에 대한 W1, b1, W2, b2 미분 값이 기록됩니다.
        원래 backw 미분 결과를 return 하지만
        여기서는 Gradient Descent방식으로 가중치 갱신까지 합니다.
        """
        W1, b1 = self.params["W1"], self.params["b1"]
        W2, b2 = self.params["W2"], self.params["b2"]
 
        N = X.shape[0# 데이터 개수
        grads = {}
 
        #p, a는 forward 결과를 가져옵니다.
        p, a = self.forward(X)
 
        # 여기에 각 파라미터에 대한 미분 값을 저장하세요.
        
        # [Soft max with CrossEntropy loss Node Back Propagation]
        # Derivate of P wrt S : P - y  # dp : (N, C)
        dp = p.copy()
        dp[np.arange(len(y)), y] -= 1
        dp /= N
        
        '''
        cf dp를 N으로 나눠주는 이유?
        W2, W1의 gradient 계산시 행렬곱에의해 하나의 원소에 N개 자료의 합계가 들어감 (Line 122, 138 참고)
        이렇게되면 gradient update시 N배된 gradient를 빼게되므로 학습이 제대로 이루어지지 않음
        이를 보정하기 위해 N으로 나눔
        
        '''
        
        # [Linear Layer 2(h2) Back propagation]
        # dL/da = (dl/ds) * (ds/da) : (N, C)*(C, H) = (N, H)
        da = dp.dot(W2.T)
        
        # dL/dW2 : (dp/dW2) * (dL/dp) : (H, N) * (N, C) = (H, C) 
        '''
        # cf. forward에서의 scores는 inf를 피하기 위한 변환이며
              Weight update엔 영향을 끼치지 않으므로 backward에서는 무시.
        '''
        grads["W2"= a.T.dot(dp)
        # dL/b2 : 1 * dl/dp : (N, C) ==> 위에서 N으로 나눠줬기 때문에 row 방향 sum == mean
        grads["b2"= np.sum(dp, axis = 0)
 
 
        # [ReLU Back propagation]
        # dL/dh : (da/dh1) ⊙ (dl/da) : (N, H) (*) ⊙ (N, H) = (N, H)
        dh = da * (a > 0)
        
        
        # [Linear Layer 1(h1) Back propagation]
        # dL/dW1 : (dh/dW1) * (dL/dh) : (D, N) * (N, H) = (D, H)
        grads["W1"= X.T.dot(dh)
        # dL/b1 : 1 * dl/dh : (N, H) ==> 위에서 N으로 나눠줬기 때문에 row 방향 sum == mean
        grads["b1"= np.sum(dh, axis = 0)
        
 
        # [Updating W, b]
        self.params["W1"-= learning_rate * grads["W1"]
        self.params["b1"-= learning_rate * grads["b1"]
        self.params["W2"-= learning_rate * grads["W2"]
        self.params["b2"-= learning_rate * grads["b2"]
 
    def accuracy(self, X, y):
        N = X.shape[0]
        p, _ = self.forward(X)
        y_pred = np.argmax(p, axis = 1)
 
        return np.sum(y_pred==y)/N
cs



2. 모델 성능

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# 하이퍼파라미터 설정
 
input_size = 32 * 32 * 3
# Hideen layer의 Node 개수
hidden_size = 50
# Output label
output_size = 10
# 1 epoch : 전체 데이터에 대해 1회 학습
epoch_size = 1000
# 1회 update할 때 쓰일 자료의 크기
batch_size = 100
learning_rate = 0.0001
# 자료 전체의 크기 N
= train_data.shape[0]
 
# 모델 만들기
nn = TwoLayerNet(input_size=input_size, hidden_size=hidden_size, output_size=output_size)
 
history = {'acc': [],'loss': []} #기록해서 그림 그리자!
 
#코드를 보며 epoch, batch에 대해서 이해해봅시다.
for i in range(epoch_size):
    for j in range(N//batch_size):
        batch_mask = np.random.choice(N, batch_size) #이번 배치에서 쓸 데이터들 인덱스 추출
        x_batch = train_data[batch_mask]
        t_batch = train_labels[batch_mask]
        
        nn.backward(x_batch, t_batch) # 가중치 갱신
    
    #accuracy와 loss를 기록해둡시다.
    history["acc"].append(nn.accuracy(test_data, test_labels))
    history["loss"].append(nn.forward(test_data, test_labels))
    
    if i % 10 == 0:
        print(i, "accuracy :", nn.accuracy(test_data, test_labels))
        print(i, "loss     :", nn.forward(test_data, test_labels))
 
'''
0 accuracy : 0.116
0 loss     : 2.3025246695631205
10 accuracy : 0.167
10 loss     : 2.3012612855824406
20 accuracy : 0.182
20 loss     : 2.2953004272665543
30 accuracy : 0.177
30 loss     : 2.2743800406795427
40 accuracy : 0.175
.
.
.
950 accuracy : 0.427
950 loss     : 1.6448010073455985
960 accuracy : 0.432
960 loss     : 1.6433935352072073
970 accuracy : 0.424
970 loss     : 1.643611897150466
980 accuracy : 0.426
980 loss     : 1.6446990155460701
990 accuracy : 0.428
990 loss     : 1.6461849583113966
'''
 
# 그림 그리기
fig = plt.figure()
ax_acc = fig.add_subplot(111)
 
ax_acc.plot(range(epoch_size), history['acc'], label='정확도(%)', color='darkred')
#plt.text(3, 14.7, "<----------------정확도(%)", verticalalignment='top', horizontalalignment='right')
plt.xlabel('epochs')
plt.ylabel('Accuracy(%)')
ax_acc.grid(linestyle='--', color='lavender')
ax_loss = ax_acc.twinx()
ax_loss.plot(range(epoch_size), history['loss'], label='오차', color='darkblue')
#plt.text(3, 2.2, "<----------------오차", verticalalignment='top', horizontalalignment='left')
plt.ylabel('Error')
ax_loss.yaxis.tick_right()
ax_loss.grid(linestyle='--', color='lavender')
 
# 그래프 표시
plt.show()
cs


accuracy.png



List of Articles
번호 제목 글쓴이 날짜 조회 수
공지 R 소스 공유 게시판 이용 관련 공지사항 1 DataMarket 2014.05.21 34569
149 투빅스 10기&11기 7주차 CNN (Alexnet) - 11기 심은선 file 심은선 2019.03.15 41
148 투빅스 10기&11기 7주차 - NLP - 11기 유기윤 file 유기윤 2019.03.14 50
147 투빅스 10기&11기 6주차 Advanced Neural Network - 11기 김대웅 file 김대웅 2019.03.12 44
» 투빅스 10기&11기 5주차 Neural Network - 11기 김대웅 file 김대웅 2019.03.07 81
145 투빅스 10기&11기 4주차 Algorithm - 10기 정윤호 UNOVATE 2019.03.04 56
144 투빅스 10기&11기 4주차 ML Performance Tuning - 11기 김대웅 김대웅 2019.02.22 92
143 투빅스 10기&11기 4주차 PCA - 11기 임채빈 임채빈 2019.02.22 94
142 투빅스 10기&11기 3주차 Clustering - 11기 한재연 file 한재연 2019.02.16 119
141 투빅스 10기&11기 3주차 Decision Tree - 11기 김유민 file 2019.02.15 110
140 투빅스 10기&11기 3주차 Clustering - 11기 김대웅 file 김대웅 2019.02.15 143
139 투빅스 10기&11기 3주차 Algorithm - 11기 한재연 file 한재연 2019.02.15 99
138 투빅스 10기&11기3주차 앙상블(Kaggle HousePrice) - 11기 이소라 file 소라찌 2019.02.15 119
137 투빅스 10기&11기 2주차 SVM, Naive Bayes, KNN - 11기 유기윤 file 유기윤 2019.02.02 197
136 투빅스 10기&11기 2주차 SVM, Naive Bayes, KNN - 11기 김대웅 file 김대웅 2019.01.31 226
135 투빅스 10기&11기 1주차 Algorithm - 11기 한재연 1 file 한재연 2019.01.31 257
134 투빅스 10기&11기 1주차 Algorithm - 11기 권혜민 file 권혜민 2019.01.31 196
133 투빅스 10&11기 1주차 Linear Regression - 11기 유기윤 file 유기윤 2019.01.24 303
132 투빅스 10&11기 1주차 Regression - 11기 강수민 file 수민 2019.01.24 283
131 투빅스 10&11기 1주차 Logistic Regression - 11기 김대웅 file 김대웅 2019.01.23 271
130 투빅스 9&10기 8주차 CNN - 10기 장유영 장유영 2018.09.20 2020
Board Pagination ‹ Prev 1 2 3 4 5 6 7 ... 8 Next ›
/ 8

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소

Designed by sketchbooks.co.kr / sketchbook5 board skin

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5