반응형
python에서 신경망 xor 연산 학습 샘플을 만들어 보았다.
# neural network xor
import math
import random
from datetime import datetime
import matplotlib.pyplot as plt
import numpy as np
# 네트워크의 학습 속도
LEARNING_RATE = 1.414213562
MOMENTUM = 0.25
# 훈련 데이타
TRAINING_DATA = [
[1.0, 0.0],
[1.0, 1.0],
[0.0, 1.0],
[0.0, 0.0]
]
# 타겟 값
TARGET_DATA = [
1.0,
0.0,
1.0,
0.0
]
MAX_LAYERS = 4
MAX_WEIGHTS = 9
MAX_EPOCHS = 10000
# 가중치
weights = [0. for i in range(MAX_WEIGHTS)] # [0] * 9
gradients = [0. for i in range(MAX_WEIGHTS)] # [0] * 9
error = [0. for i in range(MAX_LAYERS)] # [0] * 4 #error = np.zeros(4, dtype='f')
update_weights = [0. for i in range(MAX_WEIGHTS)] # [0] * 9
prev_weight_update = [0. for i in range(MAX_WEIGHTS)] # [0] * 9
rmse_array_error = [0. for i in range(MAX_EPOCHS)] # [0] * 10000 # 각 세대별 RMSE 에러 값
bias1 = 1.0
bias2 = 1.0
bias3 = 1.0
h1 = 0.0
h2 = 0.0
output_neuron = 0.0
derivative_O1 = 0.0
derivative_h1 = 0.0
derivative_h2 = 0.0
sum_output = 0.0
sum_h1 = 0.0
sum_h2 = 0.0
# sum_output
graph_sum_output = [[0. for i in range(MAX_EPOCHS)] for j in range(MAX_LAYERS)]
# 그래프 출력을 위한 버퍼
graph_derivative_O1 = [[0. for i in range(MAX_EPOCHS)] for j in range(MAX_LAYERS)]
graph_derivative_h1 = [[0. for i in range(MAX_EPOCHS)] for j in range(MAX_LAYERS)]
graph_derivative_h2 = [[0. for i in range(MAX_EPOCHS)] for j in range(MAX_LAYERS)]
'''
bias1 bias3
| |
w4 w8
| |
input1 --w0 --- h1 |
\ / \ |
\ / w6 |
w1 / \ |
\/ output
/\ /
w2 \ w7
/ \ /
/ \ /
input2 --w3----- h2
|
w5
|
bias2
'''
def sigmoid_function(x) :
sigmoid = 1.0 / ( 1.0 + np.exp(-x) )
return sigmoid
# 변수 초기화
def initialize():
global prev_weight_update, update_weights, gradients, error, rmse_array_error
for i in range(MAX_WEIGHTS):
prev_weight_update[i] = 0.0
update_weights[i] = 0.0
gradients[i] = 0.0
for i in range(MAX_LAYERS):
error[i] = 0.0
for i in range(MAX_EPOCHS):
rmse_array_error[i] = 0.0
def generate_weights() :
global weights
for i in range(MAX_WEIGHTS):
weights[i] = random.uniform(-1.0, 1.0)
print("weight[",i,"] = ", weights[i])
def train_neural_net() :
global rmse_array_error, error
# 세대(학습 횟수)
epoch = 0
while epoch < MAX_EPOCHS :
for i in range(MAX_LAYERS):
calc_hidden_layers(i)
calc_output_neuron()
graph_sum_output[i][epoch] = sum_output
calc_error(i)
calc_derivatives(i)
graph_derivative_O1[i][epoch] = derivative_O1
graph_derivative_h1[i][epoch] = derivative_h1
graph_derivative_h2[i][epoch] = derivative_h2
calc_gradients(i)
calc_updates()
# RMSE 에러 값
sum = math.pow(error[0], 2) + math.pow(error[1], 2) + math.pow(error[2], 2) + math.pow(error[3], 2)
rmse_error = math.sqrt( sum / MAX_LAYERS )
print("RMSE error: ", rmse_error)
rmse_array_error[epoch] = rmse_error
# 세대
epoch = epoch + 1
print("epoch:", epoch)
# 예외 처리 - 처음부터 다시
if epoch > 4000 and rmse_error > 0.3:
epoch = 0
initialize()
generate_weights()
def calc_hidden_layers(x):
global sum_h1, sum_h2, h1, h2, weights, bias1, bias2
sum_h1 = (TRAINING_DATA[x][0] * weights[0]) + (TRAINING_DATA[x][1] * weights[2]) + (bias1 * weights[4])
sum_h2 = (TRAINING_DATA[x][0] * weights[1]) + (TRAINING_DATA[x][1] * weights[3]) + (bias2 * weights[5])
h1 = sigmoid_function(sum_h1)
h2 = sigmoid_function(sum_h2)
def calc_output_neuron():
global sum_output, h1, h2, weights, bias3, output_neuron
sum_output = (h1 * weights[6]) + (h2 * weights[7]) + (bias3 * weights[8])
output_neuron = sigmoid_function(sum_output)
def calc_error(x):
global error, output_neuron
error[x] = output_neuron - TARGET_DATA[x]
def calc_derivatives(x):
global derivative_O1, derivative_h1, derivative_h2, sum_h1, sum_h2, weights, sum_output, error
derivative_O1 = -error[x] * ( np.exp(sum_output) / math.pow((1 + np.exp(sum_output)), 2) )
derivative_h1 = ( np.exp(sum_h1) / math.pow((1 + np.exp(sum_h1)), 2) ) * weights[6] * derivative_O1
derivative_h2 = ( np.exp(sum_h2) / math.pow((1 + np.exp(sum_h2)), 2) ) * weights[7] * derivative_O1
def calc_gradients(x):
global gradients, derivative_O1, derivative_h1, derivative_h2, h1, h2, bias1, bias2,bias3
gradients[0] = sigmoid_function(TRAINING_DATA[x][0]) * derivative_h1
gradients[1] = sigmoid_function(TRAINING_DATA[x][0]) * derivative_h2
gradients[2] = sigmoid_function(TRAINING_DATA[x][1]) * derivative_h1
gradients[3] = sigmoid_function(TRAINING_DATA[x][1]) * derivative_h2
gradients[4] = sigmoid_function(bias1) * derivative_h1
gradients[5] = sigmoid_function(bias2) * derivative_h2
gradients[6] = h1 * derivative_O1
gradients[7] = h2 * derivative_O1
gradients[8] = sigmoid_function(bias3) * derivative_O1
def calc_updates():
global update_weights, gradients, prev_weight_update
for i in range(MAX_WEIGHTS):
update_weights[i] = (LEARNING_RATE * gradients[i]) + (MOMENTUM * prev_weight_update[i])
prev_weight_update[i] = update_weights[i]
weights[i] = weights[i] + update_weights[i]
def save_data():
global rmse_array_error, weights
with open('errorData1.txt', 'w', encoding='utf-8') as f:
for i in range(MAX_EPOCHS):
line = '%d %s' % (i, rmse_array_error[i])
f.write(line) # f.write('\n'.join(lines))
f.write('\n') # f.writelines('\n')
with open('weight_data1.txt', 'w', encoding='utf-8') as f:
for i in range(MAX_WEIGHTS):
line = '%d %s' % (i, weights[i])
f.write(line)
f.write('\n')
def start_input():
global weights, sum_h1, sum_h2, h1, h2, bias1, bias2, bias3, sum_output, output_neuron
choice = 'y'
while True:
if choice == 'Y' or choice == 'y':
data1 = input("enter data 1: ")
if data1.isnumeric() == False :
continue
data2 = input("enter data 2: ")
if data2.isnumeric() == False :
continue
sum_h1 = (float(data1) * weights[0]) + (float(data2) * weights[2]) + (bias1 * weights[4])
sum_h2 = (float(data1) * weights[1]) + (float(data2) * weights[3]) + (bias2 * weights[5])
h1 = sigmoid_function(sum_h1)
h2 = sigmoid_function(sum_h2)
sum_output = (h1 * weights[6]) + (h2 * weights[7]) + (bias3 * weights[8])
output_neuron = sigmoid_function(sum_output)
print('output = ', output_neuron)
choice = input('Again? (y/n) : ')
else:
print('exit')
break
initialize()
generate_weights()
train_neural_net()
save_data()
start_input()
# ===============================================================
# sigmoid
x = np.arange( -10.0, 10.0, 0.1)
y = 1.0 / (1.0 + np.exp(-x))
plt.subplot(2, 3, 1)
plt.plot(x,y, 'r-')#plt.plot(x1, y1, 'r--', x2, y2, 'bs', x3, y3, 'g^')
plt.title('sigmoid')# 1.0 / (1.0 + np.exp(-x))
plt.axis([-10.0, 10.0, 0, 1.0])# xmin, xmax, ymin, ymax
plt.xlabel('x')
plt.ylabel('y')
# sum_output
x2 = np.arange( 0.0, 10000.0, 1.0)
y2 = graph_sum_output[0]
plt.subplot(2, 3, 2)
plt.plot(x2,y2, 'r-')#plt.plot(x1, y1, 'r--', x2, y2, 'bs', x3, y3, 'g^')
plt.title('sum_output')
plt.axis([0.0, 10000.0, -0.2, 5.0])# xmin, xmax, ymin, ymax
plt.xlabel('epoch')
plt.ylabel('sum_output')
# rmse_array_error
x2 = np.arange( 0.0, 10000.0, 1.0)
y2 = rmse_array_error
plt.subplot(2, 3, 3)
plt.plot(x2,y2, 'r-')#plt.plot(x1, y1, 'r--', x2, y2, 'bs', x3, y3, 'g^')
plt.title('RMSE Error')
plt.axis([0.0, 10000.0, 0.0, 1.0])# xmin, xmax, ymin, ymax
plt.xlabel('epoch')
plt.ylabel('RMSE error')
# derivative_O1
x3 = np.arange( 0.0, 10000.0, 1.0)
y3 = graph_derivative_O1[0]
plt.subplot(2, 3, 4)
plt.plot(x3,y3, 'r-')#plt.plot(x1, y1, 'r--', x2, y2, 'bs', x3, y3, 'g^')
plt.title('derivative_O1')
plt.axis([0.0, 10000.0, -0.05, 0.15])# xmin, xmax, ymin, ymax
plt.xlabel('epoch')
plt.ylabel('derivative_O1')
# derivative_h1
x4 = np.arange( 0.0, 10000.0, 1.0)
y4 = graph_derivative_h1[0]
plt.subplot(2, 3, 5)
plt.plot(x4,y4, 'r-')#plt.plot(x1, y1, 'r--', x2, y2, 'bs', x3, y3, 'g^')
plt.title('derivative_h1')
plt.axis([0.0, 10000.0, -0.05, 0.15])# xmin, xmax, ymin, ymax
plt.xlabel('epoch')
plt.ylabel('derivative_h1')
# derivative_h2
x5 = np.arange( 0.0, 10000.0, 1.0)
y5 = graph_derivative_h2[0]
plt.subplot(2, 3, 6)
plt.plot(x5,y5, 'r-')#plt.plot(x1, y1, 'r--', x2, y2, 'bs', x3, y3, 'g^')
plt.title('derivative_h2')
plt.axis([0.0, 10000.0, -0.05,0.15])# xmin, xmax, ymin, ymax
plt.xlabel('epoch')
plt.ylabel('derivative_h2')
fig1 = plt.gcf()
plt.tight_layout()
plt.show()
plt.draw()
fig1.savefig('nn_xor_derivative.png', dpi=200, facecolor='#eeeeee', edgecolor='blue')
결과 그래프는 다음과 같다.
#----------------------------------------------------------------
weight_data1.txt
0 -4.749828824761969
1 -3.5287652884908254
2 -4.747508485076842
3 -3.5276048615858935
4 1.816578868741784
5 5.375092217625854
6 -13.742230835984616
7 13.712746773928748
8 -6.530714643755955
#----------------------------------------------------------------
errorData1.txt
0 0.5424391889837473
1 0.5331220459189032
2 0.5304319567906218
10 0.5274519675428608
100 0.5198658296518869
200 0.5155776076419263
300 0.5046587144670703
400 0.4791696883760997
1000 0.09849463249517668
2000 0.03296842320700676
3000 0.02307589090605272
9999 0.010292985691909057
반응형
'개발 > AI,ML,ALGORITHM' 카테고리의 다른 글
MNIST 데이터셋을 이미지 파일로 복원 (0) | 2023.07.19 |
---|---|
MNIST 데이터셋 다운로드 (0) | 2023.07.19 |
2D 충돌처리 (0) | 2020.12.12 |
Generic algorithm (0) | 2020.05.19 |
neural network (0) | 2020.05.19 |