What You Just Learned

In the last few pages, you got acquainted with a new loss function (the cross-entropy loss) and a few new concepts, like numerical stability. The focus of this chapter, however, was on implementing the neural network that we designed in the previous chapter. Here is all the code that we came up with:

10_building/forward_propagation.py
 import​ ​numpy​ ​as​ ​np
 
 
 def​ ​sigmoid​(z):
 return​ 1 / (1 + np.exp(-z))
 
 
 def​ ​softmax​(logits):
  exponentials = np.exp(logits)
 return​ exponentials / np.sum(exponentials, axis=1).reshape(-1, 1)
 
 
 def​ ​loss​(Y, y_hat):
 return​ -np.sum(Y * np.log(y_hat)) / Y.shape[0]
 
 
 def​ ​prepend_bias​(X):
 return​ np.insert(X, 0, 1, axis=1)
 
 
 def​ ​forward​(X, w1, w2):
  h = sigmoid(np.matmul(prepend_bias(X), w1))
  y_hat = softmax(np.matmul(prepend_bias(h), w2))
 return​ y_hat
 
 
 def​ ​classify​(X, w1, w2):
  y_hat = forward(X, w1, w2)
  labels = np.argmax(y_hat, axis=1)
 return​ labels.reshape(-1, 1)
 
 
 def​ ​report​(iteration, X_train, Y_train, X_test, Y_test, w1, w2):
  y_hat = forward(X_train, w1, w2)
  training_loss = loss(Y_train, y_hat)
  classifications = classify(X_test, w1, w2)
  accuracy = np.average(classifications == Y_test) * 100.0
 print​(​"Iteration: ​​%5​​d, Loss: ​​%.6​​f, Accuracy: ​​%.2​​f​​%%​​"​ %
  (iteration, training_loss, accuracy))

With that, half of our neural network’s logic is done—the half that takes care of the classification phase.

This code, however, won’t be useful until we’ve also written the code that trains the network. In the next chapter we’ll do that, and we’ll test drive the entire thing.