본문으로 건너뛰기

두 문화: 기호 대 벡터

📍 우리의 위치: 4부 · 신경-기호적 발상 — 12장. 이전 장인 임베딩(Embeddings)에서는 alice, advises, p1이라는 기호들을 지도 위의 점으로 바꾸고, 거리로 진리를 대신하게 했습니다. 이제 그 기하학을 2부의 정확한 추론과 나란히 놓고 더 예리한 질문을 던집니다. 이 둘은 같은 학계 세계를 표현하는 두 가지 방식인데, 그렇다면 각각은 상대방이 할 수 없는 무엇을 해낼 수 있을까요?

두 개의 장, 하나처럼 보이는 질문에 대한 두 개의 답. 2부에서 우리는 논리에게 어떤 문장이 우리가 아는 것으로부터 따라 나오는지(follows) 물었습니다. 임베딩에서는 기하학에게 한 점이 다른 점 가까이(near) 있는지를 물었습니다. 둘 다 같은 작은 세계, 즉 alice, bob, advises, 인용 사슬 p3 → p2 → p1을 읽고 있었고, 둘 다 "인공지능"이라 불리지만, 답이 대체 무엇인가라는 근본적인 지점에서는 서로 다릅니다. 증명인가, 거리인가. 이 장은 두 전통을 나란히 놓고, 각각이 무엇을 얻고 무엇을 치르는지 이름 붙이며, 왜 이들의 약점이 정확히 정반대인지 — 이 시리즈 전체가 둘을 결합할 가치가 있다고 보는 바로 그 이유 — 를 보여줍니다. 어떤 주장도 그냥 단언으로 남겨두지 않을 것입니다. 우리는 증명기를 직접 실행해 그 증명 트리를 출력하고, 전진 연쇄 엔진이 세 번의 파동(wave)에 걸쳐 23개의 사실에서 47개의 원자로 올라가는 것을 지켜보며, 학습된 좌표로부터 TransE 점수를 손으로 재계산해 코드가 소수점 셋째 자리까지 출력하는 숫자와 일치할 때까지 확인할 것입니다.

쉽게 말하면

소문이 사실인지 판단하는 두 전문가를 상상해 보십시오. 첫 번째는 변호사입니다. 그녀는 한 치의 빈틈도 없는 증거의 사슬을 단계별로 보여줄 수 있을 때만 "그렇다"고 말할 것입니다 — 그리고 문서 하나라도 빠져 있으면, "아마도"조차 말하지 않고 아예 아무 말도 하지 않습니다. 두 번째는 노련한 형사입니다. 그는 수천 건의 사건을 보아 왔고, 한 번도 들어본 적 없는 소문에 대해서도 늘 직감을, 심지어 퍼센트까지 제시해 줄 것입니다 — 하지만 그는 유창하고 자신만만하게 틀릴 수도 있습니다. 변호사는 기호 AI입니다. 형사는 신경 AI입니다. 어느 한쪽만으로는 충분하지 않으며, 이 장의 유용한 놀라움은 이 둘의 맹점이 정확히 정반대라는 것입니다 — 이것이 바로 둘을 한 방에 넣어 보려는 이유 전부입니다.

이 장에서 다루는 내용

  • 두 전통물리적 기호 체계(physical symbol system) 프로그램과 연결주의(connectionist) 프로그램, 그리고 우리의 동반 코드 파일들이 각각 어느 쪽에서 비롯되었는지.
  • 다섯 줄로 본 대조 — 정확함 대 강건함, 설명 가능함 대 불투명함, 데이터 결손에 취약함 대 데이터를 많이 요구함, 사람이 직접 작성함 대 학습됨, 실패 시 침묵함 대 어쨌든 답을 내놓음.
  • 기호 문화, 실제로 돌려보기[23, 41, 47, 47]로 파동(wave)마다 올라가는 전진 연쇄 고정점, 그리고 감사 가능한 증명 트리를 반환하는 후진 연쇄 증명기 — 둘 다 forward_chain.pysld.py의 코드 한 줄 한 줄에 근거를 둡니다.
  • 신경 문화, 실제로 돌려보기 — 학습된 2차원 좌표로부터 손으로 재계산한 TransE 점수, 그리고 기하학이 구조를 대체로 옳게 포착하면서도 한 가지 탐침(probe)에서는 자신만만하게 틀리는 모습을 보여주는 advises 점수 전체 표.
  • 각자가 무너지는 지점 — 사실이 빠지거나 잘못 표기되었을 때 침묵하는 증명기, 그리고 단순히 거짓인 트리플에 대해 낮고 자신만만한 숫자를 내놓는 점수 매김기.
  • 거울에 비친 실패 — 유도(derives)를 나타내는 턴스타일(turnstile) ⊢와 함의(entails)를 나타내는 ⊨로 명시한 건전성과 완전성을, "결코 침묵하지 않지만 결코 확실하지도 않다"는 성질과 나란히 놓고, 왜 두 프로파일이 상호 보완적인지.
  • 인터페이스 문제 — 정확한 증명기와 미분 가능한 모델 사이의 아직 풀리지 않은 인계(handoff) 문제, 이 시리즈의 나머지 부분이 다루려는 바로 그 문제.

분야를 갈라놓은 두 전통

인공지능은 그 역사 대부분의 기간 동안 서로 거의 같은 언어를 쓰지 않는 두 개의 경쟁 프로그램이었습니다. 첫 번째는 기호 AI이며, 그 창시 신조는 물리적 기호 체계 가설(physical symbol system hypothesis)입니다. aliceadvises와 같은 토큰(token)인 기호를 명시적인 규칙으로 조작하는 시스템은 "일반적인 지적 행동을 위해 필요하고도 충분한 수단을 갖는다"는 것입니다 [1]. 이 관점에서 보면 생각한다는 것은 곧 기호를 조작하는 것입니다: 추론이란 패턴을 맞추고 규칙을 발화시키는 것이고, 지능이란 그것을 충분히 잘 해낼 때 나타나는 것입니다. 2부의 모든 것은 바로 이 발상에서 직접 갈라져 나왔습니다. 이제 곧 다시 살펴볼 전진 연쇄 엔진과 후진 연쇄 증명기는 축소판 물리적 기호 체계입니다.

