Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

128 lines
4.4KB

  1. from abc import abstractmethod
  2. from enum import Enum
  3. import numpy as np
  4. from neural_net.epoch import Epoch
  5. from neural_net.transform_layer import Layer
  6. class ModelData:
  7. def __init__(self, training_inputs, training_targets, test_inputs, test_targets):
  8. self.is_loaded = False
  9. self.training_inputs = training_inputs
  10. self.training_labels = training_targets
  11. self.test_inputs = test_inputs
  12. self.test_labels = test_targets
  13. # class TrainingSession:
  14. # def __init__(self, training_data: ModelData, learning_rate: float, nr_epochs: int, batch_size: int = 1000):
  15. # self.training_data = training_data
  16. # self.learning_rate = learning_rate
  17. # self.nr_epochs = nr_epochs
  18. # self.batch_size = batch_size
  19. # self.epochs: [Epoch] = []
  20. # for i in range(self.nr_epochs):
  21. # self.epochs.append(
  22. # Epoch(i, self.training_data.training_inputs, self.training_data.training_labels, self.batch_size))
  23. #
  24. # def get_total_training_duration(self):
  25. # duration = 0.0
  26. # for epoch in self.epochs:
  27. # duration += epoch.duration
  28. # return duration
  29. class NeuralNet:
  30. def __init__(self, layers: [Layer]):
  31. self.layers = layers
  32. self.last_loss = None
  33. self.last_accuracy = None
  34. def forward(self, inputs):
  35. outputs = inputs
  36. for layer in self.layers:
  37. outputs = layer.forward(outputs)
  38. return outputs
  39. def reset(self):
  40. for layer in self.layers:
  41. layer.reset()
  42. def backward(self, dL_dout, epoch):
  43. layer_dl_gradients = []
  44. layer_dl_bias = []
  45. layer_weights = []
  46. layer_biases = []
  47. for idx, layer in reversed(list(enumerate(self.layers))):
  48. dL_dout, dl_gradients, dl_biases, weights, biases = layer.backward(dL_dout, epoch.learning_rate)
  49. if dl_gradients is not None:
  50. layer_dl_gradients.append(dl_gradients)
  51. if dl_biases is not None:
  52. layer_dl_bias.append(dl_biases)
  53. if weights is not None:
  54. layer_weights.append(weights)
  55. if biases is not None:
  56. layer_biases.append(biases)
  57. return layer_dl_gradients, layer_dl_bias, layer_weights, layer_biases
  58. # def train(self, training_run: TrainingRun):
  59. # self.training_runs.append(training_run)
  60. #
  61. # for epoch in training_run.epochs:
  62. # epoch.start()
  63. #
  64. # for batch in epoch.batches:
  65. # batch.predictions = self.forward(batch.inputs)
  66. # dL_dout = self.loss_derivative(batch.predictions, batch.labels)
  67. #
  68. # layer_dl_gradients, layer_dl_biases, layer_weights, layer_biases = self.backward(dL_dout, training_run.learning_rate, epoch)
  69. # epoch.layer_dl_gradients.append(layer_dl_gradients)
  70. # epoch.layer_dl_biases.append(layer_dl_biases)
  71. #
  72. # epoch.finish()
  73. # epoch.loss = self.loss(epoch.all_predictions(), epoch.all_labels())
  74. #
  75. # if training_run.epoch_callback is not None:
  76. # training_run.epoch_callback(training_run, epoch)
  77. #
  78. # self.recalculate_loss(training_run.training_data.test_inputs, training_run.training_data.test_labels)
  79. # self.recalculate_loss(training_run.training_data.test_inputs, training_run.training_data.test_labels)
  80. def get_all_weights(self):
  81. all_weights = []
  82. for layer in self.layers:
  83. if hasattr(layer, 'weights'):
  84. all_weights.append(layer.weights)
  85. return all_weights
  86. def recalculate_accuracy(self, inputs, labels):
  87. raw_outputs = self.forward(inputs)
  88. predictions = raw_outputs.argmax(axis=1)
  89. num_correct_predictions = 0
  90. for idx, prediction in enumerate(predictions):
  91. if prediction == labels[idx]:
  92. num_correct_predictions += 1
  93. self.last_accuracy = num_correct_predictions / len(predictions)
  94. return self.last_accuracy
  95. def recalculate_loss(self, inputs, labels):
  96. raw_outputs = self.forward(inputs)
  97. self.last_loss = self.loss(np.array(raw_outputs), np.array(labels))
  98. return self.last_loss
  99. @abstractmethod
  100. def loss(self, outputs: np.array, labels: np.array):
  101. pass
  102. @abstractmethod
  103. def loss_derivative(self, outputs: np.array, labels: np.array):
  104. pass
  105. def predict(self, inputs):
  106. return self.forward(inputs)