def create(number_of_inputs: int, number_of_outputs: int, factor: float, a: str, a_prime: str): return Layer( a, a_prime, Matrix.randomMatrix(number_of_outputs, number_of_inputs).divide(factor), Matrix.zeroMatrix(number_of_outputs, 1) )
def propogate_backwards( self, dAl: Matrix, weights: Matrix, m: int, dactivation: Callable[[Scalar], Scalar]) -> Tuple[Matrix, Matrix, Matrix]: cacheEntry: CacheEntry = self.__cache.pop() dZ = dAl.multiply(cacheEntry.Z.apply(dactivation)) dW = dZ.dot(cacheEntry.activations.rtocol()).divide(m) dB = dZ.rowsSum().divide(m) dAl_1 = weights.rtocol().dot(dZ) return dAl_1, dW, dB
def distribute_training_data( inputs: Matrix, labels: List[str], proportion: float) -> Dict[str, Tuple[Matrix, Matrix]]: inputsT = inputs.rtocol() gouped_by_label = OvRClassifier.group_by_label(inputsT, labels) min_sample_count = min( [len(samples) for samples in gouped_by_label.values()]) OvRClassifier.logger.debug( f"Smallest samples size: {min_sample_count}") # samples_count = min_sample_count #min(min_sample_count, 0 if samples_count == None else samples_count) # OvRClassifier.logger.debug(f"Sample count: {samples_count} [min samples size: {min_sample_count}, samples_count: {samples_count}]") distributed_data: Dict[str, Tuple[List[List[float]], List[int]]] = {} for label in gouped_by_label: OvRClassifier.logger.debug(f"Generating data for: {label}") rgbs = random.choices(gouped_by_label[label], k=min_sample_count) OvRClassifier.logger.debug( f"Got {len(rgbs)} positive samples out of {len(gouped_by_label[label])}" ) mask = [1] * len(rgbs) other_data: List[List[float]] = [] for other_label in [l for l in gouped_by_label if l != label]: other_data.extend(gouped_by_label[other_label]) proportion_amount = int(len(rgbs) * proportion) negative_samples = random.choices(other_data, k=proportion_amount) OvRClassifier.logger.debug( f"Got {len(negative_samples)} negative samples out of {len(other_data)} [proportion: {proportion}]" ) rgbs.extend(negative_samples) mask.extend([0] * proportion_amount) rgbs_shuffled: List[List[float]] = [] mask_shuffled: List[int] = [] OvRClassifier.logger.debug(f"Shuffling {len(rgbs)} samples") indices = list(range(len(rgbs))) random.shuffle(indices) for idx in indices: rgbs_shuffled.append(rgbs[idx]) mask_shuffled.append(mask[idx]) distributed_data[label] = (rgbs_shuffled, mask_shuffled) return { label: (Matrix(data[0]).rtocol(), Matrix([data[1]])) for label, data in distributed_data.items() }
def test_rtocol_2x4(self): data = [[2, 5, 2, 9], [1, 2, 4, 6]] matrixT = Matrix(data) m = matrixT.rtocol() self.assertSequenceEqual(matrixT, data) self.assertEqual(matrixT.rows, 2) self.assertEqual(matrixT.colomns, 4) self.assertSequenceEqual([[2, 1], [5, 2], [2, 4], [9, 6]], m) self.assertEqual(m.rows, 4) self.assertEqual(m.colomns, 2)
def test_rtocol_2x2(self): data = [[1, 4], [5, 6]] matrixT = Matrix(data) m = matrixT.rtocol() self.assertSequenceEqual(matrixT, data) self.assertEqual(matrixT.rows, 2) self.assertEqual(matrixT.colomns, 2) self.assertSequenceEqual(m, [[1, 5], [4, 6]]) self.assertEqual(m.rows, 2) self.assertEqual(m.colomns, 2)
def propogate_forward(self, activations: Matrix, weights: Matrix, biases: Matrix, activation: Callable[[Scalar], Scalar]) -> Matrix: z = weights.dot(activations) + biases next_layer_activations = z.apply(activation) self.__cache.append(CacheEntry(z, activations)) return next_layer_activations
def test_getitem_checks_bounds(self): matrix = Matrix([[0], [1]]) self.assertRaises(IndexError, lambda: matrix[-2]) self.assertRaises(IndexError, lambda: matrix[2])
def test_dot(self, name: str, left: Matrix, right: Matrix, result: Matrix): self.assertMatrixAreEqual(left.dot(right), result)
class MatrixTest(MatrixTestCase): def test_ctor_4x1(self): m = Matrix([[1,2,3,4]]) self.assertEqual(m.rows, 1) self.assertEqual(m.colomns, 4) @parameterized.expand([ ("1x2 2x1", Matrix([[1, 4]]), Matrix([[1], [1]]), Matrix([[1.0, 4.0], [1.0, 4.0]])), ("1x2 2x2", Matrix([[1, 1]]), Matrix([[1, 4], [1, 6]]), Matrix([[1.0, 4.0], [1.0, 6.0]])), ("2x1 1x2", Matrix([[1], [1]]), Matrix([[1, 4]]), Matrix([[1.0, 4.0], [1.0, 4.0]])), ("2x1 2x2", Matrix([[1], [1]]), Matrix([[1, 4], [1, 6]]), Matrix([[1.0, 4.0], [1.0, 6.0]])), ("2x2 2x2", Matrix([[1, 1], [1, 1]]), Matrix([[1, 4], [1, 6]]), Matrix([[1.0, 4.0], [1.0, 6.0]])), ("2x2 2x1", Matrix([[1, 4], [1, 6]]), Matrix([[1], [1]]), Matrix([[1.0, 4.0], [1.0, 6.0]])), ("2x2 1x2", Matrix([[1, 4], [1, 6]]), Matrix([[1, 1]]), Matrix([[1.0, 4.0], [1.0, 6.0]])), ("2x2 2x2", Matrix([[1, 4], [1, 6]]), Matrix([[1, 1], [1, 1]]), Matrix([[1.0, 4.0], [1.0, 6.0]])), ("2x2 int", Matrix([[1, 4], [1, 6]]), 1, Matrix([[1.0, 4.0], [1.0, 6.0]])), ("2x2 float", Matrix([[1, 4], [1, 6]]), 1.0, Matrix([[1.0, 4.0], [1.0, 6.0]])) ]) def test_multiplication(self, name:str, left: Matrix, right: Matrix, result: Matrix): self.assertMatrixAreEqual(left.multiply(right), result) @parameterized.expand([ ("2x1 2x2", Matrix([[168], [168]]), Matrix([[1, 4], [1, 6]]), Matrix([[168.0, 42.0], [168.0, 28.0]])), ("1x2 2x2", Matrix([[168, 168]]), Matrix([[1, 4], [1, 6]]), Matrix([[168.0, 42.0], [168.0, 28.0]])), ("2x2 2x1", Matrix([[1, 4], [1, 6]]), Matrix([[1], [1]]), Matrix([[1.0, 4.0], [1.0, 6.0]])), ("2x2 1x2", Matrix([[1, 4], [1, 6]]), Matrix([[1, 1]]), Matrix([[1.0, 4.0], [1.0, 6.0]])), ("2x2 2x2", Matrix([[1, 4], [1, 6]]), Matrix([[1, 1], [1, 1]]), Matrix([[1.0, 4.0], [1.0, 6.0]])), ("2x2 int", Matrix([[1, 4], [1, 6]]), 1, Matrix([[1.0, 4.0], [1.0, 6.0]])), ("2x2 float", Matrix([[1, 4], [1, 6]]), 1.0, Matrix([[1.0, 4.0], [1.0, 6.0]])) ]) def test_division_operator(self, name: str, left: Matrix, right: Matrix, result: Matrix): self.assertMatrixAreEqual(left.divide(right), result) def test_random_matrix(self): with mock.patch("random.gauss", return_value = 1): randMatrix = Matrix.randomMatrix(2, 4) self.assertSequenceEqual([[1 for _ in range(4)], [1 for _ in range(4)]], randMatrix) def test_zero_matrix(self): zerMatrix = Matrix.zeroMatrix(2, 4) self.assertSequenceEqual([[0, 0, 0, 0],[0, 0, 0, 0]] , zerMatrix) @parameterized.expand([ ("3x2 3x2", Matrix([[0, 1], [0, 1], [0, 1]]), Matrix([[0, 0], [0, 0], [0, 0]]), [[0, 1], [0, 1], [0, 1]]), ("int 3x2", 1, Matrix([[0, 1], [0, 1], [0, 1]]), [[1, 2], [1, 2], [1, 2]]), ("3x2 int", Matrix([[0, 1], [0, 1], [0, 1]]), 1, [[1, 2], [1, 2], [1, 2]]), ("float 3x2", 1.0, Matrix([[0, 1], [0, 1], [0, 1]]), [[1.0, 2.0], [1.0, 2.0], [1.0, 2.0]]), ("3x2 float", Matrix([[0, 1], [0, 1], [0, 1]]), 1.0, [[1.0, 2.0], [1.0, 2.0], [1.0, 2.0]]), ("3x2 3x1", Matrix([[0, 1], [0, 1], [0, 1]]), Matrix([[1],[1],[1]]), [[1.0, 2.0], [1.0, 2.0], [1.0, 2.0]]) ]) def test_add_operation(self, name: str, left: Matrix, right: Matrix, result: Matrix): self.assertSequenceEqual(result, left + right) @parameterized.expand([ ("1x2 2x2", Matrix([[1, 1]]), Matrix([[1, 1], [1, 1]]), [[0, 0], [0, 0]]), ("2x2 1x2", Matrix([[1, 1], [1, 1]]), Matrix([[1, 1]]), [[0, 0], [0, 0]]), ("2x1 2x2", Matrix([[1], [1]]), Matrix([[1, 1], [1, 1]]), [[0, 0], [0, 0]]), ("2x2 2x1", Matrix([[1, 1], [1, 1]]), Matrix([[1], [1]]), [[0, 0], [0, 0]]), ("3x2 3x2", Matrix([[0, 1], [0, 1], [0, 1]]), Matrix([[0, 0], [0, 0], [0, 0]]), [[0, 1], [0, 1], [0, 1]]), ("int 3x2", 1, Matrix([[0, 1], [0, 1], [0, 1]]), [[1, 0], [1, 0], [1, 0]]), ("3x2 int", Matrix([[1, 1], [1, 1], [1, 1]]), 1, [[0, 0], [0, 0], [0, 0]]), ("float 3x2", 1.0, Matrix([[1, 1], [1, 1], [1, 1]]), [[0, 0], [0, 0], [0, 0]]), ("3x2 float", Matrix([[1, 1], [1, 1], [1, 1]]), 1.0, [[0, 0], [0, 0],[0, 0]]) ]) def test_subtract_operator(self, name: str, left: Matrix, right: Matrix, result: Matrix): self.assertSequenceEqual(result, left - right) @parameterized.expand([ ("4x4", Matrix([[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]), Matrix([[4], [4], [4], [4]])), ("1x7", Matrix([[0.775112467947669, 0.6748015958065318, -0.35519107689330787, -0.18816103652461777, -0.05088776646897432, 0.43913101827589524, 0.4346996995492459]]), Matrix([[1.729504902]])) ]) def test_rowsSum(self, name: str, matrix: Matrix, result: Matrix): self.assertMatrixAreEqual(result, matrix.rowsSum()) @parameterized.expand([ ("2x2 2x2", Matrix([[1, 1], [1, 1]]), Matrix([[9, 9], [9, 9]]), Matrix([[18, 18], [18, 18]])), ("1x2 2x1", Matrix([[1, 1]]), Matrix([[9], [9]]), Matrix([[18]])), ("2x1 1x2", Matrix([[1], [1]]), Matrix([[9, 9]]), Matrix([[9, 9],[9, 9]])) ]) def test_dot(self, name: str, left: Matrix, right: Matrix, result: Matrix): self.assertMatrixAreEqual(left.dot(right), result) def test_rtocol_2x2(self): data = [[1, 4], [5, 6]] matrixT = Matrix(data) m = matrixT.rtocol() self.assertSequenceEqual(matrixT, data) self.assertEqual(matrixT.rows, 2) self.assertEqual(matrixT.colomns, 2) self.assertSequenceEqual(m, [[1, 5], [4, 6]]) self.assertEqual(m.rows, 2) self.assertEqual(m.colomns, 2) def test_rtocol_2x4(self): data = [[2, 5, 2, 9], [1, 2, 4, 6]] matrixT = Matrix(data) m = matrixT.rtocol() self.assertSequenceEqual(matrixT, data) self.assertEqual(matrixT.rows, 2) self.assertEqual(matrixT.colomns, 4) self.assertSequenceEqual([[2, 1], [5, 2], [2, 4], [9, 6]], m) self.assertEqual(m.rows, 4) self.assertEqual(m.colomns, 2) def test_apply(self): matrix = Matrix([[0, 0], [0, 0]]) m = matrix.apply(lambda x: 1/(1 + math.exp(-x))) self.assertSequenceEqual([[0.5, 0.5], [0.5, 0.5]], m) def test_getitem_checks_bounds(self): matrix = Matrix([[0], [1]]) self.assertRaises(IndexError, lambda: matrix[-2]) self.assertRaises(IndexError, lambda: matrix[2])
def test_rowsSum(self, name: str, matrix: Matrix, result: Matrix): self.assertMatrixAreEqual(result, matrix.rowsSum())
def test_zero_matrix(self): zerMatrix = Matrix.zeroMatrix(2, 4) self.assertSequenceEqual([[0, 0, 0, 0],[0, 0, 0, 0]] , zerMatrix)
def test_random_matrix(self): with mock.patch("random.gauss", return_value = 1): randMatrix = Matrix.randomMatrix(2, 4) self.assertSequenceEqual([[1 for _ in range(4)], [1 for _ in range(4)]], randMatrix)
def test_division_operator(self, name: str, left: Matrix, right: Matrix, result: Matrix): self.assertMatrixAreEqual(left.divide(right), result)
def test_multiplication(self, name:str, left: Matrix, right: Matrix, result: Matrix): self.assertMatrixAreEqual(left.multiply(right), result)
def setUp(self) -> None: self.W1 = Matrix([ [ 0.36321467, -0.13679289, -0.11810279, -0.23992308, 0.19351103, -0.5146397, 0.39015177, -0.17021104, 0.07133931, -0.05576091, 0.32693727, -0.46066147, -0.07209468, -0.08587716, 0.25351855, -0.24594316, -0.03855612, -0.19629511, 0.00943928, 0.13032144 ], [ -0.24610593, 0.255968, 0.20160181, 0.11236115, 0.20143751, -0.1528862, -0.02747909, -0.20924441, -0.0599016, 0.11859109, -0.15466005, -0.08871679, -0.15365649, -0.18899373, -0.1500952, -0.00283189, -0.24983819, 0.05241694, 0.37114305, 0.16592612 ], [ -0.04289573, -0.19847987, -0.16706967, 0.37844435, 0.01136096, -0.14243656, 0.04269, 0.46963133, 0.02686836, 0.13801081, 0.06712012, -0.07876546, -0.25547484, -0.07811541, -0.04671017, 0.13117293, 0.18760239, 0.20820075, 0.06385927, 0.19792358 ], [ -0.16868851, 0.28014984, 0.11469459, -0.06665558, 0.10923598, -0.01689835, 0.25304002, 0.33984137, 0.48870952, -0.31226607, -0.32291366, -0.112802, 0.03578538, 0.19591733, 0.07057812, -0.45217794, -0.0684693, 0.18514076, 0.05145075, 0.17039088 ], [ -0.04971408, -0.04489087, 0.0417164, 0.09169034, 0.04434117, 0.02661114, -0.14996465, 0.08442583, 0.02724006, 0.25256028, 0.26808619, 0.04140223, -0.08391627, -0.14282446, 0.09469622, 0.01729377, -0.07688802, 0.00974855, -0.1386364, 0.15608471 ] ]) self.B1 = Matrix([[0.], [0.], [0.], [0.], [0.]]) self.W2 = Matrix( [[-0.19996197, 0.54761649, 0.18044695, 0.26545639, -0.48965946]]) self.B2 = Matrix([[0.]]) self.train_set_x = Matrix( [[ 1.62434536, -0.61175641, -0.52817175, -1.07296862, 0.86540763, -2.3015387, 1.74481176 ], [ -0.7612069, 0.3190391, -0.24937038, 1.46210794, -2.06014071, -0.3224172, -0.38405435 ], [ 1.13376944, -1.09989127, -0.17242821, -0.87785842, 0.04221375, 0.58281521, -1.10061918 ], [ 1.14472371, 0.90159072, 0.50249434, 0.90085595, -0.68372786, -0.12289023, -0.93576943 ], [ -0.26788808, 0.53035547, -0.69166075, -0.39675353, -0.6871727, -0.84520564, -0.67124613 ], [ -0.0126646, -1.11731035, 0.2344157, 1.65980218, 0.74204416, -0.19183555, -0.88762896 ], [ -0.74715829, 1.6924546, 0.05080775, -0.63699565, 0.19091548, 2.10025514, 0.12015895 ], [ 0.61720311, 0.30017032, -0.35224985, -1.1425182, -0.34934272, -0.20889423, 0.58662319 ], [ 0.83898341, 0.93110208, 0.28558733, 0.88514116, -0.75439794, 1.25286816, 0.51292982 ], [ -0.29809284, 0.48851815, -0.07557171, 1.13162939, 1.51981682, 2.18557541, -1.39649634 ], [ -1.44411381, -0.50446586, 0.16003707, 0.87616892, 0.31563495, -2.02220122, -0.30620401 ], [ 0.82797464, 0.23009474, 0.76201118, -0.22232814, -0.20075807, 0.18656139, 0.41005165 ], [ 0.19829972, 0.11900865, -0.67066229, 0.37756379, 0.12182127, 1.12948391, 1.19891788 ], [ 0.18515642, -0.37528495, -0.63873041, 0.42349435, 0.07734007, -0.34385368, 0.04359686 ], [ -0.62000084, 0.69803203, -0.44712856, 1.2245077, 0.40349164, 0.59357852, -1.09491185 ], [ 0.16938243, 0.74055645, -0.9537006, -0.26621851, 0.03261455, -1.37311732, 0.31515939 ], [ 0.84616065, -0.85951594, 0.35054598, -1.31228341, -0.03869551, -1.61577235, 1.12141771 ], [ 0.40890054, -0.02461696, -0.77516162, 1.27375593, 1.96710175, -1.85798186, 1.23616403 ], [ 1.62765075, 0.3380117, -1.19926803, 0.86334532, -0.1809203, -0.60392063, -1.23005814 ], [ 0.5505375, 0.79280687, -0.62353073, 0.52057634, -1.14434139, 0.80186103, 0.0465673 ]]) self.train_set_y = Matrix([[ -0.18656977, -0.10174587, 0.86888616, 0.75041164, 0.52946532, 0.13770121, 0.07782113 ]]) self.expected_W1 = Matrix([ [ 0.36323487, -0.13681289, -0.11810332, -0.2399075, 0.19350479, -0.51469112, 0.39020775, -0.17017667, 0.07139532, -0.05575124, 0.3268555, -0.46063915, -0.07204686, -0.08588028, 0.25351177, -0.24592884, -0.0385627, -0.19629864, 0.00946108, 0.1303685 ], [ -0.24617715, 0.25603144, 0.20156286, 0.11227348, 0.20143884, -0.1527616, -0.02760269, -0.20934217, -0.06005215, 0.11855739, -0.15442681, -0.08878607, -0.15375697, -0.18898914, -0.15008236, -0.00288045, -0.24982675, 0.05242914, 0.37102009, 0.16579358 ], [ -0.04292689, -0.19845777, -0.16707328, 0.37842914, 0.01136557, -0.14238876, 0.04264682, 0.46959624, 0.02681977, 0.13801013, 0.06719514, -0.07878771, -0.25551647, -0.07811397, -0.04669831, 0.13115631, 0.18759943, 0.20819955, 0.0638347, 0.19788219 ], [ -0.16875617, 0.28018386, 0.11469056, -0.06668331, 0.10923725, -0.01682986, 0.25299324, 0.33978677, 0.48864498, -0.31225229, -0.32281423, -0.11283589, 0.03573264, 0.19591664, 0.07060046, -0.45221363, -0.06848722, 0.18512237, 0.05140432, 0.17033493 ], [ -0.04964696, -0.04495106, 0.04172833, 0.09175562, 0.04433044, 0.02647285, -0.14982196, 0.08452398, 0.02739558, 0.25258589, 0.26785665, 0.0414707, -0.08379868, -0.1428332, 0.0946775, 0.01733933, -0.07689979, 0.00974022, -0.13855069, 0.15621566 ] ]) self.expected_B1 = Matrix([[5.14909138e-05], [-1.35770379e-04], [-4.52316841e-05], [-6.37707714e-05], [1.45198481e-04]]) self.expected_W2 = Matrix( [[-0.20063374, 0.54691788, 0.1796375, 0.26450398, -0.49014712]]) self.expected_B2 = Matrix([[-0.00123536]])
def test_apply(self): matrix = Matrix([[0, 0], [0, 0]]) m = matrix.apply(lambda x: 1/(1 + math.exp(-x))) self.assertSequenceEqual([[0.5, 0.5], [0.5, 0.5]], m)
def test_ctor_4x1(self): m = Matrix([[1,2,3,4]]) self.assertEqual(m.rows, 1) self.assertEqual(m.colomns, 4)
class TestModelCalculations(MatrixTestCase): @parameterized.expand([(-100, 3.72e-44), (0, 0.5), (100, 1.0)]) def test_sigmoid(self, value: float, result: float): self.assertAlmostEqual(result, sigmoid(value), 46) @parameterized.expand([(-100, 3.72e-44), (0, 0.25), (100, 0.0)]) def test_sigmoid_prime(self, value: float, result: float): self.assertAlmostEqual(result, sigmoid_prime(value), 46) @parameterized.expand([(Matrix([[0.1, 0.3, 0.5, 0.7]]), Matrix([[1.0, 2.0, 3.0, 4.0]]), Matrix([[ 2.3025850929940455, 2.05127066471314, 0.6931471805599452, -2.185218637222878 ]])), (Matrix([[0.1, 0.3, 0.5, 0.7], [0.1, 0.3, 0.5, 0.7]]), Matrix([[1.0, 2.0, 3.0, 4.0], [1.0, 2.0, 3.0, 4.0]]), Matrix([[ 2.3025850929940455, 2.05127066471314, 0.6931471805599452, -2.185218637222878 ], [ 2.3025850929940455, 2.05127066471314, 0.6931471805599452, -2.185218637222878 ]]))]) def test_error(self, y_hat: Matrix, y: Matrix, result: Matrix): self.assertMatrixAreEqual(error(y_hat, y), result) @parameterized.expand([(Matrix([[0.1, 0.3, 0.5, 0.7]]), Matrix([[1.0, 2.0, 3.0, 4.0]]), 0.7154460752610632)]) def test_cost(self, y_hat: Matrix, y: Matrix, result: float): self.assertAlmostEqual(cost(y_hat, y), result, 15) @parameterized.expand([ (Matrix([[0.1, 0.2, 0.3, 0.4]]), Matrix([[1.0, 2.0, 3.0, 4.0]]), Matrix([[-10.0, -11.25, -12.857142857142858, -15.0]])), (Matrix([[0.1, 0.2, 0.3, 0.4], [0.1, 0.2, 0.3, 0.4]]), Matrix([[1.0, 2.0, 3.0, 4.0], [1.0, 2.0, 3.0, 4.0]]), Matrix([[-10.0, -11.25, -12.857142857142858, -15.0], [-10.0, -11.25, -12.857142857142858, -15.0]])) ]) def test_error_prime(self, y_hat: Matrix, y: Matrix, result: Matrix): self.assertMatrixAreEqual(error_prime(y_hat, y), result) @parameterized.expand([ (1, 1), (0, 0), (-1, 0), ]) def test_relu(self, x: float, result: float): self.assertEquals(relu(x), result) @parameterized.expand([ (1, 1), (0, 1), (-1, 0), ]) def test_relu_prime(self, x: float, result: float): self.assertEquals(relu_prime(x), result)
from src.Mathematics.Matrix import Matrix from src.Model.Layer import Layer from src.Mathematics.Model_Calculations import cost, error_prime from src.Model.Network import Network def get_output_file_name(tag: str) -> str: p = Path(__file__) file_name = f'{p.stem}-{tag}' return path.join(p.parent, file_name) profiler = cProfile.Profile() imagesM = Matrix.randomMatrix(12288, 209) labels = Matrix([array('f', [random.choice([0, 1]) for _ in range(209)])]) layers = [ Layer.create(imagesM.rows, 5, math.sqrt(imagesM.rows), 'sigmoid', 'sigmoid_prime'), Layer.create(5, 1, math.sqrt(5), 'sigmoid', 'sigmoid_prime'), Layer.create(1, 1, math.sqrt(1), 'sigmoid', 'sigmoid_prime') ] nn = Network(layers) def doProfile(tag: str) -> None: profiler.enable() for _ in range(1): nn.train(imagesM, labels, cost, error_prime, 0.005) profiler.disable()