두 번째 프로그램은 연결주의(connectionism)이며, 두 권짜리 저작 병렬 분산 처리(Parallel Distributed Processing)에서 결정화되었습니다 [2]. 그 내기는 정반대입니다: 지능이란 기호 위의 규칙이 아니라, 데이터에 반응해 서로의 연결 강도를 조정하는 수많은 단순한 단위 — 느슨하게 말해 뉴런(neuron) — 들의 창발적(emergent) 행동이라는 것입니다. 읽어 낼 수 있는 손으로 쓴 규칙 같은 것은 없습니다. 지식은 흩어진 채로 가중치(weight) 속에 깃들어 살아갑니다. 지난 장의 TransE(번역 임베딩, translating embeddings) 모델은 하나의 작은 연결주의 시스템입니다: alice가 bob을 지도한다고 아무도 적어 놓지 않았지만, 훈련은 그 사실은 들어맞고 그 반대는 들어맞지 않는 점들의 배치를 학습해 냈습니다.

둘을 대조하기 전에, 기호주의 쪽이 실제로 돌아가는 모습을 지켜볼 가치가 있습니다. "규칙으로 기호를 조작한다"는 문구는 실제 작동 기제를 감추고 있기 때문입니다. 우리의 지식 베이스 kb.py23개의 기본 사실(FACTS 목록, 39행에서 69행까지)과 7개의 규칙(RULES 목록, 73행에서 89행까지)을 단언합니다. 기본 사실이란 ("advises", "alice", "bob")과 같은 튜플(tuple)로, 술어(predicate) 이름 뒤에 그 인자들이 따라오는 형태입니다. 이 파일의 관례(is_var, 25행)에 따르면 X처럼 대문자로 시작하는 항은 채워 넣어야 할 빈칸인 변수(variable)이고, alicep1처럼 소문자인 것은 무엇이든 고정된 상수(constant)입니다. 다음과 같은 규칙은

(("grandAdvisor", "X", "Z"), [("advises", "X", "Y"), ("advises", "Y", "Z")])

"임의의 X, Y, Z에 대해: 만약 XY를 지도하고 YZ를 지도한다면, XZ를 grand-advise한다"라고 읽힙니다. 전진 연쇄(forward chaining)는 직접 귀결 연산자(immediate-consequence operator) — TPT_P로 표기되며 forward_chain.py(42행에서 49행까지)에서 t_p로 구현됨 — 를 반복 적용함으로써 사실들로부터 규칙이 유도할 수 있는 모든 것을 계산합니다. TPT_P를 한 번 적용하는 것은 정확히 한 가지 일을 합니다: 몸체가 현재 충족된 모든 규칙을 발화시키고, 그 결과로 나온 머리들을 모두 알려진 원자들의 집합에 더하는 것입니다. 그런 다음 그 확장된 집합에 다시 TPT_P를 적용하고, 이를 어떤 라운드도 새로운 것을 더하지 못할 때까지 반복합니다. TPT_P를 한 번 더 적용해도 아무것도 변하지 않는(nxt == current, 61행) 그 안정된 집합이 바로 최소 고정점(least fixpoint)이며, 2부는 이것이 최소 허브랜드 모델(least Herbrand model)과 같음을, 즉 프로그램의 정확한 의미임을 확립했습니다.

아래 세로 막대 \lvert\cdot\rvert는 어떤 집합의 크기, 즉 원소의 개수를 나타내고, MkM_k파동 kk 이후에 알려진 원자들의 집합을 나타냅니다(따라서 M0M_0은 기본 사실들이고 M0=23\lvert M_0\rvert = 23입니다). 추적(tracing)을 켠 채로 least_fixpoint를 실행하면(52행에서 64행까지) 각 라운드 이후의 크기를 [23, 41, 47, 47]로 출력합니다. 다음은 각 파동 kk가 실제로 유도해 내는 것을 술어별로 분해한 표입니다:

파동 kk모델 크기 Mk\lvert M_k\rvert추가된 원자발화한 술어
0 (기본)23FACTS에서 곧바로 온, 단언된 사실들
141+18researcher (5), grandAdvisor (3), colleague (8), citesTransitively (2)
247+6person (5), citesTransitively (1)
347+0새로운 것 없음: 고정점에 도달함

이 파동들은 그저 늘려 놓은 것이 아닙니다. 각 파동은 그 앞 라운드가 충족시킬 수 없었던 어떤 의존성에 의해 강제된 것입니다. 파동 1은 그 몸체가 이미 기본 사실들 사이에 있는 모든 규칙을 발화시킵니다: 두 개의 부류(class) 규칙은 다섯 명의 연구자를 모두 켜고(professor 또는 studentresearcher를 함의합니다), grandAdvisor 규칙은 지도 사슬을 합성해 grandAdvisor(alice, carol), grandAdvisor(alice, dave), grandAdvisor(bob, erin)을 만들어 내며, colleague 규칙은 같은 기관을 공유하는 모든 이를 짝지어 줍니다(그리고 colleague(X, Y)가 대칭적이라고 선언되어 있지 않으므로 양쪽 순서 모두에 대해 발화합니다. 그래서 mit는 alice와 bob 사이의 순서쌍 2개를 내놓고 cmu는 carol, dave, erin 사이의 순서쌍 6개를 내놓아 도합 8개가 되는데, 이는 독자가 처음에 셀 법한 4개의 비순서쌍의 두 배입니다), 그리고 인용 추이성(citation-transitivity)의 기저 사례는 직접적인 한 홉짜리 연결 두 개, citesTransitively(p2, p1)citesTransitively(p3, p2)를 기록합니다. 이제 파동 2는 파동 1의 산출물을 필요로 했던 두 개의 규칙을 발화시킬 수 있습니다: person(X)researcher(X)를 필요로 하는데, 이것은 파동 1 전에는 존재하지 않았으므로 다섯 개의 person 원자가 이제야 비로소 모두 나타나며, 재귀적인 인용 규칙 citesTransitively(A, C) :- cites(A, B), citesTransitively(B, C)는 마침내 cites(p3, p2)를 갓 유도된 citesTransitively(p2, p1)과 사슬로 연결해 두 홉짜리 citesTransitively(p3, p1)을 결론지을 수 있습니다. 파동 3에서는 새로 충족되는 몸체가 없으므로, TPT_P는 고정점에 도달했고 엔진은 47개의 원자, 그중 24개가 유도된 상태로 멈춥니다. 재귀와 부류 사슬은 각각 정확히 한 라운드씩을 추가로 소비하며, 이것이 바로 이 상승이 한 번이 아니라 세 번의 파동을 거치는 정확한 이유입니다.

