Skip to content

Commit 43048ce

Browse files
committed
Fix code highlight
1 parent 34af03c commit 43048ce

File tree

1 file changed

+20
-21
lines changed

1 file changed

+20
-21
lines changed

manuscript/04.first-neural-network.md

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_
140140

141141
And convert all of it to Tensors (so we can use it with PyTorch):
142142

143-
```
143+
```py
144144
X_train = torch.from_numpy(X_train.to_numpy()).float()
145145
y_train = torch.squeeze(torch.from_numpy(y_train.to_numpy()).float())
146146

@@ -181,7 +181,7 @@ class Net(nn.Module):
181181
return torch.sigmoid(self.fc3(x))
182182
```
183183

184-
```
184+
```py
185185
net = Net(X_train.shape[1])
186186

187187
ann_viz(net, view=False)
@@ -207,13 +207,13 @@ Those functions must be hard to define, right?
207207

208208
Not at all, let start with the ReLU definition (one of the most widely used activation function):
209209

210-
$$
210+
{$$}
211211
\text{ReLU}(x) = \max({0, x})
212-
$$
212+
{/$$}
213213

214214
Easy peasy, the result is the maximum value of zero and the input.
215215

216-
```
216+
```py
217217
ax = plt.gca()
218218

219219
plt.plot(
@@ -231,11 +231,13 @@ The sigmoid is useful when you need to make a binary decision/classification (an
231231

232232
It is defined as:
233233

234-
$$\text{Sigmoid}(x) = \frac{1}{1+e^{-x}}$$
234+
{$$}
235+
\text{Sigmoid}(x) = \frac{1}{1+e^{-x}}
236+
{/$$}
235237

236238
The sigmoid squishes the input values between 0 and 1. But in a super kind of way:
237239

238-
```
240+
```py
239241
ax = plt.gca()
240242

241243
plt.plot(
@@ -251,7 +253,7 @@ ax.set_ylim([-1.5, 1.5]);
251253

252254
With the model in place, we need to find parameters that predict will it rain tomorrow. First, we need something to tell us how good we're currently doing:
253255

254-
```
256+
```py
255257
criterion = nn.BCELoss()
256258
```
257259

@@ -269,7 +271,7 @@ Contrary to what you might believe, optimization in Deep Learning is just satisf
269271

270272
While there are tons of optimizers you can choose from, [Adam](https://pytorch.org/docs/stable/optim.html#torch.optim.Adam) is a safe first choice. PyTorch has a well-debugged implementation you can use:
271273

272-
```
274+
```py
273275
optimizer = optim.Adam(net.parameters(), lr=0.001)
274276
```
275277

@@ -281,19 +283,19 @@ Doing massively parallel computations on GPUs is one of the enablers for modern
281283

282284
PyTorch makes it really easy to transfer all the computation to your GPU:
283285

284-
```
286+
```py
285287
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
286288
```
287289

288-
```
290+
```py
289291
X_train = X_train.to(device)
290292
y_train = y_train.to(device)
291293

292294
X_test = X_test.to(device)
293295
y_test = y_test.to(device)
294296
```
295297

296-
```
298+
```py
297299
net = net.to(device)
298300

299301
criterion = criterion.to(device)
@@ -305,7 +307,7 @@ We start by checking whether or not a CUDA device is available. Then, we transfe
305307

306308
Having a loss function is great, but tracking the accuracy of our model is something easier to understand, for us mere mortals. Here's the definition for our accuracy:
307309

308-
```
310+
```py
309311
def calculate_accuracy(y_true, y_pred):
310312
predicted = y_pred.ge(.5).view(-1)
311313
return (y_true == predicted).sum().float() / len(y_true)
@@ -315,7 +317,7 @@ We convert every value below 0.5 to 0. Otherwise, we set it to 1. Finally, we ca
315317

316318
With all the pieces of the puzzle in place, we can start training our model:
317319

318-
```
320+
```py
319321
def round_tensor(t, decimal_places=3):
320322
return round(t.item(), decimal_places)
321323

@@ -398,18 +400,15 @@ What about that accuracy? 83.6% accuracy on the test set sounds reasonable, righ
398400

399401
Training a good model can take a lot of time. And I mean weeks, months or even years. So, let's make sure that you know how you can save your precious work. Saving is easy:
400402

401-
```
403+
```py
402404
MODEL_PATH = 'model.pth'
403405

404406
torch.save(net, MODEL_PATH)
405407
```
406408

407-
/usr/local/lib/python3.6/dist-packages/torch/serialization.py:360: UserWarning: Couldn't retrieve source code for container of type Net. It won't be checked for correctness upon loading.
408-
"type " + obj.__name__ + ". It won't be checked "
409-
410409
Restoring your model is easy too:
411410

412-
```
411+
```py
413412
net = torch.load(MODEL_PATH)
414413
```
415414

@@ -421,7 +420,7 @@ Using just accuracy wouldn't be a good way to do it. Recall that our data contai
421420

422421
One way to delve a bit deeper into your model performance is to assess the precision and recall for each class. In our case, that will be _no rain_ and _rain_:
423422

424-
```
423+
```py
425424
classes = ['No rain', 'Raining']
426425

427426
y_pred = net(X_test)
@@ -447,7 +446,7 @@ You can see that our model is doing good when it comes to the _No rain_ class. W
447446

448447
One of the best things about binary classification is that you can have a good look at a simple confusion matrix:
449448

450-
```
449+
```py
451450
cm = confusion_matrix(y_test, y_pred)
452451
df_cm = pd.DataFrame(cm, index=classes, columns=classes)
453452

0 commit comments

Comments
 (0)