def softmax(a) : c = np.max(a) exp_a = np.exp(a-c) sum_exp = np.sum(exp_a) y = exp_a / sum_exp return y
def sigmoid(a) : return 1/(1+np.exp(a))
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 # MNIST 데이터 세트에서 훈련 이미지 6만장, 시험 이미지 1만장을 가져오는 함수 # flatten : 입력 이미지를 평탄화한다. 즉, 28x28 크기의 2차원 배열 이미지를 784의 1차원 배열로 만든다. # normalize : 입력 이미지를 정규화한다. 즉, 0부터 255사이의 이미지 픽셀 값을 0부터 1까지로 만든다. # one_hot_label : 레이블을 원-핫-엔코딩한다. 즉, 판단된 라벨의 확률 중 가장 높은 값만을 1로 하고 나머지는 0으로 한다.
def init_network() : with open("sample_weight.pkl", 'rb') as f: network = pickle.load(f)
return network # 'sample_weight.pkl' 파일에는 학습된 가중치 매개변수(가중치, 편향)가 dictionary 타입으로 저장되어있다. # pickle은 파이썬에서 지원하는 모듈로서, 텍스트가 아닌 자료형들을 저장할 수 있도록 한다. # 저장되어 있는 pickle 파일을 불러오면 실행 당시의 객체를 즉시 복원할 수 있어, 데이터를 빠르게 준비할 수 있다.
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 # 3층 신경망의 가중치(weight)와 편향(bias)를 받아온다. # 각 층의 가중치와 편향으로 뉴런(노드)의 출력을 계산하는 함수
x, t = get_data() network = init_network() # MNIST 데이터 세트를 얻고, 가중치와 편향을 가진 dictionary 타입의 네트워크를 생성한다.
accuracy_cnt = 0 for i in range(len(x)) : y = predict(network, x[i]) # 훈련 데이터의 크기만큼 반복 구문을 수행하면서, 이미지 데이터를 1장씩 꺼내어 3층 신경망을 통과시켜 출력 값을 계산한다.
p = np.argmax(y) # 출력 y는 0부터 9까지의 숫자에 해당하는 확률을 가진 배열이다. # np.argmax(y)는 배열에서 가장 큰 원소 값이 있는 인덱스를 반환한다. 즉, 가장 높은 확률이 있는 곳의 순서를 가져온다.
if p == t[i] : accuracy_cnt += 1 # 프로그램이 분류한 라벨과 실제 라벨이 같은지 검사한다.
print("정확도 : " + str(float(accuracy_cnt)/len(x)))
#-----------------------------------------------------------------------------------------------------------------------#
batch_size = 100 # 배치 크기, 100장의 이미지를 한꺼번에 처리한다는 의미 accuracy_batch = 0
for i in range(0, len(x), batch_size) : # 0부터 x의 크기-1 까지 배치 크기 간격으로 반복문을 수행한다. (i = 0, 100, 200 ...)
x_batch = x[i:i+batch_size] # x에는 이미지 데이터가 저장되어 있다. x의 리스트에서 이미지를 반복문의 순서대로 배치 크기만큼 가져온다. # (0~99, 100~199, 200~299 ...)
y_batch = predict(network, x_batch) # 배치 크기만큼 묶인 이미지를 3층 신경망에 한꺼번에 통과시켜 출력 값을 계산한다. # y_batch는 10개의 라벨에 대한 각각의 확률을 가진 100개의 리스트로 구성된다. 즉, y_batch의 크기는 (100x10)이다.
p = np.argmax(y_batch, axis = 1) # np.argmax는 해당 리스트에서 가장 높은 값의 인덱스, 순서의 번호를 반환한다. # axis=1은 (100x10) 크기의 y_batch에서 1차원을 구성하는 원소에서 최댓값의 인덱스를 찾도록 한것이다. # 0차원 : 각 라벨 별 이미지의 확률(100), 1차원 : 각 이미지 별 라벨의 확률(10)
accuracy_batch += np.sum(p == t[i:i+batch_size]) # 실제 라벨과 분류 라벨이 같은지 검사한다. 배열로 반환되기 때문에 모두 더하여 정확도를 계산한다.
print("정확도 : " + str(float(accuracy_batch)/len(x)))
|