Created
June 2, 2024 13:48
-
-
Save jinto/abbca44b018acf2bf088395205a8ee53 to your computer and use it in GitHub Desktop.
오차역전파_XOR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
# 활성화 함수와 그 도함수 | |
def sigmoid(x): | |
return 1 / (1 + np.exp(-x)) | |
def sigmoid_derivative(x): | |
return x * (1 - x) | |
# 학습 데이터 (하나의 샘플) | |
inputs = np.array([[0, 1]]) # 하나의 샘플로 수정 | |
labels = np.array([[0.2]]) | |
# 신경망의 구조 | |
input_nodes = inputs.shape[1] # == 2 : 입력값들은 2 차원 벡터임. | |
hidden_nodes = 2 # 은닉층에도 노드 2개를 둔다. | |
output_nodes = 1 # 출력층에는 노드 1개만 둔다. | |
# 가중치와 바이어스 초기화 | |
np.random.seed(42) | |
# 손으로 계산해보려고 쉬운 숫자들을 넣어본다. | |
hidden_weights = np.array([[0.1, 0.2], [0.3, 0.4]]) | |
hidden_bias = np.array([[0.5, 0.6]]) | |
output_weights = np.array([[0.1], [0.2]]) | |
output_bias = np.array([[0.9]]) | |
# 학습률 | |
lr = 0.1 | |
epochs = 100 | |
# 역전파 알고리즘 | |
for epoch in range(epochs): | |
# 순방향 전파 | |
hidden_input = np.dot(inputs, hidden_weights) + hidden_bias | |
hidden_nodes = sigmoid(hidden_input) | |
# 입력층 입력값 [[0 1]] | |
# 은닉층 가중치 [[0.1 0.2] | |
# [0.3 0.4]] | |
# 은닉층 편향값 [[0.5 0.6]] | |
# 은닉층 입력값 [[0.8 1. ]] | |
# 은닉층 결과값 [[0.68 0.73]] | |
output_inputs = np.dot(hidden_nodes, output_weights) + output_bias | |
output_nodes = sigmoid(output_inputs) | |
# 출력층 입력값 [[1.68544492]] | |
#print(output_weights) | |
# 출력층 가중치 [[0.1], [0.2]] | |
# 출력층 편향값 [[0.9]] | |
# 출력층 결과값 [[0.84362418]] | |
# ======== 오차 계산 =========== | |
error = labels - output_nodes | |
# 출력층 오차값 [[-0.55309898]] | |
d_output_weight = error * sigmoid_derivative(output_nodes) | |
# 출력층 조정값 [[-0.10284373]] | |
error_hidden = d_output_weight.dot(output_weights.T) | |
# 은닉층 오차값 [[-0.01028437 -0.02056875]] | |
d_hidden_weight = error_hidden * sigmoid_derivative(hidden_nodes) | |
# 은닉층 조정값 [[-0.00219993 -0.00404406]] | |
# ====== 가중치 및 바이어스 업데이트 ========== | |
output_weights += hidden_nodes.T.dot(d_output_weight) * lr | |
output_bias += np.sum(d_output_weight, axis=0, keepdims=True) * lr | |
hidden_weights += inputs.T.dot(d_hidden_weight) * lr | |
hidden_bias += np.sum(d_hidden_weight, axis=0, keepdims=True) * lr | |
# 조정된 출력층 가중치 [[0.09290405] [0.19248152]] | |
# 조정된 출력층 편향값 [[0.88971563]] | |
# 조정된 은닉층 가중치 [[0.1 0.2 ][0.29978001 0.39959559]] | |
# 조정된 은닉층 편향값 [[0.49978001 0.59959559]] | |
# 학습 결과 출력 | |
print("\n====") | |
print("은닉층 가중치:\n", hidden_weights) | |
print("은닉층 편향:\n", hidden_bias) | |
print("출력층 가중치:\n", output_weights) | |
print("출력층 편향:\n", output_bias) | |
print("\n모델 출력:\n", output_nodes) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
# 활성화 함수와 그 도함수 | |
def sigmoid(x): | |
return 1 / (1 + np.exp(-x)) | |
def sigmoid_derivative(x): | |
return x * (1 - x) | |
# 학습 데이터 (XOR 문제) | |
inputs = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) | |
outputs = np.array([[0], [1], [1], [0]]) | |
# 신경망의 구조 | |
input_nodes = inputs.shape[1] # == 2 : 입력값들은 2 차원 벡터임. | |
hidden_nodes = 2 # 은닉층에도 노드 2개를 둔다. | |
output_nodes = 1 # 출력층에는 노드 1개만 둔다. 0,1,1,0 처럼 값이 하나만 나오면 된다. | |
# 가중치와 바이어스 초기화 | |
np.random.seed(42) | |
#hidden_weights = np.random.uniform(size=(input_nodes, hidden_nodes)) | |
hidden_weights = np.array([[0.1, 0.2], [0.3, 0.4]]) | |
#hidden_bias = np.random.uniform(size=(1, hidden_nodes)) | |
hidden_bias = np.array([[0.5, 0.6]]) | |
output_weights = np.random.uniform(size=(hidden_nodes, output_nodes)) | |
output_bias = np.random.uniform(size=(1, output_nodes)) | |
# 학습률 | |
learning_rate = 0.1 | |
epochs = 10000 | |
# 역전파 알고리즘 | |
for epoch in range(epochs): | |
# 순방향 전파 | |
#print("입력층 입력값\n", inputs) | |
#print("은닉층 가중치\n", hidden_weights) | |
#print("은닉층 편향", hidden_bias) | |
hidden_input = np.dot(inputs, hidden_weights) + hidden_bias | |
# 입력층 입력값은 | |
# [[0 0] | |
# [0 1] | |
# [1 0] | |
# [1 1]] | |
# 이다. | |
# 은닉층의 가중치가 | |
# [[0.1, 0.2], | |
# [0.3, 0.4]] 이라면 | |
# 가충치 곱 결과는은 | |
# [[0. 0. ] | |
# [0.3 0.4] | |
# [0.1 0.2] | |
# [0.4 0.6]] | |
# 편향까지 더하면 [[0.5, 0.6]] 더하면 | |
# [[0.5 0.6] | |
# [0.8 1. ] | |
# [0.6 0.8] | |
# [0.9 1.2]] | |
# 가 된다. | |
# 즉, 입력층의 벡터들을 은닉층의 가중치들과 행렬곱했다. | |
# 행렬 곱 : https://ko.wikipedia.org/wiki/%ED%96%89%EB%A0%AC_%EA%B3%B1%EC%85%88 | |
#print("은닉층 입력값\n", hidden_input) | |
hidden_nodes = sigmoid(hidden_input) | |
#print("은닉층 결과값\n", hidden_nodes) | |
prediction_inputs = np.dot(hidden_nodes, output_weights) + output_bias | |
#print("출력층 입력값\n", prediction_inputs) | |
predictions = sigmoid(prediction_inputs) | |
#print("출력층 결과값\n", prediction_inputs) | |
# 오차 계산 | |
error = outputs - predictions | |
# 역방향 전파 | |
d_prediction = error * sigmoid_derivative(predictions) | |
error_hidden = d_prediction.dot(output_weights.T) | |
d_hidden = error_hidden * sigmoid_derivative(hidden_nodes) | |
# 가중치 및 바이어스 업데이트 | |
output_weights += hidden_nodes.T.dot(d_prediction) * learning_rate | |
output_bias += np.sum(d_prediction, axis=0, keepdims=True) * learning_rate | |
hidden_weights += inputs.T.dot(d_hidden) * learning_rate | |
hidden_bias += np.sum(d_hidden, axis=0, keepdims=True) * learning_rate | |
#print("\nPredicted output:\n", predicted_output[0]) | |
# 학습 결과 출력 | |
print("\n====") | |
print("은닉층 가중치:\n", hidden_weights) | |
print("은닉층 편향:\n", hidden_bias) | |
print("출력층 가충치:\n", output_weights) | |
print("출력층 편향:\n", output_bias) | |
print("\n모델 출력:\n", predictions) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment