Skip to content

Instantly share code, notes, and snippets.

@jinto
Created June 2, 2024 13:48
Show Gist options
  • Save jinto/abbca44b018acf2bf088395205a8ee53 to your computer and use it in GitHub Desktop.
Save jinto/abbca44b018acf2bf088395205a8ee53 to your computer and use it in GitHub Desktop.
오차역전파_XOR
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)
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