                 // FIXME: This isn't working correctly
                 self.outputErrorsCache[outputIndex] = output - answer[outputIndex]
             default:
-                self.outputErrorsCache[outputIndex] = self.activationDerivative(output) * (answer[outputIndex] - output)
+                self.outputErrorsCache[outputIndex] = actFunction.derivative(output) * (answer[outputIndex] - output)
             }
         }
         
         // Calculate hidden errors
         vDSP_mmul(self.outputErrorsCache, 1,
-            self.outputWeights, 1,
+            outputLayer.matrix, 1,
             &self.hiddenErrorSumsCache, 1,
             vDSP_Length(1), vDSP_Length(self.numHiddenNodes), vDSP_Length(self.numOutputs))
         for (errorIndex, error) in self.hiddenErrorSumsCache.enumerate() {
-            self.hiddenErrorsCache[errorIndex] = self.activationDerivative(self.hiddenOutputCache[errorIndex]) * error
+            self.hiddenErrorsCache[errorIndex] = actFunction.derivative(self.hiddenOutputCache[errorIndex]) * error
         }
         
         // Update output weights
-        for weightIndex in 0..<self.outputWeights.count {
-            let offset = self.outputWeights[weightIndex] + (self.momentumFactor * (self.outputWeights[weightIndex] - self.previousOutputWeights[weightIndex]))
+        for weightIndex in 0..<outputLayer.matrix.count {
+            let offset = outputLayer.matrix[weightIndex] + (self.momentumFactor * (outputLayer.matrix[weightIndex] - self.previousOutputWeights[weightIndex]))
             let errorIndex = self.outputErrorIndices[weightIndex]
             let hiddenOutputIndex = self.hiddenOutputIndices[weightIndex]
             let mfLRErrIn = self.mfLR * self.outputErrorsCache[errorIndex] * self.hiddenOutputCache[hiddenOutputIndex]
             self.newOutputWeights[weightIndex] = offset + mfLRErrIn
         }
         
-        vDSP_mmov(outputWeights, &previousOutputWeights, 1, vDSP_Length(numOutputWeights), 1, 1)
-        vDSP_mmov(newOutputWeights, &outputWeights, 1, vDSP_Length(numOutputWeights), 1, 1)
+        vDSP_mmov(outputLayer.matrix, &previousOutputWeights, 1, vDSP_Length(numOutputWeights), 1, 1)
+        vDSP_mmov(newOutputWeights, &outputLayer.matrix, 1, vDSP_Length(numOutputWeights), 1, 1)
+    
         
         // Update hidden weights
-        for weightIndex in 0..<self.hiddenWeights.count {
-            let offset = self.hiddenWeights[weightIndex] + (self.momentumFactor * (self.hiddenWeights[weightIndex]  - self.previousHiddenWeights[weightIndex]))
+        for weightIndex in 0..<hiddenLayer.matrix.count {
+            let offset = hiddenLayer.matrix[weightIndex] + (self.momentumFactor * (hiddenLayer.matrix[weightIndex]  - self.previousHiddenWeights[weightIndex]))
             let errorIndex = self.hiddenErrorIndices[weightIndex]
             let inputIndex = self.inputIndices[weightIndex]
             // Note: +1 on errorIndex to offset for bias 'error', which is ignored

            self.newHiddenWeights[weightIndex] = offset + mfLRErrIn
        }
        
        vDSP_mmov(hiddenWeights, &previousHiddenWeights, 1, vDSP_Length(numHiddenWeights), 1, 1)
        vDSP_mmov(newHiddenWeights, &hiddenWeights, 1, vDSP_Length(numHiddenWeights), 1, 1)

        // Sum and return the output errors
        return self.outputErrorsCache.reduce(0, combine: { (sum, error) -> Float in
            return sum + abs(error)

            throw FFNNError.InvalidWeightsError("Invalid number of weights provided: \(weights.count). Expected: \(self.numHiddenWeights + self.numOutputWeights)")
        }
        
        hiddenLayer.matrix = Array(weights[0..<hiddenLayer.matrix.count])
        outputLayer.matrix = Array(weights[hiddenLayer.matrix.count..<weights.count])
    }
}