다섯 줄로 본 대조

이 두 프로그램은 그저 서로 다른 기법에 그치는 것이 아닙니다. 이들은 같은 미덕들을 정반대 방향으로 맞바꿉니다. 나란히 늘어놓으면 그 패턴은 뚜렷합니다:

차원기호주의(규칙, 증명)신경망(벡터, 경사도)
답이란 무엇인가정확하고 확실함: 예 또는 아니오등급화되고 근사적임: 하나의 숫자
설명감사 가능한 증명 흔적이유가 붙지 않은 거리
빠지거나 잡음 섞인 데이터취약함: 사실이 없으면 증명도 없음강건함: 그래도 추측을 돌려줌
지식이 오는 곳사람이 직접 작성한 규칙과 사실데이터로부터 학습됨
실패하는 방식침묵함: 추측하지 않음어쨌든 답함: 자신만만하게 틀릴 수 있음

위에서 아래로 읽으면 각 줄은 양면을 지닌 동전입니다. 증명기의 확실성은 정확히 그것이 추측을 감행하지 못하게 막는 바로 그것이고, 채점기가 기꺼이 추측하려는 태도는 정확히 그것에게서 확실성을 앗아가는 바로 그것입니다. 증명은 사람이 검토할 수 있는 이유들의 사슬이고, 학습된 거리는 추론이 좌표 속으로 녹아 사라진 하나의 평결입니다. 이것은 어느 한쪽 열이 이기는 성적표가 아닙니다. 아무도 벗어나지 못한 단 하나의 거래(trade)입니다.

같은 질문, 두 가지 방식

이 거래를 구체적으로 만드는 데는 하나의 질문을 두 방언(dialect) 모두로 던져 보는 것만 한 것이 없습니다. 이 세계에서 가장 평범한 사실을 예로 들어 봅시다: alice가 bob을 지도하는가?

기호주의의 답: 스스로 영수증을 지참한 증명

기호주의의 답은 우리의 후진 연쇄 증명기인 sld.py에서 나옵니다. SLD 리졸루션(SLD resolution) — 한정절에 대한 선택적 선형 리졸루션(Selective Linear resolution for Definite clauses) — 은 프롤로그(Prolog) 뒤에 있는 전략으로, 목표(goal)에서 출발해 거꾸로 작업하며 "어떤 규칙이 이것을 결론지을 수 있을까, 그렇다면 그 규칙의 몸체는 그때 무엇을 필요로 할까?"를 묻습니다. 이 엔진의 유일한 기본 연산은 단일화(unification, unify.pyunify, 23행)입니다: 두 원자를 맞추어 보는 것은, 그 둘을 동일하게 만들어 주는 치환(substitution) — 변수를 항에 대응시키는 딕셔너리 — 을 찾아내는 것입니다. advises(alice, Y)를 사실 advises(alice, bob)에 맞춰 보면, 단일화는 변수 Y를 상수 bob에 묶고 {Y: bob}을 기록합니다. 공개적인 판정은 단 하나의 불(Boolean) 값입니다(sld.py, 78행에서 79행까지):

def provable(goal: tuple, facts=None, rules=None) -> bool:
return prove(goal, facts, rules) is not None

우리의 질문에 대해 이를 호출하면 True를 돌려줍니다. 하지만 이 불(Boolean) 값은 가장 사소한 부분일 뿐입니다: prove(63행에서 75행까지)는 증명 트리(proof tree), 즉 render 메서드가 그 추론을 들여쓰기된 흔적으로 출력해 주는 Proof 객체(19행에서 34행까지)를 돌려줍니다. advises(alice, bob)은 직접 단언된 것이므로 그 증명은 단 하나의 잎(leaf)입니다. 더 많은 것을 말해 주는 경우는 규칙이 반드시 유도해 내야 하는 사실입니다. grandAdvisor(alice, carol)을 물으면 증명기는 자신의 작업 과정을 보여줍니다. 다음은 python3 sld.py의 실제 출력입니다:

proof of grandAdvisor(alice, carol):
grandAdvisor(alice, carol)
advises(alice, bob)
advises(bob, carol)

엔진(_solve, 37행에서 60행까지)이 이를 어떻게 만들어 냈는지 따라가 봅시다. 목표는 grandAdvisor(alice, carol)입니다. 엔진은 규칙들을 훑어보고 머리 grandAdvisor(X, Z)를 찾아냅니다. 규칙의 변수들을 서로 구별되게 표준화한 뒤(rename, unify.py 51행 — 그래서 같은 규칙을 두 번 쓰더라도 결코 충돌하지 않습니다) 그 머리를 목표와 단일화하여 {X: alice, Z: carol}을 묶습니다. 그 치환 아래에서 규칙의 몸체는 두 개의 하위 목표, advises(alice, Y)advises(Y, carol)이 됩니다. 첫 번째를 사실들에 대해 풀면 Ybob에 묶이고, 이제 advises(bob, carol)이 된 두 번째를 풀면 또 다른 기본 사실에 대해 성공합니다. 단언된 사실에서 바닥을 치는 각 하위 목표는 잎이 되고, 트리는 되돌아오는 길에 조립됩니다. 이 들여쓰기된 트리 자체가 설명입니다: alice가 bob을 지도하고, bob이 carol을 지도하므로, alice는 carol을 grand-advise합니다.

