my_answers.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import numpy as np
  2. class NeuralNetwork(object):
  3. def __init__(self, input_nodes, hidden_nodes, output_nodes, learning_rate):
  4. # Set number of nodes in input, hidden and output layers.
  5. self.input_nodes = input_nodes
  6. self.hidden_nodes = hidden_nodes
  7. self.output_nodes = output_nodes
  8. # Initialize weights
  9. self.weights_input_to_hidden = np.random.normal(0.0, self.input_nodes**-0.5,
  10. (self.input_nodes, self.hidden_nodes))
  11. self.weights_hidden_to_output = np.random.normal(0.0, self.hidden_nodes**-0.5,
  12. (self.hidden_nodes, self.output_nodes))
  13. self.lr = learning_rate
  14. self.activation_function = lambda x: 1/(1 + np.exp(-x))
  15. def train(self, features, targets):
  16. """Train the network on batch of features and targets.
  17. Arguments:
  18. - features: 2D array, each row is one data record,
  19. each column is a feature
  20. - targets: 1D array of target values
  21. """
  22. n_records = features.shape[0]
  23. delta_weights_i_h = np.zeros(self.weights_input_to_hidden.shape)
  24. delta_weights_h_o = np.zeros(self.weights_hidden_to_output.shape)
  25. for X, y in zip(features, targets):
  26. final_outputs, hidden_outputs = self.forward_pass_train(X)
  27. delta_weights_i_h, delta_weights_h_o = self.backpropagation(final_outputs, hidden_outputs, X, y,
  28. delta_weights_i_h, delta_weights_h_o)
  29. self.update_weights(delta_weights_i_h, delta_weights_h_o, n_records)
  30. def forward_pass_train(self, X):
  31. """Forward Pass Method.
  32. Arguments:
  33. - X: features batch
  34. """
  35. hidden_inputs = np.dot(X, self.weights_input_to_hidden)
  36. hidden_outputs = self.activation_function(hidden_inputs)
  37. final_inputs = np.dot(hidden_outputs, self.weights_hidden_to_output)
  38. final_outputs = final_inputs
  39. return final_outputs, hidden_outputs
  40. def backpropagation(self, final_outputs, hidden_outputs, X, y,
  41. delta_weights_i_h, delta_weights_h_o):
  42. """Backpropagation.
  43. Arguments:
  44. - final_outputs: output from forward pass
  45. - y: target (i.e. label) batch
  46. - delta_weights_i_h: change in weights from input to hidden layers
  47. - delta_weights_h_o: change in weights from hidden to output layers
  48. """
  49. # Calculate error: difference between desired target & output
  50. error = y - final_outputs
  51. # Calculate the hidden layer's contribution to the error
  52. hidden_error = np.dot(self.weights_hidden_to_output, error)
  53. # Backpropagated error terms
  54. output_error_term = error * 1.0
  55. hidden_error_term = hidden_error * hidden_outputs * (1 - hidden_outputs)
  56. # Weight step (input to hidden)
  57. delta_weights_i_h += hidden_error_term * X[:, None]
  58. # Weight step (hidden to output)
  59. delta_weights_h_o += output_error_term * hidden_outputs[:, None]
  60. return delta_weights_i_h, delta_weights_h_o
  61. def update_weights(self, delta_weights_i_h, delta_weights_h_o, n_records):
  62. """Update weights on gradient descent step.
  63. Arguments:
  64. - delta_weights_i_h: change in weights from input to hidden layers
  65. - delta_weights_h_o: change in weights from hidden to output layers
  66. - n_records: number of records
  67. """
  68. # Update hidden-to-output weights with gradient descent step
  69. self.weights_hidden_to_output += self.lr * delta_weights_h_o/n_records
  70. # Update input-to-hidden weights with gradient descent step
  71. self.weights_input_to_hidden += self.lr * delta_weights_i_h/n_records
  72. def run(self, features):
  73. """Run a forward pass through the network with input features.
  74. Arguments:
  75. - features: 1D array of feature values
  76. """
  77. hidden_inputs = np.dot(features, self.weights_input_to_hidden)
  78. hidden_outputs = self.activation_function(hidden_inputs)
  79. final_inputs = np.dot(hidden_outputs, self.weights_hidden_to_output)
  80. final_outputs = final_inputs
  81. return final_outputs
  82. #########################################################
  83. # Set your hyperparameters here
  84. #########################################################
  85. iterations = 5000
  86. learning_rate = 0.5
  87. hidden_nodes = 10
  88. output_nodes = 1