|
52 | 52 | "source": [
|
53 | 53 | "import os\n",
|
54 | 54 | "import getpass\n",
|
55 |
| - "os.environ['SIMVUE_URL'] = 'https://app.simvue.io'\n", |
56 |
| - "os.environ['SIMVUE_TOKEN'] = getpass.getpass(prompt='Token: ')" |
| 55 | + "\n", |
| 56 | + "os.environ[\"SIMVUE_URL\"] = \"https://app.simvue.io\"\n", |
| 57 | + "os.environ[\"SIMVUE_TOKEN\"] = getpass.getpass(prompt=\"Token: \")" |
57 | 58 | ]
|
58 | 59 | },
|
59 | 60 | {
|
|
113 | 114 | "outputs": [],
|
114 | 115 | "source": [
|
115 | 116 | "# Dataset parameters.\n",
|
116 |
| - "num_classes = 2 # linear sequence or not.\n", |
117 |
| - "seq_max_len = 20 # Maximum sequence length.\n", |
118 |
| - "seq_min_len = 5 # Minimum sequence length (before padding).\n", |
119 |
| - "masking_val = -1 # -1 will represents the mask and be used to pad sequences to a common max length.\n", |
120 |
| - "max_value = 10000 # Maximum int value.\n", |
| 117 | + "num_classes = 2 # linear sequence or not.\n", |
| 118 | + "seq_max_len = 20 # Maximum sequence length.\n", |
| 119 | + "seq_min_len = 5 # Minimum sequence length (before padding).\n", |
| 120 | + "masking_val = (\n", |
| 121 | + " -1\n", |
| 122 | + ") # -1 will represents the mask and be used to pad sequences to a common max length.\n", |
| 123 | + "max_value = 10000 # Maximum int value.\n", |
121 | 124 | "\n",
|
122 | 125 | "# Training Parameters\n",
|
123 | 126 | "learning_rate = 0.001\n",
|
|
126 | 129 | "display_step = 10\n",
|
127 | 130 | "\n",
|
128 | 131 | "# Network Parameters\n",
|
129 |
| - "num_units = 32 # number of neurons for the LSTM layer.\n" |
| 132 | + "num_units = 32 # number of neurons for the LSTM layer." |
130 | 133 | ]
|
131 | 134 | },
|
132 | 135 | {
|
|
137 | 140 | },
|
138 | 141 | "outputs": [],
|
139 | 142 | "source": [
|
140 |
| - "#\u00a0Start a run and specify metadata\n", |
| 143 | + "# Start a run and specify metadata\n", |
141 | 144 | "run = Run()\n",
|
142 |
| - "run.init(metadata={'dataset.num_classes': num_classes,\n", |
143 |
| - " 'dataset.seq_max_len': seq_max_len,\n", |
144 |
| - " 'dataset.seq_min_len': seq_min_len,\n", |
145 |
| - " 'dataset.masking_val': masking_val,\n", |
146 |
| - " 'dataset.max_value': max_value,\n", |
147 |
| - " 'training.learning_rate': learning_rate,\n", |
148 |
| - " 'training.training_steps': training_steps,\n", |
149 |
| - " 'training.batch_size': batch_size,\n", |
150 |
| - " 'network.num_units': num_units})" |
| 145 | + "run.init(\n", |
| 146 | + " metadata={\n", |
| 147 | + " \"dataset.num_classes\": num_classes,\n", |
| 148 | + " \"dataset.seq_max_len\": seq_max_len,\n", |
| 149 | + " \"dataset.seq_min_len\": seq_min_len,\n", |
| 150 | + " \"dataset.masking_val\": masking_val,\n", |
| 151 | + " \"dataset.max_value\": max_value,\n", |
| 152 | + " \"training.learning_rate\": learning_rate,\n", |
| 153 | + " \"training.training_steps\": training_steps,\n", |
| 154 | + " \"training.batch_size\": batch_size,\n", |
| 155 | + " \"network.num_units\": num_units,\n", |
| 156 | + " }\n", |
| 157 | + ")" |
151 | 158 | ]
|
152 | 159 | },
|
153 | 160 | {
|
|
162 | 169 | "# TOY DATA GENERATOR\n",
|
163 | 170 | "# ====================\n",
|
164 | 171 | "\n",
|
| 172 | + "\n", |
165 | 173 | "def toy_sequence_data():\n",
|
166 |
| - " \"\"\" Generate sequence of data with dynamic length.\n", |
| 174 | + " \"\"\"Generate sequence of data with dynamic length.\n", |
167 | 175 | " This function generates toy samples for training:\n",
|
168 | 176 | " - Class 0: linear sequences (i.e. [1, 2, 3, 4, ...])\n",
|
169 | 177 | " - Class 1: random sequences (i.e. [9, 3, 10, 7,...])\n",
|
|
179 | 187 | " seq_len = random.randint(seq_min_len, seq_max_len)\n",
|
180 | 188 | " rand_start = random.randint(0, max_value - seq_len)\n",
|
181 | 189 | " # Add a random or linear int sequence (50% prob).\n",
|
182 |
| - " if random.random() < .5:\n", |
| 190 | + " if random.random() < 0.5:\n", |
183 | 191 | " # Generate a linear sequence.\n",
|
184 |
| - " seq = np.arange(start=rand_start, stop=rand_start+seq_len)\n", |
| 192 | + " seq = np.arange(start=rand_start, stop=rand_start + seq_len)\n", |
185 | 193 | " # Rescale values to [0., 1.].\n",
|
186 | 194 | " seq = seq / max_value\n",
|
187 | 195 | " # Pad sequence until the maximum length for dimension consistency.\n",
|
188 | 196 | " # Masking value: -1.\n",
|
189 |
| - " seq = np.pad(seq, mode='constant', pad_width=(0, seq_max_len-seq_len), constant_values=masking_val)\n", |
| 197 | + " seq = np.pad(\n", |
| 198 | + " seq,\n", |
| 199 | + " mode=\"constant\",\n", |
| 200 | + " pad_width=(0, seq_max_len - seq_len),\n", |
| 201 | + " constant_values=masking_val,\n", |
| 202 | + " )\n", |
190 | 203 | " label = 0\n",
|
191 | 204 | " else:\n",
|
192 | 205 | " # Generate a random sequence.\n",
|
|
195 | 208 | " seq = seq / max_value\n",
|
196 | 209 | " # Pad sequence until the maximum length for dimension consistency.\n",
|
197 | 210 | " # Masking value: -1.\n",
|
198 |
| - " seq = np.pad(seq, mode='constant', pad_width=(0, seq_max_len-seq_len), constant_values=masking_val)\n", |
| 211 | + " seq = np.pad(\n", |
| 212 | + " seq,\n", |
| 213 | + " mode=\"constant\",\n", |
| 214 | + " pad_width=(0, seq_max_len - seq_len),\n", |
| 215 | + " constant_values=masking_val,\n", |
| 216 | + " )\n", |
199 | 217 | " label = 1\n",
|
200 | 218 | " yield np.array(seq, dtype=np.float32), np.array(label, dtype=np.float32)"
|
201 | 219 | ]
|
|
209 | 227 | "outputs": [],
|
210 | 228 | "source": [
|
211 | 229 | "# Use tf.data API to shuffle and batch data.\n",
|
212 |
| - "train_data = tf.data.Dataset.from_generator(toy_sequence_data, output_types=(tf.float32, tf.float32))\n", |
| 230 | + "train_data = tf.data.Dataset.from_generator(\n", |
| 231 | + " toy_sequence_data, output_types=(tf.float32, tf.float32)\n", |
| 232 | + ")\n", |
213 | 233 | "train_data = train_data.repeat().shuffle(5000).batch(batch_size).prefetch(1)"
|
214 | 234 | ]
|
215 | 235 | },
|
|
250 | 270 | " x = tf.nn.softmax(x)\n",
|
251 | 271 | " return x\n",
|
252 | 272 | "\n",
|
| 273 | + "\n", |
253 | 274 | "# Build LSTM model.\n",
|
254 | 275 | "lstm_net = LSTM()"
|
255 | 276 | ]
|
|
272 | 293 | " # Average loss across the batch.\n",
|
273 | 294 | " return tf.reduce_mean(loss)\n",
|
274 | 295 | "\n",
|
| 296 | + "\n", |
275 | 297 | "# Accuracy metric.\n",
|
276 | 298 | "def accuracy(y_pred, y_true):\n",
|
277 | 299 | " # Predicted class is the index of highest score in prediction vector (i.e. argmax).\n",
|
278 | 300 | " correct_prediction = tf.equal(tf.argmax(y_pred, 1), tf.cast(y_true, tf.int64))\n",
|
279 | 301 | " return tf.reduce_mean(tf.cast(correct_prediction, tf.float32), axis=-1)\n",
|
280 | 302 | "\n",
|
| 303 | + "\n", |
281 | 304 | "# Adam optimizer.\n",
|
282 | 305 | "optimizer = tf.optimizers.Adam(learning_rate)"
|
283 | 306 | ]
|
|
290 | 313 | },
|
291 | 314 | "outputs": [],
|
292 | 315 | "source": [
|
293 |
| - "# Optimization process. \n", |
| 316 | + "# Optimization process.\n", |
294 | 317 | "def run_optimization(x, y):\n",
|
295 | 318 | " # Wrap computation inside a GradientTape for automatic differentiation.\n",
|
296 | 319 | " with tf.GradientTape() as g:\n",
|
297 | 320 | " # Forward pass.\n",
|
298 | 321 | " pred = lstm_net(x, is_training=True)\n",
|
299 | 322 | " # Compute loss.\n",
|
300 | 323 | " loss = cross_entropy_loss(pred, y)\n",
|
301 |
| - " \n", |
| 324 | + "\n", |
302 | 325 | " # Variables to update, i.e. trainable variables.\n",
|
303 | 326 | " trainable_variables = lstm_net.trainable_variables\n",
|
304 | 327 | "\n",
|
305 | 328 | " # Compute gradients.\n",
|
306 | 329 | " gradients = g.gradient(loss, trainable_variables)\n",
|
307 |
| - " \n", |
| 330 | + "\n", |
308 | 331 | " # Update weights following gradients.\n",
|
309 | 332 | " optimizer.apply_gradients(zip(gradients, trainable_variables))"
|
310 | 333 | ]
|
|
321 | 344 | "for step, (batch_x, batch_y) in enumerate(train_data.take(training_steps), 1):\n",
|
322 | 345 | " # Run the optimization to update W and b values.\n",
|
323 | 346 | " run_optimization(batch_x, batch_y)\n",
|
324 |
| - " \n", |
| 347 | + "\n", |
325 | 348 | " if step % display_step == 0 or step == 1:\n",
|
326 | 349 | " pred = lstm_net(batch_x, is_training=True)\n",
|
327 | 350 | " loss = cross_entropy_loss(pred, batch_y)\n",
|
328 | 351 | " acc = accuracy(pred, batch_y)\n",
|
329 | 352 | " print(\"step: %i, loss: %f, accuracy: %f\" % (step, loss, acc))\n",
|
330 | 353 | "\n",
|
331 | 354 | " # Log metrics to Simvue\n",
|
332 |
| - " run.log_metrics({'loss': float(loss), 'accuracy': float(acc)}, step=step)\n", |
333 |
| - " \n", |
| 355 | + " run.log_metrics({\"loss\": float(loss), \"accuracy\": float(acc)}, step=step)\n", |
| 356 | + "\n", |
334 | 357 | "# End the run\n",
|
335 |
| - "run.close() " |
| 358 | + "run.close()" |
336 | 359 | ]
|
337 | 360 | },
|
338 | 361 | {
|
|
0 commit comments