증명기는 진짜 재귀(recursion)도 같은 방식으로 다룹니다. 사슬 p3 → p2 → p1에 대해 citesTransitively(p3, p1)을 물으면, 한 단계 더 깊은 증명이 돌아옵니다. 이 역시 실제 출력입니다:

proof of citesTransitively(p3, p1):
citesTransitively(p3, p1)
cites(p3, p2)
citesTransitively(p2, p1)
cites(p2, p1)

재귀 규칙이 citesTransitively(p3, p1)에 매치되어, 이를 기본 사실 cites(p3, p2)와 더 작은 하위 목표 citesTransitively(p2, p1)로 환원했고, 그 하위 목표는 다시 규칙의 기저 사례(base case)를 거쳐 사실 cites(p2, p1)로 환원되었습니다. 모든 단계는 이름을 붙일 수 있는 규칙이자 확인할 수 있는 사실입니다. 이것이 기호주의 문화의 특징입니다: 답이 자신만의 영수증을 지참한 채로 도착하는 것입니다.

신경망의 답: 직접 계산하는 거리

이제 같은 질문을 신경망 방언으로, embeddings.py에서 던져 보겠습니다. 증명은 없습니다. 거리(distance)가 있을 뿐입니다. TransE는 모든 개체와 관계를 하나의 벡터(vector) — dd개의 숫자로 이루어진 짧은 목록으로, dd차원 공간의 한 점으로 읽힙니다(여기서는 d=2d = 2이므로 평면 위의 한 점입니다) — 로 배치하고, 관계를 하나의 이동(translation)으로 모델링합니다: 머리 개체(head entity) hh가 관계 rr을 통해 꼬리 개체(tail entity) tt와 관계를 맺는다는 것을 뜻하는 참인 트리플(triple) (h,r,t)(h, r, t)h+rth + r \approx t를 만족해야 하며, 여기서 ++는 좌표별로 벡터를 더하는 것이고 \approx는 "근사적으로 같다"로 읽습니다. 트리플의 개연성(plausibility)은 그 이동이 꼬리를 얼마나 빗나가는지를 나타내는 거리입니다(score, 79행에서 82행까지, _dist2, 32행에서 33행까지 위에 세워짐):

def score(E, R, h, r, t) -> float:
"""Plausibility as distance: lower means the translation fits better."""
dim = len(E[h])
return math.sqrt(_dist2([E[h][i] + R[r][i] for i in range(dim)], E[t]))

기호로 나타내면, 학습된 벡터를 h\mathbf{h}, r\mathbf{r}, t\mathbf{t}로, h\mathbf{h}ii번째 좌표를 hih_i로 쓸 때, 이 함수는 다음을 계산합니다.

score(h,r,t)  =  (h+r)t  =  i=1d(hi+riti)2.\text{score}(h, r, t) \;=\; \bigl\lVert (\mathbf{h} + \mathbf{r}) - \mathbf{t} \bigr\rVert \;=\; \sqrt{\sum_{i=1}^{d} \bigl(h_i + r_i - t_i\bigr)^2}.

이중 막대 \lVert \cdot \rVert는 벡터의 길이(그 노름(norm)), 즉 원점에서부터의 평범한 직선 거리를 나타내고, 기호 x\sqrt{\phantom{x}}제곱근(square root)이며, i=1d\sum_{i=1}^{d} 기호(그리스 대문자 시그마)는 "지표 ii11부터 dd까지 흐르는 동안 뒤따르는 항을 모두 더한다"는 뜻입니다. 따라서 이 점수는 이동된 머리 h+r\mathbf{h} + \mathbf{r}와 참인 꼬리 t\mathbf{t} 사이의 유클리드 거리에 지나지 않습니다: 낮을수록 더 잘 들어맞는다는 뜻입니다.

이 숫자들은 단언된 것이 아니라 학습된 것이며, 우리는 그중 하나를 완전히 손으로 재계산할 수 있습니다. python3 embeddings.py를 실행하면(처음부터 학습하는 2차원 TransE로, 13개의 개체와 5개의 관계에 걸친 18개의 트리플을 마진 순위(margin-ranking) SGD로 4000 에포크(epoch) 동안 훈련하며, 무작위 시드(seed)를 고정해 두어 실행 결과가 재현 가능합니다) 관련 좌표는 다음과 같이 정해집니다.

h=alice=(0.698,0.172),r=advises=(1.396,0.857),t=bob=(0.306,0.952).\mathbf{h} = \text{alice} = (0.698,\, -0.172), \quad \mathbf{r} = \text{advises} = (-1.396,\, -0.857), \quad \mathbf{t} = \text{bob} = (-0.306,\, -0.952).

이제 이 공식을 세 단계로 적용해 봅시다. 먼저 머리를 관계만큼 좌표별로 이동시킵니다:

h+r=(0.698+(1.396),  0.172+(0.857))=(0.698,1.029).\mathbf{h} + \mathbf{r} = \bigl(0.698 + (-1.396),\; -0.172 + (-0.857)\bigr) = (-0.698,\, -1.029).

둘째, 꼬리를 빼서 빗나감 벡터(miss vector)를 얻습니다:

(h+r)t=(0.698(0.306),  1.029(0.952))=(0.392,0.077).(\mathbf{h} + \mathbf{r}) - \mathbf{t} = \bigl(-0.698 - (-0.306),\; -1.029 - (-0.952)\bigr) = (-0.392,\, -0.077).

셋째, 그 빗나감의 길이를 구합니다: 각 좌표를 제곱하고, 더한 뒤, 제곱근을 취합니다:

