주말이 되었음 ai 공부를 치는 거여요
이번에는 최소 논리 단위 xor을 공략해 바바요.
이거는 다시 기억이 가능한 로직이 핵심이어요. xor로 하였어도 언제든지 or 이나 and로 고쳐먹어서 다른 계산 결과를 내는거도 되겠쩌.
결론 (미리 보기임) 논리 게이트는 숫자이어서 똑맞아 떨어지는 거이지 자연어 단어 같은 거는 난리가 나는 거여요.
업스테이지를 제외하고 아무 ai에 넣음.
function step(x1, x2) { console.log(y1, y2) } 위에 함수에 없는 부분인데. 은닉1, 은닉2 각 층과 사전학습 값을 넣어서 xor 문제를 해결하는 함수를 완성해줄래?
좋은 질문이에요! XOR 문제는 선형 분리 불가능하기 때문에 은닉층(hidden layer)을 둔 간단한 신경망으로 해결할 수 있습니다. 여기서는 2개의 입력(x1, x2), 은닉층 2개 노드(h1, h2), 그리고 출력층(y)를 가진 네트워크를 구현해볼게요.
아래 예시는 사전학습된 가중치와 편향 값을 직접 넣어서 XOR을 풀 수 있도록 만든 코드입니다:
function sigmoid(x) {
return 1 / (1 + Math.exp(-x));
}
function step(x1, x2) {
// ===== 은닉층 1, 2 =====
// 사전학습된 가중치와 편향 (예시 값)
const w11 = 20, w12 = 20, b1 = -10; // 은닉 노드 h1
const w21 = -20, w22 = -20, b2 = 30; // 은닉 노드 h2
const h1 = sigmoid(w11 * x1 + w12 * x2 + b1);
const h2 = sigmoid(w21 * x1 + w22 * x2 + b2);
// ===== 출력층 =====
const v1 = 20, v2 = 20, b3 = -30; // 출력 노드 y
const y = sigmoid(v1 * h1 + v2 * h2 + b3);
// 결과를 0 또는 1로 반올림
const y_bin = y >= 0.5 ? 1 : 0;
console.log(`입력: (${x1}, ${x2}) -> 은닉: (${h1.toFixed(3)}, ${h2.toFixed(3)}) -> 출력: ${y_bin}`);
return y_bin;
}
// 테스트
step(0, 0); // 0
step(0, 1); // 1
step(1, 0); // 1
step(1, 1); // 0
🔎 설명
sigmoid활성화 함수를 사용했습니다.은닉층은 두 개의 노드(h1, h2)로 구성되어 있고, XOR을 분리할 수 있도록 가중치와 편향을 설정했습니다.
출력층은 은닉층의 결과를 받아 최종 XOR 값을 출력합니다.
console.log로 각 단계의 값을 확인할 수 있습니다.
👉 위의 가중치 값들은 XOR 문제를 풀 수 있도록 설계된 대표적인 예시 값이에요. 실제로는 학습(gradient descent 등)을 통해 자동으로 찾아내지만, 여기서는 사전학습된 값을 직접 넣어 해결했습니다.
원한다면 제가 학습 과정(백프로파게이션)까지 구현해주는 예시도 보여드릴 수 있어요. 학습 버전도 보고 싶으세요?
여기서 끝이 아니어 .. 여담으로 bitnet이나 z80처럼 정밀도를 떨어뜨리는 실험도 되는 거여요.


