diff --git a/notebooks/ksj/EASE.ipynb b/notebooks/ksj/EASE.ipynb new file mode 100644 index 0000000..f044f6a --- /dev/null +++ b/notebooks/ksj/EASE.ipynb @@ -0,0 +1,224 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from scipy.sparse import csr_matrix\n", + "from datetime import datetime" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 실험용" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# 데이터 로드\n", + "data_file = \"/opt/ml/input/data/train/train_ratings.csv\"\n", + "rating_df = pd.read_csv(data_file)\n", + "\n", + "# user와 item에 대한 고유한 인덱스 생성\n", + "user_list = rating_df['user'].unique()\n", + "item_list = rating_df['item'].unique()\n", + "\n", + "user_to_index = {user: index for index, user in enumerate(user_list)}\n", + "item_to_index = {item: index for index, item in enumerate(item_list)}\n", + "\n", + "# 데이터셋에서 user, item을 인덱스로 변환\n", + "rating_df['user'] = rating_df['user'].map(user_to_index)\n", + "rating_df['item'] = rating_df['item'].map(item_to_index)\n", + "\n", + "num_users = len(user_to_index)\n", + "num_items = len(item_to_index)\n", + "\n", + "# csr_matrix 생성\n", + "rows = rating_df['user'].values\n", + "cols = rating_df['item'].values\n", + "\n", + "rating_score = 0.9\n", + "data = np.full(len(rating_df), rating_score)\n", + "rating_matrix = csr_matrix((data, (rows, cols)), shape=(num_users, num_items))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "class EASE:\n", + " def __init__(self, _lambda):\n", + " self.B = None\n", + " self._lambda = _lambda\n", + "\n", + " def train(self, X):\n", + " try:\n", + " # csr_matrix --> dense\n", + " X_dense = X.toarray()\n", + " print(\"X shape:\", X_dense.shape)\n", + " \n", + " G = X_dense.T @ X_dense\n", + " print(\"G shape:\", G.shape)\n", + " \n", + " diag_indices = np.diag_indices_from(G)\n", + " G[diag_indices] += self._lambda\n", + " print(\"G after adding lambda on diag:\", G.shape)\n", + " \n", + " # dense --> pseudo-inverse 계산\n", + " P = np.linalg.pinv(G)\n", + " print(\"P shape:\", P.shape)\n", + " \n", + " self.B = P / -np.diag(P)\n", + " self.B[diag_indices] = 0\n", + " print(\"Final B shape:\", self.B.shape)\n", + " except Exception as e:\n", + " print(\"Error occurred:\", e)\n", + "\n", + " def predict(self, X):\n", + " # csr_matrix --> dense\n", + " X_dense = X.toarray() if isinstance(X, csr_matrix) else X\n", + " return X_dense @ self.B" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "X shape: (31360, 6807)\n", + "G shape: (6807, 6807)\n", + "G after adding lambda on diag: (6807, 6807)\n", + "P shape: (6807, 6807)\n", + "Final B shape: (6807, 6807)\n" + ] + } + ], + "source": [ + "# EASE 모델 학습\n", + "_lambda = 750\n", + "ease = EASE(_lambda)\n", + "ease.train(rating_matrix)\n", + "\n", + "# 예측\n", + "predictions = ease.predict(rating_matrix)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# 상위 N개 아이템 추출\n", + "\n", + "N = 10\n", + "top_n_items_per_user = []\n", + "\n", + "# 이미 평가한 아이템은 제외\n", + "predictions[rating_matrix.nonzero()] = -np.inf\n", + "\n", + "for user_idx in range(predictions.shape[0]):\n", + " user_predictions = predictions[user_idx, :]\n", + " top_n_indices = np.argpartition(user_predictions, -N)[-N:]\n", + " top_n_indices_sorted = top_n_indices[np.argsort(user_predictions[top_n_indices])[::-1]]\n", + " top_n_items_per_user.append(top_n_indices_sorted)\n", + "\n", + "# 인덱스를 실제 아이템 ID로 변환\n", + "index_to_item = {index: item for item, index in item_to_index.items()}\n", + "top_n_items_per_user_ids = [[index_to_item[idx] for idx in user_items] for user_items in top_n_items_per_user]\n", + "\n", + "# 제출 파일 생성\n", + "result = []\n", + "for user_id, items in zip(user_list, top_n_items_per_user_ids):\n", + " for item_id in items:\n", + " result.append((user_id, item_id))\n", + "\n", + "# 저장\n", + "current_time = datetime.now().strftime('%Y%m%d-%H%M%S')\n", + "args_str = f\"submission_EASE-lam{_lambda}_tm{current_time}\"\n", + "submission_df = pd.DataFrame(result, columns=['user', 'item'])\n", + "submission_df.to_csv(f\"{args_str}.csv\", index=False)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# 하위 N개 아이템 추출\n", + "\n", + "N = 80\n", + "bottom_n_items_per_user = [] # 각 사용자별로 하위 N개 아이템의 인덱스를 저장할 리스트\n", + "\n", + "for user_idx in range(predictions.shape[0]):\n", + " user_predictions = predictions[user_idx, :]\n", + " bottom_n_indices = np.argpartition(user_predictions, N-1)[:N]\n", + " bottom_n_indices_sorted = bottom_n_indices[np.argsort(user_predictions[bottom_n_indices])]\n", + " bottom_n_items_per_user.append(bottom_n_indices_sorted)\n", + "\n", + "\n", + "bottom_n_items_per_user = np.array(bottom_n_items_per_user)\n", + "\n", + "# 인덱스를 실제 아이템 ID로 변환\n", + "index_to_item = {index: item for item, index in item_to_index.items()}\n", + "bottom_n_items_per_user_ids = [[index_to_item[idx] for idx in user_items] for user_items in bottom_n_items_per_user]\n", + "\n", + "# 제출 파일 생성\n", + "result = []\n", + "for user_id, items in zip(user_list, bottom_n_items_per_user_ids):\n", + " for item_id in items:\n", + " result.append((user_id, item_id))\n", + "\n", + "# 저장\n", + "current_time = datetime.now().strftime('%Y%m%d-%H%M%S')\n", + "args_str = f\"Negative_EASE-lam{_lambda}_tm{current_time}\"\n", + "submission_df = pd.DataFrame(result, columns=['user', 'item'])\n", + "submission_df.to_csv(f\"{args_str}.csv\", index=False)\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.8.18 ('EASE': conda)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.18" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "78251029becf62da8b58a8ef92d6c9c1752dac293e5a0befc81af987f28f6887" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/ksj/VASP.ipynb b/notebooks/ksj/VASP.ipynb new file mode 100644 index 0000000..9f27e79 --- /dev/null +++ b/notebooks/ksj/VASP.ipynb @@ -0,0 +1,559 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 150, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import pandas as pd\n", + "import numpy as np\n", + "from datetime import datetime\n", + "from tqdm import tqdm\n", + "import random\n", + "\n", + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "from torch.utils.data import Dataset, DataLoader\n", + "from scipy.sparse import csr_matrix\n", + "import torch.optim as optim\n", + "from torch.nn.utils import clip_grad_norm_\n", + "\n", + "from box import Box" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"\n", + "num_words: 모델에 입력되는 전체 아이템 수\n", + "latent: 모델의 잠재 변수 z의 차원, latent=2048로 설정\n", + "hidden: enc, dec dense layer dims\n", + "items_sampling: 대규모 아이템 데이터셋을 처리할 때 입력 아이템의 일부만 사용하는 비율, MV20M에서는 ease_items_sampling=0.33로 설정(가장 인기 있는 아이템의 약 33%만 사용)\n", + "lr: 1step_lr=0.00005, 2step_lr=0.00001\n", + "Focal Loss의 파라미터(fl_alpha, fl_gamma): Focal Loss계산시 사용, fl_alpha=0.25, fl_gamma=2.0로 설정\n", + "epochs: 1step = 50, 2step = 20, 3step=20\n", + "\"\"\"\n" + ] + }, + { + "cell_type": "code", + "execution_count": 137, + "metadata": {}, + "outputs": [], + "source": [ + "def set_seed(seed_value=42):\n", + " random.seed(seed_value)\n", + " np.random.seed(seed_value) # Numpy 모듈\n", + " torch.manual_seed(seed_value) # CPU PyTorch 함수\n", + " \n", + " # CUDA(GPU) PyTorch 시드 고정\n", + " if torch.cuda.is_available():\n", + " torch.cuda.manual_seed(seed_value)\n", + " torch.cuda.manual_seed_all(seed_value) # 멀티 GPU 사용 시\n", + " torch.backends.cudnn.deterministic = True\n", + " torch.backends.cudnn.benchmark = False\n", + "\n", + "\n", + "set_seed(42)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Preparing Data" + ] + }, + { + "cell_type": "code", + "execution_count": 138, + "metadata": {}, + "outputs": [], + "source": [ + "# 데이터 로드\n", + "data_file = \"/opt/ml/input/data/train/train_ratings.csv\"\n", + "rating_df = pd.read_csv(data_file)\n", + "\n", + "# user와 item에 대한 고유한 인덱스 생성\n", + "user_list = rating_df['user'].unique()\n", + "item_list = rating_df['item'].unique()\n", + "\n", + "user_to_index = {user: index for index, user in enumerate(user_list)}\n", + "item_to_index = {item: index for index, item in enumerate(item_list)}\n", + "\n", + "# 데이터셋에서 user, item을 인덱스로 변환\n", + "rating_df['user'] = rating_df['user'].map(user_to_index)\n", + "rating_df['item'] = rating_df['item'].map(item_to_index)\n", + "\n", + "num_users = len(user_to_index)\n", + "num_items = len(item_to_index)\n", + "\n", + "# csr_matrix 생성\n", + "rows = rating_df['user'].values\n", + "cols = rating_df['item'].values\n", + "# data = np.ones(len(rating_df)) --> 0.1599\n", + "rating_score = 1 # parameter\n", + "data = np.full(len(rating_df), rating_score)\n", + "rating_matrix = csr_matrix((data, (rows, cols)), shape=(num_users, num_items))\n", + "dense_rating_matrix = rating_matrix.toarray()" + ] + }, + { + "cell_type": "code", + "execution_count": 139, + "metadata": {}, + "outputs": [], + "source": [ + "current_time = datetime.now().strftime('%Y%m%d-%H%M%S')\n", + "config = {\n", + " 'current_time' : current_time,\n", + " \n", + " 'data_path' : \"/opt/ml/input/data/train\" , # 데이터 경로\n", + " 'submission_path' : \"/data/ephemeral/home/code_ml/output\", \n", + " 'model_path' : \"/data/ephemeral/home/code_ml/output\", # 모델 저장 경로\n", + "\n", + " 'user_to_index' : user_to_index,\n", + " 'item_to_index' : item_to_index,\n", + "\n", + " 'num_users' : num_users,\n", + " 'num_items' : num_items,\n", + " \n", + " 'rating_score' : rating_score,\n", + " \n", + " 'rating_matrix' : rating_matrix, # csr_matrix type\n", + " 'dense_rating_matrix' : dense_rating_matrix, # dense matrix\n", + " \n", + " 'batch_size' : 256,\n", + " 'latent' : 1024,\n", + " 'hidden' : 2048,\n", + " 'num_epochs': 25\n", + "}\n", + "\n", + "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n", + "config = Box(config)" + ] + }, + { + "cell_type": "code", + "execution_count": 140, + "metadata": {}, + "outputs": [], + "source": [ + "class VASPDataset(Dataset):\n", + " def __init__(self, rating_matrix=config.rating_matrix, num_users=config.num_users):\n", + " self.rating_matrix = rating_matrix\n", + " self.num_users = num_users # 전체 사용자 수\n", + " self.users = list(range(num_users))\n", + "\n", + " def __len__(self):\n", + " return self.num_users\n", + "\n", + " def __getitem__(self, idx):\n", + " user_interaction = self.rating_matrix[idx].toarray()\n", + " user_interaction_tensor = torch.FloatTensor(user_interaction)\n", + " \n", + " return (idx, user_interaction_tensor.squeeze(0))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Model" + ] + }, + { + "cell_type": "code", + "execution_count": 141, + "metadata": {}, + "outputs": [], + "source": [ + "############################## For reparameterizing ############################## \n", + "class Sampling(nn.Module):\n", + " \"\"\"\n", + " reparameterization trick\n", + " \"\"\"\n", + " def forward(self, inputs):\n", + " z_mean, z_log_var = inputs\n", + " \n", + " # z_mean과 동일한 형태 텐서 생성\n", + " # 분포 내의 실제 z값을 무작위로 선택하는 데 사용(무작위성 부여)\n", + " epsilon = torch.randn_like(z_mean) # Standard normal distribution ~ N(0,1)\n", + " return z_mean + torch.exp(0.5 * z_log_var) * epsilon\n", + "\n", + "############################## VASP ##############################\n", + "class VASPModel(nn.Module):\n", + " def __init__(self, num_words, latent=1024, hidden=1024, items_sampling=1.):\n", + " \"\"\"\n", + " num_words: 전체 아이템 수 --> same as input dim\n", + " items_sampling: 0~1값을 가짐\n", + " \"\"\"\n", + " super(VASPModel, self).__init__()\n", + " # self.sampled_items = int(num_words * items_sampling) # 실제 모델에서 사용될 아이템 수\n", + " \n", + " # # self.sampled_items가 유효한지\n", + " # assert self.sampled_items > 0 and self.sampled_items <= num_words\n", + " # # sampling 활성화 여부\n", + " # self.sampling_enabled = self.sampled_items < num_words\n", + "\n", + " self.num_items = num_words\n", + " self.latent = latent\n", + " self.hidden = hidden\n", + "\n", + " # Encoder Layers\n", + " self.encoder_layers = nn.Sequential(\n", + " nn.Linear(self.num_items, self.hidden),\n", + " nn.LayerNorm(self.hidden),\n", + " nn.SiLU(),\n", + " nn.Linear(self.hidden, self.hidden),\n", + " nn.LayerNorm(self.hidden),\n", + " nn.SiLU(),\n", + " )\n", + "\n", + " # z_mean and z_log_variance for Sampling\n", + " self.dense_mean = nn.Linear(self.hidden, self.latent)\n", + " self.dense_log_var = nn.Linear(self.hidden, self.latent)\n", + "\n", + " # Sampling Layer\n", + " self.sampling = Sampling()\n", + "\n", + " # Decoder Layers\n", + " self.decoder_layers = nn.Sequential(\n", + " nn.Linear(self.latent, self.hidden),\n", + " nn.LayerNorm(self.hidden),\n", + " nn.SiLU(),\n", + " )\n", + "\n", + " # Output Layers for Decoder\n", + " self.decoder_resnet = nn.Linear(self.hidden, self.num_items)\n", + " self.decoder_latent = nn.Linear(self.latent, self.num_items)\n", + "\n", + " # EASE Layer\n", + " self.ease = nn.Linear(self.num_items, self.num_items, bias=False)\n", + " nn.init.xavier_uniform_(self.ease.weight)\n", + " self.apply_diagonal_zero(self.ease.weight)\n", + " # self.ease.weight.data = self.ease.weight.data * (1 - torch.eye(self.num_items))\n", + "\n", + " def apply_diagonal_zero(self, weight):\n", + " # 대각행렬 0\n", + " with torch.no_grad():\n", + " weight.fill_diagonal_(0)\n", + "\n", + " def encode(self, x):\n", + " encoded = self.encoder_layers(x)\n", + " z_mean = self.dense_mean(encoded)\n", + " z_log_var = self.dense_log_var(encoded)\n", + " return z_mean, z_log_var\n", + "\n", + " def decode(self, z):\n", + " decoded = self.decoder_layers(z)\n", + " \"\"\"\n", + " self.decoder_resnet(decoded): z로부터 생성된 출력, 비선형 변환\n", + " self.decoder_latent(z): z의 다른 변환\n", + " \"\"\"\n", + " return self.decoder_resnet(decoded), self.decoder_latent(z)\n", + "\n", + " def forward(self, user_ratings):\n", + " # if self.sampling_enabled:\n", + " # sampled_x = x[:, :self.sampled_items]\n", + " # non_sampled = torch.zeros_like(x[:, self.sampled_items:])\n", + " # else:\n", + " # sampled_x = x\n", + "\n", + " # encoding --> z_mean과 z_log_var 생성\n", + " z_mean, z_log_var = self.encode(user_ratings)\n", + " \n", + " # reparameterize\n", + " z = self.sampling((z_mean, z_log_var))\n", + " \n", + " # decode\n", + " decoded_r, decoded_l = self.decode(z)\n", + "\n", + " ease_out = self.ease(user_ratings)\n", + "\n", + " # if self.sampling_enabled:\n", + " # ease_out = torch.cat([ease_out, non_sampled], dim=-1)\n", + "\n", + " return decoded_r * decoded_l * ease_out\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Loss Function" + ] + }, + { + "cell_type": "code", + "execution_count": 142, + "metadata": {}, + "outputs": [], + "source": [ + "# MultiVAE\n", + "def loss_function_vae(recon_x, x, mu, logvar, anneal=1.0):\n", + " BCE = -torch.mean(torch.sum(F.log_softmax(recon_x, 1) * x, -1))\n", + " KLD = -0.5 * torch.mean(torch.sum(1 + logvar - mu.pow(2) - logvar.exp(), dim=1))\n", + " return BCE + anneal * KLD\n", + "\n", + "# MultiDAE\n", + "def loss_function_dae(recon_x, x):\n", + " BCE = -torch.mean(torch.sum(F.log_softmax(recon_x, 1) * x, -1))\n", + " return BCE\n", + "\n", + "class SigmoidFocalCrossEntropy(nn.Module):\n", + " def __init__(self, alpha=0.25, gamma=2.0, reduction='mean'):\n", + " super(SigmoidFocalCrossEntropy, self).__init__()\n", + " self.alpha = alpha\n", + " self.gamma = gamma\n", + " self.reduction = reduction\n", + "\n", + " def forward(self, inputs, targets):\n", + " # Sigmoid 함수 적용\n", + " probs = torch.sigmoid(inputs)\n", + " # p_t 계산\n", + " pt = probs * targets + (1 - probs) * (1 - targets)\n", + " # alpha_t 계산\n", + " alpha_t = self.alpha * targets + (1 - self.alpha) * (1 - targets)\n", + " # Focal loss 계산\n", + " loss = -alpha_t * (1 - pt).pow(self.gamma) * pt.log()\n", + " \n", + " if self.reduction == 'mean':\n", + " return loss.mean()\n", + " elif self.reduction == 'sum':\n", + " return loss.sum()\n", + " else:\n", + " return loss" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### train & inference & submission" + ] + }, + { + "cell_type": "code", + "execution_count": 143, + "metadata": {}, + "outputs": [], + "source": [ + "def train(model, criterion, optimizer, data_loader, scheduler, clip_value=1.0):\n", + " model.train()\n", + " loss_val = 0\n", + " for idx, (_, user_rating) in enumerate(data_loader):\n", + " user_rating = user_rating.to(device)\n", + " optimizer.zero_grad()\n", + " output = model(user_rating)\n", + " loss = criterion(output, user_rating)\n", + " loss_val += loss.item()\n", + " loss.backward()\n", + " \n", + " clip_grad_norm_(model.parameters(), clip_value) ##\n", + " optimizer.step()\n", + " print(f\"loss: {loss.item()}\")\n", + " scheduler.step() ##\n", + " loss_val /= len(data_loader)\n", + " print(f\"loss_val: {loss_val}\")\n", + " return loss_val\n", + "\n", + "def predict(model, data_loader, \n", + " dense_rating_matrix = config.dense_rating_matrix, \n", + " N=10):\n", + " model.eval()\n", + " pred_list = None\n", + " answer_list = None\n", + "\n", + " with torch.no_grad(): \n", + " for i, (user_ids, user_ratings) in enumerate(data_loader):\n", + " user_ratings = user_ratings.to(device)\n", + " rating_pred = model(user_ratings)\n", + " batch_user_index = user_ids.cpu().numpy()\n", + " \n", + " for idx, user_idx in enumerate(batch_user_index):\n", + " rated_indices = np.where(dense_rating_matrix[user_idx] > 0)[0]\n", + " rating_pred[idx, rated_indices] = -np.inf\n", + " \n", + " # 각 사용자별로 상위 10개 아이템의 인덱스 추출\n", + " ind = np.argpartition(rating_pred.cpu().numpy(), -N)[:, -N:]\n", + " arr_ind = rating_pred[np.arange(len(rating_pred))[:, None], ind].cpu().numpy()\n", + " arr_ind_argsort = np.argsort(arr_ind)[np.arange(len(rating_pred)), ::-1]\n", + " batch_pred_list = ind[np.arange(len(rating_pred))[:, None], arr_ind_argsort]\n", + "\n", + " if i == 0:\n", + " pred_list = batch_pred_list\n", + " else:\n", + " pred_list = np.append(pred_list, batch_pred_list, axis=0)\n", + " \n", + " return pred_list\n", + "\n", + "def submission(pred_list, \n", + " item_to_index=config.item_to_index, \n", + " submission_path=config.submission_path, \n", + " current_time=config.current_time):\n", + " index_to_item = {index: item for item, index in item_to_index.items()}\n", + " top_n_items_per_user_ids = [[index_to_item[idx] for idx in user_items] for user_items in pred_list]\n", + " \n", + " result = []\n", + " for user_id, items in zip(user_list, top_n_items_per_user_ids):\n", + " for item_id in items:\n", + " result.append((user_id, item_id))\n", + " args_str = f\"submission_VASP_rs{config.rating_score}_tm{current_time}.csv\"\n", + " checkpoint_path = os.path.join(submission_path, args_str)\n", + " submission_df = pd.DataFrame(result, columns=['user', 'item'])\n", + " submission_df.to_csv(checkpoint_path, index=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Main" + ] + }, + { + "cell_type": "code", + "execution_count": 144, + "metadata": {}, + "outputs": [], + "source": [ + "vasp_dataset = VASPDataset(\n", + " num_users = config.num_users,\n", + " )\n", + "\n", + "data_loader = DataLoader(\n", + " vasp_dataset,\n", + " batch_size = config.batch_size, \n", + " shuffle = True, \n", + " pin_memory = True,\n", + " )\n", + "\n", + "model = VASPModel(num_words=config.num_items).to(device)\n", + "optimizer = optim.Adam(model.parameters(), lr=0.00005)\n", + "criterion = SigmoidFocalCrossEntropy()\n", + "\n", + "scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for epoch in range(1, config.num_epochs + 1):\n", + " tbar = tqdm(range(1))\n", + " for _ in tbar:\n", + " train_loss = train(\n", + " model = model, \n", + " criterion = criterion, \n", + " optimizer = optimizer, \n", + " data_loader = data_loader,\n", + " scheduler = scheduler)" + ] + }, + { + "cell_type": "code", + "execution_count": 146, + "metadata": {}, + "outputs": [], + "source": [ + "args_str = f\"VASP_rs{config.rating_score}_tm{current_time}.pt\"\n", + "checkpoint_path = os.path.join(config.model_path, args_str)\n", + "\n", + "# 저장\n", + "torch.save(model.state_dict(), checkpoint_path)" + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 120, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model = VASPModel(num_words=config.num_items)\n", + "saved_path = checkpoint_path\n", + "model.load_state_dict(torch.load(saved_path))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "predict_data_loader = DataLoader(\n", + " vasp_dataset,\n", + " batch_size = config.batch_size, \n", + " shuffle = False, \n", + " pin_memory = True,\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 147, + "metadata": {}, + "outputs": [], + "source": [ + "submit_df = predict(model, predict_data_loader, config.dense_rating_matrix, 10)" + ] + }, + { + "cell_type": "code", + "execution_count": 149, + "metadata": {}, + "outputs": [], + "source": [ + "submission(submit_df, config.item_to_index,\n", + " config.submission_path,\n", + " config.current_time)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.7.16 ('Bert_1')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.16" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "e72ed55ffc312d1134aeb6a658dd80a4d2d690a2719268a8a3149698fddca312" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}