나같은 고인물 수험생들은 다들 퍼셉트론 지문에 머리가 한 번씩은 깨져본 경험이 있을 것이다. 사실 내가 그랬다. 그래서 퍼셉트론 지문만 수십 번은 읽어 보았기 때문에 개념적으로는 어느정도 알고 있었다. 그냥 한 문장으로 내 이해를 설명하자면 입력 받은 걸 바탕으로 1 아니면 0을 출력해주는 단순한 노드(?)라고 생각한다.
예전에 컴퓨터 구조 수업 시간에 열심히 듣지는 않았지만 나름대로 각각의 게이트는 어셈블리에서 구현해 본 기억이 난다. 그것들을 합쳐서 CPU를 만들어 보았던 것 같은데 꽤나 지옥이었던 기억이 난다. 이번 단원에서는 그 논리 게이트들을 퍼셉트론 구조로 구현해보는 것으로 보인다. 아래에 구현하면서 한 생각들을 조금 간단하게 남겨 보았다.
코드의 구조를 위해서인지 가중치와 편향만 수정하면서 AND, NAND, OR 게이트를 구현하는 방향을 제시하여서 내 나름대로 조금 해보았다.
def AND(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5])
b = -0.7
tmp = np.sum(w * x) + b
if tmp <= 0:
return 0
else:
return 1
사실 나는 그냥 return 값을 1, 0 으로 바꿔서 해결하고 싶었지만 교재의 의도 자체가 가중치와 편향을 활용하기를 추구하는 것 같아서 각각에 양음을 변경하였다.
def NAND(x1, x2):
x = np.array([x1, x2])
w = np.array([-0.5, -0.5])
b = 0.7
tmp = np.sum(w * x) + b
if tmp <= 0:
return 0
else:
return 1
이걸 짜는 과정에서의 사고 과정을 조금 적어보자면 가중치는 대칭적인 성질을 갖고 있다고 생각해서 1,0과 0,1이 같은 상황에서는 안 건드리고 싶었다. 그래서 b만 감소시켜서 구현하였다. 혹시 앞의 말이 무슨 멍청한 소린지 싶으면 댓글 달아주면 두뇌 개선에 도움이 될 것 같다.
def OR(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5])
b = -0.2
tmp = np.sum(w * x) + b
if tmp <= 0:
return 0
else:
return 1
뭐 당연한거긴 한데 선형 범위를 퍼셉트론으로 조정하는 것이기 때문에 퍼셉트론 하나로는 XOR과 같은 것은 구현할 수 없다. 근데 뭐 여러 개 쓰면 되잖아요...라고 생각하면서 책을 읽었다.
다시 말하지만 2단원이다.(1단원은 진짜 무슨 아무것도 없어서 생략했다.) 그러니 너그러운 마음으로 XOR 구현을 해보기로 하였다. 이건 사실 한 줄에 적어보면 대충 감이 온다.
def XOR(x1, x2):
s1 = NAND(x1, x2)
s2 = OR(x1, x2)
return AND(s1, s2)
그냥 컴구 시간에 배운걸 파이썬으로 하는 느낌이었다. 솔직히 진짜 MIPS에서 할 때는 ALU CPU RAM 다 구현하느라 죽을 뻔했는데 XOR 나부랭이는 금방 할 수 있어서 그냥저냥 잘 넘어간 것 같다.