(0.392)2+(0.077)2=0.1537+0.0059=0.1596=0.399.\sqrt{(-0.392)^2 + (-0.077)^2} = \sqrt{0.1537 + 0.0059} = \sqrt{0.1596} = 0.399.

이는 정확히 이 파일이 출력하는 숫자, score advises(alice, bob) = 0.399와 같으며, 어떤 기제도 숨기지 않은 채 학습된 좌표로부터 재현된 것입니다. 모델은 "alice가 bob을 지도하는가?"라는 질문에 0.399로 답합니다 — 짧은 거리, 그럴듯한 들어맞음입니다. 이 모델은 "참(true)"이라는 단어를 한 번도 본 적이 없습니다. 그저 alice-플러스-advises가 bob 가까이에 떨어지도록 화살표들을 배치했을 뿐입니다. 하나의 사실에 대한 두 개의 판정: 증명기는 확실한 라고 말하며 그 이유를 보여주고, 임베딩은 0.399라고 말하는데, 이는 검토할 이유가 붙지 않은 등급화된 개연성(plausibility)입니다.

하나의 공유된 질문을 놓고 기호주의 문화와 신경망 문화를 대조하는 분할 패널 다이어그램입니다. 가운데의 둥근 상자에는 alice가 bob을 지도하는가라는 문구와 물음표가 적혀 있고, 거기서 왼쪽과 오른쪽으로 화살표 두 개가 갈라져 나옵니다. 인디고색으로 물들고 기호주의 문화라는 이름표가 붙은 왼쪽 패널에는 작은 증명 트리가 그려져 있습니다: 뿌리 노드 advises alice bob은 그것이 나온 단 하나의 단언된 사실 위에 놓여 있고, 그 옆에는 grandAdvisor alice carol을 위한 더 높은 트리가 advises alice bob과 advises bob carol 위에 놓여 있으며, 확실한 예, 감사 가능한 흔적이라는 캡션이 붙어 있습니다. 청록색으로 물들고 신경망 문화라는 이름표가 붙은 오른쪽 패널에는 사람, 논문, 기관, 주제를 나타내는 이름표 붙은 점들의 2차원 산점도가 그려져 있고, advises라는 이름표가 붙은 파란 화살표 하나가 alice의 점에서 뻗어 나옵니다. bob의 점까지 이어지는 짧은 초록색 선분에는 거리 0.399라는 태그와 그럴듯함이라는 표시가 붙어 있고, 멀리 떨어진 erin의 점까지 이어지는 긴 빨간색 선분에는 거리 0.929라는 태그와 그럴듯하지 않음이라는 표시가 붙어 있으며, 등급화된 개연성, 결코 확신하지 않음이라는 캡션이 붙어 있습니다. 두 패널에 걸친 하단 띠에는 거울상의 실패: 증명기는 도출할 수 없는 것 앞에서 침묵하고, 채점기는 결코 침묵하지 않지만 결코 확신하지도 않는다라고 적혀 있습니다. 하나의 질문, 두 문화: 기호주의 쪽은 여러분이 감사할 수 있는 증명 트리가 실어 나르는 확실한 예를 돌려주는 반면, 신경망 쪽은 여러분이 이름 붙일 수 있는 어떤 트리플에 대해서도 개연성을 매기지만 결코 확신에는 이르지 못하는 거리를 돌려줍니다. 저자가 AI의 도움을 받아 직접 제작한 원본 도해.

각자가 무너지는 지점

이 대조는 각 문화에게 그것이 잘 다루지 못하는 무언가를 묻는 순간, 흥미로운 것에서 중요한 것으로 바뀝니다. 각자가 상대방이라면 결코 그러지 않을 방식으로 실패하기 때문입니다.

증명기는 부재(absence) 앞에서 무너집니다. alice가 erin을 지도하는지 물어봅시다. 지도 사슬은 alice → bob → carol → erin으로 이어지므로 alice는 erin을 직접 지도하지 않으며, 증명기가 이를 기각하는 것은 옳습니다: provable(("advises", "alice", "erin"))False를 돌려주는데, 이는 prove가 모든 규칙과 사실을 뒤졌지만 목표를 맞출 방법을 찾지 못하고 None을 돌려주었기 때문입니다. 하지만 그것이 어떻게 실패하는지를 보십시오. "가능성이 낮다"거나 "0.9"라고 말하는 것이 아니라, 도출 가능한 것이 아무것도 없다고 보고할 뿐입니다. 그 사실이 정말로 거짓이든, 불완전한 지식 베이스에 그저 빠져 있을 뿐이든, 오타 하나로 사라져 버린 것이든, 그 침묵은 똑같습니다. 관계를 한 번 잘못 표기해 provable(("advize", "alice", "bob"))을 물으면, 답은 또다시 밋밋한 False입니다: 어떤 규칙의 머리도, 어떤 사실도 술어 advize를 쓰지 않으므로 단일화는 첫 단계에서 실패하고, 그 사실이 올바른 철자로는 명백히 참임에도 증명은 아무 경고도 없이 무너집니다. 기호주의 추론은 취약(brittle)합니다: 그것은 오직 사람이 직접 작성한 사실과 규칙만큼만 완전하고 깨끗하며, 그 닫힌 세계 밖에서는 우아하게 성능이 떨어지는 법이 없습니다. 그저 조용해질 뿐이며, 이는 정확히 실제 데이터가 잡음 섞이고 희소하며 오탈자투성이인 바로 그 지점에서 취약함을 뜻합니다.

