• 아래와 같이 수치미분으로 딥러닝을 구현하면 이해하긴 쉽지만 많은 연산시간이 필요함 => Back Propagation (MNIST 2탄)
  • 만약, 정확도를 더 높이고 싶다면, 은닉층의 수를 늘리거나 CNN을 사용해야 함

 

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
 
import numpy as np
from keras.datasets import mnist
from keras.utils.np_utils import to_categorical
from datetime import datetime
 
# MNIST 데이터 불러오기
(x_train, t_train), (x_test, t_test) = mnist.load_data()
 
x_train = np.reshape(x_train, (60000-1))
x_test = np.reshape(x_test, (10000-1))
 
x_train = x_train/255.0
x_test = x_test/255.0
 
t_train = to_categorical(t_train)
t_test = to_categorical(t_test)
 
print()
 
# csv 파일인 겨우
# x_train = np.loadtxt("파일경로", delimiter=',', dtype=np.float32)
 
 
def sigmoid(x):
    return 1 / (1 + np.exp(-x))
 
 
def numerical_derivative(func, x):
    delta = 1e-4
    grad = np.zeros_like(x)
 
    it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
 
    while not it.finished:
        idx = it.multi_index
 
        temp = x[idx]
        x[idx] = float(temp) + delta
        f1 = func(x)
 
        x[idx] = float(temp) - delta
        f2 = func(x)
 
        grad[idx] = (f1 - f2) / (2 * delta)
 
        x[idx] = temp
        it.iternext()
 
    return grad
 
 
class NN:
 
    def __init__(self, input_nodes, hidden_nodes, output_nodes):
 
        self.input_nodes = input_nodes
        self.hidden_nodes = hidden_nodes
        self.output_nodes = output_nodes
 
        # np.random.rand() 이걸 써주면 학습이 안된다. 이유는 잘 모르겠다.
        # Xavier/He 가중치 초기화 기법 적용
        self.W1 = np.random.randn(self.input_nodes, self.hidden_nodes) / np.sqrt(self.input_nodes/2)
        self.b1 = np.random.rand(self.hidden_nodes)
 
        self.W2 = np.random.randn(self.hidden_nodes, self.output_nodes) / np.sqrt(self.hidden_nodes/2)
        self.b2 = np.random.rand(self.output_nodes)
 
        self.learning_rate = 1e-4
 
    def feed_forward(self):
        delta = 1e-7  # log가 무한대로 발산하는 것을 막아준다
 
        z1 = np.dot(self.input_data, self.W1) + self.b1
        a1 = sigmoid(z1)
 
        z2 = np.dot(a1, self.W2) + self.b2
        y = sigmoid(z2)
 
        return -np.sum(self.target_data * np.log(y + delta) + (1 - self.target_data) * np.log((1 - y) + delta))
 
    def train(self, x_data, t_data):
 
        self.input_data = x_data
        self.target_data = t_data
 
        f = lambda x: self.feed_forward()
 
        self.W1 -= self.learning_rate * numerical_derivative(f, self.W1)
        self.b1 -= self.learning_rate * numerical_derivative(f, self.b1)
        self.W2 -= self.learning_rate * numerical_derivative(f, self.W2)
        self.b2 -= self.learning_rate * numerical_derivative(f, self.b2)
 
    def loss_eval(self):
        delta = 1e-7
 
        z1 = np.dot(self.input_data, self.W1) + self.b1
        a1 = sigmoid(z1)
 
        z2 = np.dot(a1, self.W2) + self.b2
        y = sigmoid(z2)
 
        return -np.sum(self.target_data * np.log(y + delta) + (1 - self.target_data) * np.log((1 - y) + delta))
 
    def predict(self, input_data):
 
        z1 = np.dot(input_data, self.W1) + self.b1
        a1 = sigmoid(z1)
 
        z2 = np.dot(a1, self.W2) + self.b2
        y = sigmoid(z2)
 
        return np.argmax(y)
 
    def accuracy(self, input_x, input_t):
 
        right_list = []
        wrong_list = []
 
        for idx in range(len(input_x)):
            pred = self.predict(input_x[idx])
 
            if pred == np.argmax(input_t[idx]):
                right_list.append(idx)
            else:
                wrong_list.append(idx)
 
        print("accuracy = "100*len(right_list)/len(input_x), "%")
 
 
# 모델 훈련
model = NN(78410010)
 
start_time = datetime.now()
 
for step in range(1001):
 
    idx = np.random.randint(0len(x_train)-1)  #총 6만개의 데이터중 임의로 2만개 선택
 
    model.train(x_train[idx], t_train[idx])
 
    if idx % 100 == 0:
        print("step = ", step, ", error = ", model.loss_eval())
 
        end_time = datetime.now()
        print("elapsed time = ", end_time - start_time)
        start_time = datetime.now()
 
 
# 모델 테스트
model.accuracy(x_test, t_test)
 
 
 
 
 
cs

 

위의 소스코드를 실행시키면 엄청난 연산시간이 소요된다. (반복횟수를 높이면, 정확도는 90% 이상으로 향상됨)

 

 

반응형

'머신러닝_딥러닝 > Tensorflow + Keras' 카테고리의 다른 글

(Tensorflow 2.x) Regression 1탄  (0) 2021.10.23
MNIST 2탄 (Back Propagation)  (0) 2021.10.23
XOR 문제 (딥러닝으로 해결)  (0) 2021.10.23
XOR 문제  (0) 2021.10.23
로지스틱 회귀 (Logistic Regression)  (0) 2021.10.23

+ Recent posts