인공지능
AI 필체인식(Mnist) Back propagation 구현
KyooDong
2020. 6. 7. 15:10
728x90
2020/06/06 - [AI] - AI Back propagation(오차역전파)
AI Back propagation(오차역전파)
2020/06/03 - [AI] - 딥러닝 MNIST 필기체 인식 딥러닝 MNIST 필기체 인식 Mnist 는 딥러닝 공부를 할 때 기초적이면서도 흥미로운 연습 문제에요 Training Data set(csv) 과 Test Data set(csv) 파일 링크입니다...
bubble-dev.tistory.com
이 전 글에서 오차역전파 공식을 유도하는 법에 대해서 알아봤습니다.
아래 코드의 수식들은 이 전글에서 유도된 공식으로 궁금하신 분들은 보고 오시면 좋을것같네요
코드
import numpy as np
# 데이터 로딩
test_data = np.loadtxt('mnist_test.csv', delimiter=',', dtype=np.float32)
train_data = np.loadtxt('mnist_train.csv', delimiter=',', dtype=np.float32)
# 시그모이드
def sigmoid(x):
return 1 / (1 + np.exp(-x))
class NeuralNetwork:
def __init__(self, input_nodes, hidden_nodes, output_nodes, learning_rate):
self.__input_nodes = input_nodes
self.__hidden_nodes = hidden_nodes
self.__output_nodes = output_nodes
self.__learning_rate = learning_rate
# 임의의 가중치 및 바이어스 할당
self.__W2 = np.random.randn(input_nodes, hidden_nodes) / np.sqrt(input_nodes / 2)
self.__b2 = np.random.rand(hidden_nodes)
self.__W3 = np.random.randn(hidden_nodes, output_nodes) / np.sqrt(hidden_nodes / 2)
self.__b3 = np.random.rand(output_nodes)
# 출력층
self.__A3 = np.zeros([1, output_nodes])
self.__Z3 = np.zeros([1, output_nodes])
# 은닉층
self.__A2 = np.zeros([1, hidden_nodes])
self.__Z2 = np.zeros([1, hidden_nodes])
# 입력층
self.__A1 = np.zeros([1, input_nodes])
self.__Z1 = np.zeros([1, input_nodes])
self.loss_val = self.feed_forward
def feed_forward(self):
delta = 1e-7
# 입력층 출력값 계산
self.__A1 = self.__input_data
self.__Z1 = self.__input_data
# 은닉층 출력값 계산
self.__Z2 = np.dot(self.__A1, self.__W2) + self.__b2
self.__A2 = sigmoid(self.__Z2)
# 출력층 출력값 계산
self.__Z3 = np.dot(self.__A2, self.__W3) + self.__b3
self.__A3 = sigmoid(self.__Z3)
# 크로스 엔트로피
return -np.sum(self.__target_data * np.log(self.__A3 + delta) + (1 - self.__target_data) * np.log((1 - self.__A3) + delta))
def train(self, input_data, target_data):
self.__input_data = input_data
self.__target_data = target_data
# 층별 출력값 계산
self.feed_forward()
# 출력값과 loss 를 이용한 W, b 갱신
loss3 = (self.__A3 - self.__target_data) * (self.__A3 * (1 - self.__A3))
self.__W3 = self.__W3 - self.__learning_rate * np.dot(self.__A2.T, loss3)
self.__b3 = self.__b3 - self.__learning_rate * loss3
loss2 = np.dot(loss3, self.__W3.T) * (self.__A2 * (1 - self.__A2))
self.__W2 = self.__W2 - self.__learning_rate * np.dot(self.__A1.T, loss2)
self.__b2 = self.__b2 - self.__learning_rate * loss2
def predict(self, input_data):
Z2 = np.dot(input_data, self.__W2) + self.__b2
A2 = sigmoid(Z2)
Z3 = np.dot(A2, self.__W3) + self.__b3
A3 = sigmoid(Z3)
return np.argmax(A3)
def accuracy(self, test_data):
count = 0
for i in range(len(test_data)):
label = int(test_data[i, 0])
data = ((test_data[i, 1:] / 255.0) * 0.99) + 0.01
predicted_data = self.predict(np.array(data, ndmin=2))
if label == predicted_data:
count += 1
print("Accuracy = ", 100 * (count / len(test_data)))
nn = NeuralNetwork(784, 100, 10, 0.3)
# 반복횟수
epoches = 5
for e in range(epoches):
for step in range(60000):
label = int(train_data[step, 0])
# Normalization
data = ((train_data[step, 1:] / 255.0) * 0.99) + 0.01
target_data = np.zeros(10) + 0.01
target_data[label] = 0.99
nn.train(np.array(data, ndmin=2), np.array(target_data, ndmin=2))
if step % 400 == 0:
print('step = ', step, ', errorval = ', nn.loss_val())
nn.accuracy(test_data)
결과
반복(epochs) 1회차
반복(epochs) 5회차