채점기는 확실성(certainty) 앞에서 무너집니다. 임베딩은 정반대의 문제를 갖고 있습니다: 그것은 결코 침묵하지 않습니다. 공식 (h+r)t\lVert(\mathbf{h} + \mathbf{r}) - \mathbf{t}\rVert가 어떤 세 벡터에 대해서도 정의되어 있으므로, 여러분이 이름 붙일 수 있는 모든 트리플에는 점수가 있습니다. 어디에도 나타나지 않고 어떤 규칙에서도 따라 나오지 않는 트리플인 advises(alice, erin)에 대해 물어보면, 그것은 태연하게 0.929를 돌려줍니다. 이 특정한 쌍에 대해서는 기하학이 옳습니다: 0.929는 참인 사실에 매겨진 0.399보다 크므로 둘의 순위를 올바르게 매기며, 참인 18개의 트리플 전체에 걸쳐 평균을 내 보면 점수는 1.609인 반면 무작위로 손상시킨 트리플에 대해서는 2.737입니다(mean_true_vs_corrupt, 85행에서 96행까지). 그 격차는 진짜입니다. 모델은 진정으로 이 세계의 구조를 학습해 낸 것입니다.

하지만 이 똑같은 실행은, 축소판으로나마, 신경망 문화가 안고 있는 바로 그 위험을 보여주기도 하며, 우리는 이것이 대규모에서 그저 가설에 그치는 것이 아님을 정직하게 인정해야 합니다. 학습된 좌표로부터 advises의 모든 점수 가족을 계산해 보면, 거짓인 트리플 하나가 참인 트리플 아래로 미끄러져 들어옵니다:

트리플 advises(h, t)세계 속에서 참인가?점수(낮을수록 더 그럴듯함)
alice → dave거짓(alice는 오직 bob만 지도함)0.286
alice → bob참(단언된 사실)0.399
alice → erin거짓0.929
alice → carol거짓1.024
bob → dave참(단언된 사실)1.484
carol → erin참(단언된 사실)1.598
bob → erin거짓1.809
bob → carol참(단언된 사실)1.894

맨 위 두 줄을 읽어 보십시오. 거짓인 트리플 advises(alice, dave)0.286을 받아, 0.399를 받은 참인 advises(alice, bob)보다 더 그럴듯한 것으로 나옵니다. 이 모델은 세계 속에 그저 존재하지 않는 사실을, 실제로 존재하는 사실보다 위에 올려놓게 될 것입니다. 이것이 축소판 환각(hallucination)입니다: 거짓인 무언가에 대한 자신만만하고 거리 낮은 판정이면서도, 내부의 경보는 전혀 없는 것입니다. 이는 코드의 버그가 아닙니다. 그것은 설계된 대로 작동하는 메커니즘입니다. 마진 순위(margin-ranking) 훈련(train_transe 안의 갱신, 65행에서 보호됨)은 각 참인 트리플을 오직 무작위로 표집된 손상 트리플보다 고정된 마진만큼 아래에 위치시킬 뿐입니다. 이는 전역적으로 올바른 순서를 결코 보장하지 않으며, 제곱 거리는 보고되는 제곱근에 대해 단조롭기 때문에, 이 훈련이 강제하는 순위는 오직 "참은 평균적으로 무작위 잡음을 이긴다"는 것이지 "모든 참인 트리플이 모든 거짓인 트리플을 이긴다"는 것이 아닙니다. 기하학의 그 무엇도 특정한 거짓 트리플이 가까이 떨어지는 것을 금지하지 않습니다. 신경망 문화가 잡음과 빈틈에 대해 강건(robust)한 것은 정확히 그것이 언제나 답할 것이기 때문이며, 바로 그 똑같은 이유로 신뢰할 수 없습니다(unreliable). 그것은 또한 데이터를 많이 필요로(data-hungry) 합니다: 그 기하학은 오직 그것이 훈련받은 예시만큼만 훌륭하지만, 증명기는 훈련 데이터가 전혀 필요 없이 그저 규칙만 있으면 됩니다. 3권이 다루게 될 설정인 웹 규모의 지저분한 데이터로 훈련될 경우, 이 똑같은 메커니즘은 명백히 거짓인 사실에 낮고 자신만만해 보이는 점수를 일상적으로 건네주며, 이는 그것이 틀렸다는 내부 신호가 전혀 없는 유창한 오답입니다.

거울에 비친 실패

두 실패 양상을 나란히 놓아 보면, 이 분야 전체의 모양이 드러납니다. 2부의 추론은 규칙이 함의하는 것에 대해 건전(sound)하고 완전(complete)했습니다. 이를 정확하게 말하려면 두 개의 기호가 필요합니다. 단일 턴스타일(turnstile) \vdash는 "유도한다"(derives)로 읽습니다: PaP \vdash a는 엔진이 프로그램 PP로부터 원자 aa의 증명을 만들어 낼 수 있다는 뜻입니다. 이중 턴스타일 \models는 "함의한다"(entails) 또는 "모델화한다"(models)로 읽습니다: PaP \models a는 어떤 기계가 그 증명을 실제로 적어 내든 그렇지 않든, aaPP의 모든 모델에서 참이라는 뜻입니다. 건전성(soundness)은 함의 PaPaP \vdash a \Rightarrow P \models a입니다: 엔진이 유도하는 모든 것은 진정으로 참입니다. 완전성(completeness)은 그 역인 PaPaP \models a \Rightarrow P \vdash a입니다: 참인 모든 것은 결국 유도됩니다. 우리의 혼(Horn) 프로그램에 대해서는 둘 다 성립하는데, 우리가 47개의 원자로 올라가는 것을 지켜본 전진 연쇄 고정점이 바로 최소 허브랜드 모델이기 때문이며, 따라서 \vdash\models는 정확히 똑같은 접지된(ground) 원자들을 골라냅니다. 이 증명기는 모든 참을, 오직 참만을 증명하며, 열린 세계에 대해 침묵하여, 규칙이 강제하지 않는 그 무엇에 대해서도 추측하기를 거부합니다.

임베딩은 정확히 그 사진 음화(negative)입니다. 그것은 결코 침묵하지 않으며, 여러분이 이름 붙일 수 있는 어떤 트리플에도 점수를 매기지만, 결코 확신하지도 않는데, advises(alice, dave) = 0.286이 방금 보여 주었듯 어떤 단일한 점수든 틀릴 수 있기 때문입니다. 한쪽 문화는 여러분에게 보증을 주지만 추측은 주지 않고, 다른 쪽 문화는 추측을 주지만 보증은 주지 않습니다.

