{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":52950,"databundleVersionId":5973250,"sourceType":"competition"}],"dockerImageVersionId":30648,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# <b>1 <span style='color:#9146ff'>|</span> Import Libraries</b> ","metadata":{}},{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings('ignore') \n\nimport pandas as pd \nimport numpy as np \nimport matplotlib.pyplot as plt \nimport plotly.express as px \nfrom tqdm.auto import tqdm \nimport re \nimport pyarrow.parquet as pq \nimport json \n\nfrom sklearn.model_selection import train_test_split \n\nimport torch \nimport torch.nn as nn \nfrom torch.utils.data import DataLoader , TensorDataset , Dataset , random_split \nfrom torch.optim import Adam , lr_scheduler \nfrom torchinfo import summary \nfrom torch.nn.utils.rnn import pad_sequence  ","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-02-07T13:28:43.516454Z","iopub.execute_input":"2024-02-07T13:28:43.517175Z","iopub.status.idle":"2024-02-07T13:28:46.590581Z","shell.execute_reply.started":"2024-02-07T13:28:43.517141Z","shell.execute_reply":"2024-02-07T13:28:46.589597Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DEVICE = \"cuda\" if torch.cuda.is_available() else \"mps\" if torch.backends.mps.is_available() else \"cpu\"\nprint(f\"Using {DEVICE} device\")","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:28:46.592559Z","iopub.execute_input":"2024-02-07T13:28:46.593135Z","iopub.status.idle":"2024-02-07T13:28:46.615811Z","shell.execute_reply.started":"2024-02-07T13:28:46.593102Z","shell.execute_reply":"2024-02-07T13:28:46.614747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <b>2 <span style='color:#9146ff'>|</span> Read Dataset</b> ","metadata":{}},{"cell_type":"code","source":"data_path = '/kaggle/input/asl-fingerspelling/supplemental_metadata.csv'\ndf = pd.read_csv(data_path) ","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:28:46.617044Z","iopub.execute_input":"2024-02-07T13:28:46.617828Z","iopub.status.idle":"2024-02-07T13:28:46.697474Z","shell.execute_reply.started":"2024-02-07T13:28:46.617789Z","shell.execute_reply":"2024-02-07T13:28:46.696804Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TRG_MAX_LEN = max(len(x) for x in df['phrase'])\nTRG_MAX_LEN","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:28:46.699985Z","iopub.execute_input":"2024-02-07T13:28:46.700376Z","iopub.status.idle":"2024-02-07T13:28:46.71751Z","shell.execute_reply.started":"2024-02-07T13:28:46.700343Z","shell.execute_reply":"2024-02-07T13:28:46.71663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sequence_id, file_id, phrase = df.iloc[1][['sequence_id', 'file_id', 'phrase']]\nsample_sequence_df = pq.read_table(f\"/kaggle/input/asl-fingerspelling/supplemental_landmarks/{str(33432165)}.parquet\",\n                                   filters=[[('sequence_id', '=', sequence_id)]]).to_pandas()\nprint(\"Full sequence dataset shape is {} -> (no.frames,all mediapipe landmarks)\".format(sample_sequence_df.shape))","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:28:46.718739Z","iopub.execute_input":"2024-02-07T13:28:46.719277Z","iopub.status.idle":"2024-02-07T13:28:48.091583Z","shell.execute_reply.started":"2024-02-07T13:28:46.719251Z","shell.execute_reply":"2024-02-07T13:28:48.090666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_sequence_df","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:28:48.092851Z","iopub.execute_input":"2024-02-07T13:28:48.093243Z","iopub.status.idle":"2024-02-07T13:28:48.125109Z","shell.execute_reply.started":"2024-02-07T13:28:48.093208Z","shell.execute_reply":"2024-02-07T13:28:48.12423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <b>3 <span style='color:#9146ff'>|</span> Data Preprocessing</b> ","metadata":{}},{"cell_type":"markdown","source":"**Sign Preprocessing**","metadata":{}},{"cell_type":"code","source":"LPOSE = [13,15,17,19,21]\nRPOSE = [14,16,18,20,22]\nPOSE = LPOSE + RPOSE\nPOSE","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:28:48.126255Z","iopub.execute_input":"2024-02-07T13:28:48.126589Z","iopub.status.idle":"2024-02-07T13:28:48.133639Z","shell.execute_reply.started":"2024-02-07T13:28:48.126557Z","shell.execute_reply":"2024-02-07T13:28:48.13263Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X = [f'x_right_hand_{i}' for i in range(21)] + [f'x_left_hand_{i}' for i in range(21)] + [f'x_pose_{i}' for i in POSE]\nY = [f'y_right_hand_{i}' for i in range(21)] + [f'y_left_hand_{i}' for i in range(21)] + [f'y_pose_{i}' for i in POSE]\nZ = [f'z_right_hand_{i}' for i in range(21)] + [f'z_left_hand_{i}' for i in range(21)] + [f'z_pose_{i}' for i in POSE]\nFEATURE_COLUMNS = X+Y+Z","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:28:48.134853Z","iopub.execute_input":"2024-02-07T13:28:48.135175Z","iopub.status.idle":"2024-02-07T13:28:48.143589Z","shell.execute_reply.started":"2024-02-07T13:28:48.135145Z","shell.execute_reply":"2024-02-07T13:28:48.142677Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(FEATURE_COLUMNS)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:28:48.144737Z","iopub.execute_input":"2024-02-07T13:28:48.145007Z","iopub.status.idle":"2024-02-07T13:28:48.155006Z","shell.execute_reply.started":"2024-02-07T13:28:48.144976Z","shell.execute_reply":"2024-02-07T13:28:48.154117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_IDX = [i for i, col in enumerate(FEATURE_COLUMNS)  if \"x_\" in col]\nY_IDX = [i for i, col in enumerate(FEATURE_COLUMNS)  if \"y_\" in col]\nZ_IDX = [i for i, col in enumerate(FEATURE_COLUMNS)  if \"z_\" in col]\n\nRHAND_IDX = [i for i, col in enumerate(FEATURE_COLUMNS)  if \"right\" in col]\nLHAND_IDX = [i for i, col in enumerate(FEATURE_COLUMNS)  if  \"left\" in col]\nRPOSE_IDX = [i for i, col in enumerate(FEATURE_COLUMNS)  if  \"pose\" in col and int(col[-2:]) in RPOSE]\nLPOSE_IDX = [i for i, col in enumerate(FEATURE_COLUMNS)  if  \"pose\" in col and int(col[-2:]) in LPOSE]","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:28:48.158973Z","iopub.execute_input":"2024-02-07T13:28:48.159311Z","iopub.status.idle":"2024-02-07T13:28:48.167199Z","shell.execute_reply.started":"2024-02-07T13:28:48.159286Z","shell.execute_reply":"2024-02-07T13:28:48.166363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(X_IDX),len(Y_IDX),len(Z_IDX)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:28:48.168276Z","iopub.execute_input":"2024-02-07T13:28:48.168631Z","iopub.status.idle":"2024-02-07T13:28:48.192831Z","shell.execute_reply.started":"2024-02-07T13:28:48.168586Z","shell.execute_reply":"2024-02-07T13:28:48.192069Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(RHAND_IDX),len(LHAND_IDX),len(RPOSE_IDX),len(LPOSE_IDX)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:28:48.193813Z","iopub.execute_input":"2024-02-07T13:28:48.194113Z","iopub.status.idle":"2024-02-07T13:28:48.203158Z","shell.execute_reply.started":"2024-02-07T13:28:48.19408Z","shell.execute_reply":"2024-02-07T13:28:48.202361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_to_collect = []\n\nfor file_id in tqdm(df.file_id.unique()):\n    # Assuming the paths and filtering logic are already correctly defined\n    file_df = df.loc[df[\"file_id\"] == file_id]\n    parquet_df = pq.read_table(f\"/kaggle/input/asl-fingerspelling/supplemental_landmarks/{file_id}.parquet\",\n                               columns=['sequence_id'] + FEATURE_COLUMNS).to_pandas()\n    parquet_numpy = parquet_df.to_numpy()\n    # Loop through each sequence in file\n    for seq_id, phrase in zip(file_df.sequence_id, file_df.phrase):\n        # Assuming frames extraction logic is handled as per your dataset's requirements\n        \n        frames = parquet_numpy[parquet_df.index == seq_id]\n\n        # Calculate the number of NaN values in each hand landmark\n        r_nonan = np.sum(np.sum(np.isnan(frames[:, RHAND_IDX]), axis=1) == 0)\n        l_nonan = np.sum(np.sum(np.isnan(frames[:, LHAND_IDX]), axis=1) == 0)\n        no_nan = max(r_nonan, l_nonan)\n\n        if 2*len(phrase) < no_nan:\n            # Prepare data entry for each sequence\n            data_entry = {}\n            for i, column_name in enumerate(FEATURE_COLUMNS):\n                # Flatten and store each feature's values\n                data_entry[column_name] = frames[:, i].flatten()\n            # Store phrase as a feature\n            data_entry[\"text\"] = phrase\n\n            # Append this entry to our collection list\n            data_to_collect.append(data_entry)\n\n# Convert collected data into a DataFrame\nhands_df = pd.DataFrame(data_to_collect)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:28:48.204232Z","iopub.execute_input":"2024-02-07T13:28:48.205004Z","iopub.status.idle":"2024-02-07T13:29:44.686719Z","shell.execute_reply.started":"2024-02-07T13:28:48.204973Z","shell.execute_reply":"2024-02-07T13:29:44.685861Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Select columns for 'right' including specified pose columns\nright_hand_cols = [col for col in hands_df.columns if 'right_hand' in col]\nright_pose_cols = [f'{dim}_pose_{i}' for i in [14, 16, 18, 20, 22] for dim in ['x', 'y', 'z']]\nright_cols = right_hand_cols + right_pose_cols\n\n# Select columns for 'left' including specified pose columns\nleft_hand_cols = [col for col in hands_df.columns if 'left_hand' in col]\nleft_pose_cols = [f'{dim}_pose_{i}' for i in [13, 15, 17, 19, 21] for dim in ['x', 'y', 'z']]\nleft_cols = left_hand_cols + left_pose_cols\n\n# Function to concatenate values of given columns for a row\ndef concat_cols(row, cols):\n    return [row[col] for col in cols]\n\n# Concatenate values for 'right' and 'left'\nhands_df['right'] = hands_df.apply(concat_cols, cols=right_cols, axis=1)\nhands_df['left'] = hands_df.apply(concat_cols, cols=left_cols, axis=1)\n\n# Create a new DataFrame with desired columns\nhands_df = hands_df[[ 'right', 'left','text']].copy()\n","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:29:44.68787Z","iopub.execute_input":"2024-02-07T13:29:44.68815Z","iopub.status.idle":"2024-02-07T13:30:09.949466Z","shell.execute_reply.started":"2024-02-07T13:29:44.688119Z","shell.execute_reply":"2024-02-07T13:30:09.948666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"hands_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:30:09.950687Z","iopub.execute_input":"2024-02-07T13:30:09.951042Z","iopub.status.idle":"2024-02-07T13:30:10.836494Z","shell.execute_reply.started":"2024-02-07T13:30:09.95101Z","shell.execute_reply":"2024-02-07T13:30:10.835451Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"hands_df['right'] = hands_df['right'].apply(lambda x: np.array(x).T)\nhands_df['left'] = hands_df['left'].apply(lambda x: np.array(x).T)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:30:10.837823Z","iopub.execute_input":"2024-02-07T13:30:10.838148Z","iopub.status.idle":"2024-02-07T13:30:16.935134Z","shell.execute_reply.started":"2024-02-07T13:30:10.838102Z","shell.execute_reply":"2024-02-07T13:30:16.934354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def resize_pad_array(arr, target_frames=128, num_features=78):\n    current_frames = arr.shape[0]\n    if current_frames > target_frames:\n        # Truncate the array if it has more than target_frames\n        return arr[:target_frames]\n    elif current_frames < target_frames:\n        # Pad the array with zeros if it has less than target_frames\n        padding = np.zeros((target_frames - current_frames, num_features))\n        return np.vstack([arr, padding])\n    else:\n        # Return the array as is if it already matches the target_frames\n        return arr\n\n# Apply the normalization function to each row for 'right' and 'left' columns\nfor index, row in tqdm(hands_df.iterrows()):\n    hands_df.at[index, 'right'] = resize_pad_array(row['right'])\n    hands_df.at[index, 'left'] = resize_pad_array(row['left'])\n\n# Verify the changes\nfor index, row in hands_df.iterrows():\n    print(f\"Right shape: {row['right'].shape}, Left shape: {row['left'].shape}\")\n    break","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:30:16.93623Z","iopub.execute_input":"2024-02-07T13:30:16.936519Z","iopub.status.idle":"2024-02-07T13:30:21.546498Z","shell.execute_reply.started":"2024-02-07T13:30:16.936495Z","shell.execute_reply":"2024-02-07T13:30:21.5455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"frame_num = 128\nnum_rows = len(hands_df.text)\nfor row in tqdm(range(num_rows)): # Mirror left hand \n    \n    for frame in range(frame_num):\n        left_row_frame = hands_df.left[row][frame]\n        # [:21 x_hand,21:42 y_hand,42:63 z_hand,63:68 x_pose, 68:73 y_pose 73:78 z_pose]\n        left_row_frame[:21] = 1 -  left_row_frame[:21]\n        left_row_frame[63:68] = 1- left_row_frame[63:68] \n        hands_df.left[row][frame] = left_row_frame","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:30:21.554279Z","iopub.execute_input":"2024-02-07T13:30:21.554551Z","iopub.status.idle":"2024-02-07T13:33:31.956589Z","shell.execute_reply.started":"2024-02-07T13:30:21.554528Z","shell.execute_reply":"2024-02-07T13:33:31.955627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def dominant_hand(row):\n    lnan = np.count_nonzero(np.isnan(row['left']))\n    rnan = np.count_nonzero(np.isnan(row['right']))\n    if lnan < rnan:\n        return row['left']\n    else:\n        return row['right']","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:31.957974Z","iopub.execute_input":"2024-02-07T13:33:31.958651Z","iopub.status.idle":"2024-02-07T13:33:31.964439Z","shell.execute_reply.started":"2024-02-07T13:33:31.958591Z","shell.execute_reply":"2024-02-07T13:33:31.963486Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"hands_df['sign'] = hands_df.apply(dominant_hand, axis=1)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:31.965701Z","iopub.execute_input":"2024-02-07T13:33:31.966032Z","iopub.status.idle":"2024-02-07T13:33:33.53255Z","shell.execute_reply.started":"2024-02-07T13:33:31.965999Z","shell.execute_reply":"2024-02-07T13:33:33.531752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"hands_df = hands_df[['sign','text']].copy()","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:33.533676Z","iopub.execute_input":"2024-02-07T13:33:33.53397Z","iopub.status.idle":"2024-02-07T13:33:33.567947Z","shell.execute_reply.started":"2024-02-07T13:33:33.533944Z","shell.execute_reply":"2024-02-07T13:33:33.567098Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"hands_df['sign'] = hands_df['sign'].apply(lambda x: np.where(np.isnan(x), 0, x)) # remove NaN","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:33.593667Z","iopub.execute_input":"2024-02-07T13:33:33.593935Z","iopub.status.idle":"2024-02-07T13:33:34.62568Z","shell.execute_reply.started":"2024-02-07T13:33:33.593912Z","shell.execute_reply":"2024-02-07T13:33:34.624664Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"hands_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:34.627005Z","iopub.execute_input":"2024-02-07T13:33:34.627774Z","iopub.status.idle":"2024-02-07T13:33:35.109352Z","shell.execute_reply.started":"2024-02-07T13:33:34.627738Z","shell.execute_reply":"2024-02-07T13:33:35.108479Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Text Preprocessing**","metadata":{}},{"cell_type":"code","source":"with open (\"/kaggle/input/asl-fingerspelling/character_to_prediction_index.json\", \"r\") as f:\n    char_to_num = json.load(f)\n\n# Add pad_token, start pointer and end pointer to the dict\npad_token = 'P'\nstart_token = '<'\nend_token = '>'\npad_token_idx = 59\nstart_token_idx = 60\nend_token_idx = 61\n\nchar_to_num[pad_token] = pad_token_idx\nchar_to_num[start_token] = start_token_idx\nchar_to_num[end_token] = end_token_idx\nnum_to_char = {j:i for i,j in char_to_num.items()}","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:35.110425Z","iopub.execute_input":"2024-02-07T13:33:35.110768Z","iopub.status.idle":"2024-02-07T13:33:35.120176Z","shell.execute_reply.started":"2024-02-07T13:33:35.110743Z","shell.execute_reply":"2024-02-07T13:33:35.119322Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(char_to_num)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:35.121303Z","iopub.execute_input":"2024-02-07T13:33:35.12159Z","iopub.status.idle":"2024-02-07T13:33:35.131493Z","shell.execute_reply.started":"2024-02-07T13:33:35.121566Z","shell.execute_reply":"2024-02-07T13:33:35.130546Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(char_to_num) # n_classes ","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:35.132755Z","iopub.execute_input":"2024-02-07T13:33:35.133138Z","iopub.status.idle":"2024-02-07T13:33:35.14137Z","shell.execute_reply.started":"2024-02-07T13:33:35.133108Z","shell.execute_reply":"2024-02-07T13:33:35.140481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"hands_df['text'] = hands_df['text'].apply(lambda x: start_token+x+end_token)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:35.142582Z","iopub.execute_input":"2024-02-07T13:33:35.143207Z","iopub.status.idle":"2024-02-07T13:33:35.166132Z","shell.execute_reply.started":"2024-02-07T13:33:35.143173Z","shell.execute_reply":"2024-02-07T13:33:35.165479Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"hands_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:35.172374Z","iopub.execute_input":"2024-02-07T13:33:35.17263Z","iopub.status.idle":"2024-02-07T13:33:35.655869Z","shell.execute_reply.started":"2024-02-07T13:33:35.172598Z","shell.execute_reply":"2024-02-07T13:33:35.65497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <b>4 <span style='color:#9146ff'>|</span> Split the data</b> ","metadata":{}},{"cell_type":"code","source":"train_src , test_src , train_trg , test_trg = train_test_split(hands_df['sign'].tolist() , hands_df['text'].tolist() , train_size = 0.80 , random_state = 42) \nlen(train_src) , len(test_src)  ","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:35.656827Z","iopub.execute_input":"2024-02-07T13:33:35.657088Z","iopub.status.idle":"2024-02-07T13:33:35.685543Z","shell.execute_reply.started":"2024-02-07T13:33:35.657065Z","shell.execute_reply":"2024-02-07T13:33:35.68471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <b>5 <span style='color:#9146ff'>|</span> Data Pipeline</b> ","metadata":{}},{"cell_type":"code","source":"BATCH_SIZE = 64","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:35.686577Z","iopub.execute_input":"2024-02-07T13:33:35.686864Z","iopub.status.idle":"2024-02-07T13:33:35.694435Z","shell.execute_reply.started":"2024-02-07T13:33:35.686841Z","shell.execute_reply":"2024-02-07T13:33:35.693655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class InvalidDatasetException(Exception):\n    \n    def __init__(self,len_of_paths,len_of_labels):\n        super().__init__(\n            f\"Number of paths ({len_of_paths}) is not compatible with number of labels ({len_of_labels})\"\n        )","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:35.695328Z","iopub.execute_input":"2024-02-07T13:33:35.695584Z","iopub.status.idle":"2024-02-07T13:33:35.704237Z","shell.execute_reply.started":"2024-02-07T13:33:35.695562Z","shell.execute_reply":"2024-02-07T13:33:35.703471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CustomData(Dataset) : \n    def __init__(self , sign_df , text_df) : \n        self.sign_df = sign_df \n        self.text_df = text_df \n        if len(self.sign_df) != len(self.text_df) : \n            raise InvalidDatasetException(self.sign_df , self.text_df) \n        \n    def __len__(self) : \n        return len(self.sign_df) \n    \n    def __getitem__(self , idx) :  \n             \n        sign = torch.tensor(self.sign_df[idx] , dtype = torch.float32) \n        txt = self.text_df[idx]\n        \n        return sign , txt  ","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:35.705137Z","iopub.execute_input":"2024-02-07T13:33:35.705389Z","iopub.status.idle":"2024-02-07T13:33:35.714638Z","shell.execute_reply.started":"2024-02-07T13:33:35.705367Z","shell.execute_reply":"2024-02-07T13:33:35.713818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_set = CustomData(train_src , train_trg) \ntest_set = CustomData(test_src , test_trg) ","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:35.715721Z","iopub.execute_input":"2024-02-07T13:33:35.716245Z","iopub.status.idle":"2024-02-07T13:33:35.725005Z","shell.execute_reply.started":"2024-02-07T13:33:35.716213Z","shell.execute_reply":"2024-02-07T13:33:35.724092Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def vectorization(data):\n    processed_data = []\n    for (sign , txt) in tqdm(data,total=len(list(data))) :\n        sign_tensor = torch.tensor(sign, dtype=torch.float32)\n        txt_tensor = torch.tensor([char_to_num[letter] for letter in txt],dtype=torch.long)\n        processed_data.append((sign_tensor,txt_tensor))\n    return processed_data","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:35.725926Z","iopub.execute_input":"2024-02-07T13:33:35.726197Z","iopub.status.idle":"2024-02-07T13:33:35.73475Z","shell.execute_reply.started":"2024-02-07T13:33:35.726168Z","shell.execute_reply":"2024-02-07T13:33:35.734014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_set = vectorization(train_set) \ntest_set = vectorization(test_set)  ","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:35.735799Z","iopub.execute_input":"2024-02-07T13:33:35.736395Z","iopub.status.idle":"2024-02-07T13:33:39.56051Z","shell.execute_reply.started":"2024-02-07T13:33:35.736362Z","shell.execute_reply":"2024-02-07T13:33:39.559549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def collate_fn(data):\n    sign_data, txt_data = [], []\n    \n    for sign_vector, txt_vector in data:\n        sign_data.append(torch.tensor(sign_vector))  # Ensure sign_vector is in the correct form\n        # Assuming txt_vector is already a tensor or a list that can be converted to a tensor\n        txt_data.append(torch.tensor(txt_vector, dtype=torch.long))  # Ensure correct type for txt_vector\n    \n    # Stack sign_data to create a batched tensor\n    sign_data = torch.stack(sign_data)\n    # Pad txt_data sequences\n    txt_data = pad_sequence(sequences=txt_data, padding_value=pad_token_idx , batch_first=True)\n    \n    return sign_data, txt_data","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:39.562049Z","iopub.execute_input":"2024-02-07T13:33:39.562457Z","iopub.status.idle":"2024-02-07T13:33:39.570072Z","shell.execute_reply.started":"2024-02-07T13:33:39.562418Z","shell.execute_reply":"2024-02-07T13:33:39.569033Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.manual_seed(42) \ntrain_dataloader = DataLoader(\n    dataset = train_set , \n    batch_size = BATCH_SIZE , \n    shuffle = True , \n    num_workers = 4 , \n    pin_memory = True , \n    collate_fn=collate_fn\n)\n\ntorch.manual_seed(42) \nval_dataloader = DataLoader(\n    dataset = test_set , \n    batch_size = BATCH_SIZE , \n    num_workers = 4 , \n    pin_memory = True , \n    collate_fn=collate_fn\n)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:39.571241Z","iopub.execute_input":"2024-02-07T13:33:39.571515Z","iopub.status.idle":"2024-02-07T13:33:39.583548Z","shell.execute_reply.started":"2024-02-07T13:33:39.571491Z","shell.execute_reply":"2024-02-07T13:33:39.582661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"the size of the train dataloader {len(train_dataloader)} batches of {BATCH_SIZE}\")","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:39.584623Z","iopub.execute_input":"2024-02-07T13:33:39.584912Z","iopub.status.idle":"2024-02-07T13:33:39.591949Z","shell.execute_reply.started":"2024-02-07T13:33:39.584887Z","shell.execute_reply":"2024-02-07T13:33:39.591028Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"the size of the validation dataloader {len(val_dataloader)} batches of {BATCH_SIZE}\")","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:39.593036Z","iopub.execute_input":"2024-02-07T13:33:39.593846Z","iopub.status.idle":"2024-02-07T13:33:39.604563Z","shell.execute_reply.started":"2024-02-07T13:33:39.593819Z","shell.execute_reply":"2024-02-07T13:33:39.603648Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sign_sample , trg_sample = next(iter(train_dataloader))\nsign_sample , trg_sample = sign_sample.to(DEVICE) , trg_sample.to(DEVICE)\nsign_sample.shape , trg_sample.shape","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:39.60564Z","iopub.execute_input":"2024-02-07T13:33:39.606849Z","iopub.status.idle":"2024-02-07T13:33:40.586896Z","shell.execute_reply.started":"2024-02-07T13:33:39.606824Z","shell.execute_reply":"2024-02-07T13:33:40.585805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <b>6 <span style='color:#9146ff'>|</span> Build our Transformer</b> ","metadata":{}},{"cell_type":"markdown","source":"<span style='font-size:25px;font-weight:bold'>1- <span style='color:#9146ff'>LandmarkEmbedding</span></span>","metadata":{}},{"cell_type":"code","source":"class LandmarkEmbedding(nn.Module) : \n    def __init__(self , num_hid) : \n        super(LandmarkEmbedding , self).__init__() \n        \n        self.conv1 = nn.Conv1d(in_channels=78, out_channels=num_hid, kernel_size=11, stride=2, padding=5)\n        self.conv2 = nn.Conv1d(in_channels=num_hid, out_channels=num_hid, kernel_size=11, stride=2, padding=5)\n        self.conv3 = nn.Conv1d(in_channels=num_hid, out_channels=num_hid, kernel_size=11, stride=2, padding=5) \n        \n        self.relu = nn.ReLU(inplace = True) \n         \n        \n    def forward(self , x) :  \n        x = x.permute(0 , 2 , 1) \n        x = self.relu(self.conv1(x))\n        x = self.relu(self.conv2(x))\n        x = self.relu(self.conv3(x))  \n        x = x.permute(0 , 2 , 1)\n        \n        return x ","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:40.588272Z","iopub.execute_input":"2024-02-07T13:33:40.588581Z","iopub.status.idle":"2024-02-07T13:33:40.597174Z","shell.execute_reply.started":"2024-02-07T13:33:40.588553Z","shell.execute_reply":"2024-02-07T13:33:40.596256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style='font-size:25px;font-weight:bold'>2- <span style='color:#9146ff'>Encoder</span></span>","metadata":{}},{"cell_type":"code","source":"class Encoder(nn.Module) : \n    def __init__(\n        self ,  \n        embedding_dim , \n        n_heads , \n        fc_dim , \n        dropout_rate = 0.1\n    ) : \n        super(Encoder , self).__init__() \n        \n        self.MHA = nn.MultiheadAttention(embed_dim=embedding_dim , num_heads=n_heads , batch_first=True).to(DEVICE)\n        \n        self.fc = nn.Sequential(\n            nn.Linear(embedding_dim , fc_dim) , \n            nn.ReLU(inplace = True) , \n            nn.Linear(fc_dim , embedding_dim)\n        ).to(DEVICE)\n        \n        self.norm1 = nn.LayerNorm(embedding_dim , eps=1e-6).to(DEVICE) \n        self.norm2 = nn.LayerNorm(embedding_dim , eps=1e-6).to(DEVICE) \n        \n        self.dropout1 = nn.Dropout(dropout_rate).to(DEVICE)\n        self.dropout2 = nn.Dropout(dropout_rate).to(DEVICE)\n        \n    def forward(self , x) : \n        attn_out , _ = self.MHA(x , x , x) # (batch_size , seqlen , embedding_dim) \n        attn_out = self.dropout1(attn_out) \n        \n        out1 = self.norm1(x + attn_out) # (batch_size , seqlen , embedding_dim) \n        \n        fc_out = self.dropout2(self.fc(out1)) # (batch_size , seqlen , embedding_dim) \n        \n        enc_out = self.norm2(out1 + fc_out) # (batch_size , seqlen , embedding_dim) \n        \n        return enc_out","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:40.598239Z","iopub.execute_input":"2024-02-07T13:33:40.598497Z","iopub.status.idle":"2024-02-07T13:33:40.61339Z","shell.execute_reply.started":"2024-02-07T13:33:40.598474Z","shell.execute_reply":"2024-02-07T13:33:40.61243Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style='font-size:25px;font-weight:bold'>3- <span style='color:#9146ff'>Decoder</span></span>","metadata":{}},{"cell_type":"code","source":"class Decoder(nn.Module) : \n    def __init__(\n        self ,  \n        embedding_dim , \n        n_heads , \n        fc_dim , \n        dropout_rate = 0.1\n    ) : \n        super(Decoder , self).__init__() \n        \n        self.MHA1 = nn.MultiheadAttention(embed_dim=embedding_dim , num_heads=n_heads , batch_first=True).to(DEVICE)\n        self.MHA2 = nn.MultiheadAttention(embed_dim=embedding_dim , num_heads=n_heads , batch_first=True).to(DEVICE)\n        \n        self.fc = nn.Sequential(\n            nn.Linear(embedding_dim , fc_dim) , \n            nn.ReLU(inplace = True) , \n            nn.Linear(fc_dim , embedding_dim)\n        ).to(DEVICE)\n        \n        self.norm1 = nn.LayerNorm(embedding_dim , eps=1e-6).to(DEVICE) \n        self.norm2 = nn.LayerNorm(embedding_dim , eps=1e-6).to(DEVICE) \n        self.norm3 = nn.LayerNorm(embedding_dim , eps=1e-6).to(DEVICE)\n        \n        self.dropout1 = nn.Dropout(dropout_rate).to(DEVICE)\n        self.dropout2 = nn.Dropout(dropout_rate).to(DEVICE)\n        self.dropout3 = nn.Dropout(dropout_rate).to(DEVICE) \n        \n    def look_ahead_mask(self , trg) : \n        # The look-ahead mask is used to mask the future tokens in a sequence. In other words,\n        # the mask indicates which entries should not be used\n    \n        # Returns a lower triangular matrix filled with 1s. The shape of the mask is (target_size, target_size)\n        # tensor([[[[0., 1., 1.],\n                  #  [0., 0., 1.],\n                  #  [0., 0., 0.]]]])\n     \n        batch_size , trg_len , _ = trg.shape \n    \n        trg_mask = torch.tril(torch.ones((batch_size , trg_len)) , diagonal=0).to(DEVICE)\n    \n        return trg_mask \n    \n    \n    def forward(self , x , enc_output) : \n        # enc_output shape : (batch_size , seqlen , embedding_dim) \n        # x shape : (batch_size , seqlen)\n        \n        dec_mask = self.look_ahead_mask(x) \n        \n        attn1 , _= self.MHA1(x , x , x , dec_mask) \n        attn1 = self.dropout1(attn1) \n        out1 = self.norm1(attn1 + x) # (batch_size , seqlen , embedding_dim) \n        \n        attn2 , _= self.MHA2(out1 , enc_output , enc_output) \n        attn2 = self.dropout2(attn2)\n        out2 = self.norm2(attn2 + out1) # (batch_size , seqlen , embedding_dim) \n        \n        fc_out = self.dropout3(self.fc(out2)) \n        dec_out = self.norm3(fc_out + out2) # (batch_size , seqlen , embedding_dim) \n        \n        return dec_out ","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:40.61459Z","iopub.execute_input":"2024-02-07T13:33:40.614876Z","iopub.status.idle":"2024-02-07T13:33:40.628137Z","shell.execute_reply.started":"2024-02-07T13:33:40.614852Z","shell.execute_reply":"2024-02-07T13:33:40.627361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style='font-size:25px;font-weight:bold'>4- <span style='color:#9146ff'>Transformer</span></span>","metadata":{}},{"cell_type":"code","source":"class Transformer(nn.Module) : \n    def __init__(\n        self , \n        num_layers , \n        embedding_dim , \n        num_heads , \n        fc_dim , \n        num_classes , \n        src_max_length , \n        trg_max_length , \n        dropout_rate = 0.1\n    ) : \n        super(Transformer , self).__init__() \n        \n        self.num_layers = num_layers \n        \n        self.enc_dropout = nn.Dropout(dropout_rate).to(DEVICE)\n        self.dec_dropout = nn.Dropout(dropout_rate).to(DEVICE)\n        \n        self.landmark_embedding = LandmarkEmbedding(embedding_dim).to(DEVICE)\n        \n        self.dec_embedding = nn.Embedding(num_classes , embedding_dim).to(DEVICE)\n        self.dec_pos_encoding = nn.Embedding(trg_max_length , embedding_dim).to(DEVICE)\n        \n        self.enc_layers = [Encoder(embedding_dim , num_heads , fc_dim , dropout_rate)\n                          for _ in range(num_layers)] \n        \n        self.dec_layers = [Decoder(embedding_dim , num_heads , fc_dim , dropout_rate)\n                          for _ in range(num_layers)] \n        \n        self.fc_out = nn.Linear(embedding_dim , num_classes).to(DEVICE) \n        \n    def forward(self , src , trg) : \n        batch_size , seqlen = trg.shape\n        \n        # encoder\n        enc_out = self.enc_dropout(self.landmark_embedding(src)) # (batch_size , seqlen , embedding_dim)\n        \n        for i in range(self.num_layers) : \n            enc_out = self.enc_layers[i](enc_out) # (batch_size , seqlen , embedding_dim)\n            \n        # decoder \n        positions = torch.arange(0, seqlen).expand(batch_size, seqlen).to(DEVICE) \n        \n        dec_out = self.dec_dropout((self.dec_embedding(trg) + self.dec_pos_encoding(positions))) # (batch_size , seqlen , embedding_dim)\n        \n        for i in range(self.num_layers) : \n            dec_out = self.dec_layers[i](dec_out , enc_out) \n            \n        out = self.fc_out(dec_out) \n        \n        return out","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:40.629222Z","iopub.execute_input":"2024-02-07T13:33:40.629488Z","iopub.status.idle":"2024-02-07T13:33:40.643544Z","shell.execute_reply.started":"2024-02-07T13:33:40.629466Z","shell.execute_reply":"2024-02-07T13:33:40.642665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# set hyperparameters\nEPOCHS = 100 \nEMBEDDING_DIM = 200 \nFC_DIM = 400  \nNUM_LAYERS = 4 \nNUM_HEADS = 4 \nDROPOUT_RATE = 0.1 \nNUM_CLASSES = len(char_to_num) \nSRC_MAXLEN = frame_num\nTRG_MAXLEN = 64\nLR = 0.0001\n\nmodel = Transformer(\n    NUM_LAYERS , \n    EMBEDDING_DIM , \n    NUM_HEADS , \n    FC_DIM , \n    NUM_CLASSES , \n    SRC_MAXLEN , \n    TRG_MAXLEN , \n    DROPOUT_RATE\n).to(DEVICE) ","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:40.644825Z","iopub.execute_input":"2024-02-07T13:33:40.645465Z","iopub.status.idle":"2024-02-07T13:33:40.717502Z","shell.execute_reply.started":"2024-02-07T13:33:40.645432Z","shell.execute_reply":"2024-02-07T13:33:40.71683Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"temp_trg_out = model(sign_sample , trg_sample) \ntemp_trg_out.shape","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:40.718487Z","iopub.execute_input":"2024-02-07T13:33:40.718754Z","iopub.status.idle":"2024-02-07T13:33:41.429119Z","shell.execute_reply.started":"2024-02-07T13:33:40.718731Z","shell.execute_reply":"2024-02-07T13:33:41.428208Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"summary(model , input_data = [sign_sample , trg_sample])","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:41.430254Z","iopub.execute_input":"2024-02-07T13:33:41.430559Z","iopub.status.idle":"2024-02-07T13:33:41.451344Z","shell.execute_reply.started":"2024-02-07T13:33:41.430533Z","shell.execute_reply":"2024-02-07T13:33:41.450481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <b>7 <span style='color:#9146ff'>|</span> Loss , Optimizer and Metrics</b> ","metadata":{}},{"cell_type":"code","source":"optimizer = Adam(model.parameters() , lr = LR , betas=(0.9 , 0.999) , eps = 1e-9) \ncriterion = nn.CrossEntropyLoss(ignore_index=pad_token_idx)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:41.452315Z","iopub.execute_input":"2024-02-07T13:33:41.452552Z","iopub.status.idle":"2024-02-07T13:33:43.001398Z","shell.execute_reply.started":"2024-02-07T13:33:41.452531Z","shell.execute_reply":"2024-02-07T13:33:43.000427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def accuracy_fn(y_true , y_pred) : \n    preds = torch.argmax(y_pred , dim = 1) \n    \n    correct = torch.eq(preds , y_true).float() \n    \n    acc = correct.mean() \n    \n    return acc","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:43.002639Z","iopub.execute_input":"2024-02-07T13:33:43.003104Z","iopub.status.idle":"2024-02-07T13:33:43.007973Z","shell.execute_reply.started":"2024-02-07T13:33:43.003075Z","shell.execute_reply":"2024-02-07T13:33:43.007087Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"load_model = False \nsave_model = True","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:43.009309Z","iopub.execute_input":"2024-02-07T13:33:43.009599Z","iopub.status.idle":"2024-02-07T13:33:43.020282Z","shell.execute_reply.started":"2024-02-07T13:33:43.009557Z","shell.execute_reply":"2024-02-07T13:33:43.019489Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def save_checkpoint(state, filename=\"my_checkpoint.pth.tar\"):\n    print(\"=> Saving checkpoint\")\n    torch.save(state, filename)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:43.021393Z","iopub.execute_input":"2024-02-07T13:33:43.021962Z","iopub.status.idle":"2024-02-07T13:33:43.030643Z","shell.execute_reply.started":"2024-02-07T13:33:43.021929Z","shell.execute_reply":"2024-02-07T13:33:43.029779Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_checkpoint(checkpoint, model, optimizer):\n    print(\"=> Loading checkpoint\")\n    model.load_state_dict(checkpoint[\"state_dict\"])\n    optimizer.load_state_dict(checkpoint[\"optimizer\"])","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:43.031789Z","iopub.execute_input":"2024-02-07T13:33:43.032355Z","iopub.status.idle":"2024-02-07T13:33:43.041159Z","shell.execute_reply.started":"2024-02-07T13:33:43.032322Z","shell.execute_reply":"2024-02-07T13:33:43.040419Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <b>8 <span style='color:#9146ff'>|</span> Train our model</b> ","metadata":{}},{"cell_type":"code","source":"def train_step(src , trg) : \n    decoder_input = trg[: , :-1] \n    trg_reals = trg[: , 1:].reshape(-1)\n    \n    preds= model(src , decoder_input)  \n    \n    preds = preds.reshape(-1 , preds.shape[2])\n    \n    loss = criterion(preds , trg_reals)\n    \n    optimizer.zero_grad()\n    \n    loss.backward()\n    \n    # weights clipping to avoid exploding\n    torch.nn.utils.clip_grad_norm(parameters=model.parameters(),max_norm=1) \n    \n    optimizer.step()\n     \n    acc = accuracy_fn(trg_reals , preds) \n    \n    return loss , acc","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:43.042238Z","iopub.execute_input":"2024-02-07T13:33:43.042978Z","iopub.status.idle":"2024-02-07T13:33:43.051517Z","shell.execute_reply.started":"2024-02-07T13:33:43.042945Z","shell.execute_reply":"2024-02-07T13:33:43.05075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def val_step(src , trg) :\n    decoder_input = trg[: , :-1] \n    trg_reals = trg[: , 1:].reshape(-1) \n    \n    preds= model(src , decoder_input) \n    \n    preds = preds.reshape(-1 , preds.shape[2]) \n    \n    loss = criterion(preds , trg_reals) \n    \n    acc = accuracy_fn(trg_reals , preds) \n    \n    return loss , acc ","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:43.052489Z","iopub.execute_input":"2024-02-07T13:33:43.05278Z","iopub.status.idle":"2024-02-07T13:33:43.063258Z","shell.execute_reply.started":"2024-02-07T13:33:43.052751Z","shell.execute_reply":"2024-02-07T13:33:43.062431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_losses = []\ntrain_accuracies = []\nval_losses = []\nval_accuracies = [] \nfor epoch in tqdm(range(EPOCHS)) :  \n    epoch_train_loss = 0 \n    epoch_train_acc = 0 \n    epoch_val_loss = 0 \n    epoch_val_acc = 0 \n    \n    model.train()\n    for x_train , y_train in train_dataloader : \n        x_train , y_train = x_train.to(DEVICE) , y_train.to(DEVICE)\n        \n        train_loss , train_acc = train_step(x_train , y_train) \n        \n        epoch_train_loss += train_loss \n        epoch_train_acc += train_acc \n    \n    model.eval()\n    with torch.no_grad() : \n        for x_val , y_val in val_dataloader :\n            x_val , y_val = x_val.to(DEVICE) , y_val.to(DEVICE)\n            val_loss , val_acc = val_step(x_val , y_val) \n            \n            epoch_val_loss += val_loss\n            epoch_val_acc += val_acc \n            \n    train_losses.append((epoch_train_loss / len(train_dataloader)).cpu().detach().numpy())\n    train_accuracies.append((epoch_train_acc / len(train_dataloader)).cpu().detach().numpy())\n    val_losses.append((epoch_val_loss / len(val_dataloader)).cpu().detach().numpy())\n    val_accuracies.append((epoch_val_acc / len(val_dataloader)).cpu().detach().numpy()) \n    \n    if (epoch + 1) % 10 == 0 : \n            print(f\"[Epoch :  {epoch+1}/{EPOCHS}] [Train Loss : {train_losses[-1]}] [Train Accuracy : {train_accuracies[-1]}]\\n[Validation Loss : {val_losses[-1]}] [Validation Accuracy : {val_accuracies[-1]}]\\n\")","metadata":{"execution":{"iopub.status.busy":"2024-02-07T13:33:43.064224Z","iopub.execute_input":"2024-02-07T13:33:43.064497Z","iopub.status.idle":"2024-02-07T14:05:16.461964Z","shell.execute_reply.started":"2024-02-07T13:33:43.064473Z","shell.execute_reply":"2024-02-07T14:05:16.460822Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"figure , axis = plt.subplots(1,2,figsize=(10,5))\n\n\naxis[0].plot(train_losses , label='train')\naxis[0].plot(val_losses , label='val')\naxis[0].set_title('Training/validation loss over Epochs')\naxis[0].set_xlabel('Epochs')\naxis[0].set_ylabel('loss')\naxis[0].legend()\n\n[1]\naxis[1].plot(train_accuracies, label='train')\naxis[1].plot(val_accuracies, label='val')\naxis[1].set_title('Training/validation accuracy over Epochs')\naxis[1].set_xlabel('epoch')\naxis[1].set_ylabel('Accuracy')\naxis[1].legend()","metadata":{"execution":{"iopub.status.busy":"2024-02-07T14:05:16.463852Z","iopub.execute_input":"2024-02-07T14:05:16.464654Z","iopub.status.idle":"2024-02-07T14:05:16.978705Z","shell.execute_reply.started":"2024-02-07T14:05:16.464595Z","shell.execute_reply":"2024-02-07T14:05:16.977662Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <b>8 <span style='color:#9146ff'>|</span> Evaluation</b> ","metadata":{}},{"cell_type":"markdown","source":"# <b>9 <span style='color:#9146ff'>|</span> Bleu Score</b> ","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}