{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install transformers","metadata":{"id":"_RDH-YQsQ2K0","outputId":"bd648dcd-0ba2-4327-d319-26d07f22629d","_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-08-25T21:42:30.115179Z","iopub.execute_input":"2023-08-25T21:42:30.115789Z","iopub.status.idle":"2023-08-25T21:42:45.795593Z","shell.execute_reply.started":"2023-08-25T21:42:30.115748Z","shell.execute_reply":"2023-08-25T21:42:45.794473Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install datasets","metadata":{"id":"gmtfOHQSQ-nS","outputId":"a4d2554d-16d0-4600-e9f6-dc27d13e943e","execution":{"iopub.status.busy":"2023-08-25T21:42:45.798429Z","iopub.execute_input":"2023-08-25T21:42:45.799041Z","iopub.status.idle":"2023-08-25T21:42:57.164774Z","shell.execute_reply.started":"2023-08-25T21:42:45.799001Z","shell.execute_reply":"2023-08-25T21:42:57.163593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Libraries","metadata":{"id":"jprcZhTyetFF"}},{"cell_type":"code","source":"import os\nimport json\nimport copy\nimport pandas as pd\nimport numpy as np\nimport re\n\nimport tqdm\n\nfrom datasets import load_metric\n\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nfrom torch.utils.data import DataLoader, Dataset, TensorDataset, random_split\n\nfrom sklearn.metrics import f1_score, precision_score, recall_score\n\nfrom transformers import AutoModel, AutoTokenizer, BatchEncoding\nfrom transformers import get_linear_schedule_with_warmup\nfrom transformers import AdamW\n\nfrom typing import Optional, Dict, Tuple, List, Callable\nfrom dataclasses import dataclass","metadata":{"id":"Q28akqg88aFa","execution":{"iopub.status.busy":"2023-08-25T22:22:26.438951Z","iopub.execute_input":"2023-08-25T22:22:26.439330Z","iopub.status.idle":"2023-08-25T22:22:26.446716Z","shell.execute_reply.started":"2023-08-25T22:22:26.439300Z","shell.execute_reply":"2023-08-25T22:22:26.445761Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Configurations, Global Variables","metadata":{"id":"bhpx9K0z8gWE"}},{"cell_type":"code","source":"path_config = {\n    'train_data': '/kaggle/input/3-aikuthon/train.csv',\n    'test_data': '/kaggle/input/3-aikuthon/test.csv',\n    'model': '/kaggle/working/'\n    }\n\nmodel_config = {\n    'base_model': 'klue/roberta-small'#'klue/roberta-base',\n}\n\noptim_config = {\n    'lr': 1e-4,\n#     'betas': (0.9, 0.99),\n#     'eps': 1e-8,\n     'weight_decay': 0.001\n}\n\ndata_config = {\n    'max_length': 70,\n    'batch_size': 100,\n    'train_size': 0.8,\n    'val_size': 0.2\n}\n\ntrain_config = {\n    'epochs': 3\n}","metadata":{"id":"zsov7ZBhCZcD","execution":{"iopub.status.busy":"2023-08-25T22:22:26.819666Z","iopub.execute_input":"2023-08-25T22:22:26.820366Z","iopub.status.idle":"2023-08-25T22:22:26.827344Z","shell.execute_reply.started":"2023-08-25T22:22:26.820324Z","shell.execute_reply":"2023-08-25T22:22:26.826331Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"genre2idx = {'발라드': 0, '록/메탈': 1, '댄스': 2, 'POP': 4, \n             'R&B/Soul': 5, '랩/힙합': 7, '성인가요/트로트': 16}\norig2flat = {'0': 0, '1': 1, '2': 2, '4': 3,'5': 4, '7': 5, '16': 6}\nflat2orig = {v: k for k, v in orig2flat.items()}","metadata":{"execution":{"iopub.status.busy":"2023-08-25T22:22:26.979073Z","iopub.execute_input":"2023-08-25T22:22:26.979344Z","iopub.status.idle":"2023-08-25T22:22:26.985257Z","shell.execute_reply.started":"2023-08-25T22:22:26.979319Z","shell.execute_reply":"2023-08-25T22:22:26.984172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataset, DataLoader","metadata":{"id":"Tg3XP0-q8rOu"}},{"cell_type":"code","source":"class CustomDataset(Dataset):\n    def __init__(self, path: str, tokenizer: Callable, data_config: Dict[str, int]):\n        self.data = self._preprocess_data(path)\n        self.tokenizer = tokenizer\n        self.data_config = data_config\n    \n    \n    def __len__(self):\n        return len(self.data)\n    \n    \n    def __getitem__(self, idx):\n        row = self.data.iloc[idx]\n        sentence = row['artist'] + '[SEP]' + self._get_season(row['month']) + '[SEP]' + str(row['year'])  + '[SEP]' + row['song_name'] + '[SEP]' + row['lyrics']\n        input = self.tokenizer(sentence, max_length=self.data_config['max_length'],\n                               truncation=True, padding='max_length')\n        input_ids = input['input_ids']\n        attention_mask = input['attention_mask']\n        \n        return {\n            'ids': torch.LongTensor([row['id']]),\n            'input_ids': torch.LongTensor(input_ids),\n            'attention_mask': torch.LongTensor(attention_mask),\n            'labels': torch.LongTensor([row['genre']])\n        }\n                 \n    \n    def _preprocess_data(self, path):\n        data = pd.read_csv(path)\n        data = data.drop('adults', axis=1)\n        \n        # text 형태로된 데이터에 대해 괄호, 불용어, 개행문자 등을 제거하고 전처리합니다.\n        data['lyrics'] = data['lyrics'].apply(self._preprocess_func)\n        data['song_name'] = data['song_name'].apply(self._preprocess_func)\n        data['artist'] = data['artist'].apply(self._preprocess_func)\n        \n        # date 정보를 year, month, day로 나눕니다.\n        data = pd.concat([data, data['date'].str.split('.', expand=True)], axis=1).drop('date', axis=1)\n        \n        # 분류할 장르가 포함되지 않은 행을 제거합니다.\n        data['genre'] = data['genre'].str.split(',', expand=False)\n        data['genre'] = data['genre'].apply(self._filter_genre)\n        data = data.explode('genre')\n        \n        # nan값을 가진 행을 제거합니다.\n        data = data.dropna()\n        \n        # 제목 재설정\n        data = data.rename(columns=({'Unnamed: 0':'id', 0: 'year', 1: 'month', 2: 'day'}))\n        \n        # 형태 변환\n        data['id'] = data['id'].astype('float')\n        data['year'] = data['year'].astype('int64')\n        data['month'] = data['month'].astype('int64')\n        return data\n    \n    def _get_season(self, month):\n        if 11 > month > 9:\n            return '가을'\n        elif month > 6:\n            return '여름'\n        elif month > 2:\n            return '봄'\n        else:\n            return '겨울'\n    \n    def _preprocess_func(self, row):\n        pattern = re.compile(r'\\([^)]*\\)')\n        row = re.sub(pattern, '', row)\n        row = row.replace('\\n', ' ')\n        row = row.strip()\n        return row\n    \n    def _filter_genre(self, genres):\n        genres = list(set.intersection(set(genres), set(map(lambda x: str(x), genre2idx.values()))))\n        if not genres:\n            genres = np.nan\n        else:\n            genres = [orig2flat[x] for x in genres]\n        return genres","metadata":{"id":"JSjLcT8mYezD","execution":{"iopub.status.busy":"2023-08-25T22:22:27.319434Z","iopub.execute_input":"2023-08-25T22:22:27.319712Z","iopub.status.idle":"2023-08-25T22:22:27.337203Z","shell.execute_reply.started":"2023-08-25T22:22:27.319687Z","shell.execute_reply":"2023-08-25T22:22:27.336021Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DataIterator():\n    def __init__(self, path_config: Dict[str, str], data_config: Dict[str, int], tokenizer: Callable):\n        dataset = CustomDataset(path_config['train_data'], tokenizer, data_config)\n        train_dataset, val_dataset = random_split(dataset, [data_config['train_size'], data_config['val_size']])\n        \n        self.train = DataLoader(\n            train_dataset,\n            batch_size=data_config['batch_size'], shuffle=True, drop_last=True\n        )\n\n        self.val = DataLoader(\n            val_dataset,\n            batch_size=data_config['batch_size'], shuffle=False, drop_last=True\n        )","metadata":{"id":"x1jAPAid82HX","execution":{"iopub.status.busy":"2023-08-25T22:22:27.475066Z","iopub.execute_input":"2023-08-25T22:22:27.475330Z","iopub.status.idle":"2023-08-25T22:22:27.482943Z","shell.execute_reply.started":"2023-08-25T22:22:27.475306Z","shell.execute_reply":"2023-08-25T22:22:27.480523Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model\n","metadata":{"id":"UU-BFyaTItwU"}},{"cell_type":"code","source":"@dataclass\nclass ModelArgs:\n    dropout: int = 0.3\n    n_label: int = len(genre2idx.values())","metadata":{"execution":{"iopub.status.busy":"2023-08-25T22:22:27.800987Z","iopub.execute_input":"2023-08-25T22:22:27.801279Z","iopub.status.idle":"2023-08-25T22:22:27.806685Z","shell.execute_reply.started":"2023-08-25T22:22:27.801255Z","shell.execute_reply":"2023-08-25T22:22:27.805624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Classifier(nn.Module):\n    def __init__(self, args: ModelArgs, d_model: int = 768):\n        super(Classifier, self).__init__()\n        self.fc_out = nn.Linear(d_model, args.n_label)\n\n    def forward(self, x):\n        x = self.fc_out(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2023-08-25T22:22:27.957493Z","iopub.execute_input":"2023-08-25T22:22:27.957761Z","iopub.status.idle":"2023-08-25T22:22:27.963381Z","shell.execute_reply.started":"2023-08-25T22:22:27.957737Z","shell.execute_reply":"2023-08-25T22:22:27.962474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class AttentionPoolingLayer(nn.Module):\n    def __init__(self, d_model: int=768):\n        super(AttentionPoolingLayer, self).__init__()\n        self.linear = torch.nn.Linear(d_model, 1)\n        \n    def forward(self, bert_outputs):\n        x = torch.stack([bert_outputs.hidden_states[i][:, 0, :].squeeze() for i in range(1, len(bert_outputs.hidden_states))])\n        energy = self.linear(x)\n        attention = F.softmax(energy, dim=0)\n        pooled_output = torch.sum(attention * x, dim=0)\n        return pooled_output","metadata":{"execution":{"iopub.status.busy":"2023-08-25T22:22:28.093305Z","iopub.execute_input":"2023-08-25T22:22:28.093926Z","iopub.status.idle":"2023-08-25T22:22:28.101412Z","shell.execute_reply.started":"2023-08-25T22:22:28.093892Z","shell.execute_reply":"2023-08-25T22:22:28.099934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CustomModel(nn.Module):\n    def __init__(self, args: ModelArgs):\n        super(CustomModel, self).__init__()\n        \n        self.roberta = AutoModel.from_pretrained(model_config['base_model'])\n\n        self.attention_pooling = AttentionPoolingLayer(self.roberta.config.hidden_size)\n        self.classifier = Classifier(ModelArgs, self.roberta.config.hidden_size)\n        self.linear = nn.Linear(self.roberta.config.hidden_size*2, 1)\n\n        self.relu = torch.nn.ReLU()\n\n    def forward(self, input_ids, attention_mask, **kwargs):\n        outputs = self.roberta(\n          input_ids=input_ids,\n          attention_mask=attention_mask,\n          output_hidden_states=True,\n          token_type_ids=None\n          )\n        \n        last_hidden_state = outputs[0]\n        mean_pooling_embeddings = torch.mean(last_hidden_state, 1)\n        _, max_pooling_embeddings = torch.max(last_hidden_state, 1)\n        mean_max_embeddings = torch.cat((mean_pooling_embeddings, max_pooling_embeddings), 1)\n        \n        mean_max_pooled_outputs = self.linear(mean_max_embeddings)\n        \n        attention_pooled_outputs = self.attention_pooling(outputs)\n        logits = self.classifier(attention_pooled_outputs + mean_max_pooled_outputs)\n\n        return logits","metadata":{"id":"WkyrAEhAQBQV","execution":{"iopub.status.busy":"2023-08-25T22:22:28.268884Z","iopub.execute_input":"2023-08-25T22:22:28.269159Z","iopub.status.idle":"2023-08-25T22:22:28.278660Z","shell.execute_reply.started":"2023-08-25T22:22:28.269135Z","shell.execute_reply":"2023-08-25T22:22:28.277567Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Metric","metadata":{"id":"5Ka98lsxi--Y"}},{"cell_type":"code","source":"class MetricCalculator():\n    def __init__(self):\n        self.total_precision = []\n\n\n    def print(self):\n        print(f'Precision : {self.total_precision.count(True) / len(self.total_precision)}')\n\n\n    def clean(self):\n        self.total_precision = []\n\n\n    def calc(self, y_pred, y_true):\n        y_pred = [int(torch.argmax(x)) for x in y_pred.cpu()]\n        y_true = y_true.cpu()\n        tmp = [i == int(j) for i, j in zip(y_pred, y_true)]\n        self.total_precision += tmp","metadata":{"id":"Mu7_xv2NAPwF","execution":{"iopub.status.busy":"2023-08-25T22:22:28.702461Z","iopub.execute_input":"2023-08-25T22:22:28.702757Z","iopub.status.idle":"2023-08-25T22:22:28.710883Z","shell.execute_reply.started":"2023-08-25T22:22:28.702732Z","shell.execute_reply":"2023-08-25T22:22:28.709733Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Trainer():\n    def __init__(self, model: nn.Module, optimizer: Callable, data_iterator: DataIterator, loss_fn,\n                 scheduler: Optional[torch.optim.lr_scheduler._LRScheduler] = None):\n        self.device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n        self.model = model.to(self.device)\n        self.optimizer = optimizer\n        self.scheduler = scheduler if scheduler else None\n        self.data_iterator = data_iterator\n        self.loss_fn = loss_fn\n        self.metric_calculator = MetricCalculator()\n        self.train_loss = []\n        self.test_loss = []\n    \n\n    def fit(self, epochs):\n        for epoch in range(1, epochs + 1):\n            self.train(epoch)\n            self.val(epoch)\n    \n    \n    def train(self, epoch):\n        self._train_step(epoch, self.data_iterator.train)\n    \n    \n    def val(self, epoch):\n        self._val_step(epoch, self.data_iterator.val)\n        \n        \n    def _train_step(self, epoch, data_loader):\n        data_iter = tqdm.tqdm(enumerate(data_loader), desc=f\"train #{epoch}\",\n                              total=len(data_loader), bar_format=\"{l_bar}{bar:30}{r_bar}{bar:-30b}\")\n        self.model.train()\n        running_loss = []\n        for i, data in data_iter:\n            data = {k: v.to(self.device) for k, v in data.items()}\n            labels = data['labels']\n            logits = self.model.forward(**data)\n            loss = self.loss_fn(logits, labels.view(-1))\n            loss.backward()\n            self.optimizer.step()\n            self.optimizer.zero_grad()\n            if self.scheduler: self.scheduler.step()   \n            running_loss.append(loss.item())\n            data_iter.set_postfix({\n                \"epoch\": epoch,\n                \"iteration\": i,\n                \"loss\": sum(running_loss) / len(running_loss)})\n            self.metric_calculator.calc(logits, labels)\n        self.train_loss += running_loss\n        self.metric_calculator.print()\n        self.metric_calculator.clean()\n    \n    \n    def _val_step(self, epoch, data_loader):\n        data_iter = tqdm.tqdm(enumerate(data_loader), desc=f\"test #{epoch}\",\n                              total=len(data_loader), bar_format=\"{l_bar}{bar:30}{r_bar}{bar:-30b}\")\n        self.model.eval()\n        running_loss = []\n        for i, data in data_iter:\n            data = {k: v.to(self.device) for k, v in data.items()}\n            labels = data['labels']\n            with torch.no_grad():\n                logits = self.model.forward(**data)\n                loss = self.loss_fn(logits, labels.view(-1))\n            running_loss.append(loss.item())\n            data_iter.set_postfix({\n                \"epoch\": epoch,\n                \"iteration\": i,\n                \"loss\": sum(running_loss) / len(running_loss)})\n            self.metric_calculator.calc(logits, labels)\n        \n        running_loss = sum(running_loss) / len(running_loss)\n        if not running_loss or (running_loss < (min(self.test_loss) if self.test_loss else 0)):\n            self.save(epoch, '/kaggle/working', f\"{running_loss:.3}\")\n            \n        self.test_loss.append(running_loss)\n        self.metric_calculator.print()\n        self.metric_calculator.clean()\n    \n    def save(self, epoch, file_path, loss):\n        file_path = os.path.join(file_path, f\"{loss}.pt\")\n        torch.save(self.model.state_dict(), file_path)\n        self.model.to(self.device)\n        print(f\"EP:{epoch} | Model Saved on: {file_path}\")","metadata":{"id":"YL0yp7zSaX9B","execution":{"iopub.status.busy":"2023-08-25T22:22:28.898684Z","iopub.execute_input":"2023-08-25T22:22:28.898982Z","iopub.status.idle":"2023-08-25T22:22:28.919445Z","shell.execute_reply.started":"2023-08-25T22:22:28.898951Z","shell.execute_reply":"2023-08-25T22:22:28.918420Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 학습","metadata":{}},{"cell_type":"code","source":"tokenizer = AutoTokenizer.from_pretrained(model_config['base_model'])\nmodel = CustomModel(ModelArgs)\noptimizer = AdamW(params=filter(lambda x: x.requires_grad, model.parameters()), **optim_config)\ndata_iterator = DataIterator(path_config, data_config, tokenizer)\nloss_fn = nn.CrossEntropyLoss()\n    \ntrainer = Trainer(model, optimizer, data_iterator, loss_fn)\n    \ntrainer.fit(train_config['epochs'])","metadata":{"id":"0DERGprGu3Ci","execution":{"iopub.status.busy":"2023-08-25T22:22:29.334509Z","iopub.execute_input":"2023-08-25T22:22:29.334780Z","iopub.status.idle":"2023-08-25T22:47:39.192037Z","shell.execute_reply.started":"2023-08-25T22:22:29.334756Z","shell.execute_reply":"2023-08-25T22:47:39.190197Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 모델 평가","metadata":{"id":"VTLJM3T2jEse"}},{"cell_type":"code","source":"model = CustomModel(ModelArgs).cuda()\nmodel.load_state_dict(torch.load(os.path.join(path_config['model'], '0.486.pt')))\nmodel.eval()\ntokenizer = AutoTokenizer.from_pretrained(model_config['base_model'])","metadata":{"execution":{"iopub.status.busy":"2023-08-25T22:47:47.129961Z","iopub.execute_input":"2023-08-25T22:47:47.131126Z","iopub.status.idle":"2023-08-25T22:47:48.278248Z","shell.execute_reply.started":"2023-08-25T22:47:47.131086Z","shell.execute_reply":"2023-08-25T22:47:48.277064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class TestDataset(Dataset):\n    def __init__(self, path: str, tokenizer: Callable, data_config: Dict[str, int]):\n        self.data = self._preprocess_data(path)\n        self.tokenizer = tokenizer\n        self.data_config = data_config\n    \n    \n    def __len__(self):\n        return len(self.data)\n    \n    \n    def __getitem__(self, idx):\n        row = self.data.iloc[idx]\n        \n        sentence = row['artist'] + '[SEP]' + self._get_season(row['month']) + '[SEP]' + str(row['year'])  + '[SEP]' + row['song_name'] + '[SEP]' + row['lyrics']\n        input = self.tokenizer(sentence, max_length=self.data_config['max_length'],\n                               truncation=True, padding='max_length')\n        input_ids = input['input_ids']\n        attention_mask = input['attention_mask']\n        \n        return {\n            'ids': torch.LongTensor([row['id']]),\n            'input_ids': torch.LongTensor(input_ids),\n            'attention_mask': torch.LongTensor(attention_mask),\n        }\n    \n    def _get_season(self, month):\n        if 11 > month > 9:\n            return '가을'\n        elif month > 6:\n            return '여름'\n        elif month > 2:\n            return '봄'\n        else:\n            return '겨울'\n                 \n    \n    def _preprocess_data(self, path):\n        data = pd.read_csv(path)\n        data = data.drop('adults', axis=1)\n        \n        data['lyrics'] = data['lyrics'].apply(self._preprocess_func)\n        data['song_name'] = data['song_name'].apply(self._preprocess_func)\n        data['artist'] = data['artist'].apply(self._preprocess_func)\n\n        data['date'] = data['date'].str.replace('-', '1980.04.21')\n        data = pd.concat([data, data['date'].str.split('.', expand=True)], axis=1).drop('date', axis=1)\n        \n        data = data.rename(columns=({'Unnamed: 0':'id', 0: 'year', 1: 'month', 2: 'day'}))\n        \n        data['id'] = data['id'].astype('float').fillna(method='ffill')\n        data['year'] = data['year'].astype('float').fillna(method='ffill')\n        data['month'] = data['month'].astype('float').fillna(method='ffill')\n        data['day'] = data['day'].astype('float').fillna(method='ffill')\n        return data\n    \n    \n    def _preprocess_func(self, row):\n        pattern = re.compile(r'\\([^)]*\\)')\n        row = re.sub(pattern, '', row)\n        row = row.replace('\\n', ' ')\n        row = row.strip()\n        return row","metadata":{"execution":{"iopub.status.busy":"2023-08-25T22:53:47.788271Z","iopub.execute_input":"2023-08-25T22:53:47.788700Z","iopub.status.idle":"2023-08-25T22:53:47.817031Z","shell.execute_reply.started":"2023-08-25T22:53:47.788663Z","shell.execute_reply":"2023-08-25T22:53:47.815883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tmp = TestDataset(path_config['test_data'], tokenizer, data_config)","metadata":{"execution":{"iopub.status.busy":"2023-08-25T22:53:48.167544Z","iopub.execute_input":"2023-08-25T22:53:48.167831Z","iopub.status.idle":"2023-08-25T22:53:48.600884Z","shell.execute_reply.started":"2023-08-25T22:53:48.167805Z","shell.execute_reply":"2023-08-25T22:53:48.599893Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ans = {}\nfor data_idx in tqdm.tqdm(range(len(tmp))):\n    input_ids = torch.LongTensor(tmp[data_idx]['input_ids']).unsqueeze(0).cuda()\n    attention_mask = torch.LongTensor(tmp[data_idx]['attention_mask']).unsqueeze(0).cuda()\n    ans[int(tmp[data_idx]['ids'])]= flat2orig[int(torch.argmax(model.forward(input_ids, attention_mask)))]","metadata":{"execution":{"iopub.status.busy":"2023-08-25T22:53:53.716591Z","iopub.execute_input":"2023-08-25T22:53:53.716974Z","iopub.status.idle":"2023-08-25T22:56:25.725886Z","shell.execute_reply.started":"2023-08-25T22:53:53.716942Z","shell.execute_reply":"2023-08-25T22:56:25.724841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test = pd.DataFrame.from_dict(data=ans, orient='index').reset_index()\ndf_test = df_test.rename(columns=({0: 'genre', 'index': 'id'}))\n\nRESULT_PATH = f'/kaggle/working/final2.csv'\ndf_test.to_csv(RESULT_PATH, index=False)\ndf_test","metadata":{"execution":{"iopub.status.busy":"2023-08-25T22:56:27.835608Z","iopub.execute_input":"2023-08-25T22:56:27.835984Z","iopub.status.idle":"2023-08-25T22:56:27.885738Z","shell.execute_reply.started":"2023-08-25T22:56:27.835953Z","shell.execute_reply":"2023-08-25T22:56:27.884848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}