{"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":"markdown","source":"# Abstract \n\nThis competition was open-ended, which made coming up with a problem and solution trickier than in clearly-defined contests. My lack of knowledge and vocabulary for horse racing compounded this difficulty. The notebook (https://www.kaggle.com/code/neereshkumar/big-data-derby-2022-track-analysis/notebook) ended up being a helpful resource here.\n\nI decided to tackle the first problem that came to mind revolving around gps position tracking data: trajectory prediction.\n\nPredicting the trajectory of a single horse would be interesting, but instead I decided to use all of the racing horses' paths in order to predict the trajectory of a target horse. Being able to have a model regress the position of a horse from some early point in the race as far as it could go felt like a cool problem to have visualized.\n\nThere is a slight problem, however. Since I am using *every* horse's position in order to predict the trajectory of a target horse, I would need to predict *all* of the horses in order to track a single one any further than a single step. To alleviate this problem I decided to tackle predicting *all* of the horses paths at once.\n\nThe path prediction model is a regular transformer architecture. Representing positions over time felt like a natural fit for tokens.\n\nUnfortunately, in the time I allocated to this project, I was not able to train a working transformer. I tried to train a 3-layer Linear DNN as well, to the same result. Ultimately, this project represents a practice effort for me - this being my first time using a transformer for a regression problem - rather than a competitive submission.\n\n# BETA\n\nThis is an experimental correction for the main published version (6).","metadata":{}},{"cell_type":"code","source":"!pip install positional-encodings[pytorch]","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:19:45.743858Z","iopub.execute_input":"2022-11-22T07:19:45.744328Z","iopub.status.idle":"2022-11-22T07:19:58.776737Z","shell.execute_reply.started":"2022-11-22T07:19:45.744247Z","shell.execute_reply":"2022-11-22T07:19:58.775547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport plotly.offline as pyo\nimport plotly.graph_objects as go\nimport plotly.express as px\nfrom plotly.subplots import make_subplots\nimport geopandas\nfrom shapely.geometry import Point\nimport datetime\nfrom tqdm import tqdm\nfrom os import path","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-11-22T07:19:58.780115Z","iopub.execute_input":"2022-11-22T07:19:58.780775Z","iopub.status.idle":"2022-11-22T07:20:01.435423Z","shell.execute_reply.started":"2022-11-22T07:19:58.780742Z","shell.execute_reply":"2022-11-22T07:20:01.434530Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Visualizing the tracks\n\nTrying to pin down how gps locations were tracked was confusing at first. I knew that the tracking table had columns for latitude and longitude, but how to extract rows into the recorded trajectory of a single horse in a single race took some time to figure out. In order to solve this, I needed to know how to identify a single race and a single horse. The way I found to identify a single race was by grouping by the combination of track id, race date, and race number. Then I discovered - probably via Googling - that the column for horse id was called \"program number\", which was a surprise.\n\nI use my new knowledge of how to isolate a single race - or in this case a single track - to plot the three unique tracks used. This could be optimized by selecting only a single race.","metadata":{}},{"cell_type":"code","source":"start_table = pd.read_csv('../input/big-data-derby-2022/nyra_start_table.csv')\nrace_table = pd.read_csv('../input/big-data-derby-2022/nyra_race_table.csv')\ntracking_table = pd.read_csv('../input/big-data-derby-2022/nyra_tracking_table.csv')\n\ncomplete_table = pd.read_csv('../input/big-data-derby-2022/nyra_2019_complete.csv', low_memory = False)","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:20:01.437018Z","iopub.execute_input":"2022-11-22T07:20:01.437370Z","iopub.status.idle":"2022-11-22T07:20:24.879834Z","shell.execute_reply.started":"2022-11-22T07:20:01.437334Z","shell.execute_reply":"2022-11-22T07:20:24.878777Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def draw_track(subtable):\n    subtable.sort_values('trakus_index')\n    center_lat = subtable['latitude'].mean()\n    center_lon = subtable['longitude'].mean()\n    fig = px.scatter_mapbox(\n        subtable, \n        lat=\"latitude\", \n        lon=\"longitude\", \n        color=\"track_id\", \n        mapbox_style=\"stamen-terrain\", \n        center={'lat': center_lat, 'lon': center_lon}, \n        zoom=14, \n        width=500, \n        height=500,\n    )\n    fig.show()","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:20:24.882776Z","iopub.execute_input":"2022-11-22T07:20:24.883201Z","iopub.status.idle":"2022-11-22T07:20:24.890625Z","shell.execute_reply.started":"2022-11-22T07:20:24.883157Z","shell.execute_reply":"2022-11-22T07:20:24.888818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bel_track_entry = race_table[race_table['track_id'] == 'BEL'].iloc[0]\nbel_track_sample = tracking_table[\n    (tracking_table['track_id'] == bel_track_entry['track_id']) & \\\n    (tracking_table['race_date'] == bel_track_entry['race_date'])\n]\ndraw_track(bel_track_sample)","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:20:24.892656Z","iopub.execute_input":"2022-11-22T07:20:24.893078Z","iopub.status.idle":"2022-11-22T07:20:26.304946Z","shell.execute_reply.started":"2022-11-22T07:20:24.893045Z","shell.execute_reply":"2022-11-22T07:20:26.303140Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"aqu_track_entry = race_table[race_table['track_id'] == 'AQU'].iloc[0]\naqu_track_sample = tracking_table[\n    (tracking_table['track_id'] == aqu_track_entry['track_id']) & \\\n    (tracking_table['race_date'] == aqu_track_entry['race_date'])\n]\ndraw_track(aqu_track_sample)","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:20:26.306098Z","iopub.execute_input":"2022-11-22T07:20:26.306441Z","iopub.status.idle":"2022-11-22T07:20:26.970512Z","shell.execute_reply.started":"2022-11-22T07:20:26.306409Z","shell.execute_reply":"2022-11-22T07:20:26.969635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sar_track_entry = race_table[race_table['track_id'] == 'SAR'].iloc[0]\nsar_track_sample = tracking_table[\n    (tracking_table['track_id'] == sar_track_entry['track_id']) & \\\n    (tracking_table['race_date'] == sar_track_entry['race_date'])\n]\ndraw_track(sar_track_sample)","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:20:26.971851Z","iopub.execute_input":"2022-11-22T07:20:26.972384Z","iopub.status.idle":"2022-11-22T07:20:27.799000Z","shell.execute_reply.started":"2022-11-22T07:20:26.972350Z","shell.execute_reply":"2022-11-22T07:20:27.796563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Projecting data to workable coordinate space\n\nThe gps coordinates are transformed into local meter coordinates to avoid projection deformaties from raw GPS. I don't actually know if any projection issues are possible at the GPS scale, but may as well be careful. I figure it will also help control the scale of positions as I operate with a deep learning model.\n\nThe first projection is from GPS (epsg:4326) to UTM zone 18N (EPSG:32618). This projection nicely covers each of the three tracks, or at least it seemed to. Once they were in this projection (which is in meters), I offset all positions by the minimum x and y values. This localized the coordinate space to about 0-1000 on the x and y scales, which I deemed sufficient to operate.","metadata":{}},{"cell_type":"code","source":"def plot_local_meter_track(track):\n    series = geopandas.GeoSeries([Point(x,y) for x, y in zip(track['longitude'], track['latitude'])])\n    geo_df = geopandas.GeoDataFrame(geometry=series, crs='epsg:4326')\n    # convert to UTM zone 18N\n    new_crs = geo_df.to_crs('EPSG:32618')\n    new_series = new_crs['geometry']\n    new_series_bounds = new_series.total_bounds\n    new_series = new_series.translate(-new_series_bounds[0], -new_series_bounds[1])\n#     new_series = new_series.rotate(np.pi/2, origin=(0, 0), use_radians=True)\n    new_series.plot()","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:20:27.800576Z","iopub.execute_input":"2022-11-22T07:20:27.801660Z","iopub.status.idle":"2022-11-22T07:20:27.809396Z","shell.execute_reply.started":"2022-11-22T07:20:27.801621Z","shell.execute_reply":"2022-11-22T07:20:27.808491Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_local_meter_track(bel_track_sample)","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:20:27.810898Z","iopub.execute_input":"2022-11-22T07:20:27.811758Z","iopub.status.idle":"2022-11-22T07:20:35.212382Z","shell.execute_reply.started":"2022-11-22T07:20:27.811700Z","shell.execute_reply":"2022-11-22T07:20:35.211433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_local_meter_track(aqu_track_sample)","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:20:35.216132Z","iopub.execute_input":"2022-11-22T07:20:35.217732Z","iopub.status.idle":"2022-11-22T07:20:42.494349Z","shell.execute_reply.started":"2022-11-22T07:20:35.217693Z","shell.execute_reply":"2022-11-22T07:20:42.493431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_local_meter_track(sar_track_sample)","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:20:42.495851Z","iopub.execute_input":"2022-11-22T07:20:42.496213Z","iopub.status.idle":"2022-11-22T07:20:52.510725Z","shell.execute_reply.started":"2022-11-22T07:20:42.496167Z","shell.execute_reply":"2022-11-22T07:20:52.509825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Precompute localized coords \n\nUnfortunately, localizing the coordinates time-consuming, so the process is memoized. The data loader in a future part of this notebook reads races from precomputed files rather than localizes coordinates on the fly. This successfully sped up the training process but dramatically slowed my ability to navigate the workspace's file system in Kaggle. Perhaps next time I will use a folder here and hope that that helps.","metadata":{}},{"cell_type":"code","source":"print('localizing coordinate system...')\n\nprint('reading tables')\nrace_table = pd.read_csv('../input/big-data-derby-2022/nyra_race_table.csv')\ntracking_table = pd.read_csv('../input/big-data-derby-2022/nyra_tracking_table.csv')\n\nprint('converting coords')\ntracking_table_geo = geopandas.GeoDataFrame(\n    tracking_table, \n    geometry=geopandas.points_from_xy(tracking_table.longitude, tracking_table.latitude), \n    crs='epsg:4326', # gps\n).to_crs('EPSG:32618') # UTM zone 18N\n\nprint('calculating bounds')\ntracking_table_geo_bounds = {\n    track_id: tracking_table_geo[tracking_table_geo['track_id'] == track_id]['geometry'].total_bounds\n    for track_id in race_table['track_id'].unique()\n}\n\nfor key, track in tqdm(tracking_table_geo.groupby(['track_id', 'race_date', 'race_number'])):\n    name = f'{key[0]}_{key[1]}_{key[2]}'\n    if not path.exists(f'{name}.geojson'):\n        track_bounds = tracking_table_geo_bounds[key[0]]\n        track['geometry'] = track['geometry'].translate(-track_bounds[0], -track_bounds[1])\n        track.to_file(f'{name}.geojson')\n        \nprint('done localizing coordinate system...')","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:20:52.512020Z","iopub.execute_input":"2022-11-22T07:20:52.512580Z","iopub.status.idle":"2022-11-22T07:21:19.900525Z","shell.execute_reply.started":"2022-11-22T07:20:52.512543Z","shell.execute_reply":"2022-11-22T07:21:19.899498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nfrom torch.utils.data import Dataset\nfrom torch.nn import Transformer, Linear, ReLU, Sequential\nimport pytorch_lightning as pl\nfrom pytorch_lightning.callbacks import ModelCheckpoint\nfrom torch.utils.data import DataLoader\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom positional_encodings.torch_encodings import PositionalEncoding2D, Summer","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:21:19.901900Z","iopub.execute_input":"2022-11-22T07:21:19.902362Z","iopub.status.idle":"2022-11-22T07:21:23.842591Z","shell.execute_reply.started":"2022-11-22T07:21:19.902324Z","shell.execute_reply":"2022-11-22T07:21:23.841403Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataset / Learning target\n\nThe dataset encapsulates the learning process. The transformer is given the previous paths of all horses and asked to predict each of the horses' next steps. All of this is done in Cartesian coordinates. The paths are randomly translated and rotated during training to help build location and rotation invariance and help the model focus on relative trajectories. \n\nA single epoch consists of a single clip randomly sampled from each race. The number of horses and timesteps is padded to 14 and the clip size respectively with 0s. Perhaps this could also be solved by transformer masking?\n\nAs I was learning about masking in transformers, it occured to me that this learning process could have been parallelized. I could have asked the transformer to predict, for each time step, the next time step, while masking the future steps. However, I stuck to keeping things simple and did not implement that.\n\nNote that the learning process is similar to next-word(s)-prediction.","metadata":{}},{"cell_type":"code","source":"class HorseDataset(Dataset):\n    def __init__(self, train = True, clip_size = 20, random_translate = None, random_rotate = None):\n        self.effective_clip_size = clip_size + 1 # include prediction step\n        self.random_translate = random_translate\n        self.random_rotate = random_rotate\n        \n        self.race_table = pd.read_csv('../input/big-data-derby-2022/nyra_race_table.csv')\n        \n        num_races = len(self.race_table.index)\n        predictable_train_test_gen = np.random.default_rng(0)\n        indices = np.arange(start=0, stop=num_races)\n        predictable_train_test_gen.shuffle(indices)\n        num_train = int(num_races * 0.8)\n        train_indices = indices[:num_train]\n        test_indices = indices[num_train:]\n        \n        self.race_table = self.race_table.iloc[train_indices if train else test_indices]\n            \n    def __getitem__(self, idx):\n        entry = self.race_table.iloc[idx]\n        \n        name = f'{entry[\"track_id\"]}_{entry[\"race_date\"]}_{entry[\"race_number\"]}'\n        track = geopandas.read_file(f'{name}.geojson')\n        \n        all_horses = track['program_number'].unique().tolist()\n        \n        # Find largest overlapping trakus_index range to take a clip from\n        trakus_start, trakus_end = None, None\n        for horse in all_horses:\n            horse_track = track[track['program_number'] == horse]\n            horse_trakus_start, horse_trakus_end = horse_track['trakus_index'].min(), horse_track['trakus_index'].max()\n            trakus_start = horse_trakus_start if trakus_start == None or horse_trakus_start > trakus_start else trakus_start\n            trakus_end = horse_trakus_end if trakus_end == None or horse_trakus_end < trakus_end else trakus_end\n        \n        clip_size = min(self.effective_clip_size, trakus_end - trakus_start + 1)\n        clip_start = np.random.randint(low=trakus_start, high=trakus_end-(clip_size-1)+1)\n        clips = []\n        for horse in all_horses:\n            horse_track = track[\n                (track['program_number'] == horse) & \\\n                (track['trakus_index'] >= clip_start) & \\\n                (track['trakus_index'] <= clip_start + clip_size - 1)\n            ]\n            clips.append(horse_track)\n        joined_clips = clips[0].append(clips[1:])\n                \n        # data augmentation\n        if self.random_rotate is not None:\n            random_rotation = np.random.uniform(low=-self.random_rotate, high=self.random_rotate)\n            joined_clips['geometry'] = joined_clips['geometry'].rotate(random_rotation, origin=(0, 0), use_radians=True)\n        if self.random_translate is not None:\n            random_translation = np.random.uniform(low=-self.random_translate, high=self.random_translate, size=2)\n            joined_clips['geometry'] = joined_clips['geometry'].translate(random_translation[0], random_translation[1])\n        \n        all_numpy_raw = []\n        for horse in all_horses:\n            horse_trace = joined_clips[joined_clips['program_number'] == horse]\n            horse_trace = horse_trace.sort_values('trakus_index')\n            all_numpy_raw.append([\n                np.array([p.x, p.y], dtype=np.float32) for p in horse_trace['geometry']\n            ])\n        all_numpy = np.stack(all_numpy_raw, axis=1)\n                        \n        # crop/pad horses to 14\n        all_numpy = all_numpy[:, :14, :]\n        steps_dim, horses_dim, position_dim = all_numpy.shape\n        padding = 14 - horses_dim\n        all_numpy = np.concatenate([np.zeros((steps_dim, padding, position_dim)), all_numpy], axis=1)\n                \n        # pad by prepending with zeros to match clip size\n        steps_dim, horses_dim, position_dim = all_numpy.shape\n        padding = self.effective_clip_size - steps_dim\n        all_numpy = np.concatenate([np.zeros((padding, horses_dim, position_dim)), all_numpy])\n                        \n        return {\n#             'track_id': entry['track_id'],\n#             'race_date': entry['race_date'],\n#             'race_number': entry['race_number'],\n#             'program_numbers': all_horses,\n#             'geo_df': joined_clips['geometry'],\n#             'sequence': torch.tensor(all_numpy),\n            'sequence_head': torch.tensor(all_numpy[:-1]).to(dtype=torch.float32),\n            'sequence_tail': torch.tensor(all_numpy[-1:].squeeze(0)).to(dtype=torch.float32),\n        }\n    \n    def __len__(self):\n        return len(self.race_table.index)","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:21:23.844586Z","iopub.execute_input":"2022-11-22T07:21:23.845796Z","iopub.status.idle":"2022-11-22T07:21:23.867208Z","shell.execute_reply.started":"2022-11-22T07:21:23.845756Z","shell.execute_reply":"2022-11-22T07:21:23.865216Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Reveal a data point from the dataset. The dataset is not deterministic so the exact sample will vary by run.","metadata":{}},{"cell_type":"code","source":"ds = HorseDataset(\n    clip_size=10, \n    train=True,\n    random_translate=200,\n    random_rotate=np.pi,\n)\nentry = ds[0]\nx, y = entry['sequence_head'], entry['sequence_tail']\nx = x.view(-1, 2)\nplt.scatter(x[:, 0], x[:, 1])\ny = y.view(-1, 2)\nplt.scatter(y[:, 0], y[:, 1])","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:21:23.868928Z","iopub.execute_input":"2022-11-22T07:21:23.869620Z","iopub.status.idle":"2022-11-22T07:21:24.415515Z","shell.execute_reply.started":"2022-11-22T07:21:23.869582Z","shell.execute_reply":"2022-11-22T07:21:24.414470Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The full architecture is an encoder-decoder structure with 2D sinusoidal position encodings. Tokens are generated by projecting local coordinate pairs into large dimensional vectors. The other option was to use grouped horse and/or path segments as tokens, but I opted for the simpler option. 2D position encodings are then added to each token. Horses are represented in one dimension and position steps are represented in the other. Before this process starts, coordinates are scaled to approximately 0-1 and then descaled at the end of the process.","metadata":{}},{"cell_type":"code","source":"class GroupTrajectoryPredictionTransformerModel(pl.LightningModule):\n    def __init__(self, d_model=512):\n        super().__init__()\n        self.d_model = d_model\n        self.projection_layer = nn.Linear(2, d_model)\n        self.position_encodings = Summer(PositionalEncoding2D(d_model))\n        self.transformer = Transformer(d_model=d_model, batch_first=True)\n        self.deprojection_layer = nn.Linear(d_model, 2)\n\n    def forward(self, src):\n        batch_dim, steps_dim, horses_dim, position_dim = src.shape\n        \n#         src /= 1000.0\n                \n        encoder_tokens = self.projection_layer(src)\n        encoder_tokens = self.position_encodings(encoder_tokens)\n        encoder_tokens = encoder_tokens.view(batch_dim, steps_dim * horses_dim, self.d_model)\n        \n        decoder_tokens = torch.zeros((batch_dim, 1, horses_dim, self.d_model), dtype=torch.float32, device=src.device)\n        decoder_tokens = self.position_encodings(decoder_tokens)\n        decoder_tokens = decoder_tokens.view(batch_dim, 1 * horses_dim, self.d_model)\n                                \n        predicted_tokens = self.transformer(encoder_tokens, decoder_tokens)\n        predicted_output = self.deprojection_layer(predicted_tokens)\n        \n#         predicted_output *= 1000.0\n                \n        return predicted_output\n        \n\n    def training_step(self, batch, batch_idx):\n        x, y = batch['sequence_head'], batch['sequence_tail']\n        x, y = x / 1000.0, y / 1000.0\n        y_hat = self(x)\n        loss = F.mse_loss(y_hat, y)\n        self.log(\"training_loss_transformer_scaled\", loss.item())\n        if batch_idx % 20 == 0:\n            print(loss.item())\n        return loss\n    \n    def on_after_backward(self):\n        print(self.transformer.encoder.layers[0].linear1.weight.grad)\n\n    def configure_optimizers(self):\n        return torch.optim.Adam(self.parameters(), lr=1e-4)","metadata":{"execution":{"iopub.status.busy":"2022-11-22T17:38:51.521648Z","iopub.execute_input":"2022-11-22T17:38:51.522029Z","iopub.status.idle":"2022-11-22T17:38:51.534860Z","shell.execute_reply.started":"2022-11-22T17:38:51.521996Z","shell.execute_reply":"2022-11-22T17:38:51.533658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_loader = DataLoader(\n    HorseDataset(\n        clip_size=10, \n        train=True,\n        random_translate=200,\n        random_rotate=np.pi,\n    ), \n    batch_size=16,\n)\ncheckpoint_callback = ModelCheckpoint(\n    monitor='training_loss_transformer_scaled',\n    dirpath='transformer-scaled-chkpt/',\n    filename='transformer-scaled-{epoch:02d}-{training_loss_transformer_scaled:.3f}'\n)\ntrainer = pl.Trainer(\n    max_epochs=100, \n#     max_epochs=1,\n    callbacks=[checkpoint_callback],\n     accelerator=\"gpu\",\n)\nmodel = GroupTrajectoryPredictionTransformerModel()\n\ntrainer.fit(model, train_dataloaders=train_loader)","metadata":{"execution":{"iopub.status.busy":"2022-11-22T17:21:15.102616Z","iopub.execute_input":"2022-11-22T17:21:15.102984Z","iopub.status.idle":"2022-11-22T17:29:27.735066Z","shell.execute_reply.started":"2022-11-22T17:21:15.102953Z","shell.execute_reply":"2022-11-22T17:29:27.734057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Unfortunately, I was not able to get the transformer to show good results. The training process did not seem to help the transformer learn to predict the next positions of the horses. The training loss values were jagged and overall did not decrease past any reasonable margin. Loss values were consistently 1e5 or higher, representing large differences in the correct local positions and the ones predicted.\n\nA linear model was trained as a baseline for comparison.","metadata":{}},{"cell_type":"code","source":"# class GroupTrajectoryPredictionLinearModel(pl.LightningModule):\n#     def __init__(self, clip_size, num_horses):\n#         super().__init__()\n#         self.clip_size = clip_size\n#         self.num_horses = num_horses\n#         self.linear_net = Sequential(\n#             Linear(clip_size * num_horses * 2, 4096),\n#             ReLU(),\n#             Linear(4096, 4096),\n#             ReLU(),\n#             Linear(4096, 1 * num_horses * 2),\n#         )\n\n#     def forward(self, src):\n#         batch_dim, steps_dim, horses_dim, position_dim = src.shape\n        \n#         src /= 10000.0\n#         src_linearized = src.view(batch_dim, steps_dim * horses_dim * position_dim)\n#         output_linearized = self.linear_net(src_linearized)\n#         output = output_linearized.view(batch_dim, horses_dim, position_dim)\n#         output *= 10000.0\n        \n#         return output\n        \n\n#     def training_step(self, batch, batch_idx):\n#         x, y = batch['sequence_head'], batch['sequence_tail']\n#         y_hat = self(x)\n#         loss = F.mse_loss(y_hat, y)\n#         self.log(\"training_loss_linear\", loss.item())\n#         print(loss.item())\n#         return loss\n\n#     def configure_optimizers(self):\n#         return torch.optim.Adam(self.parameters(), lr=0.01)","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:21:35.671063Z","iopub.status.idle":"2022-11-22T07:21:35.671871Z","shell.execute_reply.started":"2022-11-22T07:21:35.671593Z","shell.execute_reply":"2022-11-22T07:21:35.671620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train_loader = DataLoader(\n#     HorseDataset(\n#         clip_size=10, \n#         train=True,\n#         random_translate=200,\n#         random_rotate=np.pi,\n#     ), \n#     batch_size=16,\n# )\n# checkpoint_callback = ModelCheckpoint(\n#     monitor='training_loss_linear',\n#     dirpath='linear-chkpt/',\n#     filename='linear-{epoch:02d}-{training_loss_linear:.3f}'\n# )\n# trainer = pl.Trainer(\n#     max_epochs=50, \n# #     max_epochs=1,\n#     callbacks=[checkpoint_callback],\n#     accelerator=\"gpu\",\n# )\n# model = GroupTrajectoryPredictionLinearModel(clip_size=10, num_horses=14)\n\n# trainer.fit(model, train_dataloaders=train_loader)","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:21:35.673377Z","iopub.status.idle":"2022-11-22T07:21:35.674130Z","shell.execute_reply.started":"2022-11-22T07:21:35.673853Z","shell.execute_reply":"2022-11-22T07:21:35.673880Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Training was terminated after 20 epochs due to no improvement. The graph of the training loss per batch is shown below. The loss graph of the transformer looked just like this one.","metadata":{}},{"cell_type":"markdown","source":"![Capture.PNG](attachment:30889047-6794-4ad0-a0d6-3c05c93a2886.PNG)","metadata":{},"attachments":{"30889047-6794-4ad0-a0d6-3c05c93a2886.PNG":{"image/png":"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"}}},{"cell_type":"markdown","source":"# Visualize predicted path\n\nThe end goal of this process was intended to be visualizing the path predicted by the transformer (and linear model). Despite poor results, I show the predictions anyways.","metadata":{}},{"cell_type":"code","source":"def predict_a_path_using_model(model):\n    generate_step_count = 100\n    use_clip_size = 10\n    ds = HorseDataset(clip_size=use_clip_size)\n    entry = ds[0]\n    path = entry['sequence_head']\n    for _ in range(generate_step_count):\n        predict = model(path[-use_clip_size:].unsqueeze(0) / 1000.0).detach() * 1000.0\n        path = torch.cat([path, predict])\n    plt.scatter(path[:use_clip_size, :, 0].view(-1, 2), path[:use_clip_size, :, 1].view(-1, 2))\n    plt.scatter(path[use_clip_size:, :, 0].view(-1, 2), path[use_clip_size:, :, 1].view(-1, 2))","metadata":{"execution":{"iopub.status.busy":"2022-11-22T17:39:28.591761Z","iopub.execute_input":"2022-11-22T17:39:28.592133Z","iopub.status.idle":"2022-11-22T17:39:28.600817Z","shell.execute_reply.started":"2022-11-22T17:39:28.592100Z","shell.execute_reply":"2022-11-22T17:39:28.599504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# predict_a_path_using_model(\n#     GroupTrajectoryPredictionLinearModel.load_from_checkpoint('linear-chkpt/linear-epoch=10-training_loss_linear=85736.977.ckpt', clip_size=10, num_horses=14)\n# )","metadata":{"execution":{"iopub.status.busy":"2022-11-22T07:21:35.677503Z","iopub.status.idle":"2022-11-22T07:21:35.678228Z","shell.execute_reply.started":"2022-11-22T07:21:35.677957Z","shell.execute_reply":"2022-11-22T07:21:35.677982Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"I don't know how to preserve my weights across versions so here is the first run's results:\n\n![Capture.PNG](attachment:8d0a79b3-c7c5-4714-8814-fa64fa300537.PNG)","metadata":{},"attachments":{"8d0a79b3-c7c5-4714-8814-fa64fa300537.PNG":{"image/png":"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"}}},{"cell_type":"code","source":"predict_a_path_using_model(\n    GroupTrajectoryPredictionTransformerModel.load_from_checkpoint('transformer-chkpt/transformer-epoch=22-training_loss_transformer=91313.344.ckpt')\n)","metadata":{"execution":{"iopub.status.busy":"2022-11-22T17:33:21.020031Z","iopub.execute_input":"2022-11-22T17:33:21.020429Z","iopub.status.idle":"2022-11-22T17:33:36.590412Z","shell.execute_reply.started":"2022-11-22T17:33:21.020396Z","shell.execute_reply":"2022-11-22T17:33:36.589393Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"I don't know how to preserve my weights across versions so here is the first run's results:\n\n![Capture.PNG](attachment:308a1f63-2962-4946-aae0-a49b5b7ef5dd.PNG)","metadata":{},"attachments":{"308a1f63-2962-4946-aae0-a49b5b7ef5dd.PNG":{"image/png":"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"}}},{"cell_type":"code","source":"predict_a_path_using_model(\n    GroupTrajectoryPredictionTransformerModel.load_from_checkpoint('transformer-scaled-chkpt/transformer-scaled-epoch=45-training_loss_transformer_scaled=0.081.ckpt')\n)","metadata":{"execution":{"iopub.status.busy":"2022-11-22T17:39:31.177300Z","iopub.execute_input":"2022-11-22T17:39:31.177673Z","iopub.status.idle":"2022-11-22T17:39:46.436520Z","shell.execute_reply.started":"2022-11-22T17:39:31.177640Z","shell.execute_reply":"2022-11-22T17:39:46.435511Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The orange dots are the predictions. The blue dots, where visible, represent the initial path.","metadata":{}},{"cell_type":"markdown","source":"# Conclusion\n\nTo make this process feasible more time and effort needs to be put into fixing the transformer model and ensuring data correctness. Despite my failure to create a working transformer model, I believe my solution is creative. Representing cartesian coordinates as tokens and posing the problem as next-word(s)-prediction is a good way to represent the problem.\n\nI believe transformer models have worked in time sequence prediction problems. I'm sure my process or data representation could be improved to create a decent model.\n\nAn example of an initial bug was the input horse paths had out-of-order time steps due to the accidental discarding of sorted results (Geopandas sort_values is NOT in-place by default). Because of this, the transformer not only had to predict a time step but also predict which time step it was predicting, leading to nonsense results. It is possible that some other bug is causing training to fail.","metadata":{}}]}