인공지능 AI

[딥러닝/머신러닝]논리게이트 XOR문제(XOR problem)

Logistic Regression(미분)을 이용했을때 (추후에 Logistic Regression 게시글도 게시예정)

XOR 게이트를 구현이 불가능하다.

AND, OR, NAND게이트는 1개의 분류 시스템만으로도 구현가능하지만

XOR게이트는 여러개의 분류시스템을 조합해서 구현해야한다.

그래서 미분을 사용했던 머신러닝이 아닌 (머신러닝의 다른 한 분야인) 딥러닝을 이용한다.

 

딥러닝의 핵심 아이디어가 여러 분류 시스템을 조합하여 데이터 특성과 상관관계를 분석하는 것이다.

 

기본적으로 우리가 알고 있는 AND OR NAND XOR게이트의 정답 데이터는 

AND: 0001

OR:0111

NAND:1110

XOR:0110

이다.

입력데이터는 각각 ([0,0],[0,1],[1,0],[1,1])이다.

(입력 데이터는 x1,x2 2개, 출력데이터는 0또는 1의 논리테이블을 가진다.)

이러한 트레이닝(학습)데이터를 분류 알고리즘(머신러닝)을 적용해보도록 하겠다.

논리게이트는 손실함수로 cross-entropy이용하여 선형회귀값계산하는 Regression과 sigmoid함수값 출력하는 classification으로 구성된 시스템으로 나타낼 수 있다.([머신러닝]Linear Regression/Classification 참조)

 

 

외부 함수 sigmoid(), dericative() 

import numpy as np

#외부함수(external function)

def sigmoid(x)L #0또는1을 출력하기 위한 sigmoid함수
  return 1/(1+np.exp(-x)) #입력 x에 대해서 결과가 1이 나올 확률을 의미
  
def derivative(f,input_data): #미분함수(머신러닝 미분파트 게시글 참조)
  delta_x=1e-4
  it=np.nditer(input_data, flags=['multi_index'])
  ret=np.zeros_like(input_data)
  
  while not it.finished:
    idx=it.multi_index
    tmp=input_data[idx]
    
    input_data[idx]=float(tmp)+delta_x
    fx1=f(input_data)
    
    input_data[idx]=float(tmp)-delta_x
    fx2=f(input_data)
    ret[idx]=(fx1-fx2)/(2*delta_x)
    
    input_data[idx]=tmp
    it.iternext()
    
  return ret

논리게이트 클래스 정의 (코드)

#논리게이트(Logic Gate)클래스

Class LogicGate:
  def __init__(self,gate_name,xdata,tdata):
  	#xdata,tdata,W,b 초기화
    self.name=gate_name
    self.xdata=xdata.reshape(4,2) #입력데이터 초기화_(0,0)(0,1)(1,0)(1,1) 4개 경우의 2개입력데이터
    self.tdata=tdata.reshape(4,1) #정답데이터 초기화_4개 경우의 1개데이터(0 or 1)
    self.W=np.random.rand(2,1) #가중치W 초기화(weight:x1 x2 2개)
    self.b=np.random.rand(1) #바이어스 b 초기화 
    self.learning_rate=1e-2 #학습률 Learning Rate 초기화 (10)
    
  def loss_func(self): #손실함수(cross_entropy)
    delta=1e-7 #log 무한대 발산 방지
    z=np.dot(self.xdata, self.W)+self.b
    #각각의 입력에 대하여 결과가 1이 나올 확률을 구함
    y=sigmoid(z)
    #정답이 1일때는 시그모이드 그대로 활용
    #정답이 0일때는 1이 나올확률을 역전시켜 0이 나올 확률을 만들어 활용 
    return -np.sum(self.tdata*np.log(y+delta)+(1-self.tdata)*np.log((1-y)+delta))
    
  def loss_val(self): #손실함수값 계산
    delta=1e-7 #log 무한대발산방지
    z=np.dot(self.xdata,self.W)+self.b
    y=sigmoid(z)
    return -np.sum(self.tdata*np.log(y+delta)+(1-self.data)*np.log((1-y)+delta))
  
  #수치미분을 이용하여 손실함수가 최소가 될때까지 학습하는 함수 
  def train(self): #경사하강법 이용하여 W,b업데이트
    f=lambda x : self.loss_func()
    print("Initial loss value=", self_loss_val())
    
    for step in range(8001):
      self.W -= self.learning_rate * derivative(f,self.W)
      self.b -= self.learning_rate * derivative(f,self.b)
      
      if(step % 1000 ==0):
        print("step=",step,"loss value=", self.loss_val())
        
  def predict(self,xdata) #미래값 예측 predict
    z=np.dot(input_data, self.W)+self.b
    y=sigmoid(z)
    
    if y>0.5:
      result=1
    else:
      result=0
    return y, result 