(위에 그림은 gpt 무료로 그림)
Hello world (edited) • Playground • Svelte
<script>
var x1 = $state(0)
var x2 = $state(0)
var w11 = $state(0)
var w12 = $state(0)
var b1 = $state(0)
var w21 = $state(0)
var w22 = $state(0)
var b2 = $state(0)
var v1 = $state(0)
var v2 = $state(0)
var b3 = $state(0)
var h1 = $state(0)
var h2 = $state(0)
var r1 = $state(0)
function sigmoid(x) {
return 1 / (1 + Math.exp(-x));
}
$effect(() => {
h1 = sigmoid(w11 * x1 + w12 * x2 + b1)
h2 = sigmoid(w21 * x1 + w22 * x2 + b2)
r1 = sigmoid(v1 * h1 + v2 * h2 + b3)
})
function resetAll() {
x1 = 0; x2 = 0;
w11 = 0; w12 = 0; b1 = 0;
w21 = 0; w22 = 0; b2 = 0;
v1 = 0; v2 = 0; b3 = 0;
}
</script>
<table>
<tbody>
<!-- 입력값을 라디오 버튼으로 -->
<tr>
<td>입력</td>
<td colspan="3">
<label>
<input type="radio" name="inputs" value="[0,0]"
on:change={() => { x1 = 0; x2 = 0; }} checked />
(0,0)
</label>
<label>
<input type="radio" name="inputs" value="[0,1]"
on:change={() => { x1 = 0; x2 = 1; }} />
(0,1)
</label>
<label>
<input type="radio" name="inputs" value="[1,0]"
on:change={() => { x1 = 1; x2 = 0; }} />
(1,0)
</label>
<label>
<input type="radio" name="inputs" value="[1,1]"
on:change={() => { x1 = 1; x2 = 1; }} />
(1,1)
</label>
</td>
</tr>
<tr>
<td colspan="4">x1, x2 = {x1}, {x2}</td>
</tr>
<!-- 은닉 노드 1 -->
<tr>
<td><span class="output">h1 = {h1.toFixed(3)}</span></td>
<td>
<input type="range" bind:value={w11} min="-9" max="9" step="1" />
<span>w11: {w11}</span>
</td>
<td>
<input type="range" bind:value={w12} min="-9" max="9" step="1" />
<span>w12: {w12}</span>
</td>
<td>
<input type="range" bind:value={b1} min="-9" max="9" step="1" />
<span>b1: {b1}</span>
</td>
</tr>
<!-- 은닉 노드 2 -->
<tr>
<td><span class="output">h2 = {h2.toFixed(3)}</span></td>
<td>
<input type="range" bind:value={w21} min="-9" max="9" step="1" />
<span>w21: {w21}</span>
</td>
<td>
<input type="range" bind:value={w22} min="-9" max="9" step="1" />
<span>w22: {w22}</span>
</td>
<td>
<input type="range" bind:value={b2} min="-9" max="9" step="1" />
<span>b2: {b2}</span>
</td>
</tr>
<!-- 출력 -->
<tr>
<td><span class="output final">r1 = {r1.toFixed(3)}</span></td>
<td>
<input type="range" bind:value={v1} min="-9" max="9" step="1" />
<span>v1: {v1}</span>
</td>
<td>
<input type="range" bind:value={v2} min="-9" max="9" step="1" />
<span>v2: {v2}</span>
</td>
<td>
<input type="range" bind:value={b3} min="-9" max="9" step="1" />
<span>b3: {b3}</span>
</td>
</tr>
</tbody>
</table>
<div class="controls">
<button on:click={resetAll}>🔄 Reset</button>
</div>
<style>
table {
border-collapse: collapse;
margin: 1em auto;
background: #f9f9f9;
border-radius: 8px;
padding: 1em;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
td {
padding: 0.5em;
vertical-align: top;
text-align: center;
}
label {
display: block;
font-size: 0.9em;
margin-bottom: 0.2em;
color: #333;
}
input[type="range"] {
width: 100%;
}
td span {
display: inline-block;
min-width: 30px;
font-weight: bold;
color: #555;
}
.output {
font-weight: bold;
color: #007acc;
font-size: 1.1em;
}
.output.final {
color: #d9534f;
font-size: 1.2em;
}
.controls {
text-align: center;
margin-top: 1em;
}
button {
padding: 0.5em 1em;
font-size: 1em;
border: none;
border-radius: 6px;
background: #007acc;
color: white;
cursor: pointer;
transition: background 0.2s;
}
button:hover {
background: #005fa3;
}
</style>
물론 ㅂㅌ들은 더 줄어야 흡족하다 이겠쩌.

Hello world (edited) • Playground • Svelte
<script>
var x1 = $state(0)
var x2 = $state(0)
var w11 = $state(0)
var w12 = $state(0)
var b1 = $state(0)
var w21 = $state(0)
var w22 = $state(0)
var b2 = $state(0)
var v1 = $state(0)
var v2 = $state(0)
var b3 = $state(0)
var h1 = $state(0)
var h2 = $state(0)
var r1 = $state(0)
function sigmoid(x) {
return 1 / (1 + Math.exp(-x));
}
function relu(x) {
return Math.max(0, x);
}
$effect(() => {
h1 = relu(w11 * x1 + w12 * x2 + b1)
h2 = relu(w21 * x1 + w22 * x2 + b2)
r1 = relu(v1 * h1 + v2 * h2 + b3)
})
function resetAll() {
x1 = 0; x2 = 0;
w11 = 0; w12 = 0; b1 = 0;
w21 = 0; w22 = 0; b2 = 0;
v1 = 0; v2 = 0; b3 = 0;
}
</script>
<table>
<tbody>
<!-- 입력값을 라디오 버튼으로 -->
<tr>
<td>입력</td>
<td colspan="3">
<label>
<input type="radio" name="inputs" value="[0,0]"
on:change={() => { x1 = 0; x2 = 0; }} checked />
(0,0)
</label>
<label>
<input type="radio" name="inputs" value="[0,1]"
on:change={() => { x1 = 0; x2 = 1; }} />
(0,1)
</label>
<label>
<input type="radio" name="inputs" value="[1,0]"
on:change={() => { x1 = 1; x2 = 0; }} />
(1,0)
</label>
<label>
<input type="radio" name="inputs" value="[1,1]"
on:change={() => { x1 = 1; x2 = 1; }} />
(1,1)
</label>
</td>
</tr>
<tr>
<td colspan="4">x1, x2 = {x1}, {x2}</td>
</tr>
<!-- 은닉 노드 1 -->
<tr>
<td><span class="output">h1 = {h1.toFixed(3)}</span></td>
<td>
<input type="range" bind:value={w11} min="-9" max="9" step="1" />
<span>w11: {w11}</span>
</td>
<td>
<input type="range" bind:value={w12} min="-9" max="9" step="1" />
<span>w12: {w12}</span>
</td>
<td>
<input type="range" bind:value={b1} min="-9" max="9" step="1" />
<span>b1: {b1}</span>
</td>
</tr>
<!-- 은닉 노드 2 -->
<tr>
<td><span class="output">h2 = {h2.toFixed(3)}</span></td>
<td>
<input type="range" bind:value={w21} min="-9" max="9" step="1" />
<span>w21: {w21}</span>
</td>
<td>
<input type="range" bind:value={w22} min="-9" max="9" step="1" />
<span>w22: {w22}</span>
</td>
<td>
<input type="range" bind:value={b2} min="-9" max="9" step="1" />
<span>b2: {b2}</span>
</td>
</tr>
<!-- 출력 -->
<tr>
<td><span class="output final">r1 = {r1.toFixed(3)}</span></td>
<td>
<input type="range" bind:value={v1} min="-9" max="9" step="1" />
<span>v1: {v1}</span>
</td>
<td>
<input type="range" bind:value={v2} min="-9" max="9" step="1" />
<span>v2: {v2}</span>
</td>
<td>
<input type="range" bind:value={b3} min="-9" max="9" step="1" />
<span>b3: {b3}</span>
</td>
</tr>
</tbody>
</table>
<div class="controls">
<button on:click={resetAll}>🔄 Reset</button>
</div>
<style>
table {
border-collapse: collapse;
margin: 1em auto;
background: #f9f9f9;
border-radius: 8px;
padding: 1em;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
td {
padding: 0.5em;
vertical-align: top;
text-align: center;
}
label {
display: block;
font-size: 0.9em;
margin-bottom: 0.2em;
color: #333;
}
input[type="range"] {
width: 100%;
}
td span {
display: inline-block;
min-width: 30px;
font-weight: bold;
color: #555;
}
.output {
font-weight: bold;
color: #007acc;
font-size: 1.1em;
}
.output.final {
color: #d9534f;
font-size: 1.2em;
}
.controls {
text-align: center;
margin-top: 1em;
}
button {
padding: 0.5em 1em;
font-size: 1em;
border: none;
border-radius: 6px;
background: #007acc;
color: white;
cursor: pointer;
transition: background 0.2s;
}
button:hover {
background: #005fa3;
}
</style>