이 사각지대들은 서로 겹치는 것이 아니라 거울처럼 마주 보고 있으므로, 서로를 상쇄할 후보가 됩니다. 증명기가 침묵에 빠지는 곳 — 빠진 사실, 새로운 개체, 잡음 섞이거나 잘못 표기된 입력 — 에서도 채점기는 여전히 숫자를 하나 감행합니다. 채점기가 환각을 일으키는 곳 — 어떤 엄격한 규칙을 위반하는 자신만만한 판정 — 에서는 증명기가 불가능한 것을 거부하는 검사 역할을 할 수 있습니다. 이것이 바로 두 전통의 자연스러운 해결책이라고 주장되는 "제3의 물결(third wave)"인 신경-기호 AI(neuro-symbolic AI)의 논지 전체입니다: 기호 또는 벡터를 선택하는 것이 아니라, 증명기처럼 추론하면서 동시에 기하학처럼 일반화하는 시스템을 공학적으로 만들어 내는 것입니다 [3]. 이 시리즈의 나머지는, 상당 부분, 그 방법에 대한 연구입니다.

아직 풀리지 않은 부분

이 상호 보완성은 말하기는 쉽지만 만들어 내기는 어려우며, 그 어려움은 단 한 곳에 있습니다: 바로 인터페이스(interface)입니다. 증명기와 임베딩을 나란히 돌려 놓고 둘의 의견을 평균 내는 것만으로는 충분하지 않습니다. 증명기의 가치는 보증(guarantee), 즉 건전성이고, 임베딩의 가치는 강건함(robustness), 즉 결코 포기하지 않는다는 것입니다. 문제는, 이 둘을 이어 붙이는 가장 뻔한 방법들이 정확히 여러분이 지키려던 그 속성을 파괴해 버린다는 것입니다. 미분 가능한 모델이 증명으로 흘러 들어가는 사실을 제안하도록 내버려 두면, 단 하나의 환각을 일으킨 전제만으로도 그것이 아래로 도달할 수 있는 모든 것을 오염시킵니다. 기하학의 확신이 거짓인 트리플 advises(alice, carol)을 사실 베이스에 슬쩍 밀어 넣었다고 해 봅시다. 같은 훈련된 모델은 이 트리플에 기만적으로 낮은 1.024를 매기는데, 이는 진정으로 참인 여러 트리플보다도 낮은 점수입니다. 건전한 엔진은 이 썩은 전제를 실제 사실 advises(carol, erin)과 태연하게 사슬로 연결하고, grand-advising 규칙을 발화시켜, 거짓인 grandAdvisor(alice, erin)유도해 냅니다. 조작된 잎 위에 세워진, 흠잡을 데 없는 증명 트리입니다. 이 작은 세계에서는 피해가 거기서 멈춥니다. advises 사실은 오직 grand-advising 규칙에만 먹이를 줄 수 있기 때문입니다. person이라는 신분은 부류 소속에서 내려오고 colleague 쌍은 소속 기관에서 내려오므로, 주입된 지도 사실은 그 어느 쪽에도 닿을 수 없으며, 대표적인 환각 사례인 advises(alice, dave)는 공교롭게도 아무것으로도 이어지지 않습니다(dave는 아무도 지도하지 않고, 아무도 alice를 지도하지 않습니다). 훨씬 더 많은 규칙이 술어를 공유하는 웹 규모에서는, 바로 그 하나의 나쁜 전제가 훨씬 더 멀리까지 연쇄적으로 퍼져 나갑니다. 어느 쪽이든 보증은 사라지며, 더 나쁘게는 조용히 사라집니다. 오염된 증명이 진짜 증명과 정확히 똑같이 신뢰할 만해 보이기 때문입니다. 반대 방향으로 밀어붙여, 엄격한 논리적 제약이 기하학을 옥죄도록 내버려 두면, 그 모델은 애초에 열린 세계에 대해 추측할 수 있게 해 주었던 바로 그 유연성을 잃을 수 있습니다. 강건함이 사라집니다. 그 이음매를 가로질러 정보를 전달하는 방법 — 증명을 경사도로, 경사도를 증명으로 — 을, 어느 한쪽의 확실성이 새어 나가거나 다른 쪽의 커버리지(coverage)가 무너지지 않도록 하면서 찾아내는 것이 이 분야의 중심적인 미해결 문제이며, 어떤 단 하나의 설계도 이를 해결하지 못했습니다. 그 인터페이스는, 그 여러 형태 속에서, 남은 권들이 다루는 주제입니다.

왜 중요한가

이 장은 이 책 전체의 경첩(hinge)입니다. 이 장 이전의 모든 것은 두 극을 따로따로 세워 놓았습니다: 1부와 2부는 우리에게 정확하고 설명 가능하며 침묵하는 논리를 주었고, 3부는 유창하고 일반화하지만 오류를 저지를 수 있는 기하학을 주었습니다. 이 둘을 거울상의 강점을 지닌 두 문화라고 이름 붙이는 것이야말로 "여기 두 가지 기법이 있다"를 "이 둘을 결합할 이유가 여기 있다"로 바꾸어 놓는 일입니다. 이 대조를 내면화한 실무자는 이 분야를 올바르게 읽어 냅니다: 어떤 시스템이 "설명 가능하다"는 주장을 들으면 히트맵(heat-map)이 아니라 sld.py가 출력하는 것과 같은 증명 흔적을 찾아야 하고, "잡음을 다룬다"는 주장을 들으면 우리의 장난감 모델이 거짓인 트리플에 0.286점을 매겼던 것처럼, 그것이 자신만만하게 틀렸을 때 무슨 일이 일어나는지를 물어야 합니다. 두 극 가운데 어느 쪽도 충분하지 않으며 그 실패들이 상호 보완적이라는 것을 일단 받아들이고 나면, 남는 유일하게 흥미로운 질문은 그 둘을 어떻게 결합할 것인가이며 — 이것이 바로 다음 장이 그려 내는 지도입니다.

