|
17 | 17 | },
|
18 | 18 | {
|
19 | 19 | "cell_type": "code",
|
20 |
| - "execution_count": 6, |
| 20 | + "execution_count": 1, |
21 | 21 | "metadata": {},
|
22 |
| - "outputs": [ |
23 |
| - { |
24 |
| - "name": "stdout", |
25 |
| - "output_type": "stream", |
26 |
| - "text": [ |
27 |
| - "The autoreload extension is already loaded. To reload it, use:\n", |
28 |
| - " %reload_ext autoreload\n" |
29 |
| - ] |
30 |
| - } |
31 |
| - ], |
| 22 | + "outputs": [], |
32 | 23 | "source": [
|
33 | 24 | "import math\n",
|
34 | 25 | "import torch\n",
|
35 | 26 | "import gpytorch\n",
|
| 27 | + "import tqdm.notebook as tqdm\n", |
36 | 28 | "from matplotlib import pyplot as plt\n",
|
37 | 29 | "\n",
|
38 | 30 | "%matplotlib inline\n",
|
|
45 | 37 | "metadata": {},
|
46 | 38 | "source": [
|
47 | 39 | "### Downloading Data\n",
|
48 |
| - "We will be using the 3droad UCI dataset which contains a total of 278,319 data points. The next cell will download this dataset from a Google drive and load it." |
| 40 | + "We will be using the 3droad UCI dataset which contains a total of 434,874 data points. We will split the data in half for training and half for testing.\n", |
| 41 | + "\n", |
| 42 | + "The next cell will download this dataset from a Google drive and load it." |
49 | 43 | ]
|
50 | 44 | },
|
51 | 45 | {
|
52 | 46 | "cell_type": "code",
|
53 |
| - "execution_count": 3, |
| 47 | + "execution_count": 2, |
54 | 48 | "metadata": {},
|
55 |
| - "outputs": [ |
56 |
| - { |
57 |
| - "name": "stdout", |
58 |
| - "output_type": "stream", |
59 |
| - "text": [ |
60 |
| - "Downloading '3droad' UCI dataset...\n" |
61 |
| - ] |
62 |
| - } |
63 |
| - ], |
| 49 | + "outputs": [], |
64 | 50 | "source": [
|
65 | 51 | "import urllib.request\n",
|
66 | 52 | "import os.path\n",
|
|
76 | 62 | },
|
77 | 63 | {
|
78 | 64 | "cell_type": "code",
|
79 |
| - "execution_count": 5, |
| 65 | + "execution_count": 3, |
80 | 66 | "metadata": {},
|
81 |
| - "outputs": [], |
| 67 | + "outputs": [ |
| 68 | + { |
| 69 | + "name": "stdout", |
| 70 | + "output_type": "stream", |
| 71 | + "text": [ |
| 72 | + "Num train: 217437\n", |
| 73 | + "Num test: 217437\n" |
| 74 | + ] |
| 75 | + } |
| 76 | + ], |
82 | 77 | "source": [
|
83 | 78 | "import numpy as np\n",
|
84 | 79 | "\n",
|
85 | 80 | "N = data.shape[0]\n",
|
86 | 81 | "# make train/val/test\n",
|
87 |
| - "n_train = int(0.8 * N)\n", |
| 82 | + "n_train = int(0.5 * N)\n", |
| 83 | + "\n", |
88 | 84 | "train_x, train_y = data[:n_train, :-1], data[:n_train, -1]\n",
|
89 | 85 | "test_x, test_y = data[n_train:, :-1], data[n_train:, -1]\n",
|
90 | 86 | "\n",
|
|
106 | 102 | "output_device = torch.device('cuda:0')\n",
|
107 | 103 | "\n",
|
108 | 104 | "train_x, train_y = train_x.to(output_device), train_y.to(output_device)\n",
|
109 |
| - "test_x, test_y = test_x.to(output_device), test_y.to(output_device)" |
| 105 | + "test_x, test_y = test_x.to(output_device), test_y.to(output_device)\n", |
| 106 | + "\n", |
| 107 | + "print(\n", |
| 108 | + " f\"Num train: {train_y.size(-1)}\\n\"\n", |
| 109 | + " f\"Num test: {test_y.size(-1)}\"\n", |
| 110 | + ")" |
110 | 111 | ]
|
111 | 112 | },
|
112 | 113 | {
|
|
120 | 121 | },
|
121 | 122 | {
|
122 | 123 | "cell_type": "code",
|
123 |
| - "execution_count": 7, |
| 124 | + "execution_count": 4, |
124 | 125 | "metadata": {},
|
125 | 126 | "outputs": [],
|
126 | 127 | "source": [
|
|
139 | 140 | "\n",
|
140 | 141 | "# initialize likelihood and model\n",
|
141 | 142 | "likelihood = gpytorch.likelihoods.GaussianLikelihood().cuda()\n",
|
142 |
| - "model = ExactGPModel(train_x, train_y, likelihood).cuda()" |
| 143 | + "model = ExactGPModel(train_x, train_y, likelihood).cuda()\n", |
| 144 | + "\n", |
| 145 | + "# Because we know some properties about this dataset,\n", |
| 146 | + "# we will initialize the lengthscale to be somewhat small\n", |
| 147 | + "# This step isn't necessary, but it will help the model converge faster.\n", |
| 148 | + "model.covar_module.base_kernel.lengthscale = 0.05" |
143 | 149 | ]
|
144 | 150 | },
|
145 | 151 | {
|
146 | 152 | "cell_type": "code",
|
147 |
| - "execution_count": null, |
| 153 | + "execution_count": 5, |
148 | 154 | "metadata": {
|
149 | 155 | "scrolled": false
|
150 | 156 | },
|
151 |
| - "outputs": [], |
| 157 | + "outputs": [ |
| 158 | + { |
| 159 | + "data": { |
| 160 | + "application/vnd.jupyter.widget-view+json": { |
| 161 | + "model_id": "691194d2d51e4d389fef9f0f7cb34f6b", |
| 162 | + "version_major": 2, |
| 163 | + "version_minor": 0 |
| 164 | + }, |
| 165 | + "text/plain": [ |
| 166 | + "Training: 0%| | 0/25 [00:00<?, ?it/s]" |
| 167 | + ] |
| 168 | + }, |
| 169 | + "metadata": {}, |
| 170 | + "output_type": "display_data" |
| 171 | + } |
| 172 | + ], |
152 | 173 | "source": [
|
153 | 174 | "# Find optimal model hyperparameters\n",
|
154 | 175 | "model.train()\n",
|
|
158 | 179 | "optimizer = torch.optim.Adam(model.parameters(), lr=0.1) # Includes GaussianLikelihood parameters\n",
|
159 | 180 | "\n",
|
160 | 181 | "# \"Loss\" for GPs - the marginal log likelihood\n",
|
161 |
| - "mll = gpytorch.mlls.ExactMarginalLogLikelihood(likelihood, model)\n", |
| 182 | + "mll = gpytorch.mlls.ExactMarginalLogLikelihood(model.likelihood, model)\n", |
162 | 183 | "\n",
|
163 | 184 | "import time\n",
|
164 |
| - "training_iter = 50\n", |
165 |
| - "for i in range(training_iter):\n", |
| 185 | + "training_iter = 25\n", |
| 186 | + "iterator = tqdm.tqdm(range(training_iter), desc=\"Training\")\n", |
| 187 | + "for i in iterator:\n", |
166 | 188 | " start_time = time.time()\n",
|
167 | 189 | " # Zero gradients from previous iteration\n",
|
168 | 190 | " optimizer.zero_grad()\n",
|
169 | 191 | " # Output from model\n",
|
170 | 192 | " output = model(train_x)\n",
|
171 | 193 | " # Calc loss and backprop gradients\n",
|
172 | 194 | " loss = -mll(output, train_y)\n",
|
| 195 | + " print_values = dict(\n", |
| 196 | + " loss=loss.item(),\n", |
| 197 | + " ls=model.covar_module.base_kernel.lengthscale.norm().item(),\n", |
| 198 | + " os=model.covar_module.outputscale.item(),\n", |
| 199 | + " noise=model.likelihood.noise.item(),\n", |
| 200 | + " mu=model.mean_module.constant.item(),\n", |
| 201 | + " )\n", |
| 202 | + " iterator.set_postfix(**print_values)\n", |
173 | 203 | " loss.backward()\n",
|
174 |
| - " print('Iter %d/%d - Loss: %.3f lengthscale: %.3f noise: %.3f' % (\n", |
175 |
| - " i + 1, training_iter, loss.item(),\n", |
176 |
| - " model.covar_module.base_kernel.lengthscale.item(),\n", |
177 |
| - " model.likelihood.noise.item()\n", |
178 |
| - " ))\n", |
179 |
| - " optimizer.step()\n", |
180 |
| - " print(time.time() - start_time)" |
| 204 | + " optimizer.step()" |
181 | 205 | ]
|
182 | 206 | },
|
183 | 207 | {
|
184 | 208 | "cell_type": "code",
|
185 |
| - "execution_count": 12, |
| 209 | + "execution_count": 6, |
186 | 210 | "metadata": {},
|
187 |
| - "outputs": [ |
188 |
| - { |
189 |
| - "name": "stdout", |
190 |
| - "output_type": "stream", |
191 |
| - "text": [ |
192 |
| - "Compiling libKeOpstorchd7ba409487 in /home/jake.gardner/.cache/pykeops-1.1.1//build-libKeOpstorchd7ba409487:\n", |
193 |
| - " formula: Sum_Reduction(((((Var(0,1,2) * Sqrt(Sum(Square((Var(1,18,0) - Var(2,18,1)))))) + (IntCst(1) + (Var(3,1,2) * Square(Sqrt(Sum(Square((Var(1,18,0) - Var(2,18,1))))))))) * Exp((Var(4,1,2) * Sqrt(Sum(Square((Var(1,18,0) - Var(2,18,1)))))))) * Var(5,3320,1)),0)\n", |
194 |
| - " aliases: Var(0,1,2); Var(1,18,0); Var(2,18,1); Var(3,1,2); Var(4,1,2); Var(5,3320,1); \n", |
195 |
| - " dtype : float32\n", |
196 |
| - "... Done.\n", |
197 |
| - "Compiling libKeOpstorch7385e76d34 in /home/jake.gardner/.cache/pykeops-1.1.1//build-libKeOpstorch7385e76d34:\n", |
198 |
| - " formula: Sum_Reduction(((((Var(0,1,2) * Sqrt(Sum(Square((Var(1,18,0) - Var(2,18,1)))))) + (IntCst(1) + (Var(3,1,2) * Square(Sqrt(Sum(Square((Var(1,18,0) - Var(2,18,1))))))))) * Exp((Var(4,1,2) * Sqrt(Sum(Square((Var(1,18,0) - Var(2,18,1)))))))) * Var(5,1,1)),0)\n", |
199 |
| - " aliases: Var(0,1,2); Var(1,18,0); Var(2,18,1); Var(3,1,2); Var(4,1,2); Var(5,1,1); \n", |
200 |
| - " dtype : float32\n", |
201 |
| - "... Done.\n", |
202 |
| - "Compiling libKeOpstorch97105370ea in /home/jake.gardner/.cache/pykeops-1.1.1//build-libKeOpstorch97105370ea:\n", |
203 |
| - " formula: Sum_Reduction(((((Var(0,1,2) * Sqrt(Sum(Square((Var(1,18,0) - Var(2,18,1)))))) + (IntCst(1) + (Var(3,1,2) * Square(Sqrt(Sum(Square((Var(1,18,0) - Var(2,18,1))))))))) * Exp((Var(4,1,2) * Sqrt(Sum(Square((Var(1,18,0) - Var(2,18,1)))))))) * Var(5,100,1)),0)\n", |
204 |
| - " aliases: Var(0,1,2); Var(1,18,0); Var(2,18,1); Var(3,1,2); Var(4,1,2); Var(5,100,1); \n", |
205 |
| - " dtype : float32\n", |
206 |
| - "... Done.\n" |
207 |
| - ] |
208 |
| - } |
209 |
| - ], |
| 211 | + "outputs": [], |
210 | 212 | "source": [
|
211 | 213 | "# Get into evaluation (predictive posterior) mode\n",
|
212 | 214 | "model.eval()\n",
|
213 |
| - "likelihood.eval()\n", |
214 | 215 | "\n",
|
215 | 216 | "# Test points are regularly spaced along [0,1]\n",
|
216 | 217 | "# Make predictions by feeding model through likelihood\n",
|
217 | 218 | "with torch.no_grad(), gpytorch.settings.fast_pred_var():\n",
|
218 |
| - " observed_pred = likelihood(model(test_x))" |
| 219 | + " observed_pred = model.likelihood(model(test_x))" |
219 | 220 | ]
|
220 | 221 | },
|
221 | 222 | {
|
|
227 | 228 | },
|
228 | 229 | {
|
229 | 230 | "cell_type": "code",
|
230 |
| - "execution_count": 15, |
| 231 | + "execution_count": 7, |
231 | 232 | "metadata": {},
|
232 | 233 | "outputs": [
|
233 | 234 | {
|
234 |
| - "data": { |
235 |
| - "text/plain": [ |
236 |
| - "tensor(0.1068, device='cuda:0')" |
237 |
| - ] |
238 |
| - }, |
239 |
| - "execution_count": 15, |
240 |
| - "metadata": {}, |
241 |
| - "output_type": "execute_result" |
| 235 | + "name": "stdout", |
| 236 | + "output_type": "stream", |
| 237 | + "text": [ |
| 238 | + "RMSE: 0.138\n" |
| 239 | + ] |
242 | 240 | }
|
243 | 241 | ],
|
244 | 242 | "source": [
|
245 |
| - "torch.sqrt(torch.mean(torch.pow(observed_pred.mean - test_y, 2)))" |
| 243 | + "rmse = (observed_pred.mean - test_y).square().mean().sqrt().item()\n", |
| 244 | + "print(f\"RMSE: {rmse:.3f}\")" |
246 | 245 | ]
|
247 | 246 | }
|
248 | 247 | ],
|
249 | 248 | "metadata": {
|
250 | 249 | "anaconda-cloud": {},
|
251 | 250 | "kernelspec": {
|
252 |
| - "display_name": "Python 3", |
| 251 | + "display_name": "Python 3 (ipykernel)", |
253 | 252 | "language": "python",
|
254 | 253 | "name": "python3"
|
255 | 254 | },
|
|
263 | 262 | "name": "python",
|
264 | 263 | "nbconvert_exporter": "python",
|
265 | 264 | "pygments_lexer": "ipython3",
|
266 |
| - "version": "3.7.1" |
| 265 | + "version": "3.8.0" |
267 | 266 | }
|
268 | 267 | },
|
269 | 268 | "nbformat": 4,
|
|
0 commit comments