손실함수 값을 계산하고 현재의 손실함수값을 알려주는 

loss_func() loss_value() 에 대한 내용은 [머신러닝]Linear Regression/Classification 파트 보면 자세히 나온다.

train(), derivative()는 [머신러닝]미분파트 보면 자세히 나온다.

 

자, 이제 논리게이트 검증을 해보겠다.

 

AND 트레이닝 데이터

#AND 학습코드
xdata=np.array([ [0,0],[0,1],[1,0],[1,1] ]) #입력데이터
tdata=np.array([0,0,0,1]) #AND정답데이터

AND_obj=LogicGate("AND_GATE",xdata,tdata)
AND_obj=train()

for input_data in xdata:
  (sigmoid_val, logical_val)=AND_obj.predict(input_data)
  print(input_data,"=",logical_val)

OR 트레이닝 데이터

#OR 학습코드
xdata=np.array([[0,0],[0,1],[1,0],[1,1]])
tdata=np.array([0,1,1,1])

OR_obj=LogicGate("OR_GATE",xdata,tdata)
OR_obj=train()

for input_data in xdata:
  (sigmoid_val, logical_val)=OR_obj.predict(input_data)
  print(input_data,"=",logical_val)

NAND 트레이닝 데이터

#NAND 학습코드
xdata=np.array([[0,0],[0,1],[1,0],[1,1]])
tdata=np.array([1,1,1,0])

NAND_obj=LogicGate("NAND_GATE",xdata,tdata)
NAND_obj=train()

for input_data in xdata:
  (sigmoid_val,logical_val)=NAND_obj.predict(input_data)
  print(input_data,"=",logical_val)

그리고 대망의 XOR는 위와 같은 방법과 다르게 구현된다.

위와 같은 Classification알고리즘 만으로는 분류가 어렵다.(하나의 직선만으로는 두 데이터를 가르기힘듦)

그래서 NAND, OR, AND 조합으로 구성한다.

논리회로에서 배우는 내용인데 XOR=AND(NAND,OR)이다.

XOR(x1,x2) = AND(NAND(x1,x2) , OR(x1,x2)) 

이는 논리회로의 MultiLater개념을 활용한 것이다.

 

#XOR 학습코드
#NAND_obj, OR_obj, AND_obj 객체는 이미 생성된 것으로 가정.
input_data=np.array([[0,0],[0,1],[1,0],[1,1]])

s1=[] #NAND출력
s2=[] #OR출력
new_input_data=[] #AND 입력
final_output=[] #AND 출력

for index in range(len(input_data)):
  s1=NAND_obj.predict(input_data[index]) #NAND출력
  s2=OR_obj.predict(input_data[index]) #OR출력
  
  new_input_data.append(s1[-1]) #AND 입력
  new_input_data.append(s2[-1]) #OR 입력
  
  (sigmoid_val, logical_val)=AND_obj.predict(np.array(new_input_data)) #s1,s2입력
  
  final_output.append(logical_val) #AND출력, 즉 XOR 출력
  new_input_data=[] #AND 입력 초기화
  
for index in range(len(input_data)):
  print(input_data[index], "=",final_output[index])

 

 

딥러닝은 이렇게 Classification시스템을 다양하게 조합해서 데이터를 분석하고 미래값을 예측하는 머신러닝의 한 분야다.

다변수함수수치미분.py
0.00MB