핵심 용어

  • 기호 AI(Symbolic AI) — 지능을 기호에 대한 규칙 지배적인 조작으로 다루는 전통이며, 정확하고 설명 가능하지만 사람이 직접 작성한 지식 바깥의 무엇에 대해서든 취약합니다.
  • 물리적 기호 체계 가설(Physical symbol system hypothesis) — 기호를 조작하는 시스템은 일반적인 지적 행동을 위해 필요하고도 충분한 수단을 갖는다는 주장입니다.
  • 연결주의(Connectionism) — 병렬 분산 처리(Parallel Distributed Processing)에서 결정화된 전통으로, 지능을 데이터에 대해 연결 가중치를 조정하는 수많은 단순한 단위로부터 창발하는 것으로 다룹니다.
  • 직접 귀결 연산자 TPT_P와 최소 고정점(Immediate-consequence operator and least fixpoint) — "충족된 모든 규칙을 발화시키고 머리들을 모은다"는 한 라운드의 작업이며, 새로운 것이 더 이상 나타나지 않을 때까지 반복됩니다. 그 안정된 집합이 프로그램의 의미이며, 여기서는 [23, 41, 47, 47]이라는 파동을 거쳐 도달합니다.
  • SLD 리졸루션(SLD resolution) — 한정절에 대한 선택적 선형 리졸루션(Selective Linear resolution for Definite clauses)으로, 프롤로그(Prolog)와 우리의 sld.py 뒤에 있는 후진 연쇄 증명 전략입니다. 그저 예/아니오가 아니라 증명 트리를 돌려줍니다.
  • 단일화와 치환(Unification and substitution) — 두 원자를 동일하게 만들어 주는 변수-항 딕셔너리를 찾아냄으로써 그 둘을 맞추는 것이며, 두 추론 엔진이 공유하는 유일한 기본 연산입니다.
  • 증명 흔적(Proof trace) — 목표(goal)를 확립하는, 규칙과 사실로 이루어진 감사 가능한 트리이며, 기호주의 문화에 내장된 설명입니다.
  • 점수(Score, TransE) — 머리-플러스-관계에서 꼬리까지의 거리 (h+r)t\lVert(\mathbf{h}+\mathbf{r})-\mathbf{t}\rVert이며, 낮을수록 더 그럴듯한 등급화된 개연성이고, 여러분이 이름 붙일 수 있는 어떤 트리플에 대해서도 정의되어 있습니다.
  • 취약함(Brittleness) — 기호주의의 실패 양상입니다: 빠지거나, 부재하거나, 잘못 표기된 사실은 성능이 떨어진 답이 아니라 아예 증명도 답도 내놓지 못하게 만듭니다.
  • 환각(Hallucination) — 신경망의 실패 양상입니다: advises(alice, dave) = 0.286처럼, 그저 거짓인 무언가에 대해 자신만만하고 거리 낮은 점수를 내놓으면서도, 그것이 틀렸다는 내부 신호는 전혀 없는 것입니다.
  • 건전성(\vdash \Rightarrow \models)과 완전성(\models \Rightarrow \vdash) 대 결코 침묵하지 않지만 결코 확신하지도 않음(Soundness and completeness versus never silent, never certain) — 두 문화의 거울상 프로필입니다: 논리는 오직 참인 것만을, 그리고 참인 모든 것을 증명하지만 결코 추측하지 않으며, 기하학은 언제나 답하지만 언제나 틀릴 수 있습니다.
  • 인터페이스 문제(The interface problem) — 정확한 증명기와 미분 가능한 모델 사이에서, 한쪽의 보증이나 다른 쪽의 강건함을 잃지 않으면서 정보를 주고받는, 아직 풀리지 않은 과제입니다.

이 다음으로 이어지는 것

이제 우리는 그 긴장을 깔끔하게 정리해 두었습니다: 두 문화, advises(alice, bob)에 대한 두 개의 답, 증명 트리 대 0.399라는 거리, 정확히 정반대인 두 실패 양상, 그리고 우리가 둘 다를 동시에 갖는 것을 가로막고 서 있는 하나의 인터페이스 문제입니다. 당연히 다음으로 떠오르는 질문은 이 둘을 결합하는 방법이 몇 가지나 있는가이며, 그 답은 이미 잘 알려진 형태를 갖고 있는 것으로 드러납니다. 다음 장인 카우츠 분류법: 결합의 여섯 방식은 신경망 프론트엔드가 기호주의 솔버(solver)에 입력을 공급하는 것에서부터 기호주의 교사가 신경망 학생을 빚어내는 것에 이르기까지, 이 분야를 정의하는 신경-기호 아키텍처 지도를 펼쳐 놓으며, 모든 하이브리드(hybrid) 시스템 — 이 시리즈의 나머지가 만들어 낼 것들을 포함해 — 을 하나의 도표 위에 자리매김할 어휘를 우리에게 건네줍니다.


동반 코드: examples/logic/forward_chain.py는 최소 고정점을 계산하고 파동 크기 [23, 41, 47, 47]을 출력합니다. examples/logic/sld.py는 위에서 보여 준 증명 트리들을 prove가 돌려주는 후진 연쇄 증명기입니다. examples/logic/embeddings.py는 2차원 TransE를 훈련시키고 점수를 출력합니다 — 이 모든 것은 examples/logic/kb.py의 공유된 세계 위에서, 순수한 표준 라이브러리 파이썬만으로 이루어져 있습니다. python3 examples/logic/forward_chain.py, python3 examples/logic/sld.py, python3 examples/logic/embeddings.py를 실행하면, advises(alice, dave) = 0.286이라는 환각을 포함해 이 장의 모든 숫자를 재현할 수 있습니다.