{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 12wk-1: 순환신경망 (2) – 순환신경망의 이해, `rNNCell`, `RNNCell`\n",
"\n",
"최규빈 \n",
"2024-05-20\n",
"\n",
"
\n",
"\n",
"# 1. 강의영상\n",
"\n",
"\n",
"\n",
"# 2. Import"
],
"id": "78d0a653-2956-4f76-8d7a-0ffd9dc18868"
},
{
"cell_type": "code",
"execution_count": 177,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import torch\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt"
],
"id": "68a71a91-0657-43d7-8cfc-e72fc147979e"
},
{
"cell_type": "code",
"execution_count": 178,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"soft = torch.nn.Softmax(dim=1)"
],
"id": "1fbd5352-e660-4eda-9543-a84e6e92a3f2"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 3. AbAcAd – 실패\n",
"\n",
"## A. Data\n",
"\n",
"`-` 데이터 정리"
],
"id": "cb9c3e93-4a1b-443e-ad8d-e4e22b361b01"
},
{
"cell_type": "code",
"execution_count": 179,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"txt = list('AbAcAd'*50)\n",
"txt[:10]"
],
"id": "e78e111f-fc9e-4ae8-8f56-501e12c4825d"
},
{
"cell_type": "code",
"execution_count": 180,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"df_train = pd.DataFrame({'x':txt[:-1], 'y':txt[1:]})\n",
"df_train[:5]"
],
"id": "1e07fd45-4b69-4d7f-91e8-ff57735da758"
},
{
"cell_type": "code",
"execution_count": 181,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"x = torch.tensor(df_train.x.map({'A':0,'b':1,'c':2,'d':3}))\n",
"y = torch.tensor(df_train.y.map({'A':0,'b':1,'c':2,'d':3}))"
],
"id": "ba5f69ec-12b0-4dc2-8e53-9548e6ae5979"
},
{
"cell_type": "code",
"execution_count": 182,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"x[:8],y[:8]"
],
"id": "3da4f678-9e3a-4e6c-b5a1-9a36342011da"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## B. 풀이 – 실패"
],
"id": "e75b8c01-90cb-4359-98a1-f3639d02b163"
},
{
"cell_type": "code",
"execution_count": 183,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"net = torch.nn.Sequential(\n",
" torch.nn.Embedding(4,2),\n",
" torch.nn.Tanh(),\n",
" torch.nn.Linear(2,4)\n",
")\n",
"ebdd,tanh,linr = net\n",
"ebdd.weight.data = ebdd.weight.data*0 +0.1\n",
"linr.weight.data = linr.weight.data*0 +0.1\n",
"linr.bias.data = linr.bias.data*0 +0.1\n",
"#\n",
"loss_fn = torch.nn.CrossEntropyLoss()\n",
"optimizr = torch.optim.Adam(net.parameters(),lr=0.1)\n",
"#---#\n",
"for epoc in range(200):\n",
" # 1 \n",
" netout = net(x)\n",
" # 2 \n",
" loss = loss_fn(netout,y)\n",
" # 3 \n",
" loss.backward()\n",
" # 4 \n",
" optimizr.step()\n",
" optimizr.zero_grad()"
],
"id": "929ff988-258e-4253-9303-a4ac1ca78cca"
},
{
"cell_type": "code",
"execution_count": 169,
"metadata": {
"tags": []
},
"outputs": [
{
"output_type": "display_data",
"metadata": {},
"data": {
"image/png": "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\nE2atkAAAAABJRU5ErkJggg==\n"
}
}
],
"source": [
"h = tanh(ebdd(x))\n",
"yhat = soft(net(x))\n",
"mat = torch.concat([h,yhat],axis=1).data[:10]\n",
"plt.matshow(mat,cmap=\"bwr\",vmin=-1,vmax=1)\n",
"plt.axvline(1.5,color=\"lime\")\n",
"plt.xticks(ticks=range(6),labels=[r\"$h_1$\",r\"$h_2$\",r\"$P_A$\",r\"$P_b$\",r\"$P_c$\",r\"$P_d$\"]);"
],
"id": "ba1aad55-5a72-481e-889b-248aef03db34"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 망했음\n",
"- 왜?\n",
"\n",
"`-` 일단 망한건 망한거고 분석을 위해서 숫자좀 체크하자."
],
"id": "60b26de0-2f1e-436c-8963-c5ab1b0fab6c"
},
{
"cell_type": "code",
"execution_count": 168,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"net(x)"
],
"id": "64139efc-eec1-4cc8-b335-2c86264e4b88"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## C. 실패한 풀이의 다른구현1\n",
"\n",
"`-` B를 다른방식으로 구현해보자.\n",
"\n",
"`-` 새로운 방식의 데이터 정리"
],
"id": "48f62e02-2a7c-4eb3-8570-f7d9d629acf5"
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"x = torch.tensor(df_train.x.map({'A':0,'b':1,'c':2,'d':3}))\n",
"y = torch.tensor(df_train.y.map({'A':0,'b':1,'c':2,'d':3}))\n",
"X = torch.nn.functional.one_hot(x).float()\n",
"y = torch.nn.functional.one_hot(y).float()"
],
"id": "865f058a-1b21-4d82-a50d-bee58b535c8e"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 사용자 정의 Hnet를 사용"
],
"id": "75eb46de-c1d8-4d4c-bf95-1184eba91bbf"
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"class Hnet(torch.nn.Module):\n",
" def __init__(self):\n",
" super().__init__()\n",
" self.i2h = torch.nn.Linear(4,2,bias=False)\n",
" self.tanh = torch.nn.Tanh()\n",
" def forward(self,X):\n",
" h = self.tanh(self.i2h(X))\n",
" return h\n",
"hnet = Hnet()\n",
"linr = torch.nn.Linear(2,4)\n",
"hnet.i2h.weight.data = hnet.i2h.weight.data*0 + 0.1\n",
"linr.weight.data = linr.weight.data*0 + 0.1\n",
"linr.bias.data = linr.bias.data*0 + 0.1\n",
"# \n",
"loss_fn = torch.nn.CrossEntropyLoss()\n",
"optimizr = torch.optim.Adam(list(hnet.parameters())+list(linr.parameters()),lr=0.1)\n",
"#---#\n",
"for epoc in range(200):\n",
" # 1 \n",
" h = hnet(X)\n",
" netout = linr(h)\n",
" # 2 \n",
" loss = loss_fn(netout,y)\n",
" # 3 \n",
" loss.backward()\n",
" # 4 \n",
" optimizr.step()\n",
" optimizr.zero_grad()"
],
"id": "91bb1b4d-8671-44da-8f0e-6576df02496e"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 이것도 숫자좀 체크해보자."
],
"id": "bf8e40a5-2260-4d7d-a8a1-e1b98597fd47"
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"linr(hnet(X))"
],
"id": "aee6eda1-6939-48a0-a929-eb105982b367"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 이전코드와 결과가 같음\n",
"\n",
"## D. 실패한 풀이의 다른구현2\n",
"\n",
"`# 예비학습` – 아래를 관찰하자."
],
"id": "97dc5117-9f01-498f-a2c7-4e8ce271bd52"
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"X = torch.tensor(\n",
" [[1., 0., 0., 0.],\n",
" [0., 1., 0., 0.]]\n",
")\n",
"linr = torch.nn.Linear(4,2)"
],
"id": "058e9ca0-4bf0-49d6-a968-010284db3388"
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"linr(X)"
],
"id": "a42696f7-11c7-4d06-9ae2-9d3d0acfedbf"
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"linr(X[[0]]),linr(X[[1]])"
],
"id": "6f7c7d53-d9bd-45f2-94f9-20d81609e825"
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"linr(X[0]),linr(X[1])"
],
"id": "b3df9f9a-06d2-430b-82cc-63689ae8d204"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`#`\n",
"\n",
"`-` 또 다른방식의 구현"
],
"id": "0efe2e69-912e-4615-b3fa-2f3fe616df87"
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"x = torch.tensor(df_train.x.map({'A':0,'b':1,'c':2,'d':3}))\n",
"y = torch.tensor(df_train.y.map({'A':0,'b':1,'c':2,'d':3}))\n",
"X = torch.nn.functional.one_hot(x).float()\n",
"y = torch.nn.functional.one_hot(y).float()"
],
"id": "602c9df3-02d9-4bc2-a0f3-79f6808bc61d"
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"class Hnet(torch.nn.Module):\n",
" def __init__(self):\n",
" super().__init__()\n",
" self.i2h = torch.nn.Linear(4,2,bias=False)\n",
" self.tanh = torch.nn.Tanh()\n",
" def forward(self,X):\n",
" h = self.tanh(self.i2h(X))\n",
" return h\n",
"hnet = Hnet()\n",
"linr = torch.nn.Linear(2,4)\n",
"hnet.i2h.weight.data = hnet.i2h.weight.data*0 + 0.1\n",
"linr.weight.data = linr.weight.data*0 + 0.1\n",
"linr.bias.data = linr.bias.data*0 + 0.1\n",
"# \n",
"loss_fn = torch.nn.CrossEntropyLoss()\n",
"optimizr = torch.optim.Adam(list(hnet.parameters())+list(linr.parameters()),lr=0.1)\n",
"#---#\n",
"L = len(X)\n",
"for epoc in range(200):\n",
" # 1~2 \n",
" loss = 0 \n",
" for t in range(L):\n",
" Xt,yt = X[t],y[t]\n",
" ht = hnet(Xt)\n",
" ot = linr(ht)\n",
" loss = loss + loss_fn(ot,yt)\n",
" loss = loss/L\n",
" # 3 \n",
" loss.backward()\n",
" # 4 \n",
" optimizr.step()\n",
" optimizr.zero_grad()"
],
"id": "0561d418-68d7-45a1-a72c-f6ed06c8f9ef"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 이것도 숫자좀 체크해보자."
],
"id": "147a90e5-3770-4e0e-859d-eae94a7e6e34"
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"linr(hnet(X))"
],
"id": "5453fd9f-8824-4e3d-93af-2e634ccb3fc8"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 임베딩공간의 해석"
],
"id": "7aadb9a2-5d82-4a3a-8e83-5e440ce7da03"
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"h = hnet(X)"
],
"id": "189bc840-a27b-40da-87ce-f35ac91d1574"
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"h.shape"
],
"id": "d62b1a49-a9d2-4680-b300-f39e011b77b7"
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"h1,h2 = h.T.data\n",
"# h1 = h[:,0].data\n",
"# h2 = h[:,1].data"
],
"id": "1f01d3f4-ae66-408f-9975-a1d8067098e9"
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {
"tags": []
},
"outputs": [
{
"output_type": "display_data",
"metadata": {},
"data": {
"image/png": "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\nNPT4+/srJiZGWVlZHuVZWVlKSEioc79Vq1bplltu0SuvvKKf//znDZ7HGKO8vDyFhYXVuj0gIEBB\nQUEeCwAAsBfLb2/NmTNHKSkpGjp0qOLj4/X888+rsLBQ06ZNk3RyFOarr77SihUrJJ0MPDfffLOe\neuopxcXFuUeJOnfuLKfTKUmaN2+e4uLi1LdvX5WVlWnRokXKy8vTM888Y3V3AABAO2V56ElOTta3\n336rhx9+WMXFxYqOjta6desUEREhSSouLlZhYaG7/nPPPaeqqirdcccduuOOO9zlU6ZMUUZGhiTp\nyJEjuu2221RSUiKn06nBgwdr69atGjZsmNXdAQAA7ZTl7+lpi870OX8AANDyzvT7m9fwAgAAWyD0\nAAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAA\nWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0\nAAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAA\nWyD0AAAAWyD0AAAAWyD0AAAAWyD0AAAAW2iR0LNkyRJFRkYqMDBQMTExevfdd+utv2XLFsXExCgw\nMFDnn3++li5d6lVn9erVGjBggAICAjRgwACtWbPGquYDAIAOwPLQk5mZqdmzZ+v+++/Xnj17dPnl\nl+uaa65RYWFhrfULCgr0s5/9TJdffrn27Nmj3//+95o5c6ZWr17trpOTk6Pk5GSlpKRo7969SklJ\n0YQJE7R9+3aruwMAANophzHGWHmC2NhYDRkyRM8++6y7rH///rr++us1f/58r/r33nuv3nrrLe3b\nt89dNm3aNO3du1c5OTmSpOTkZJWVlentt99210lKSlKPHj20atWqBttUVlYmp9Mpl8uloKCgM+ke\nAABoIWf6/W3pSE9FRYV27dqlxMREj/LExERlZ2fXuk9OTo5X/TFjxmjnzp2qrKyst05dxywvL1dZ\nWZnHAgAA7MXS0HP48GGdOHFCISEhHuUhISEqKSmpdZ+SkpJa61dVVenw4cP11qnrmPPnz5fT6XQv\nvXv3Pt0uAQCAdqpFJjI7HA6PdWOMV1lD9U8tb8ox09LS5HK53EtRUVGT2g8AANo/XysPHhwcLB8f\nH68RmEOHDnmN1NQIDQ2ttb6vr6/OOuuseuvUdcyAgAAFBAScbjcAAEAHYOlIj7+/v2JiYpSVleVR\nnpWVpYSEhFr3iY+P96r/zjvvaOjQofLz86u3Tl3HBAAAsHSkR5LmzJmjlJQUDR06VPHx8Xr++edV\nWFioadOmSTp56+mrr77SihUrJJ18Uuvpp5/WnDlzlJqaqpycHKWnp3s8lTVr1ixdccUVWrBgga67\n7jq9+eab2rBhg7Zt22Z1dwAAQDtleehJTk7Wt99+q4cffljFxcWKjo7WunXrFBERIUkqLi72eGdP\nZGSk1q1bpzvvvFPPPPOMwsPDtWjRIo0fP95dJyEhQa+++qr+8Ic/6IEHHtAFF1ygzMxMxcbGWt0d\nAADQTln+np62iPf0AADQ/rTp9/QAAAC0FYQeAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABgC4Qe\nAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABg\nC4QeAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABgC4Qe\nAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABgC4QeAABgC5aGntLSUqWkpMjp\ndMrpdColJUVHjhyps35lZaXuvfdeDRo0SF27dlV4eLhuvvlmHTx40KPeyJEj5XA4PJaJEyda2RUA\nANDOWRp6brrpJuXl5Wn9+vVav3698vLylJKSUmf9//73v9q9e7ceeOAB7d69W2+88YY+/fRTjRs3\nzqtuamqqiouL3ctzzz1nZVcAAEA752vVgfft26f169crNzdXsbGxkqQXXnhB8fHxys/PV1RUlNc+\nTqdTWVlZHmWLFy/WsGHDVFhYqD59+rjLu3TpotDQUKuaDwAAOhjLRnpycnLkdDrdgUeS4uLi5HQ6\nlZ2d3ejjuFwuORwOde/e3aN85cqVCg4O1sCBA3X33Xfr6NGjdR6jvLxcZWVlHgsAALAXy0Z6SkpK\n1KtXL6/yXr16qaSkpFHHOH78uO677z7ddNNNCgoKcpdPmjRJkZGRCg0N1Ycffqi0tDTt3bvXa5So\nxvz58zVv3rzT6wgAAOgQmjzSM3fuXK9JxKcuO3fulCQ5HA6v/Y0xtZafqrKyUhMnTlR1dbWWLFni\nsS01NVWjR49WdHS0Jk6cqL/+9a/asGGDdu/eXeux0tLS5HK53EtRUVFTuw0AANq5Jo/0TJ8+vcEn\npc477zy9//77+vrrr722ffPNNwoJCal3/8rKSk2YMEEFBQX617/+5THKU5shQ4bIz89P+/fv15Ah\nQ7y2BwQEKCAgoN5jAACAjq3JoSc4OFjBwcEN1ouPj5fL5dKOHTs0bNgwSdL27dvlcrmUkJBQ5341\ngWf//v3atGmTzjrrrAbP9dFHH6myslJhYWGN7wgAALAVyyYy9+/fX0lJSUpNTVVubq5yc3OVmpqq\nsWPHejy51a9fP61Zs0aSVFVVpRtuuEE7d+7UypUrdeLECZWUlKikpEQVFRWSpM8//1wPP/ywdu7c\nqS+++ELr1q3TjTfeqMGDB2v48OFWdQcAALRzlr6nZ+XKlRo0aJASExOVmJioiy++WC+99JJHnfz8\nfLlcLknSgQMH9NZbb+nAgQO69NJLFRYW5l5qnvjy9/fXxo0bNWbMGEVFRWnmzJlKTEzUhg0b5OPj\nY2V3AABAO+YwxpjWbkRLKysrk9PplMvlanC+EAAAaBvO9Pub394CAAC2QOgBAAC2QOgBAAC2QOgB\nAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2\nQOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgB\nAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2QOgBAAC2\nQOgBAAC2YGnoKS0tVUpKipxOp5xOp1JSUnTkyJF697nlllvkcDg8lri4OI865eXlmjFjhoKDg9W1\na1eNGzdOBw4csLAnAACgvbM09Nx0003Ky8vT+vXrtX79euXl5SklJaXB/ZKSklRcXOxe1q1b57F9\n9uzZWrNmjV599VVt27ZNx44d09ixY3XixAmrugIAANo5X6sOvG/fPq1fv165ubmKjY2VJL3wwguK\nj49Xfn6+oqKi6tw3ICBAoaGhtW5zuVxKT0/XSy+9pNGjR0uSXn75ZfXu3VsbNmzQmDFjmr8zAACg\n3bNspCcnJ0dOp9MdeCQpLi5OTqdT2dnZ9e67efNm9erVSxdddJFSU1N16NAh97Zdu3apsrJSiYmJ\n7rLw8HBFR0fXedzy8nKVlZV5LAAAwF4sCz0lJSXq1auXV3mvXr1UUlJS537XXHONVq5cqX/9619a\nuHCh3nvvPV111VUqLy93H9ff3189evTw2C8kJKTO486fP989r8jpdKp3795n0DMAANAeNTn0zJ07\n12ui8anLzp07JUkOh8Nrf2NMreU1kpOT9fOf/1zR0dG69tpr9fbbb+vTTz/V2rVr621XfcdNS0uT\ny+VyL0VFRU3oMQAA6AiaPKdn+vTpmjhxYr11zjvvPL3//vv6+uuvvbZ98803CgkJafT5wsLCFBER\nof3790uSQkNDVVFRodLSUo/RnkOHDikhIaHWYwQEBCggIKDR5wQAAB1Pk0NPcHCwgoODG6wXHx8v\nl8ulHTt2aNiwYZKk7du3y+Vy1RlOavPtt9+qqKhIYWFhkqSYmBj5+fkpKytLEyZMkCQVFxfrww8/\n1B//+MemdgcAANiEZXN6+vfvr6SkJKWmpio3N1e5ublKTU3V2LFjPZ7c6tevn9asWSNJOnbsmO6+\n+27l5OToiy++0ObNm3XttdcqODhYv/jFLyRJTqdTU6dO1V133aWNGzdqz549mjx5sgYNGuR+mgsA\nAOBUlj2yLkkrV67UzJkz3U9ajRs3Tk8//bRHnfz8fLlcLkmSj4+PPvjgA61YsUJHjhxRWFiYrrzy\nSmVmZqpbt27ufZ544gn5+vpqwoQJ+v777zVq1ChlZGTIx8fHyu4AAIB2zGGMMa3diJZWVlYmp9Mp\nl8uloKCg1m4OAABohDP9/ua3twAAgC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0QegAA\ngC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0Q\negAAgC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0QegAA\ngC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0QegAAgC0QegAAgC1YGnpKS0uVkpIip9Mp\np9OplJQUHTlypN59HA5Hrcuf/vQnd52RI0d6bZ84caKVXQEAAO2cr5UHv+mmm3TgwAGtX79eknTb\nbbcpJSVFf//73+vcp7i42GP97bff1tSpUzV+/HiP8tTUVD388MPu9c6dOzdjywEAQEdjWejZt2+f\n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\ndvz4ceN0Os3SpUuNMSf/aP38/Myrr77qrvPVV1+ZTp06mfXr1zd72xvj448/NpI8/lBycnKMJPPJ\nJ580+jjXXXedueqqqzzKRowYYWbNmtVcTT1jp9vXKVOmmOuuu67O7R35uu7YscNI8vgXcVu4rsOG\nDTPTpk3zKOvXr5+57777aq1/zz33mH79+nmU/eY3vzFxcXHu9QkTJpikpCSPOmPGjDETJ05splaf\nnqb2tTYDBgww8+bNc6839t9rLa2pfa0JPaWlpXUes6Ne1zVr1hiHw2G++OILd1lbva4/1pjQ05Kf\nV25vnaaCggKVlJQoMTHRXRYQEKARI0YoOztbkrRr1y5VVlZ61AkPD1d0dLS7TkvLycmR0+lUbGys\nuywuLk5Op7PRbfr666+1du1aTZ061WvbypUrFRwcrIEDB+ruu+92/6J9aziTvm7evFm9evXSRRdd\npNTUVB06dMi9raNeV0lyuVxyOBxet3hb87pWVFRo165dHv+8JSkxMbHOvuXk5HjVHzNmjHbu3KnK\nysp667TWNZROr6+nqq6u1tGjR9WzZ0+P8mPHjikiIkLnnnuuxo4dqz179jRbu0/HmfR18ODBCgsL\n06hRo7Rp0yaPbR31uqanp2v06NGKiIjwKG9r1/V0tOTn1ZY/ONocSkpKJEkhISEe5SEhIfryyy/d\ndfz9/dWjRw+vOjX7t7SSkhL16tXLq7xXr16NbtOLL76obt266Ze//KVH+aRJkxQZGanQ0FB9+OGH\nSktL0969e5WVldUsbW+q0+3rNddcoxtvvFEREREqKCjQAw88oKuuukq7du1SQEBAh72ux48f1333\n3aebbrrJ4wf/Wvu6Hj58WCdOnKj1s1ZX30pKSmqtX1VVpcOHDyssLKzOOq11DaXT6+upFi5cqO++\n+04TJkxwl/Xr108ZGRkaNGiQysrK9NRTT2n48OHau3ev+vbt26x9aKzT6WtYWJief/55xcTEqLy8\nXC+99JJGjRqlzZs364orrpBU97Vvz9e1uLhYb7/9tl555RWP8rZ4XU9HS35eO3TomTt3rubNm1dv\nnffee09Dhw497XM4HA6PdWOMV9mpGlOnqRrbV8m7zU1t07JlyzRp0iQFBgZ6lKemprr/d3R0tPr2\n7auhQ4dq9+7dGjJkSKOO3RhW9zU5Odn9v6OjozV06FBFRERo7dq1XkGvKcc9HS11XSsrKzVx4kRV\nV1dryZIlHtta6ro2pKmftdrqn1p+Op/flnC67Vq1apXmzp2rN9980yMEx8XFeUzGHz58uIYMGaLF\nixdr0aJFzdfw09CUvkZFRSkqKsq9Hh8fr6KiIv35z392h56mHrMlnW67MjIy1L17d11//fUe5W35\nujZVS31eO3TomT59eoNPmZx33nmndezQ0FBJJxNqWFiYu/zQoUPuNBoaGqqKigqVlpZ6jAocOnRI\nCQkJp3XeujS2r++//76+/vprr23ffPONV4quzbvvvqv8/HxlZmY2WHfIkCHy8/PT/v37m/XLsaX6\nWiMsLEwRERHav3+/pI53XSsrKzVhwgQVFBToX//6l8coT22suq51CQ4Olo+Pj9f/o/vxZ+1UoaGh\ntdb39fXVWWedVW+dpvxtNLfT6WuNzMxMTZ06Va+//rpGjx5db91OnTrpsssuc/9Nt4Yz6euPxcXF\n6eWXX3avd7TraozRsmXLlJKSIn9//3rrtoXrejpa9PPapBlANtDUicwLFixwl5WXl9c6kTkzM9Nd\n5+DBg21iwuv27dvdZbm5uY2e8DplyhSvp3vq8sEHHxhJZsuWLafd3jNxpn2tcfjwYRMQEGBefPFF\nY0zHuq4VFRXm+uuvNwMHDjSHDh1q1Lla47oOGzbM3H777R5l/fv3r3cic//+/T3Kpk2b5jUx8ppr\nrvGok5SU1CYmvDalr8YY88orr5jAwMAGJ4zWqK6uNkOHDjW33nrrmTT1jJ1OX081fvx4c+WVV7rX\nO9J1Neb/Jm9/8MEHDZ6jrVzXH1MjJzK31OeV0PODL7/80uzZs8fMmzfP/OQnPzF79uwxe/bsMUeP\nHnXXiYqKMm+88YZ7/bHHHjNOp9O88cYb5oMPPjC/+tWvan1k/dxzzzUbNmwwu3fvNldddVWbeLT5\n4osvNjk5OSYnJ8cMGjTI69HmU/tqjDEul8t06dLFPPvss17H/Oyzz8y8efPMe++9ZwoKCszatWtN\nv379zODBg9tVX48ePWruuusuk52dbQoKCsymTZtMfHy8Oeecczrcda2srDTjxo0z5557rsnLy/N4\n5LW8vNwY03aua83jvunp6ebjjz82s2fPNl27dnU/yXLfffeZlJQUd/2aR2DvvPNO8/HHH5v09HSv\nR2D//e9/Gx8fH/PYY4+Zffv2mccee6xNPdrc2L6+8sorxtfX1zzzzDN1vlZg7ty5Zv369ebzzz83\ne/bsMbfeeqvx9fX1CMmtoal9feKJJ8yaNWvMp59+aj788ENz3333GUlm9erV7jod5brWmDx5somN\nja31mG31uh49etT9HSrJPP7442bPnj3up0Jb8/NK6PnBlClTjCSvZdOmTe46kszy5cvd69XV1eah\nhx4yoaGhJiAgwFxxxRVeafz7778306dPNz179jSdO3c2Y8eONYWFhS3Uq9p9++23ZtKkSaZbt26m\nW7duZtKkSV6PgJ7aV2OMee6550znzp1rfUdLYWGhueKKK0zPnj2Nv7+/ueCCC8zMmTO93m/T0pra\n1//+978mMTHRnH322cbPz8/06dPHTJkyxeuadYTrWlBQUOvf/I//7tvSdX3mmWdMRESE8ff3N0OG\nDPEYaZoyZYoZMWKER/3NmzebwYMHG39/f3PeeefVGtZff/11ExUVZfz8/Ey/fv08vjxbU1P6OmLE\niFqv4ZQpU9x1Zs+ebfr06WP8/f3N2WefbRITE012dnYL9qhuTenrggULzAUXXGACAwNNjx49zE9/\n+lOzdu1ar2N2hOtqzMlR5c6dO5vnn3++1uO11etaMzpV199ka35eHcb8MFsIAACgA+M9PQAAwBYI\nPQAAwBYIPQAAwBYIPQAAwBYIPQAAwBYIPQAAwBYIPQAAwBYIPQAAwBYIPQAAwBYIPQAAwBYIPQAA\nwBYIPQAAwBb+P1MhJd5sMn6uAAAAAElFTkSuQmCC\n"
}
}
],
"source": [
"plt.plot(h1[::6],h2[::6],'X',label=\"A\")\n",
"plt.plot(h1[1::6],h2[1::6],'X',label=\"b\")\n",
"plt.plot(h1[2::6],h2[2::6],'X',label=\"A\")\n",
"plt.plot(h1[3::6],h2[3::6],'X',label=\"c\")\n",
"plt.plot(h1[4::6],h2[4::6],'X',label=\"A\")\n",
"plt.plot(h1[5::6],h2[5::6],'X',label=\"d\")\n",
"plt.legend()"
],
"id": "75938155-6b21-404e-805e-bbdb707201bf"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> 임베딩공간의 해석? b,c,d는 사실상 같은 문자로 취급한다.\n",
"\n",
"# 4. `AbAcAd` – 성공\n",
"\n",
"## A. 순환신경망의 모티브\n",
"\n",
"***(예비생각1) ${\\boldsymbol h}$에 대한 이해***\n",
"\n",
"`-` ${\\boldsymbol h}$는 사실 문자열 “Abcd”들을 숫자로 바꾼 표현이라\n",
"해석할 수 있음. 즉 원핫인코딩과 다른 또 다른 형태의 숫자표현이라 해석할\n",
"수 있다.\n",
"\n",
"`-` 사실 ${\\boldsymbol h}$는 원핫인코딩보다 약간 더 (1) 액기스만 남은\n",
"느낌 + (2) 숙성된 느낌을 준다\n",
"\n",
"- (why1) ${\\boldsymbol h}$는 ${\\boldsymbol x}$ 보다\n",
" ${\\boldsymbol y}$를 예측함에 좀 더 직접적인 역할을 한다. 즉\n",
" ${\\boldsymbol x}$ 숫자보다 ${\\boldsymbol h}$ 숫자가 잘 정리되어 있고\n",
" (차원이 낮고) 입력의 특징을 잘 정리한 (추천시스템의 MBTI처럼)\n",
" 의미있는 숫자이다.\n",
"- (why2) ${\\boldsymbol x}$는 학습없이 그냥 얻어지는 숫자표현이지만,\n",
" ${\\boldsymbol h}$는 학습을 통하여 고치고 고치고 고친 숫자표현이다.\n",
"\n",
"결론: 사실 ${\\boldsymbol h}$는 잘 숙성되어있는 입력정보\n",
"${\\boldsymbol x}$ 그 자체로 해석 할 수 있다.\n",
"\n",
"***(예비생각2) [수백년전통을 이어가는\n",
"방법](https://www.joongang.co.kr/article/24087690#home)***\n",
"\n",
" “1리터에 500만원에 낙찰된 적 있습니다.”\n",
" “2kg에 1억원 정도 추산됩니다.”\n",
" “20여 종 종자장을 블렌딩해 100ml에 5000만원씩 분양 예정입니다.”\n",
"\n",
" 모두 씨간장(종자장) 가격에 관한 실제 일화다.\n",
"\n",
" (중략...)\n",
"\n",
" 위스키나 와인처럼 블렌딩을 하기도 한다. \n",
" 새로 담근 간장에 씨간장을 넣거나, 씨간장독에 햇간장을 넣어 맛을 유지하기도 한다. \n",
" 이를 겹장(또는 덧장)이라 한다. \n",
" 몇몇 종갓집에선 씨간장 잇기를 몇백 년째 해오고 있다. \n",
" 매년 새로 간장을 담가야 이어갈 수 있으니 불씨 꺼트리지 않는 것처럼 굉장히 어려운 일이다.\n",
" 이렇게 하는 이유는 집집마다 내려오는 고유 장맛을 잃지 않기 위함이다. \n",
" 씨간장이란 그만큼 소중한 주방의 자산이며 정체성이다.\n",
"\n",
"덧장: 새로운간장을 만들때, 옛날간장을 섞어서 만듬\n",
"\n",
"`*` 기존방식 -\n",
"$\\text{콩물} \\overset{\\text{숙성}}{\\longrightarrow} \\text{간장}$\n",
"\n",
"`*` 수백년 전통의 간장맛을 유지하는 방식\n",
"\n",
"- $\\text{콩물}_1 \\overset{\\text{숙성}}{\\longrightarrow} \\text{간장}_1$\n",
"- $\\text{콩물}_2, \\text{간장}_1 \\overset{\\text{숙성}}{\\longrightarrow} \\text{간장}_2$\n",
"- $\\text{콩물}_3, \\text{간장}_2 \\overset{\\text{숙성}}{\\longrightarrow} \\text{간장}_3$\n",
"\n",
"`*` 수백년 전통의 간장맛을 유지하면서 조리를 한다면?\n",
"\n",
"- $\\text{콩물}_1 \\overset{\\text{숙성}}{\\longrightarrow} \\text{간장}_1 \\overset{\\text{조리}}{\\longrightarrow} \\text{간장계란밥}_1$\n",
"- $\\text{콩물}_2, \\text{간장}_1 \\overset{\\text{숙성}}{\\longrightarrow} \\text{간장}_2 \\overset{\\text{조리}}{\\longrightarrow} \\text{간장계란밥}_2$\n",
"- $\\text{콩물}_3, \\text{간장}_2 \\overset{\\text{숙성}}{\\longrightarrow} \\text{간장}_3 \\overset{\\text{조리}}{\\longrightarrow} \\text{간장계란밥}_3$\n",
"\n",
"점점 맛있는 간장계란밥이 탄생함\n",
"\n",
"`*` 알고리즘의 편의상 아래와 같이 생각해도 무방\n",
"\n",
"- $\\text{콩물}_1, \\text{간장}_0 \\overset{\\text{숙성}}{\\longrightarrow} \\text{간장}_1 \\overset{\\text{조리}}{\\longrightarrow} \\text{간장계란밥}_1$,\n",
" $\\text{간장}_0=\\text{맹물}$\n",
"- $\\text{콩물}_2, \\text{간장}_1 \\overset{\\text{숙성}}{\\longrightarrow} \\text{간장}_2 \\overset{\\text{조리}}{\\longrightarrow} \\text{간장계란밥}_2$\n",
"- $\\text{콩물}_3, \\text{간장}_2 \\overset{\\text{숙성}}{\\longrightarrow} \\text{간장}_3 \\overset{\\text{조리}}{\\longrightarrow} \\text{간장계란밥}_3$\n",
"\n",
"***아이디어***\n",
"\n",
"`*` 수백년 전통의 간장맛을 유지하면서 조리하는 과정을 수식으로? (콩물을\n",
"$x$로, 간장을 $h$로!!)\n",
"\n",
"- $\\boldsymbol{x}_1, \\boldsymbol{h}_0 \\overset{\\text{숙성}}{\\longrightarrow} \\boldsymbol{h}_1 \\overset{\\text{조리}}{\\longrightarrow} \\hat{\\boldsymbol y}_1$\n",
"- $\\boldsymbol{x}_2, \\boldsymbol{h}_1 \\overset{\\text{숙성}}{\\longrightarrow} \\boldsymbol{h}_2 \\overset{\\text{조리}}{\\longrightarrow} \\hat{\\boldsymbol y}_2$\n",
"- $\\boldsymbol{x}_3, \\boldsymbol{h}_2 \\overset{\\text{숙성}}{\\longrightarrow} \\boldsymbol{h}_3 \\overset{\\text{조리}}{\\longrightarrow} \\hat{\\boldsymbol y}_3$\n",
"\n",
"이제 우리가 배울것은 (1) “$\\text{콩물}_{t}$”와 “$\\text{간장}_{t-1}$”로\n",
"“$\\text{간장}_t$”를 `숙성`하는 방법 (2) “$\\text{간장}_t$”로\n",
"“$\\text{간장계란밥}_t$를 `조리`하는 방법이다\n",
"\n",
"즉 `숙성`담당 네트워크와 `조리`담당 네트워크를 각각 만들어 학습하면\n",
"된다.\n",
"\n",
"## B. 순환신경망 알고리즘\n",
"\n",
"***`# 버전1`***\n",
"\n",
"**step 1**: 일단 $\\text{간장}_0(={\\boldsymbol h}_0)$을 맹물로 초기화\n",
"한다. 즉 아래를 수행한다.\n",
"\n",
"$${\\boldsymbol h}_0 = [[0,0]]$$\n",
"\n",
"이때 ${\\boldsymbol h}_0 = [[0,0]]$ 은 이론상에서는 shape이 (1,2) 이지만\n",
"알고리즘 상에서는 shape 을 (2,)로 생각해도 무방하다.\n",
"\n",
"**step 2**: $\\text{콩물}_1(={\\boldsymbol x}_1)$,\n",
"$\\text{간장}_0(={\\boldsymbol h}_0)$ 을 이용하여\n",
"$\\text{간장}_1(={\\boldsymbol h}_1)$을 숙성한다. 즉 아래를 수행한다.\n",
"\n",
"$${\\boldsymbol h}_1= \\tanh({\\boldsymbol x}_1{\\bf W}_{ih}+{\\boldsymbol h}_0{\\bf W}_{hh}+{\\boldsymbol b}_{ih}+{\\boldsymbol b}_{hh})$$\n",
"\n",
"이때 변수들의 차원은 아래와 같다.\n",
"\n",
"- ${\\boldsymbol x}_1$: (1,4) 이지만 (4,) 로 생각한다.\n",
"- ${\\boldsymbol h}_0$,${\\boldsymbol h}_1$: (1,2) 이지만 (2,) 로\n",
" 생각한다.\n",
"- ${\\bf W}_{ih}$: (4,2) // ${\\bf W}_{hh}$: (2,2) //\n",
" ${\\boldsymbol b}_{ih}$: (1,2) // ${\\boldsymbol b}_{hh}$: (1,2) 로\n",
" 생각한다.\n",
"\n",
"**step 3:** $\\text{간장}_1$을 이용하여 $\\text{간장계란밥}_1$을 만든다.\n",
"그리고 $\\hat{\\boldsymbol y}_1$을 만든다.\n",
"\n",
"$${\\boldsymbol o}_1= {\\bf W}_{ho}{\\boldsymbol h}_1+{\\boldsymbol b}_{ho}$$\n",
"\n",
"$$\\hat{\\boldsymbol y}_1 = \\text{soft}({\\boldsymbol o}_1)$$\n",
"\n",
"**step 4**: $t=2,3,4,5,\\dots,L$ 에 대하여 step2-3을 반복한다.\n",
"\n",
"`#`\n",
"\n",
"***`# 버전2`***\n",
"\n",
"init $\\boldsymbol{h}_0$\n",
"\n",
"for $t$ in $1:L$\n",
"\n",
"- ${\\boldsymbol h}_t= \\tanh({\\boldsymbol x}_t{\\bf W}_{ih}+{\\boldsymbol h}_{t-1}{\\bf W}_{hh}+{\\boldsymbol b}_{ih}+{\\boldsymbol b}_{hh})$\n",
"- ${\\boldsymbol o}_t= {\\bf W}_{ho}{\\boldsymbol h}_1+{\\boldsymbol b}_{ho}$\n",
"- $\\hat{\\boldsymbol y}_t = \\text{soft}({\\boldsymbol o}_t)$\n",
"\n",
"`#`\n",
"\n",
"***`# 버전3`***\n",
"\n",
"``` python\n",
"ht = [0,0]\n",
"for t in 1:T \n",
" ht = tanh(linr(xt)+linr(ht))\n",
" ot = linr(ht)\n",
" yt_hat = soft(ot)\n",
"```\n",
"\n",
"- 코드상으로는 $h_t$와 $h_{t-1}$의 구분이 교모하게 사라진다. (그래서\n",
" 오히려 좋아)\n",
"\n",
"`#`\n",
"\n",
"`-` 따라서 실질적인 전체코드는 아래와 같은 방식으로 구현할 수 있다.\n",
"\n",
"``` python\n",
"class rNNCell(torch.nn.Module):\n",
" def __init__(self):\n",
" super().__init__()\n",
" linr1 = torch.nn.Linear(?,?) \n",
" linr2 = torch.nn.Linear(?,?) \n",
" tanh = torch.nn.Tanh()\n",
" def forward(self,Xt,ht):\n",
" ht = tanh(lrnr1(Xt)+lrnr2(ht))\n",
" return ht\n",
"\n",
"init ht\n",
"rnncell = rNNCell()\n",
"\n",
"for t in 1:L \n",
" Xt, yt = X[t], y[t]\n",
" ht = rnncell(Xt, ht)\n",
" ot = linr(ht) \n",
" loss = loss + loss_fn(ot, yt)\n",
"```\n",
"\n",
"## C. 구현1 – rNNCell\n",
"\n",
"`-` 데이터정리"
],
"id": "e4471752-9c82-4977-87b0-cfb4ca18d8e4"
},
{
"cell_type": "code",
"execution_count": 184,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"x = torch.tensor(df_train.x.map({'A':0,'b':1,'c':2,'d':3}))\n",
"y = torch.tensor(df_train.y.map({'A':0,'b':1,'c':2,'d':3}))\n",
"X = torch.nn.functional.one_hot(x).float()\n",
"y = torch.nn.functional.one_hot(y).float()"
],
"id": "a330fa04-c5aa-4b49-a039-aea2c021fde7"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 순환신경망으로 적합"
],
"id": "388b165e-e723-4712-bdcf-3e2d681f96f8"
},
{
"cell_type": "code",
"execution_count": 185,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"class rNNCell(torch.nn.Module):\n",
" def __init__(self):\n",
" super().__init__()\n",
" self.i2h = torch.nn.Linear(4,2) \n",
" self.h2h = torch.nn.Linear(2,2) \n",
" self.tanh = torch.nn.Tanh()\n",
" def forward(self,Xt,ht):\n",
" ht = self.tanh(self.i2h(Xt)+self.h2h(ht))\n",
" return ht\n",
"torch.manual_seed(43052) # 시드고정해야만 답나옴 --> 임베딩공간이 부족하다는 의미 (사실상 6개의 문자니까!)\n",
"rnncell = rNNCell() # 너는 간장숙성을 담당해라\n",
"cook = torch.nn.Linear(2,4) # 너는 요리를 담당해라. \n",
"#\n",
"loss_fn = torch.nn.CrossEntropyLoss()\n",
"optimizr = torch.optim.Adam(list(rnncell.parameters())+ list(cook.parameters()),lr=0.1)\n",
"#---#\n",
"L = len(X)\n",
"for epoc in range(200):\n",
" ## 1~2 \n",
" ht = torch.zeros(2) # 첫간장은 맹물\n",
" loss = 0\n",
" for t in range(L):\n",
" Xt, yt = X[t], y[t]\n",
" ht = rnncell(Xt, ht)\n",
" ot = cook(ht) \n",
" loss = loss + loss_fn(ot, yt)\n",
" loss = loss/L\n",
" ## 3 \n",
" loss.backward()\n",
" ## 4 \n",
" optimizr.step()\n",
" optimizr.zero_grad()"
],
"id": "c3342da3-e525-423a-bd86-650417ef23cc"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 결과 확인 및 시각화"
],
"id": "28c06ca6-4774-4941-8693-72aa410ebec7"
},
{
"cell_type": "code",
"execution_count": 186,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"h = torch.zeros(L,2)\n",
"water = torch.zeros(2)\n",
"h[0] = rnncell(X[0],water)\n",
"for t in range(1,L):\n",
" h[t] = rnncell(X[t],h[t-1])\n",
"yhat = soft(cook(h))\n",
"yhat "
],
"id": "b4363fca-4577-41eb-bcbb-3d2dff7fd6ab"
},
{
"cell_type": "code",
"execution_count": 187,
"metadata": {
"tags": []
},
"outputs": [
{
"output_type": "display_data",
"metadata": {},
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAVwAAAI4CAYAAAAmm1H9AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90\nbGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9h\nAAAPYQGoP6dpAAAYyklEQVR4nO3dfWyddd348c/pxjq2tR3DDNi9IjMQYBtjZMPwMOcQwSAQwIcA\nohLUROIYjyJMRQSDlcR7EjGiIxFBMkT/WCRG4UYUYfIQ2NaNgDJxwMqTgwk9XaftPXp+f0z6uyts\n6+lOP9d6eL2SE3quXSfX57t2711cp+tVqlQqlQBg2DUUPQDAu4XgAiQRXIAkgguQRHABkgguQBLB\nBUgiuABJBBcgieACJKmL4F522WVx6qmnFj1GzdTbeoBt6iK47e3tcfjhhxc9Rs3U23rmz58fpVIp\nSqVS7LHHHnHwwQfHsmXLih5rSOppLRH1tZ6RsJa6CO6aNWvqKlD1tJ5KpRLt7e3R1tYWL7/8cqxb\nty7mzZsX5557bjz77LNFj1eVelpLRH2tZ6SsZcQHt6OjIzZt2hQNDQ1xwgknxLhx4+Lggw+ORx99\ntOjRhqTe1vPXv/41urq6Yt68ebHvvvvGtGnT4qtf/Wps3bo11q5dW/R4VamntUTU13pGylpGfHDb\n29sjIuLGG2+MxYsXx5o1a2L//fePK6+8stjBhqje1rNy5coolUoxa9as/m0vvPBCRETss88+RY01\nJPW0loj6Ws9IWUtdBHevvfaKX/ziF/GhD30oDjrooDj99NPj1VdfjYiIM844I/baa6/4xCc+UfCk\ng7Oj9XR0dMSCBQti+vTpMWvWrPjlL39Z9Lg7tWrVqpg2bVo0NzdHRMTTTz8dX/7yl2P27Nnx/ve/\nv3+/j33sY7FgwYKCphycna3l17/+dSxatKjgKQdvsJ+bkaDatXzwgx+M5557LnnKOgnuaaedFpMn\nT+7ftn79+jjwwAMjIuLCCy+M2267rajxqraj9YwePTpuuOGGeOqpp+J3v/tdXHLJJdHd3V3gtDu3\ncuXKeO6552LChAkxduzYmD17dsyYMSPuvvvuaGjY9uW3evXqeOWVV+Ivf/lLwdPu2M7Wsnbt2jji\niCOKHnPQBvO5GSmqXctzzz0XBxxwQPqcI+t39R20t7fH0UcfPWDb6tWrY/bs2RERcdxxx0VTU1MB\nkw3Njtaz33779a9r8uTJMWnSpPjHP/5RwJSDt3r16rj88sujvb091q9fH1u2bImf/vSnA/4376qr\nrorvfOc7MX78+HjttdcKnHbHdraWtWvXxp///OeYM2dOzJgxI9atW1fwxDu2s/U8//zzccopp/TH\n68UXXyx44u3b2VqefPLJOOqoo+Lwww+PJUuWRGtrayFzjujgdnV1xbPPPvu2s4r29vb+MI0k1azn\n8ccfj76+vsK+cAZj/fr18cYbb8QJJ5wQBx54YEyZMiVKpdKAfR599NHo6emJ+fPnx6GHHhpPPfVU\nQdPu2GDWsnbt2th///1j5cqVsWjRoliyZElB0+7cztbT29sbJ598cnzlK1+J9vb2ePDBB3era6H/\n187W8s9//jPOOuus+MlPfhJr1qyJ+++/f8C13kwjOrjt7e3R0NAQhx12WP+2559/Pl5//fURGdzB\nrmfTpk3x2c9+NpYuXVrAlIP31hsZc+bM2e4+V111VVx77bUREbt1cHe2lp6enujt7Y2FCxdGRMSs\nWbN267P1na1n+fLlcdRRR8X8+fMjImLSpEkxevTozBEHbTBreeu9j4iIgw8+uLDg7p6/g4O0Zs2a\nOOSQQ2Ls2LH921avXh0TJ04s5PrMrhrMenp6euKMM86IxYsXxzHHHFPQpIOzatWqOPDAA2PixInv\n+OsPPvhgrFixIs4+++yIiNi8eXN86lOfSpxw8Ha2lieffDKmT58+4Lp0UX+oB2Nn63niiSfiyCOP\nzB1qiAbzufm/n4tVq1bFGWeckTTdf6i8C/zhD3+ofPzjHy96jF3W19dXOeussypXX3110aPUxIIF\nCyp/+tOf+p+vWLGicvzxxxc40dDdcsstlenTp1d6e3srf//73ytz586tvPrqq0WPNWTf//73Kxdc\ncEGlUqlUtm7dWtm0aVPBEw3df//3f1cuvvjiSqVSqdxzzz2VhoaGSrlcLmSWUqVS37dJ/8hHPhKr\nVq2K7u7umDRpUixfvnzE/M39n1asWBHz588f8Lf1z372swGXIEaK++67L6677rr4/e9/379t48aN\nMXv27HjppZcKnGxoLrvsshg/fnzcdddd0dfXF9/73vfi+OOPL3qsIevq6oozzzwzNmzYEHvssUf8\n+Mc/HnHfKvaWjRs3xkknnRSVSiVmzpwZDz30UDzzzDOFzFL3wQXYXYzoN80ARhLBBUgiuABJBBcg\n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\n"
}
}
],
"source": [
"mat = torch.concat([h,yhat],axis=1).data[:10]\n",
"plt.matshow(mat,cmap='bwr',vmin=-1,vmax=1)\n",
"plt.axvline(x=1.5,color='lime')\n",
"plt.xticks(range(6),[r'$h_1$',r'$h_2$',r'$P_A$',r'$P_b$',r'$P_c$',r'$P_d$']);"
],
"id": "bf3ab824-4b5a-4065-bd9f-337862e4264c"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` yhat 값 분석"
],
"id": "adce6bec-db85-4ae4-b50c-6e57b6c72ddc"
},
{
"cell_type": "code",
"execution_count": 188,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"yhat.data.numpy().round(3)[:10]"
],
"id": "d51a242e-0ad0-456f-bd50-56cc6cc5696b"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 미세하지만 뒤로갈수록 좀 더 성능이 좋다.\n",
"\n",
"`-` h1,h2 분석 (= 임베딩스페이스 분석)"
],
"id": "230ac82d-dbf0-4ef6-8316-84e5a78e8247"
},
{
"cell_type": "code",
"execution_count": 189,
"metadata": {
"tags": []
},
"outputs": [
{
"output_type": "display_data",
"metadata": {},
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjgAAAGdCAYAAAAfTAk2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90\nbGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9h\nAAAPYQGoP6dpAAA7g0lEQVR4nO3de3RU1cH//8+QywQoGcBAEiSGqBguQQtBSILcBEJoEX1ECRUi\numharNyMVqXewPW1iC1SQQH1CQYUIVpM9VeQGhBQmnBPKCgitdGgJHJZYQZQcoHz+4Myj8PkCjnJ\n5OT9Wuusxdlnn7P39jDMxz37zNgMwzAEAABgIS0auwMAAAD1jYADAAAsh4ADAAAsh4ADAAAsh4AD\nAAAsh4ADAAAsh4ADAAAsh4ADAAAsx7+xO9AYzp8/ryNHjqhNmzay2WyN3R0AAFALhmHo1KlT6tSp\nk1q0qH6OplkGnCNHjigiIqKxuwEAAC7D4cOH1blz52rrNMuA06ZNG0kX/gMFBwc3cm8AAEBtuFwu\nRUREuN/Hq9MsA87Fj6WCg4MJOAAANDG1WV7CImMAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5\nBBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5pgacTz75RLfddps6deokm82mv/3tbzWes2XLFsXGxioo\nKEjXXnutli5d6lVnzZo16tGjh+x2u3r06KGsrCwTel83vZb3cm+V7QMAgIZjasA5c+aMbrrpJr38\n8su1ql9QUKBf/OIXGjhwoPLy8vSHP/xB06dP15o1a9x1cnNzlZycrJSUFO3du1cpKSkaN26ctm/f\nbtYwanRpiKlpH4C3V6Z87N4q2wdQvYUbDynq8bVatPGQx/7C/+43NzbDMIwGachmU1ZWlu64444q\n6zz22GP64IMPdODAAXfZlClTtHfvXuXm5kqSkpOT5XK59OGHH7rrJCUlqV27dlq1alWt+uJyueRw\nOOR0Ouvlt6hqE2D2Tdp3xe0AVlWbEPPg0lsboCdA07Rw4yG9mP2le3/A9Vfpn/8+4d5PG3GDpg/r\nWu01ujy+1v3nr5//pde+L6jL+7dPrcHJzc1VYmKiR9nIkSO1a9culZeXV1snJyenyuuWlpbK5XJ5\nbAAAWMWCn4QbSR7hprLjl/ppmKnNflPgUwGnuLhYoaGhHmWhoaGqqKjQ8ePHq61TXFxc5XXnzp0r\nh8Ph3iIiIuq13zXNzjB7AwAw00Mjbqj2eFoNx63IpwKO5P0T6Bc/QftpeWV1qvvp9FmzZsnpdLq3\nw4cP12OPa/6IijU4QPVq+viJj6eA6k0f1lUDrr+q0mO3XB+iaTV8PGVFPhVwwsLCvGZijh49Kn9/\nf1111VXV1rl0Vuen7Ha7goODPTYAvqOmNTgsNAaqt3DjIa+PpS7a+u/j7oXHValpjY2vrMGpC58K\nOPHx8crOzvYo++ijj9S3b18FBARUWychIaHB+gkAgC+paY3Ni3Vcg1PX477I1IBz+vRp5efnKz8/\nX9KFx8Dz8/NVWFgo6cJHR/fee6+7/pQpU/TNN98oLS1NBw4c0LJly5Senq5HHnnEXWfGjBn66KOP\nNG/ePH3xxReaN2+eNmzYoJkzZ5o5lGpdusampn0AAOrTpWtwbrk+pNrjzYGpj4lv3rxZQ4cO9Sqf\nNGmSMjIydN999+nrr7/W5s2b3ce2bNmihx56SJ999pk6deqkxx57TFOmTPE4/69//auefPJJ/ec/\n/9F1112n5557TnfeeWet+1Xfj4kDuHI//RjqwaW3eu0DqN7CjYe0IPtLpY24QdOGdXXvP1THR8Sr\n4gsfU9Xl/bvBvgfHlxBwAADwZLXvwSHgEHAAAGgSmuwX/QEAANQHAg4AALAcAg4AALAcAg4AALAc\nAg4AALAcAg4AALAcAg4AALAcAg4AALAcAg4AALAcAg4AALAcAg4AALAcAg4AALAcAg4AALAcAg4A\nALAcAg4AALAcAg4AALAcAg4AALAcAg4AALAcAg4AALAcAg4AALAcAg4AALAcAg4AALAcAg4AALAc\nAg4AALAcAg4AALAcAg4AALAcAg4AALAcAg4AALAcAg4AALAcAg4AALCcBgk4ixcvVlRUlIKCghQb\nG6tPP/20yrr33XefbDab19azZ093nYyMjErrnD17tiGGAwAAfJzpASczM1MzZ87UE088oby8PA0c\nOFCjRo1SYWFhpfVfeuklFRUVubfDhw+rffv2uvvuuz3qBQcHe9QrKipSUFCQ2cMBAABNgOkB58UX\nX9TkyZP161//Wt27d9df/vIXRUREaMmSJZXWdzgcCgsLc2+7du1SSUmJ7r//fo96NpvNo15YWJjZ\nQwEAAE2EqQGnrKxMu3fvVmJiokd5YmKicnJyanWN9PR0DR8+XJGRkR7lp0+fVmRkpDp37qzRo0cr\nLy+vymuUlpbK5XJ5bAAAwLpMDTjHjx/XuXPnFBoa6lEeGhqq4uLiGs8vKirShx9+qF//+tce5d26\ndVNGRoY++OADrVq1SkFBQRowYIAOHTpU6XXmzp0rh8Ph3iIiIi5/UAAAwOc1yCJjm83msW8YhldZ\nZTIyMtS2bVvdcccdHuVxcXGaOHGibrrpJg0cOFDvvPOObrjhBi1atKjS68yaNUtOp9O9HT58+LLH\nAgAAfJ+/mRcPCQmRn5+f12zN0aNHvWZ1LmUYhpYtW6aUlBQFBgZWW7dFixa6+eabq5zBsdvtstvt\ndes8AABoskydwQkMDFRsbKyys7M9yrOzs5WQkFDtuVu2bNG///1vTZ48ucZ2DMNQfn6+wsPDr6i/\nAADAGkydwZGktLQ0paSkqG/fvoqPj9drr72mwsJCTZkyRdKFj4++++47rVixwuO89PR09e/fXzEx\nMV7XnDNnjuLi4tS1a1e5XC4tXLhQ+fn5euWVV8weDgAAaAJMDzjJyck6ceKEnn32WRUVFSkmJkbr\n1q1zPxVVVFTk9Z04TqdTa9as0UsvvVTpNU+ePKnf/OY3Ki4ulsPhUO/evfXJJ5+oX79+Zg8HAAA0\nATbDMIzG7kRDc7lccjgccjqdCg4ObuzuAACAWqjL+ze/RQUAACyHgAMAACyHgAMAACyHgAMAACyH\ngAMAACyHgAMAACyHgAMAACyHgAMAACyHgAMAACyHgAMAACyHgAMAACyHgAMAACyHgAMAACyHgAMA\nACyHgAMAACyHgAMAACyHgAMAACyHgAMAACyHgAMAACyHgAMAACyHgAMAACyHgAMAACyHgAMAACyH\ngAMAACyHgAMAACyHgAMAACyHgAMAACyHgAMAACyHgAMAACyHgAMAACyHgAMAACynQQLO4sWLFRUV\npaCgIMXGxurTTz+tsu7mzZtls9m8ti+++MKj3po1a9SjRw/Z7Xb16NFDWVlZZg8DAAA0EaYHnMzM\nTM2cOVNPPPGE8vLyNHDgQI0aNUqFhYXVnnfw4EEVFRW5t65du7qP5ebmKjk5WSkpKdq7d69SUlI0\nbtw4bd++3ezhAACAJsBmGIZhZgP9+/dXnz59tGTJEndZ9+7ddccdd2ju3Lle9Tdv3qyhQ4eqpKRE\nbdu2rfSaycnJcrlc+vDDD91lSUlJateunVatWlVjn1wulxwOh5xOp4KDg+s+KAAA0ODq8v5t6gxO\nWVmZdu/ercTERI/yxMRE5eTkVHtu7969FR4ermHDhmnTpk0ex3Jzc72uOXLkyCqvWVpaKpfL5bEB\nAADrMjXgHD9+XOfOnVNoaKhHeWhoqIqLiys9Jzw8XK+99prWrFmj9957T9HR0Ro2bJg++eQTd53i\n4uI6XXPu3LlyOBzuLSIi4gpHBgAAfJl/QzRis9k89g3D8Cq7KDo6WtHR0e79+Ph4HT58WH/+8581\naNCgy7rmrFmzlJaW5t53uVyEHAAALMzUGZyQkBD5+fl5zawcPXrUawamOnFxcTp06JB7PywsrE7X\ntNvtCg4O9tgAAIB1mRpwAgMDFRsbq+zsbI/y7OxsJSQk1Po6eXl5Cg8Pd+/Hx8d7XfOjjz6q0zUB\nAIB1mf4RVVpamlJSUtS3b1/Fx8frtddeU2FhoaZMmSLpwsdH3333nVasWCFJ+stf/qIuXbqoZ8+e\nKisr01tvvaU1a9ZozZo17mvOmDFDgwYN0rx583T77bfr/fff14YNG7R161azhwMAAJoA0wNOcnKy\nTpw4oWeffVZFRUWKiYnRunXrFBkZKUkqKiry+E6csrIyPfLII/ruu+/UsmVL9ezZU2vXrtUvfvEL\nd52EhAStXr1aTz75pJ566ildd911yszMVP/+/c0eDgAAaAJM/x4cX8T34AAA0PT4zPfgAAAANAYC\nDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAA\nsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwC\nDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAA\nsBwCDgAAsJwGCTiLFy9WVFSUgoKCFBsbq08//bTKuu+9955GjBihDh06KDg4WPHx8frHP/7hUScj\nI0M2m81rO3v2rNlDAQAATYDpASczM1MzZ87UE088oby8PA0cOFCjRo1SYWFhpfU/+eQTjRgxQuvW\nrdPu3bs1dOhQ3XbbbcrLy/OoFxwcrKKiIo8tKCjI7OEAAIAmwGYYhmFmA/3791efPn20ZMkSd1n3\n7t11xx13aO7cubW6Rs+ePZWcnKynn35a0oUZnJkzZ+rkyZOX1SeXyyWHwyGn06ng4ODLugYAAGhY\ndXn/NnUGp6ysTLt371ZiYqJHeWJionJycmp1jfPnz+vUqVNq3769R/np06cVGRmpzp07a/To0V4z\nPD9VWloql8vlsQEAAOsyNeAcP35c586dU2hoqEd5aGioiouLa3WN+fPn68yZMxo3bpy7rFu3bsrI\nyNAHH3ygVatWKSgoSAMGDNChQ4cqvcbcuXPlcDjcW0RExOUPCgAA+LwGWWRss9k89g3D8CqrzKpV\nqzR79mxlZmaqY8eO7vK4uDhNnDhRN910kwYOHKh33nlHN9xwgxYtWlTpdWbNmiWn0+neDh8+fGUD\nAgAAPs3fzIuHhITIz8/Pa7bm6NGjXrM6l8rMzNTkyZP17rvvavjw4dXWbdGihW6++eYqZ3Dsdrvs\ndnvdOg8AAJosU2dwAgMDFRsbq+zsbI/y7OxsJSQkVHneqlWrdN999+ntt9/WL3/5yxrbMQxD+fn5\nCg8Pv+I+AwCAps/UGRxJSktLU0pKivr27av4+Hi99tprKiws1JQpUyRd+Pjou+++04oVKyRdCDf3\n3nuvXnrpJcXFxblnf1q2bCmHwyFJmjNnjuLi4tS1a1e5XC4tXLhQ+fn5euWVV8weDgAAaAJMDzjJ\nyck6ceKEnn32WRUVFSkmJkbr1q1TZGSkJKmoqMjjO3FeffVVVVRU6MEHH9SDDz7oLp80aZIyMjIk\nSSdPntRvfvMbFRcXy+FwqHfv3vrkk0/Ur18/s4cDAACaANO/B8cX8T04AAA0PT7zPTgAAACNgYAD\nAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAs\nh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4AD\nAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAs\nh4ADAAAsp0ECzuLFixUVFaWgoCDFxsbq008/rbb+li1bFBsbq6CgIF177bVaunSpV501a9aoR48e\nstvt6tGjh7KysszqPgAAaGJMDziZmZmaOXOmnnjiCeXl5WngwIEaNWqUCgsLK61fUFCgX/ziFxo4\ncKDy8vL0hz/8QdOnT9eaNWvcdXJzc5WcnKyUlBTt3btXKSkpGjdunLZv3272cAAAQBNgMwzDMLOB\n/v37q0+fPlqyZIm7rHv37rrjjjs0d+5cr/qPPfaYPvjgAx04cMBdNmXKFO3du1e5ubmSpOTkZLlc\nLn344YfuOklJSWrXrp1WrVpVY59cLpccDoecTqeCg4OvZHgAAKCB1OX929QZnLKyMu3evVuJiYke\n5YmJicrJyan0nNzcXK/6I0eO1K5du1ReXl5tnaquWVpaKpfL5bEBAADrMjXgHD9+XOfOnVNoaKhH\neWhoqIqLiys9p7i4uNL6FRUVOn78eLV1qrrm3Llz5XA43FtERMTlDgkAADQBDbLI2GazeewbhuFV\nVlP9S8vrcs1Zs2bJ6XS6t8OHD9ep/wAAoGnxN/PiISEh8vPz85pZOXr0qNcMzEVhYWGV1vf399dV\nV11VbZ2qrmm322W32y93GAAAoIkxdQYnMDBQsbGxys7O9ijPzs5WQkJCpefEx8d71f/oo4/Ut29f\nBQQEVFunqmsCAIDmxdQZHElKS0tTSkqK+vbtq/j4eL322msqLCzUlClTJF34+Oi7777TihUrJF14\nYurll19WWlqaUlNTlZubq/T0dI+no2bMmKFBgwZp3rx5uv322/X+++9rw4YN2rp1q9nDAQAATYDp\nASc5OVknTpzQs88+q6KiIsXExGjdunWKjIyUJBUVFXl8J05UVJTWrVunhx56SK+88oo6deqkhQsX\nauzYse46CQkJWr16tZ588kk99dRTuu6665SZman+/fubPRwAANAEmP49OL6I78EBAKDp8ZnvwQEA\nAGgMBBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5\nBBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwA\nAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5BBwAAGA5\nBBwAAGA5BBwAAGA5pgackpISpaSkyOFwyOFwKCUlRSdPnqyyfnl5uR577DH16tVLrVu3VqdOnXTv\nvffqyJEjHvWGDBkim83msY0fP97MoQAAgCbE1IBzzz33KD8/X+vXr9f69euVn5+vlJSUKuv/8MMP\n2rNnj5566int2bNH7733nr788kuNGTPGq25qaqqKiorc26uvvmrmUAAAQBPib9aFDxw4oPXr12vb\ntm3q37+/JOn1119XfHy8Dh48qOjoaK9zHA6HsrOzPcoWLVqkfv36qbCwUNdcc427vFWrVgoLCzOr\n+wAAoAkzLeDk5ubK4XC4w40kxcXFyeFwKCcnp9KAUxmn0ymbzaa2bdt6lK9cuVJvvfWWQkNDNWrU\nKD3zzDNq06ZNfQ4BAADUwfzk0e4/P5z5d6/9hmRawCkuLlbHjh29yjt27Kji4uJaXePs2bN6/PHH\ndc899yg4ONhdPmHCBEVFRSksLEz79+/XrFmztHfvXq/Zn4tKS0tVWlrq3ne5XHUcDQAAqM5Pw0xV\n+w0Zcuq8Bmf27NleC3wv3Xbt2iVJstlsXucbhlFp+aXKy8s1fvx4nT9/XosXL/Y4lpqaquHDhysm\nJkbjx4/XX//6V23YsEF79uyp9Fpz5851L3R2OByKiIio67ABAEATUucZnKlTp9b4xFKXLl30r3/9\nS99//73XsWPHjik0NLTa88vLyzVu3DgVFBTo448/9pi9qUyfPn0UEBCgQ4cOqU+fPl7HZ82apbS0\nNPe+y+Ui5AAAYGF1DjghISEKCQmpsV58fLycTqd27Nihfv36SZK2b98up9OphISEKs+7GG4OHTqk\nTZs26aqrrqqxrc8++0zl5eUKDw+v9Ljdbpfdbq/xOgAA4PJcuuamsuMNybTHxLt3766kpCSlpqZq\n27Zt2rZtm1JTUzV69GiPBcbdunVTVlaWJKmiokJ33XWXdu3apZUrV+rcuXMqLi5WcXGxysrKJElf\nffWVnn32We3atUtff/211q1bp7vvvlu9e/fWgAEDzBoOAACoRnXhpjbH65up34OzcuVK9erVS4mJ\niUpMTNSNN96oN99806POwYMH5XQ6JUnffvutPvjgA3377bf6+c9/rvDwcPeWk5MjSQoMDNTGjRs1\ncuRIRUdHa/r06UpMTNSGDRvk5+dn5nAAAEATYdpTVJLUvn17vfXWW9XWMQzD/ecuXbp47FcmIiJC\nW7ZsqZf+VccwDFVUVOjcuXOmt9VY/Pz85O/vX6tF3wAANCWmBpymqqysTEVFRfrhhx8auyuma9Wq\nlcLDwxUYGNjYXQEANGGVfe9NY34Pjs2oacrEglwulxwOh5xOp9cTWufPn9ehQ4fk5+enDh06KDAw\n0JIzHIZhqKysTMeOHdO5c+fUtWtXtWjBb68CAHxXde/fl2IG5xJlZWU6f/68IiIi1KpVq8bujqla\ntmypgIAAffPNNyorK1NQUFBjdwkAgHrB/7JXobnMZjSXcQIAmhfe3QAAgOUQcAAAgOUQcCwoJydH\nfn5+SkpKauyuAADQKAg4Jlm48ZCiHl+rRRsPeewv/O++mZYtW6Zp06Zp69atKiwsNL09AAB8DU9R\nmWDhxkN6MftLSdL87C+1reCE/vnvE5LkLp8+rKspbZ85c0bvvPOOdu7cqeLiYmVkZOjpp582pS0A\nAHwVMzgmWPDfEHPRxXBT1fH6lJmZqejoaEVHR2vixIl64403avx2aAAArIaAY4KHRtxQ7fG0Go5f\nifT0dE2cOFGSlJSUpNOnT2vjxo2mtQcAgC8i4Jhg+rCuGnD9VZUeu+X6EE0z6eOpgwcPaseOHRo/\nfrwkyd/fX8nJyVq2bJkp7QEA4KtYg2OChRsPeX0sddHWfx/Xoo2HTAk56enpqqio0NVXX+0uMwxD\nAQEBKikpUbt27eq9TQAAfBEzOCaoaY3NiyaswamoqNCKFSs0f/585efnu7e9e/cqMjJSK1eurPc2\nAQDwVQQcE1y6BueW60OqPV4f/v73v6ukpESTJ09WTEyMx3bXXXcpPT293tsEAMBXEXBMMH1YV6WN\nuEE2SQ+PuEFv/bq/ez9txA2mPCKenp6u4cOHy+FweB0bO3as8vPztWfPnnpvFwAAX2QzmuEzxNX9\n3PrZs2dVUFCgqKioZvHr2s1tvACApqu69+9LMYMDAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAs\nh4ADAAAsh4ADAAAsh4ADAAAsh4ADAAAsh4BjIUOGDNHMmTMbuxsAADQ6Ag4AALAcAo5ZtrwgzW4r\nbfnTJfsvNGavAABoFgg4ZtjygrTpOUmGtOn/ScvH/GT/OVNDTkVFhaZOnaq2bdvqqquu0pNPPqlm\n+HuqAIBmjoBjhk1/9Nwv2FL98Xq0fPly+fv7a/v27Vq4cKEWLFig//3f/zWtPQAAfJGpAaekpEQp\nKSlyOBxyOBxKSUnRyZMnqz3nvvvuk81m89ji4uI86pSWlmratGkKCQlR69atNWbMGH377bcmjqSO\nhv6hhuNPmNZ0RESEFixYoOjoaE2YMEHTpk3TggULTGsPAABfZGrAueeee5Sfn6/169dr/fr1ys/P\nV0pKSo3nJSUlqaioyL2tW7fO4/jMmTOVlZWl1atXa+vWrTp9+rRGjx6tc+fOmTWUuhn8qBQ1uPJj\n1w6RBv/etKbj4uJks9nc+/Hx8Tp06JDv/LcBAKAB+Jt14QMHDmj9+vXatm2b+vfvL0l6/fXXFR8f\nr4MHDyo6OrrKc+12u8LCwio95nQ6lZ6erjfffFPDhw+XJL311luKiIjQhg0bNHLkyPofTF1tecH7\nY6mL/rP5wsJjE0MOAADNnWkzOLm5uXI4HO5wI12YXXA4HMrJyan23M2bN6tjx4664YYblJqaqqNH\nj7qP7d69W+Xl5UpMTHSXderUSTExMTVet8HUtMZm03OmNb1t2zav/a5du8rPz8+0NgEA8DWmBZzi\n4mJ17NjRq7xjx44qLi6u8rxRo0Zp5cqV+vjjjzV//nzt3LlTt956q0pLS93XDQwMVLt27TzOCw0N\nrfK6paWlcrlcHpupLl2Dc+2Q6o/Xo8OHDystLU0HDx7UqlWrtGjRIs2YMcO09gAA8EV1DjizZ8/2\nWgR86bZr1y5J8lgLcpFhGJWWX5ScnKxf/vKXiomJ0W233aYPP/xQX375pdauXVttv6q77ty5c90L\nnR0OhyIiIuow4ssw+NH/LiS2SUOflO59/yf7T1w4bpJ7771XP/74o/r166cHH3xQ06ZN029+8xvT\n2gMAwBfVeQ3O1KlTNX78+GrrdOnSRf/617/0/fffex07duyYQkNDa91eeHi4IiMjdejQIUlSWFiY\nysrKVFJS4jGLc/ToUSUkJFR6jVmzZiktLc2973K5Gibk/DTIXLpvgs2bN7v/vGTJElPbAgDAl9U5\n4ISEhCgkJKTGevHx8XI6ndqxY4f69esnSdq+fbucTmeVQaQyJ06c0OHDhxUeHi5Jio2NVUBAgLKz\nszVu3DhJUlFRkfbv368XXqj8C/Tsdrvsdnut2wQAAE2baWtwunfvrqSkJKWmpmrbtm3atm2bUlNT\nNXr0aI8nqLp166asrCxJ0unTp/XII48oNzdXX3/9tTZv3qzbbrtNISEh+p//+R9JksPh0OTJk/Xw\nww9r48aNysvL08SJE9WrVy/3U1UAAKB5M+0xcUlauXKlpk+f7n7iacyYMXr55Zc96hw8eFBOp1OS\n5Ofnp3379mnFihU6efKkwsPDNXToUGVmZqpNmzbucxYsWCB/f3+NGzdOP/74o4YNG6aMjAyeFAIA\nAJIkm9EMf6jI5XLJ4XDI6XQqODjY49jZs2dVUFCgqKgoBQUFNVIPG05zGy8AoOmq7v37UvwWFQAA\nsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCDgAAsBwCjgXl5OTIz89PSUlJjd0VAAAaBQHHJEv3\nLtWNy2/Uq3tf9dhfunep6W0vW7ZM06ZN09atW1VYWGh6ewAA+BpTv8m4uVq6d6leyX9FkvRy/sva\n+f1ObS/aLknu8ik3TTGl7TNnzuidd97Rzp07VVxcrIyMDD399NOmtAUAgK9iBscEi/MXe+xfDDdV\nHa9PmZmZio6OVnR0tCZOnKg33nhDzfDLqgEAzRwBxwS/+/nvqj3+4M8fNK3t9PR0TZw4UZKUlJSk\n06dPa+PGjaa1BwCALyLgmGDKTVPUP7x/pcfiwuP025t+a0q7Bw8e1I4dOzR+/HhJkr+/v5KTk7Vs\n2TJT2gMAwFexBscES/cu9fpY6qJtRdv06t5XTQk56enpqqio0NVXX+0uMwxDAQEBKikpUbt27eq9\nTQAALjrQrbv7z92/OOC135CYwTFBTWtsLi40rk8VFRVasWKF5s+fr/z8fPe2d+9eRUZGauXKlfXe\nJgAAF/00zNRm32wEHBNcugYnLjyu2uP14e9//7tKSko0efJkxcTEeGx33XWX0tPT671NAAB8FQHH\nBFNumqIHf/6gbLJp6s+n6vXE1937D/78QVMeEU9PT9fw4cPlcDi8jo0dO1b5+fnas2dPvbcLAIAv\nshnN8Blil8slh8Mhp9Op4OBgj2Nnz55VQUGBoqKiFBQU1Eg9bDjNbbwAAPNU9zFUfazBqe79+1LM\n4AAAgCtW0xob1uAAAABcIQIOAACwHAIOAAC4Ypeusalp32x80R8AAKgXjR1qfooZHAAAYDkEHAAA\nYDkEHAAAYDkEHAAAYDkEHAAAYDkEHAAAYDkEHJMcW7xYB7r30PElSzz2jy1e3Mg9AwDA+gg4Jji2\neLGOL1wkGYaOvbRQ39x/v3v/+MJFpoWc8+fPa968ebr++utlt9t1zTXX6LnnnjOlLQAAfBkBxwTH\nF73ssf9D7rZqj9eXWbNmad68eXrqqaf0+eef6+2331ZoaKgpbQEA4MtMDTglJSVKSUmRw+GQw+FQ\nSkqKTp48We05Nput0u1Pf/qTu86QIUO8jo8fP97ModRJyLSp1R7vMH1avbd56tQpvfTSS3rhhRc0\nadIkXXfddbrlllv061//ut7bAgDA15kacO655x7l5+dr/fr1Wr9+vfLz85WSklLtOUVFRR7bsmXL\nZLPZNHbsWI96qampHvVeffVVM4dSJx1+9zu1io+r9FjrhHiFPPBAvbd54MABlZaWatiwYfV+bQAA\nmhrTfovqwIEDWr9+vbZt26b+/ftLkl5//XXFx8fr4MGDio6OrvS8sLAwj/33339fQ4cO1bXXXutR\n3qpVK6+6vuLY4sVeH0tddCYnV8eXLKn3kNOyZct6vR4AAE2ZaTM4ubm5cjgc7nAjSXFxcXI4HMrJ\nyanVNb7//nutXbtWkydP9jq2cuVKhYSEqGfPnnrkkUd06tSpeuv7lappjc2xhYvqvc2uXbuqZcuW\n2rhxY71fGwCApsa0GZzi4mJ17NjRq7xjx44qLi6u1TWWL1+uNm3a6M477/QonzBhgqKiohQWFqb9\n+/dr1qxZ2rt3r7Kzsyu9TmlpqUpLS937LperDiOpu5BpUy88NfVfrRPidSYn1+N4fQsKCtJjjz2m\nRx99VIGBgRowYICOHTumzz77rNKACACAldU54MyePVtz5sypts7OnTslXVgwfCnDMCotr8yyZcs0\nYcIEBQUFeZSnpqa6/xwTE6OuXbuqb9++2rNnj/r06eN1nblz59bY5/rU4Xe/k3RhJqfD9GkKeeCB\nC4+OL3pZIdOmuo/Xt6eeekr+/v56+umndeTIEYWHh2vKlCmmtAUAgC+zGYZh1OWE48eP6/jx49XW\n6dKli95++22lpaV5PTXVtm1bLViwQPfff3+11/j00081aNAg5efn66abbqq2rmEYstvtevPNN5Wc\nnOx1vLIZnIiICDmdTgUHB3vUPXv2rAoKChQVFeUVrKyouY0XANB0uVwuORyOSt+/L1XnGZyQkBCF\nhITUWC8+Pl5Op1M7duxQv379JEnbt2+X0+lUQkJCjeenp6crNja2xnAjSZ999pnKy8sVHh5e6XG7\n3S673V7jdQAAgDWYtsi4e/fuSkpKUmpqqrZt26Zt27YpNTVVo0eP9niCqlu3bsrKyvI41+Vy6d13\n3630O1y++uorPfvss9q1a5e+/vprrVu3Tnfffbd69+6tAQMGmDUcAADQhJj6PTgrV65Ur169lJiY\nqMTERN1444168803PeocPHhQTqfTo2z16tUyDEO/+tWvvK4ZGBiojRs3auTIkYqOjtb06dOVmJio\nDRs2yM/Pz8zhAACAJqLOa3CsoLrP8JrbmpTmNl4AQNNVlzU4/BYVAACwHAIOAACwHAIOAACwHAIO\nAACwHAIOAACwHAIOAACwHAKOBeXk5MjPz09JSUmN3RUAABoFAcckO9cW6JUpH2vXugKP/Z1rC0xv\ne9myZZo2bZq2bt2qwsJC09sDAMDX1Pm3qFCznWsLtOP/uxBktn9QoO++PKlvvyiRJHf5zb+MMqXt\nM2fO6J133tHOnTtVXFysjIwMPf3006a0BQCAr2IGxwQXQ8xFF8NNVcfrU2ZmpqKjoxUdHa2JEyfq\njTfeUDP8smoAQDNHwDFBv9uqn53pP8ac2Rvpwq+wT5w4UZKUlJSk06dPa+PGjaa1BwCALyLgmODm\nX0apc7d2lR7r3K2d+v7CnIBz8OBB7dixQ+PHj5ck+fv7Kzk5WcuWLTOlPQAAfBVrcEywc22B18dS\nF337RYl2rSswJeSkp6eroqJCV199tbvMMAwFBASopKRE7dpVHroAALAaZnBMUNMam+0f1P8anIqK\nCq1YsULz589Xfn6+e9u7d68iIyO1cuXKem8TAABfRcAxwaVrcC79uKqmNTqX4+9//7tKSko0efJk\nxcTEeGx33XWX0tPT671NAAB8FQHHBDf/MsodYvqPidLtM3u79/vdFmXKI+Lp6ekaPny4HA6H17Gx\nY8cqPz9fe/bsqfd2AQDwRTajGT5D7HK55HA45HQ6FRwc7HHs7NmzKigoUFRUlIKCghqphw2nuY0X\nANB0Vff+fSlmcAAAgOUQcAAAgOUQcAAAgOUQcAAAgOUQcAAAgOUQcAAAgOUQcAAAgOUQcAAAgOUQ\ncAAAgOUQcCxuyJAhmjlzZmN3AwCABkXAAQAAlkPAMUnumlWan3ybtq1Z7bGfu2ZVI/cMAADr82/s\nDlhR7ppVynlnpSTpn++8pcOf71Ph/r2S5C6PH/urem/3zJkzeuCBB/Tee++pTZs2euSRR+q9DQAA\nmgJmcEyQ887bHvsXw01Vx+vL73//e23atElZWVn66KOPtHnzZu3evduUtgAA8GWmBpznnntOCQkJ\natWqldq2bVurcwzD0OzZs9WpUye1bNlSQ4YM0WeffeZRp7S0VNOmTVNISIhat26tMWPG6NtvvzVh\nBJcnYdw91R4fMG5Cvbd5+vRppaen689//rNGjBihXr16afny5Tp37ly9twUAQKVmO/5vq2y/AZka\ncMrKynT33XfrgQceqPU5L7zwgl588UW9/PLL2rlzp8LCwjRixAidOnXKXWfmzJnKysrS6tWrtXXr\nVp0+fVqjR4/2mTfz+LG/0jUxN1V67JpeP1fc2PH13uZXX32lsrIyxcfHu8vat2+v6Ojoem8LAAAv\nl4aYmvZNZmrAmTNnjh566CH16tWrVvUNw9Bf/vIXPfHEE7rzzjsVExOj5cuX64cfftDbb1/4WMfp\ndCo9PV3z58/X8OHD1bt3b7311lvat2+fNmzYYOZwai13zSqvj6UuKtyX7154XJ8Mw6j3awIA0FT5\n1BqcgoICFRcXKzEx0V1mt9s1ePBg5eTkSJJ2796t8vJyjzqdOnVSTEyMu05jq2mNzT//u9C4Pl1/\n/fUKCAjQtm3b3GUlJSX68ssv670tAAB8nU8FnOLiYklSaGioR3loaKj7WHFxsQIDA9WuXbsq61yq\ntLRULpfLYzPTpWtwrun182qP14ef/exnmjx5sn7/+99r48aN2r9/v+677z61aOFTtxgAYFWznVd2\nvJ7V+d1v9uzZstls1W67du26ok7ZbDaPfcMwvMouVV2duXPnyuFwuLeIiIgr6l9N4sf+SgnjJkiy\nacC4ibr7yf/n3k8YN8GUR8Ql6U9/+pMGDRqkMWPGaPjw4brlllsUGxtrSlsAAHioaY1NA6/BqfP3\n4EydOlXjx1e/SLZLly6X1ZmwsDBJF2ZpwsPD3eVHjx51z+qEhYWprKxMJSUlHrM4R48eVUJCQqXX\nnTVrltLS0tz7LperQULOT4PMpftm+NnPfqY333xTb775prvs97//valtAgDgi+occEJCQhQSEmJG\nXxQVFaWwsDBlZ2erd+/eki48ibVlyxbNmzdPkhQbG6uAgABlZ2dr3LhxkqSioiLt379fL7zwQqXX\ntdvtstvtpvQZAAD4HlMXaBQWFio/P1+FhYU6d+6c8vPzlZ+fr9OnT7vrdOvWTVlZWZIufDQ1c+ZM\n/fGPf1RWVpZ7HUmrVq10zz0X1q04HA5NnjxZDz/8sDZu3Ki8vDxNnDhRvXr10vDhw80cDgAAqMql\na2xq2jeZqT/V8PTTT2v58uXu/YuzMps2bdKQIUMkSQcPHpTT+X+DfvTRR/Xjjz/qd7/7nUpKStS/\nf3999NFHatOmjbvOggUL5O/vr3HjxunHH3/UsGHDlJGRIT8/PzOHAwAAqtPIoeanbEYz/AIVl8sl\nh8Mhp9Op4OBgj2Nnz55VQUGBoqKiFBQU1Eg9bDjNbbwAgKaruvfvS/EMMQAAsBwCThXOnz/f2F1o\nEM1lnACA5sXUNThNUWBgoFq0aKEjR46oQ4cOCgwMrPE7eJoiwzBUVlamY8eOqUWLFgoMDGzsLgEA\nUG8IOJdo0aKFoqKiVFRUpCNHjjR2d0zXqlUrXXPNNXzjMQDAUgg4lQgMDNQ111yjiooKn/mFcjP4\n+fnJ39/fkjNUAIDmjYBTBZvNpoCAAAUEBDR2VwAAQB3xuQQAALAcAg4AALAcAg4AALCcZrkG5+KX\nN7tcrkbuCQAAqK2L79u1+RGGZhlwTp06JUmKiIho5J4AAIC6OnXqlBwOR7V1muVvUZ0/f15HjhxR\nmzZtqnxE2uVyKSIiQocPH67x9y6aMsZpLYzTWprLOKXmM1bGeWUMw9CpU6fUqVOnGr+/rVnO4LRo\n0UKdO3euVd3g4GBL/yW8iHFaC+O0luYyTqn5jJVxXr6aZm4uYpExAACwHAIOAACwHAJOFex2u555\n5hnZ7fbG7oqpGKe1ME5raS7jlJrPWBlnw2mWi4wBAIC1MYMDAAAsh4ADAAAsh4ADAAAsh4ADAAAs\np9kGnOeee04JCQlq1aqV2rZtW6tzDMPQ7Nmz1alTJ7Vs2VJDhgzRZ5995lGntLRU06ZNU0hIiFq3\nbq0xY8bo22+/NWEEtVNSUqKUlBQ5HA45HA6lpKTo5MmT1Z5js9kq3f70pz+56wwZMsTr+Pjx400e\nTdUuZ5z33Xef1xji4uI86jT1+1leXq7HHntMvXr1UuvWrdWpUyfde++9OnLkiEc9X7ifixcvVlRU\nlIKCghQbG6tPP/202vpbtmxRbGysgoKCdO2112rp0qVeddasWaMePXrIbrerR48eysrKMqv7tVaX\ncb733nsaMWKEOnTooODgYMXHx+sf//iHR52MjIxKX69nz541eyjVqss4N2/eXOkYvvjiC496Tf1+\nVvZvjs1mU8+ePd11fPF+fvLJJ7rtttvUqVMn2Ww2/e1vf6vxHJ94fRrN1NNPP228+OKLRlpamuFw\nOGp1zvPPP2+0adPGWLNmjbFv3z4jOTnZCA8PN1wul7vOlClTjKuvvtrIzs429uzZYwwdOtS46aab\njIqKCpNGUr2kpCQjJibGyMnJMXJycoyYmBhj9OjR1Z5TVFTksS1btsyw2WzGV1995a4zePBgIzU1\n1aPeyZMnzR5OlS5nnJMmTTKSkpI8xnDixAmPOk39fp48edIYPny4kZmZaXzxxRdGbm6u0b9/fyM2\nNtajXmPfz9WrVxsBAQHG66+/bnz++efGjBkzjNatWxvffPNNpfX/85//GK1atTJmzJhhfP7558br\nr79uBAQEGH/961/ddXJycgw/Pz/jj3/8o3HgwAHjj3/8o+Hv729s27atoYblpa7jnDFjhjFv3jxj\nx44dxpdffmnMmjXLCAgIMPbs2eOu88YbbxjBwcFer9vGVNdxbtq0yZBkHDx40GMMP32dWeF+njx5\n0mN8hw8fNtq3b28888wz7jq+eD/XrVtnPPHEE8aaNWsMSUZWVla19X3l9dlsA85Fb7zxRq0Czvnz\n542wsDDj+eefd5edPXvWcDgcxtKlSw3DuPCXNyAgwFi9erW7znfffWe0aNHCWL9+fb33vSaff/65\nIcnjL0xubq4hyfjiiy9qfZ3bb7/duPXWWz3KBg8ebMyYMaO+unpFLneckyZNMm6//fYqj1v1fu7Y\nscOQ5PGPcGPfz379+hlTpkzxKOvWrZvx+OOPV1r/0UcfNbp16+ZR9tvf/taIi4tz748bN85ISkry\nqDNy5Ehj/Pjx9dTruqvrOCvTo0cPY86cOe792v4b1pDqOs6LAaekpKTKa1rxfmZlZRk2m834+uuv\n3WW+eD9/qjYBx1den832I6q6KigoUHFxsRITE91ldrtdgwcPVk5OjiRp9+7dKi8v96jTqVMnxcTE\nuOs0pNzcXDkcDvXv399dFhcXJ4fDUev+fP/991q7dq0mT57sdWzlypUKCQlRz5499cgjj7h/pb2h\nXck4N2/erI4dO+qGG25Qamqqjh496j5mxfspSU6nUzabzeuj2ca6n2VlZdq9e7fHf2dJSkxMrHJc\nubm5XvVHjhypXbt2qby8vNo6jXHvpMsb56XOnz+vU6dOqX379h7lp0+fVmRkpDp37qzRo0crLy+v\n3vpdV1cyzt69eys8PFzDhg3Tpk2bPI5Z8X6mp6dr+PDhioyM9Cj3pft5OXzl9dksf2zzchQXF0uS\nQkNDPcpDQ0P1zTffuOsEBgaqXbt2XnUunt+QiouL1bFjR6/yjh071ro/y5cvV5s2bXTnnXd6lE+Y\nMEFRUVEKCwvT/v37NWvWLO3du1fZ2dn10ve6uNxxjho1SnfffbciIyNVUFCgp556Srfeeqt2794t\nu91uyft59uxZPf7447rnnns8fgCvMe/n8ePHde7cuUpfW1WNq7i4uNL6FRUVOn78uMLDw6us0xj3\nTrq8cV5q/vz5OnPmjMaNG+cu69atmzIyMtSrVy+5XC699NJLGjBggPbu3auuXbvW6xhq43LGGR4e\nrtdee02xsbEqLS3Vm2++qWHDhmnz5s0aNGiQpKrveVO9n0VFRfrwww/19ttve5T72v28HL7y+rRU\nwJk9e7bmzJlTbZ2dO3eqb9++l92GzWbz2DcMw6vsUrWpUxe1Hafk3d+69mfZsmWaMGGCgoKCPMpT\nU1Pdf46JiVHXrl3Vt29f7dmzR3369KnVtWti9jiTk5Pdf46JiVHfvn0VGRmptWvXegW6uly3rhrq\nfpaXl2v8+PE6f/68Fi9e7HGsIe5nTer62qqs/qXll/N6Ndvl9mnVqlWaPXu23n//fY+gGxcX57E4\nfsCAAerTp48WLVqkhQsX1l/H66gu44yOjlZ0dLR7Pz4+XocPH9af//xnd8Cp6zUbyuX2KSMjQ23b\nttUdd9zhUe6r97OufOH1aamAM3Xq1Bqf/OjSpctlXTssLEzShWQaHh7uLj969Kg7hYaFhamsrEwl\nJSUe/9d/9OhRJSQkXFa7lantOP/1r3/p+++/9zp27Ngxr+RcmU8//VQHDx5UZmZmjXX79OmjgIAA\nHTp0qN7eEBtqnBeFh4crMjJShw4dkmSt+1leXq5x48apoKBAH3/8scfsTWXMuJ9VCQkJkZ+fn9f/\nuf30tXWpsLCwSuv7+/vrqquuqrZOXf5O1KfLGedFmZmZmjx5st59910NHz682rotWrTQzTff7P57\n3NCuZJw/FRcXp7feesu9b6X7aRiGli1bppSUFAUGBlZbt7Hv5+Xwmddnva3maaLqush43rx57rLS\n0tJKFxlnZma66xw5cqTRF6Vu377dXbZt27ZaL0qdNGmS19M2Vdm3b58hydiyZctl9/dyXek4Lzp+\n/Lhht9uN5cuXG4ZhnftZVlZm3HHHHUbPnj2No0eP1qqthr6f/fr1Mx544AGPsu7du1e7yLh79+4e\nZVOmTPFaxDhq1CiPOklJSY2+KLUu4zQMw3j77beNoKCgGhd2XnT+/Hmjb9++xv33338lXb0ilzPO\nS40dO9YYOnSoe98q99Mw/m9R9b59+2pswxfu50+plouMfeH12WwDzjfffGPk5eUZc+bMMX72s58Z\neXl5Rl5ennHq1Cl3nejoaOO9995z7z///POGw+Ew3nvvPWPfvn3Gr371q0ofE+/cubOxYcMGY8+e\nPcatt97a6I8V33jjjUZubq6Rm5tr9OrVy+ux4kvHaRiG4XQ6jVatWhlLlizxuua///1vY86cOcbO\nnTuNgoICY+3atUa3bt2M3r17N5lxnjp1ynj44YeNnJwco6CgwNi0aZMRHx9vXH311Za6n+Xl5caY\nMWOMzp07G/n5+R6PnZaWlhqG4Rv38+Ljtunp6cbnn39uzJw502jdurX76ZLHH3/cSElJcde/+Bjq\nQw89ZHz++edGenq612Oo//znPw0/Pz/j+eefNw4cOGA8//zzPvNYcW3H+fbbbxv+/v7GK6+8UuUj\n/LNnzzbWr19vfPXVV0ZeXp5x//33G/7+/h5BuKHVdZwLFiwwsrKyjC+//NLYv3+/8fjjjxuSjDVr\n1rjrWOF+XjRx4kSjf//+lV7TF+/nqVOn3O+RkowXX3zRyMvLcz+J6auvz2YbcCZNmmRI8to2bdrk\nriPJeOONN9z758+fN5555hkjLCzMsNvtxqBBg7wS+I8//mhMnTrVaN++vdGyZUtj9OjRRmFhYQON\nytuJEyeMCRMmGG3atDHatGljTJgwwetRzEvHaRiG8eqrrxotW7as9LtQCgsLjUGDBhnt27c3AgMD\njeuuu86YPn2613fINKS6jvOHH34wEhMTjQ4dOhgBAQHGNddcY0yaNMnrXjX1+1lQUFDp3/Of/l33\nlfv5yiuvGJGRkUZgYKDRp08fj9mjSZMmGYMHD/aov3nzZqN3795GYGCg0aVLl0rD+LvvvmtER0cb\nAQEBRrdu3TzeMBtLXcY5ePDgSu/dpEmT3HVmzpxpXHPNNUZgYKDRoUMHIzEx0cjJyWnAEVWuLuOc\nN2+ecd111xlBQUFGu3btjFtuucVYu3at1zWb+v00jAszwy1btjRee+21Sq/ni/fz4oxTVX8PffX1\naTOM/678AQAAsAi+BwcAAFgOAQcAAFgOAQcAAFgOAQcAAFgOAQcAAFgOAQcAAFgOAQcAAFgOAQcA\nAFgOAQcAAFgOAQcAAFgOAQcAAFgOAQcAAFjO/w+MFVSV3/PPKgAAAABJRU5ErkJggg==\n"
}
}
],
"source": [
"h1,h2 = h.T.data\n",
"plt.plot(h1[::6],h2[::6],'X',label=\"A\")\n",
"plt.plot(h1[1::6],h2[1::6],'X',label=\"b\")\n",
"plt.plot(h1[2::6],h2[2::6],'X',label=\"A\")\n",
"plt.plot(h1[3::6],h2[3::6],'X',label=\"c\")\n",
"plt.plot(h1[4::6],h2[4::6],'X',label=\"A\")\n",
"plt.plot(h1[5::6],h2[5::6],'X',label=\"d\")\n",
"plt.legend()"
],
"id": "266df1a1-73a6-49e2-9e92-d27486b3dbef"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## D. 구현2 – RNNCell\n",
"\n",
"ref: \n",
"\n",
"`-` 데이터정리"
],
"id": "3cae167f-dbe2-4594-ae98-16025d298f45"
},
{
"cell_type": "code",
"execution_count": 190,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"x = torch.tensor(df_train.x.map({'A':0,'b':1,'c':2,'d':3}))\n",
"y = torch.tensor(df_train.y.map({'A':0,'b':1,'c':2,'d':3}))\n",
"X = torch.nn.functional.one_hot(x).float()\n",
"y = torch.nn.functional.one_hot(y).float()"
],
"id": "8b8daf72-5ac5-4c74-8a72-7ef25200118c"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` Net설계 및 가중치 설정 (구현1과 동일하도록 가중치 초기화)"
],
"id": "ec04c608-d567-4cd4-b015-d86ffb1a3f69"
},
{
"cell_type": "code",
"execution_count": 191,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"torch.manual_seed(43052) \n",
"_rnncell = rNNCell()\n",
"cook = torch.nn.Linear(2,4)"
],
"id": "1fbc71da-14ff-4c76-b720-76219e68b0fb"
},
{
"cell_type": "code",
"execution_count": 192,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"rnncell = torch.nn.RNNCell(4,2)\n",
"rnncell.weight_ih.data = _rnncell.i2h.weight.data \n",
"rnncell.weight_hh.data = _rnncell.h2h.weight.data \n",
"rnncell.bias_ih.data = _rnncell.i2h.bias.data \n",
"rnncell.bias_hh.data = _rnncell.h2h.bias.data "
],
"id": "8dcb7639-e51e-4d87-bcb4-8e99796fbe5e"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 손실함수 및 옵티마이저 설정"
],
"id": "5a722a1c-2831-413b-bea5-b9b2aca9041f"
},
{
"cell_type": "code",
"execution_count": 193,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"loss_fn = torch.nn.CrossEntropyLoss() \n",
"optimizr = torch.optim.Adam(list(rnncell.parameters())+list(cook.parameters()),lr=0.1)"
],
"id": "340c3efc-7c07-4d98-90c2-6a153cf0c02e"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 학습"
],
"id": "e26569dc-dc42-4db9-b52a-112cf39798f6"
},
{
"cell_type": "code",
"execution_count": 194,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"L = len(X)\n",
"for epoc in range(200):\n",
" ## 1~2 \n",
" ht = torch.zeros(2) # 첫간장은 맹물\n",
" loss = 0\n",
" for t in range(L):\n",
" Xt, yt = X[t], y[t]\n",
" ht = rnncell(Xt, ht)\n",
" ot = cook(ht) \n",
" loss = loss + loss_fn(ot, yt)\n",
" loss = loss/L\n",
" ## 3 \n",
" loss.backward()\n",
" ## 4 \n",
" optimizr.step()\n",
" optimizr.zero_grad()"
],
"id": "80f84d12-df66-4b34-a5ee-8561dafeb636"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 결과확인"
],
"id": "307f4d07-0204-4a7e-afe7-8aa1c107de23"
},
{
"cell_type": "code",
"execution_count": 195,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"h = torch.zeros(L,2)\n",
"water = torch.zeros(2)\n",
"h[0] = rnncell(X[0],water)\n",
"for t in range(1,L):\n",
" h[t] = rnncell(X[t],h[t-1])\n",
"yhat = soft(cook(h))\n",
"yhat"
],
"id": "21017b68-d5b7-4cc4-b9cc-b31835db7cc2"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 구현1과 같은 결과\n",
"\n",
"# 5. HW: hello\n",
"\n",
"아래와 같이 hello가 반복되는 자료가 있다고 하자."
],
"id": "578b90b0-6804-438a-adcb-40a40238493f"
},
{
"cell_type": "code",
"execution_count": 176,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"txt = list('hello'*100)\n",
"txt[:10]"
],
"id": "a0d23169-85b2-4c86-93d8-b702ca18995e"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`(1)` `rNNCell`을 이용하여 학습하라. (적절한 은닉노드수를 설정할 것)\n",
"\n",
"`(2)` `torch.nn.RNNCell`을 이용하여 (1)의 결과를 재현하라."
],
"id": "24ed08b3-a383-486d-8aef-b0708d98d101"
}
],
"nbformat": 4,
"nbformat_minor": 5,
"metadata": {
"kernelspec": {
"name": "python3",
"display_name": "Python 3 (ipykernel)",
"language": "python"
},
"language_info": {
"name": "python",
"codemirror_mode": {
"name": "ipython",
"version": "3"
},
"file_extension": ".py",
"mimetype": "text/x-python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.13"
}
}
}