{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"name":" New york taxi GRU_LSTM monthly_preprocessing .ipynb","provenance":[{"file_id":"15dcbg9FseoYPBRIO1F0dtjnP3P1Puniq","timestamp":1631964684465},{"file_id":"1q4otCUdBI8Y0yRo9Tp59GS-8NJpdBpjN","timestamp":1631960919368},{"file_id":"1sW5Y9qlaJuMCfPHwrWBG9qcBqQXuxi-4","timestamp":1631562729044}],"collapsed_sections":[]},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"}},"cells":[{"cell_type":"code","metadata":{"id":"ANisF3yfliXJ"},"source":["import numpy as np\n","import pandas as pd\n","import matplotlib.pyplot as plt\n","import seaborn as sns\n","from sklearn.model_selection import train_test_split\n","from sklearn.metrics import mean_squared_error,r2_score\n","from sklearn import linear_model\n","\n","import torch\n","import torch.nn as nn\n","from torch.autograd import Variable\n","import folium\n","from folium import FeatureGroup, LayerControl, Map, Marker\n","from folium.plugins import HeatMap\n","from folium.plugins import TimestampedGeoJson\n","from folium.plugins import MarkerCluster"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"ViBRhX2slsYR","executionInfo":{"status":"ok","timestamp":1641730076996,"user_tz":-60,"elapsed":18222,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}},"outputId":"9e0bc7e6-4a39-44c1-d413-36bfd92b27df"},"source":["from google.colab import drive\n","drive.mount(\"/content/gdrive\")"],"execution_count":4,"outputs":[{"output_type":"stream","name":"stdout","text":["Mounted at /content/gdrive\n"]}]},{"cell_type":"code","metadata":{"id":"1R8YVA4MuWL6","executionInfo":{"status":"ok","timestamp":1641730101346,"user_tz":-60,"elapsed":24033,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}}},"source":["df_july = pd.read_csv('/content/gdrive/My Drive/Taxi Demand Prediction/Datasets/yellow_tripdata_2016-07.csv')"],"execution_count":5,"outputs":[]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/","height":444},"id":"pw9zxJTBuwTp","executionInfo":{"status":"ok","timestamp":1641730105177,"user_tz":-60,"elapsed":433,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}},"outputId":"e1722d54-536b-4827-ffae-009269039791"},"source":["df_july.head()"],"execution_count":6,"outputs":[{"output_type":"execute_result","data":{"text/html":["\n","
\n","
\n","
\n","\n","
\n"," \n"," \n"," | \n"," | \n"," VendorID | \n"," tpep_pickup_datetime | \n"," tpep_dropoff_datetime | \n"," passenger_count | \n"," trip_distance | \n"," RatecodeID | \n"," store_and_fwd_flag | \n"," PULocationID | \n"," DOLocationID | \n"," payment_type | \n"," fare_amount | \n"," extra | \n"," mta_tax | \n"," tip_amount | \n"," tolls_amount | \n"," improvement_surcharge | \n"," total_amount | \n","
\n"," \n"," \n"," \n"," 1 | \n"," 2016-07-10 06:56:05 | \n"," 2016-07-10 06:59:53 | \n"," 1 | \n"," 0.50 | \n"," 1 | \n"," N | \n"," 263 | \n"," 236 | \n"," 1 | \n"," 4.5 | \n"," 1.0 | \n"," 0.5 | \n"," 2.70 | \n"," 0.0 | \n"," 0.3 | \n"," 9.00 | \n"," NaN | \n"," NaN | \n","
\n"," \n"," 2 | \n"," 2016-07-10 10:50:18 | \n"," 2016-07-10 10:55:21 | \n"," 5 | \n"," 1.34 | \n"," 1 | \n"," N | \n"," 142 | \n"," 163 | \n"," 1 | \n"," 6.0 | \n"," 0.0 | \n"," 0.5 | \n"," 1.36 | \n"," 0.0 | \n"," 0.3 | \n"," 8.16 | \n"," NaN | \n"," NaN | \n","
\n"," \n"," 2016-07-10 10:50:18 | \n"," 2016-07-10 11:08:38 | \n"," 1 | \n"," 9.48 | \n"," 1 | \n"," N | \n"," 74 | \n"," 66 | \n"," 1 | \n"," 27.0 | \n"," 0.0 | \n"," 0.5 | \n"," 0.00 | \n"," 0.0 | \n"," 0.3 | \n"," 27.80 | \n"," NaN | \n"," NaN | \n","
\n"," \n"," 1 | \n"," 2016-07-10 10:50:19 | \n"," 2016-07-10 10:55:14 | \n"," 1 | \n"," 1.00 | \n"," 1 | \n"," N | \n"," 264 | \n"," 264 | \n"," 2 | \n"," 5.5 | \n"," 0.0 | \n"," 0.5 | \n"," 0.00 | \n"," 0.0 | \n"," 0.3 | \n"," 6.30 | \n"," NaN | \n"," NaN | \n","
\n"," \n"," 2016-07-10 10:50:19 | \n"," 2016-07-10 10:55:47 | \n"," 1 | \n"," 0.90 | \n"," 1 | \n"," N | \n"," 48 | \n"," 68 | \n"," 2 | \n"," 5.5 | \n"," 0.0 | \n"," 0.5 | \n"," 0.00 | \n"," 0.0 | \n"," 0.3 | \n"," 6.30 | \n"," NaN | \n"," NaN | \n","
\n"," \n","
\n","
\n","
\n"," \n"," \n","\n"," \n","
\n","
\n"," "],"text/plain":[" VendorID ... total_amount\n","1 2016-07-10 06:56:05 2016-07-10 06:59:53 ... NaN\n","2 2016-07-10 10:50:18 2016-07-10 10:55:21 ... NaN\n"," 2016-07-10 10:50:18 2016-07-10 11:08:38 ... NaN\n","1 2016-07-10 10:50:19 2016-07-10 10:55:14 ... NaN\n"," 2016-07-10 10:50:19 2016-07-10 10:55:47 ... NaN\n","\n","[5 rows x 17 columns]"]},"metadata":{},"execution_count":6}]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"SiDk1qvhdmNL","executionInfo":{"status":"ok","timestamp":1641730109263,"user_tz":-60,"elapsed":422,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}},"outputId":"4a4b84f3-be7c-47c1-8e73-55ce7983716d"},"source":["df_july.shape[0]"],"execution_count":7,"outputs":[{"output_type":"execute_result","data":{"text/plain":["10294080"]},"metadata":{},"execution_count":7}]},{"cell_type":"code","metadata":{"id":"XFEZZxDzmBvc","executionInfo":{"status":"ok","timestamp":1641730113564,"user_tz":-60,"elapsed":421,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}}},"source":["df_july = df_july.drop(['RatecodeID','payment_type','fare_amount','extra','mta_tax','tip_amount','tolls_amount','improvement_surcharge','total_amount'],1)"],"execution_count":8,"outputs":[]},{"cell_type":"code","metadata":{"id":"dPtcgGGKmZkD","executionInfo":{"status":"ok","timestamp":1641730117893,"user_tz":-60,"elapsed":1371,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}}},"source":["df_july.dropna(how = 'any', inplace = True)"],"execution_count":9,"outputs":[]},{"cell_type":"code","metadata":{"id":"8tAjCysJmiMv"},"source":["# taxi_carry = np.array(np.where(df_jan['passenger_count']>4))"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"pXfZQENCmoWt","executionInfo":{"status":"ok","timestamp":1641730119835,"user_tz":-60,"elapsed":341,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}}},"source":["df_july['pickup_datetime'] = pd.to_datetime(df_july['tpep_pickup_datetime'])"],"execution_count":10,"outputs":[]},{"cell_type":"code","metadata":{"id":"djmnkLqTvC1t","executionInfo":{"status":"ok","timestamp":1641730121569,"user_tz":-60,"elapsed":363,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}}},"source":["df_july['demand'] = df_july['passenger_count']*(df_july['trip_distance']) #demand ratio"],"execution_count":11,"outputs":[]},{"cell_type":"code","metadata":{"id":"aY_12dWLz4-Q","executionInfo":{"status":"ok","timestamp":1641730403763,"user_tz":-60,"elapsed":280220,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}}},"source":["df_july.to_csv('/content/gdrive/My Drive/Taxi Demand Prediction/Datasets/yellow_tripdata_2016-07_processed.csv')"],"execution_count":12,"outputs":[]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/","height":337},"id":"oeK5ASrbvPzC","executionInfo":{"status":"ok","timestamp":1641730427738,"user_tz":-60,"elapsed":428,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}},"outputId":"ddc37257-c753-4bb8-ac11-2bbd9eb3e756"},"source":["df_july.head()"],"execution_count":13,"outputs":[{"output_type":"execute_result","data":{"text/html":["\n"," \n","
\n","
\n","\n","
\n"," \n"," \n"," | \n"," | \n"," VendorID | \n"," tpep_pickup_datetime | \n"," tpep_dropoff_datetime | \n"," passenger_count | \n"," trip_distance | \n"," store_and_fwd_flag | \n"," PULocationID | \n"," DOLocationID | \n"," pickup_datetime | \n"," demand | \n","
\n"," \n"," \n"," \n"," 1 | \n"," 2016-07-10 06:56:05 | \n"," 2016-07-10 06:59:53 | \n"," 1 | \n"," 0.50 | \n"," 1 | \n"," N | \n"," 236 | \n"," 1 | \n"," 4.5 | \n"," 1970-01-01 00:00:00.000000001 | \n"," N | \n","
\n"," \n"," 2 | \n"," 2016-07-10 10:50:18 | \n"," 2016-07-10 10:55:21 | \n"," 5 | \n"," 1.34 | \n"," 1 | \n"," N | \n"," 163 | \n"," 1 | \n"," 6.0 | \n"," 1970-01-01 00:00:00.000000005 | \n"," N | \n","
\n"," \n"," 2016-07-10 10:50:18 | \n"," 2016-07-10 11:08:38 | \n"," 1 | \n"," 9.48 | \n"," 1 | \n"," N | \n"," 66 | \n"," 1 | \n"," 27.0 | \n"," 1970-01-01 00:00:00.000000001 | \n"," N | \n","
\n"," \n"," 1 | \n"," 2016-07-10 10:50:19 | \n"," 2016-07-10 10:55:14 | \n"," 1 | \n"," 1.00 | \n"," 1 | \n"," N | \n"," 264 | \n"," 2 | \n"," 5.5 | \n"," 1970-01-01 00:00:00.000000001 | \n"," N | \n","
\n"," \n"," 2016-07-10 10:50:19 | \n"," 2016-07-10 10:55:47 | \n"," 1 | \n"," 0.90 | \n"," 1 | \n"," N | \n"," 68 | \n"," 2 | \n"," 5.5 | \n"," 1970-01-01 00:00:00.000000001 | \n"," N | \n","
\n"," \n","
\n","
\n","
\n"," \n"," \n","\n"," \n","
\n","
\n"," "],"text/plain":[" VendorID ... demand\n","1 2016-07-10 06:56:05 2016-07-10 06:59:53 ... N\n","2 2016-07-10 10:50:18 2016-07-10 10:55:21 ... N\n"," 2016-07-10 10:50:18 2016-07-10 11:08:38 ... N\n","1 2016-07-10 10:50:19 2016-07-10 10:55:14 ... N\n"," 2016-07-10 10:50:19 2016-07-10 10:55:47 ... N\n","\n","[5 rows x 10 columns]"]},"metadata":{},"execution_count":13}]},{"cell_type":"code","metadata":{"id":"njbijJnem1Fw","executionInfo":{"status":"ok","timestamp":1641730437526,"user_tz":-60,"elapsed":882,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}}},"source":["X = df_july.drop(['VendorID','passenger_count','trip_distance','store_and_fwd_flag'], axis = 1)\n","\n","y = df_july['demand']"],"execution_count":14,"outputs":[]},{"cell_type":"code","metadata":{"id":"oeY2TOs7nBn0","executionInfo":{"status":"ok","timestamp":1641730441043,"user_tz":-60,"elapsed":404,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}}},"source":["cont_cols = ['PULocationID',\n"," 'DOLocationID']\n"," \n","conts_data = np.stack([df_july[col].values for col in cont_cols], 1)"],"execution_count":15,"outputs":[]},{"cell_type":"code","metadata":{"id":"Wv-1z8hRnDRB","executionInfo":{"status":"ok","timestamp":1641730443420,"user_tz":-60,"elapsed":2,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}}},"source":["X = torch.tensor(conts_data, dtype = torch.float)"],"execution_count":16,"outputs":[]},{"cell_type":"code","metadata":{"id":"JcD8AwCBnFLF","colab":{"base_uri":"https://localhost:8080/","height":170},"executionInfo":{"status":"error","timestamp":1641730481914,"user_tz":-60,"elapsed":572,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}},"outputId":"d3a8e3e9-c24a-4fda-ed9c-bf71762ed9c1"},"source":["y = torch.tensor(df_july['demand'].values, dtype=torch.float).reshape(-1,1)"],"execution_count":18,"outputs":[{"output_type":"error","ename":"TypeError","evalue":"ignored","traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)","\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdf_july\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'demand'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfloat\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m","\u001b[0;31mTypeError\u001b[0m: can't convert np.ndarray of type numpy.object_. The only supported types are: float64, float32, float16, complex64, complex128, int64, int32, int16, int8, uint8, and bool."]}]},{"cell_type":"code","metadata":{"id":"tUdNi7JqnG1V"},"source":["class LSTM1(nn.Module):\n"," \"\"\"LSTM architecture\"\"\"\n","\n"," def __init__(self, input_size, hidden_size, num_layers, seq_length=1):\n"," super(LSTM1, self).__init__()\n"," self.input_size = input_size # input size\n"," self.hidden_size = hidden_size # hidden state\n"," self.num_layers = num_layers # number of layers\n"," self.seq_length = seq_length # sequence length\n","\n"," self.lstm = nn.LSTM(input_size=input_size, hidden_size=hidden_size, num_layers=num_layers, batch_first=True,\n"," dropout=0.1)\n"," self.fc_1 = nn.Linear(hidden_size, 16) # fully connected 1\n"," self.fc_2 = nn.Linear(16, 8) # fully connected 2\n"," self.fc = nn.Linear(8, 1) # fully connected last layer\n","\n"," self.dropout = nn.Dropout(0.1)\n"," self.relu = nn.ReLU()\n","\n"," def forward(self, x):\n"," \"\"\"\n","\n"," :param x: input features\n"," :return: prediction results\n"," \"\"\"\n"," x = x.unsqueeze(0)\n"," h_0 = Variable(torch.zeros(self.num_layers, x.size(0), self.hidden_size)) # hidden state\n"," c_0 = Variable(torch.zeros(self.num_layers, x.size(0), self.hidden_size)) # internal state\n"," output, (hn, cn) = self.lstm(x, (h_0, c_0)) # lstm with input, hidden, and internal state\n","\n"," hn_o = torch.Tensor(hn.detach().numpy()[-1, :, :])\n"," hn_o = hn_o.view(-1, self.hidden_size)\n"," hn_1 = torch.Tensor(hn.detach().numpy()[1, :, :])\n"," hn_1 = hn_1.view(-1, self.hidden_size)\n","\n"," out = self.relu(self.fc_1(self.relu(hn_o + hn_1)))\n"," out = self.relu(self.fc_2(out))\n"," out = self.dropout(out)\n"," out = self.fc(out)\n"," return out\n"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"W_jQ8Stjnw_3"},"source":["class GRUModel(nn.Module):\n"," def __init__(self, input_dim, hidden_dim, layer_dim, output_dim, dropout_prob):\n"," super(GRUModel, self).__init__()\n","\n"," # Defining the number of layers and the nodes in each layer\n"," self.layer_dim = layer_dim\n"," self.hidden_dim = hidden_dim\n","\n"," # GRU layers\n"," self.gru = nn.GRU(\n"," input_dim, hidden_dim, layer_dim, batch_first=True, dropout=dropout_prob\n"," )\n","\n"," # Fully connected layer\n"," self.fc = nn.Linear(hidden_dim, output_dim)\n","\n"," def forward(self, x):\n"," x = x.unsqueeze(0) #this removes the error \"input must have 3 dimensions, got 2\"\n"," # Initializing hidden state for first input with zeros\n"," h0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_()\n","\n"," # Forward propagation by passing in the input and hidden state into the model\n"," out, _ = self.gru(x, h0.detach())\n","\n"," # Reshaping the outputs in the shape of (batch_size, seq_length, hidden_size)\n"," # so that it can fit into the fully connected layer\n"," out = out[:, -1, :]\n","\n"," # Convert the final state to our desired output shape (batch_size, output_dim)\n"," out = self.fc(out)\n","\n"," return out"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"N6lXYb_DobtI","executionInfo":{"status":"ok","timestamp":1631964358537,"user_tz":-120,"elapsed":204,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}},"outputId":"3e2c059c-ca42-4a7c-86fd-97af312485ae"},"source":["X.shape[1]"],"execution_count":null,"outputs":[{"output_type":"execute_result","data":{"text/plain":["4"]},"metadata":{},"execution_count":27}]},{"cell_type":"code","metadata":{"id":"bXcFCk_snJhb"},"source":["model = LSTM1(X.shape[1], 16, 2)\n","model_2 = GRUModel(X.shape[1], 16, 2, 1, 0.1)"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"Ille-yPTnL4B"},"source":["criterion = nn.SmoothL1Loss()\n","optimizer = torch.optim.Adam(model.parameters(), lr = 0.01)"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"6ijsOfMinOfG"},"source":["batch_size = 10000\n","test_size = int(batch_size * .2)\n","\n","X_train = X[:batch_size-test_size]\n","X_test = X[batch_size-test_size:batch_size]\n","y_train = y[:batch_size-test_size]\n","y_test = y[batch_size-test_size:batch_size]"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"tg7wxTvwnQQQ","executionInfo":{"status":"ok","timestamp":1631964369747,"user_tz":-120,"elapsed":207,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}},"outputId":"7303b89f-d7b1-4974-cb16-3bf567c85b51"},"source":["print(X_train.shape)\n","print(y_train.shape)\n","print(X_test.shape)\n","print(y_test.shape)"],"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["torch.Size([8000, 4])\n","torch.Size([8000, 1])\n","torch.Size([2000, 4])\n","torch.Size([2000, 1])\n"]}]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"pqv5BBqgnSVf","executionInfo":{"status":"ok","timestamp":1631964381364,"user_tz":-120,"elapsed":9294,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}},"outputId":"5f5e467b-614c-4bad-cd26-9ba05c270fdb"},"source":["import time\n","start_time = time.time()\n","\n","epochs = 10\n","losses = []\n","\n","for i in range(epochs):\n"," i+=1\n"," y_pred = model(X_train)\n"," loss = criterion(y_pred, y_train) # RMSE\n"," losses.append(loss)\n"," \n"," \n"," if i%25 == 1:\n"," print(f'epoch: {i:3} loss: {loss.item():10.8f}')\n","\n"," optimizer.zero_grad()\n"," loss.backward()\n"," optimizer.step()\n","\n","print(f'epoch: {i:3} loss: {loss.item():10.8f}') \n","print(f'\\nDuration: {time.time() - start_time:.0f} seconds') "],"execution_count":null,"outputs":[{"output_type":"stream","name":"stderr","text":["/usr/local/lib/python3.7/dist-packages/torch/nn/modules/loss.py:921: UserWarning: Using a target size (torch.Size([8000, 1])) that is different to the input size (torch.Size([1, 1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.\n"," return F.smooth_l1_loss(input, target, reduction=self.reduction, beta=self.beta)\n"]},{"output_type":"stream","name":"stdout","text":["epoch: 1 loss: 4.69094992\n","epoch: 10 loss: 4.21567631\n","\n","Duration: 9 seconds\n"]}]},{"cell_type":"code","metadata":{"colab":{"base_uri":"https://localhost:8080/","height":279},"id":"fTeXMiWynVE_","executionInfo":{"status":"ok","timestamp":1631964386029,"user_tz":-120,"elapsed":680,"user":{"displayName":"Faheem Ahmed Abbasi","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GhgtOF28sy7gFBpnhma6GfiWjvqUh1r3ss-fhJtog=s64","userId":"04247060777971177506"}},"outputId":"456d74bf-dd1e-46c1-ca62-f8bf7e088c46"},"source":["plt.plot(range(epochs), losses)\n","plt.ylabel('RMSE Loss')\n","plt.xlabel('epoch');"],"execution_count":null,"outputs":[{"output_type":"display_data","data":{"image/png":"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\n","text/plain":["