명제와 논리 연산

명제

명제란? (1) 명제 : 그 내용이 참인지 거짓인지를 명확하게 판별할 수 있는 문장이나 식
① 참인 명제 : 내용이 항상 옳은 명제
② 거짓인 명제 : 내용에 대하여 한 가지라도 옳지 않은 경우가 있는 명제
출처:네이버 지식백과 '명제

'5는 3보다 크다.' 와 '5는 3보다 작다.'라는 문장은 둘 다 명제지만,
전자는 참인 명제, 후자는 거짓인 명제이다.

하지만 '나는 파이썬보다는 똑똑하다.'같은 주관적인(?) 문장은 명제가 될 수 없다.

p -> q 이면 p 는 '충분 조건', q는 '필요 조건'

고등학생 때는 p 가 '총'을 쏴서 q가 '피'를 흘린다고 외웠지만
우리는 ..얼은이니까..!
똑같이 외워주고 이와 더불어서
p 집합이 q 집합의 부분집합임을 잘 알아두도록 하자.

진리표

p q p->q
T T T
F T T
F F T
T F F

굵은 글씨 부분이 많이들 헷갈리는 부분인 것 같은데,
이건 특정 명제를 가져와서 부정을 해보기보다는 집합의 개념으로 명제를 이해하는게 깔끔할 것 같다.

p가 거짓이라면 ~p의 집합 내에는 원소가 아무것도 없는 공집합일 것이고,
공집합은 모든 집합의 부분집합이므로 모든 q에 대해 부분집합,
즉 모든 q에 대한 충분조건이 될 수 있는 것이다.

논리 연산

집합과 명제, 논리는 철학책 좀 보거나 어릴때 '논리야, 놀자!'책을 한번이라도 봤다면
개념 이해가 엄청나게 어렵진 않을 것이다.
하지만.. 왜 코드로 구현하려니 머리가 터질 것 같은지..?

Boolean Algebra

집합 {0, 1}과 NOT, AND, OR연산으로 구성되는 식과 그에 대한 연산 0 = True 1 = False

논리 논리식 논리회로
NOT \bar{A}
OR A + B
AND A\cdot B
XOR A \oplus B
NOR \bar{A + B}
NAND \bar{A \cdot B}

출처:위키백과 논리회로

이제 코드를 확인해보자 ..!

아래 코드에서는 numpy를 import한 뒤에
인공신경망의 마지막 layer에서 처리해주는 연산인 시그모이드 함수를 정의해준다.

AND 연산

AND 연산은 x, y 모두 True 여야 True 값을 결과로 얻을 수 있는 연산이고,
표로 시각화하면 다음과 같다.

x y result
0 0 0
0 1 0
1 0 0
1 1 1

이 때 wx, wy, bias 에 넣어준 값은 weight value,
즉 각 레이어에서 입력된 변수에 곱해주는 가중치로 임의의 값인데,
위 표와 같이 result 값을 얻을 수 있다면 어떤 상수가 들어가든 상관 없다

OR 연산

OR 연산은 아래 표와 같이 x, y 둘 중 하나라도 True 라면 결과값이 True인 "합집합"과 비슷한 개념으로 이해하면 된다.

x y result
0 0 0
0 1 1
1 0 1
1 1 1

이 연산도 동일하게 가중치를 랜덤으로 돌려보았다

NAND 연산

not AND 연산이니까 AND연산의 결과에서 not만 붙여주면 아래와 같은 표를 얻을 수 있다

x y result
0 0 1
0 1 1
1 0 1
1 1 0

코드에서도 간단하게,
AND 연산과 같은 절댓값을 가지지만 부호만 다른 가중치를 넣어주면 된다

NOR 연산

not OR 연산 == OR연산의 결과에서 not 붙여주기!

x y result
0 0 1
0 1 0
1 0 0
1 1 0

이 코드도 OR 연산에서 부호만 바꿔주었다.

이상 구현해봤던 AND, OR, NAND, NOR 연산은 선형분리가 가능하다는 점을 기억하자.

선형 분리가 불가능한

XOR 연산

입력값 두 개가 같으면 False, 다르면 True를 반환하는데
사람한테 설명하면 쉽지만 이걸 컴퓨터한테 알려주기가 쉽지만은 않다.

x y result
0 0 0
0 1 1
1 0 1
1 1 0

XOR 연산을 구현하는 방법은
1)NOR 연산 활용
2)NAND, OR, AND 연산 활용
두 가지를 배웠다.

코드를 한 줄 한 줄 살펴보면,

결국 우리가 원하는 건 c,d 값이 같으면 0, 다르면 1이 출력되는 것이다.

c d result
0 0 0
0 1 1
1 0 1
1 1 0

우리는 아래 두 가지로 분류해서 c,d의 값을 살펴볼 수 있다.

1) (x,y)=(0,0) or (1,1) 일 때

(x,y) a b c d
(0,0) 0 0 0 0
(1,1) 0 0 0 0

(0파티..!)

2) (x,y)= (1,0) or (0,1) 일 때

(x,y) a b c d
(1,0) 0 0 0 1
(0,1) 0 0 0 1

이렇게 c,d를 정의해줌으로써 XOR를 구현할 수 있다.

이보다 더 간단하게 XOR을 구현하는 방법도 있다.

코드는 NOR 다섯개를 가지고 오는 것보다 훨씬 간단하다!
얘도 하나하나 따져보면 머리가 훨씬 덜 아픈 느낌이다.

(x,y) a b
(0,0) 1 0
(1,0) 1 1
(1,0) 1 1
(1,1) 0 1
a b c
1 0 0
1 1 1
1 1 1
0 1 0

이렇게 논리 게이트 구현 완료!