def test_network_convergence(self): with catch_stdout() as out: bpnet = algorithms.GradientDescent( (2, 3, 1), step=0.1, verbose=True, show_epoch=100 ) bpnet.train(xor_zero_input_train, xor_zero_target_train, epochs=3, epsilon=1e-5) terminal_output = out.getvalue() self.assertEqual(1, terminal_output.count("Network didn't converge")) with catch_stdout() as out: bpnet = algorithms.GradientDescent( (2, 3, 1), step=0.1, verbose=True, show_epoch=100 ) bpnet.train(xor_zero_input_train, xor_zero_target_train, epochs=1e3, epsilon=1e-3) terminal_output = out.getvalue() self.assertEqual(1, terminal_output.count("Network converged"))
def test_nn_init_logging(self): with catch_stdout() as out: algorithms.GradientDescent((2, 3, 1), verbose=False) terminal_output = out.getvalue() self.assertEqual("", terminal_output.strip()) with catch_stdout() as out: algorithms.GradientDescent((2, 3, 1), verbose=True) terminal_output = out.getvalue() self.assertNotEqual("", terminal_output.strip()) self.assertIn("verbose = True", terminal_output)
def test_nn_init_logging(self): with catch_stdout() as out: gdnet = algorithms.GradientDescent((2, 3, 1), verbose=False) terminal_output = out.getvalue() self.assertEqual("", terminal_output.strip()) with catch_stdout() as out: gdnet = algorithms.GradientDescent((2, 3, 1), verbose=True) terminal_output = out.getvalue() self.assertNotEqual("", terminal_output.strip()) self.assertIn("verbose = True", terminal_output)
def test_basic_storage(self): input_data = np.random.random((100, 2)) target_data = np.random.random(100) > 0.5 pnn = algorithms.PNN(std=0.123, verbose=True) pnn.train(input_data, target_data) stored_pnn = pickle.dumps(pnn) loaded_pnn = pickle.loads(stored_pnn) testcases = [ ('pnn', pnn), ('loaded_pnn', loaded_pnn), ] for name, network in testcases: print("Test case name: {}".format(name)) self.assertAlmostEqual(network.std, 0.123) self.assertAlmostEqual(network.verbose, True) with catch_stdout() as out: network.logs.stdout = out network.logs.write("Test message") terminal_output = out.getvalue() self.assertIn("Test message", terminal_output) pnn_prediction = pnn.predict(input_data) loaded_pnn_prediction = loaded_pnn.predict(input_data) np.testing.assert_array_almost_equal(loaded_pnn_prediction, pnn_prediction)
def test_show_epoch_valid_cases(self): Case = namedtuple("Case", "show_epoch should_be_n_times n_epochs") cases = ( # Show 10 epochs and the last one would be 11 Case(show_epoch='10 times', should_be_n_times=11, n_epochs=100), Case(show_epoch='1 time', should_be_n_times=2, n_epochs=10), Case(show_epoch='1 times', should_be_n_times=2, n_epochs=10), # Should be equal to the number of epochs Case(show_epoch='100 times', should_be_n_times=10, n_epochs=10), Case(show_epoch=5, should_be_n_times=3, n_epochs=10), Case(show_epoch=100, should_be_n_times=2, n_epochs=10), ) for case in cases: with catch_stdout() as out: bpnet = algorithms.GradientDescent( (2, 3, 1), step=0.1, verbose=True, show_epoch=case.show_epoch ) bpnet.train(xor_zero_input_train, xor_zero_target_train, epochs=case.n_epochs) terminal_output = out.getvalue() self.assertEqual(case.should_be_n_times, terminal_output.count(" ms "))
def test_table_drawing(self): table_drawing_result = textwrap.dedent(""" ------------------------------ | Col 1 | Col 2 | Col 3 | ------------------------------ | test | 33.0 | val | | test2 | -3.0 | val 2 | ------------------------------ | Warning message | ------------------------------ | test3 | 0.0 | val 3 | ------------------------------ """).strip() table_drawing = table.TableBuilder( table.Column("Col 1"), table.Column("Col 2", dtype=float), table.Column("Col 3", width=10), ) with catch_stdout() as out: table_drawing.start() table_drawing.row(['test', 33, 'val']) table_drawing.row(['test2', -3, 'val 2']) table_drawing.message("Warning message") table_drawing.row(['test3', 0, 'val 3']) table_drawing.finish() terminal_output = out.getvalue().strip() terminal_output = terminal_output.replace('\r', '') # Use assertTrue to make sure that it won't through # all variables in terminal in case of error self.assertTrue(table_drawing_result == terminal_output)
def test_disabled_logging_table_print(self): with catch_stdout() as out: logs = TerminalLogger(enable=False) logs.table([[1, 2], [3, 4]], headers=['A', 'B']) terminal_output = out.getvalue() self.assertEqual("", terminal_output)
def test_summary_table_delay_limit(self): with catch_stdout() as out: network = algorithms.GradientDescent((3, 2), verbose=True) network.train(simple_input_train, simple_target_train, epochs=20) terminal_output = out.getvalue() self.assertIn("Too many outputs", terminal_output)
def test_show_epoch_valid_cases(self): Case = namedtuple("Case", "show_epoch should_be_n_times n_epochs") cases = ( # Show 10 epochs and the last one would be 11 Case(show_epoch='10 times', should_be_n_times=11, n_epochs=100), Case(show_epoch='1 time', should_be_n_times=2, n_epochs=10), Case(show_epoch='1 times', should_be_n_times=2, n_epochs=10), # Should be equal to the number of epochs Case(show_epoch='100 times', should_be_n_times=10, n_epochs=10), Case(show_epoch=5, should_be_n_times=3, n_epochs=10), Case(show_epoch=100, should_be_n_times=2, n_epochs=10), ) for case in cases: with catch_stdout() as out: bpnet = algorithms.GradientDescent( (2, 3, 1), step=0.1, verbose=True, show_epoch=case.show_epoch ) bpnet.train(xor_zero_input_train, xor_zero_target_train, epochs=case.n_epochs) terminal_output = out.getvalue() # One of the choices has to be true whether other # choices should give count equal to zero. time_counts = ( terminal_output.count(" μs ") + terminal_output.count(" ms ") + terminal_output.count(" ns ") ) self.assertEqual(case.should_be_n_times, time_counts)
def test_logging_methods(self): with catch_stdout() as out: logs = TerminalLogger() Case = namedtuple("Case", "method msg_args expectation") test_cases = (Case(logs.write, msg_args=["Simple text"], expectation="Simple text"), Case( logs.message, msg_args=["TEST", "Message"], expectation=r"\[.*TEST.*\] Message", ), Case( logs.title, msg_args=["Title"], expectation=r"\n.*Title.*\n", ), Case( logs.error, msg_args=["Error message"], expectation=r"\[.*ERROR.*\] Error message", ), Case( logs.warning, msg_args=["Warning message"], expectation=r"\[.*WARN.*\] Warning message", )) for test_case in test_cases: test_case.method(*test_case.msg_args) terminal_output = out.getvalue() self.assertRegexpMatches(terminal_output, test_case.expectation)
def test_discrete_hn_warning(self): with catch_stdout() as out: algorithms.DiscreteHopfieldNetwork(verbose=True, n_times=100, mode='sync') terminal_output = out.getvalue() self.assertIn('only in `async` mode', terminal_output)
def test_progressbar_with_long_update_freq(self): with catch_stdout() as out: iterator = Progressbar(range(10), file=out, update_freq=100) for i in iterator: pass terminal_output = out.getvalue() self.assertIn('0/10', terminal_output)
def test_error_plot_and_validation_error_warnings(self): with catch_stdout() as out: network = algorithms.GradientDescent((2, 3, 1), verbose=True) network.errors = ErrorHistoryList([1, 2]) network.validation_errors = ErrorHistoryList([None]) plots.error_plot(network, ax=None, show=False) terminal_output = out.getvalue() self.assertIn("error will be ignored", terminal_output)
def test_iter_until_converge_critical_cases(self): with catch_stdout() as out: network = algorithms.GradientDescent((2, 3, 1), verbose=True) iterator = iter_until_converge(network, epsilon=1e-5, max_epochs=5) for epoch in iterator: network.errors.append(np.nan) terminal_output = out.getvalue() self.assertIn('NaN or Inf', terminal_output)
def test_nn_training(self): x_train, x_test, y_train, y_test = simple_classification() with catch_stdout() as out: gdnet = algorithms.GradientDescent((10, 20, 1), verbose=True) gdnet.train(x_train, y_train, x_test, y_test, epochs=4) terminal_output = out.getvalue() self.assertIn("Start training", terminal_output) self.assertIn("-----", terminal_output)
def test_logging_switcher(self): class A(Verbose): def callme(self): self.logs.message("TEST", "output") with catch_stdout() as out: a = A(verbose=True) a.callme() terminal_output = out.getvalue() self.assertIn("TEST", terminal_output) self.assertIn("output", terminal_output) a.verbose = False with catch_stdout() as out: a.callme() terminal_output = out.getvalue() self.assertNotIn("TEST", terminal_output) self.assertNotIn("output", terminal_output)
def test_terminal_output_frequency(self): with catch_stdout() as out: data = np.random.random((1000, 2)) target = np.random.random((1000, 1)) bpnet = algorithms.GradientDescent((2, 1, 1), verbose=True, show_epoch=1) bpnet.train(data, target, epochs=100) terminal_output = out.getvalue() self.assertEqual(1, terminal_output.count("Too many outputs"))
def test_parse_show_epoch_property(self): with catch_stdout() as out: network = algorithms.GradientDescent( (2, 3, 1), show_epoch='5 times', verbose=True ) show_epoch = parse_show_epoch_property(network, 100, epsilon=1e-2) self.assertEqual(show_epoch, 1) terminal_output = out.getvalue() self.assertIn("Can't use", terminal_output)
def test_show_network_options_function(self): with catch_stdout() as out: # Disable verbose and than enable it again just # to make sure that `show_network_options` won't # trigger in the __init__ method network = algorithms.GradientDescent((2, 3, 1), verbose=False) network.verbose = True show_network_options(network) terminal_output = out.getvalue() self.assertIn('step', terminal_output)
def test_simple_progressbar(self): with catch_stdout() as out: iterator = progressbar(range(10), mininterval=0., file=sys.stdout) for i in iterator: time.sleep(0.1) terminal_output = out.getvalue() self.assertRegexpMatches( terminal_output, '\|{}{}\|\s{}/10\s+{}\%.+'.format('#' * i, '-' * (10 - i), i, i * 10))
def test_terminal_output_frequency(self): with catch_stdout() as out: data = np.random.random((1000, 2)) target = np.random.random((1000, 1)) bpnet = algorithms.GradientDescent( (2, 1, 1), verbose=True, show_epoch=1 ) bpnet.train(data, target, epochs=100) terminal_output = out.getvalue() self.assertEqual(1, terminal_output.count("Too many outputs"))
def test_show_network_options_function(self): # Suppose not to fail with catch_stdout() as out: # Disable verbose and than enable it again just # to make sure that `show_network_options` won't # trigger in the __init__ method network = algorithms.GradientDescent((2, 3, 1), verbose=False) network.verbose = True show_network_options(network) terminal_output = out.getvalue() self.assertIn('step', terminal_output)
def test_drawing_state_raises(self): table_drawing = table.TableBuilder( table.Column("Col 1"), table.Column("Col 2"), ) with catch_stdout(): table_drawing.start() with self.assertRaises(table.TableDrawingError): table_drawing.start() with self.assertRaises(table.TableDrawingError): table_drawing.header()
def test_drawing_state_raises(self): table_drawing = table.TableDrawer( table.Column("Col 1"), table.Column("Col 2"), ) with catch_stdout(): table_drawing.start() with self.assertRaises(table.TableDrawingError): table_drawing.start() with self.assertRaises(table.TableDrawingError): table_drawing.header()
def test_network_training_summary_inline(self): with catch_stdout() as out: network = algorithms.GradientDescent((2, 3, 1), verbose=False) x = np.zeros((5, 2)) y = np.zeros((5, 1)) network.verbose = True n_epochs = 10 network.train(x, y, summary='inline', epochs=n_epochs) terminal_output = out.getvalue().strip() # `n_epochs - 1` becuase \n appears only between # inline summary lines self.assertEqual(terminal_output.count('\n'), n_epochs - 1)
def test_network_training_summary_inline(self): with catch_stdout() as out: network = algorithms.GradientDescent((2, 3, 1), verbose=False) x = np.zeros((5, 2)) y = np.zeros((5, 1)) network.verbose = True n_epochs = 10 network.train(x, y, summary='inline', epochs=n_epochs) terminal_output = out.getvalue().strip() # `n_epochs - 1` because \n appears only between # inline summary lines. # Also network prints 5 additional lines at the beggining self.assertEqual(terminal_output.count('\n'), 5 + n_epochs - 1)
def test_logging_info_about_the_data(self): network = algorithms.GradientDescent((2, 3, 1)) x = np.zeros((5, 2)) x_test = np.zeros((3, 2)) y = np.zeros((4, 1)) with self.assertRaisesRegexp(ValueError, "feature shape"): logging_info_about_the_data(network, x, y) with catch_stdout() as out: network = algorithms.GradientDescent((2, 3, 1), verbose=True) logging_info_about_the_data(network, [x, x], [x_test, x_test]) terminal_output = out.getvalue() self.assertIn("[(5, 2), (5, 2)]", terminal_output) self.assertIn("[(3, 2), (3, 2)]", terminal_output)
def test_nn_training(self): x_train, x_test, y_train, y_test = simple_classification() with catch_stdout() as out: gdnet = algorithms.GradientDescent( (10, 20, 1), verbose=True, batch_size='all', ) gdnet.train(x_train, y_train, x_test, y_test, epochs=4) y_predicted = gdnet.predict(x_test) terminal_output = out.getvalue() self.assertIn("Start training", terminal_output) self.assertIn("------", terminal_output) self.assertEqual(y_predicted.size, y_test.size)
def test_gd_apply_batches(self): def function(x): time.sleep(0.02) print() return 12345 with catch_stdout() as out: apply_batches(function=function, arguments=[np.ones(100)], batch_size=10, logger=TerminalLogger(), show_progressbar=True, show_error_output=True) terminal_output = out.getvalue() self.assertIn('12345', terminal_output) self.assertIn('error', terminal_output)
def test_simple_progressbar(self): with catch_stdout() as out: iterator = progressbar( range(10), mininterval=0., file=sys.stdout ) for i in iterator: time.sleep(0.1) terminal_output = out.getvalue() self.assertRegexpMatches( terminal_output, '\|{}{}\|\s{}/10\s+{}\%.+'.format( '#' * i, '-' * (10 - i), i, i * 10 ) )
def test_gd_apply_batches(self): def function(x): time.sleep(0.02) print() return 12345 with catch_stdout() as out: apply_batches( function=function, arguments=[np.ones(100)], batch_size=10, logger=TerminalLogger(), show_progressbar=True, show_error_output=True ) terminal_output = out.getvalue() self.assertIn('12345', terminal_output) self.assertIn('error', terminal_output)
def test_network_architecture_output(self): expected_architecture = textwrap.dedent(""" ----------------------------------------------- | # | Input shape | Layer Type | Output shape | ----------------------------------------------- | 1 | 2 | Input | 2 | | 2 | 2 | Sigmoid | 3 | | 3 | 3 | Sigmoid | 1 | ----------------------------------------------- """).strip() with catch_stdout() as out: network = algorithms.GradientDescent((2, 3, 1), verbose=True) network.architecture() terminal_output = out.getvalue().replace('\r', '') # Use assertTrue to make sure that it won't through # all variables in terminal in case of error self.assertTrue(expected_architecture in terminal_output)
def test_network_architecture_output(self): expected_architecture = textwrap.dedent(""" ╭───┬─────────────┬────────────┬──────────────╮ │ # │ Input shape │ Layer type │ Output shape │ ├───┼─────────────┼────────────┼──────────────┤ │ 1 │ 2 │ Input │ 2 │ │ 2 │ 2 │ Sigmoid │ 3 │ │ 3 │ 3 │ Sigmoid │ 1 │ ╰───┴─────────────┴────────────┴──────────────╯ """).strip() with catch_stdout() as out: network = algorithms.GradientDescent((2, 3, 1), verbose=True) network.architecture() terminal_output = out.getvalue().replace('\r', '') # Use assertTrue to make sure that it won't through # all variables in terminal in case of error self.assertIn(expected_architecture, terminal_output)
def test_network_architecture_output(self): expected_architecture = textwrap.dedent(""" ----------------------------------------------- | # | Input shape | Layer type | Output shape | ----------------------------------------------- | 1 | 2 | Input | 2 | | 2 | 2 | Sigmoid | 3 | | 3 | 3 | Sigmoid | 1 | ----------------------------------------------- """).strip() with catch_stdout() as out: network = algorithms.GradientDescent((2, 3, 1), verbose=True) network.architecture() terminal_output = out.getvalue().replace('\r', '') # Use assertTrue to make sure that it won't through # all variables in terminal in case of error self.assertIn(expected_architecture, terminal_output)
def test_table_drawing(self): table_drawing = table.TableBuilder( table.Column("Col 1"), table.Column("Col 2", dtype=float), table.Column("Col 3", width=10), ) with catch_stdout() as out: table_drawing.start() table_drawing.row(['test', 33, 'val']) table_drawing.row(['test2', -3, 'val 2']) table_drawing.message("Warning message") table_drawing.row(['test3', 0, 'val 3']) table_drawing.finish() terminal_output = out.getvalue().strip() self.assertEqual(table_drawing_result, terminal_output.replace('\r', ''))
def test_summary_table_slow_training(self): with catch_stdout() as out: network = algorithms.GradientDescent((2, 3, 1), verbose=True) summary = SummaryTable(network, table_builder=table.TableBuilder( table.Column(name="Epoch #"), table.NumberColumn(name="Train err", places=4), table.NumberColumn(name="Valid err", places=4), table.TimeColumn(name="Time", width=10), stdout=network.logs.write), delay_limit=0, delay_history_length=1) for _ in range(3): network.training.epoch_time = 0.1 summary.show_last() terminal_output = out.getvalue() self.assertNotIn("Too many outputs", terminal_output)
def test_summary_table_slow_training(self): with catch_stdout() as out: network = algorithms.GradientDescent((2, 3, 1), verbose=True) summary = SummaryTable( network, table_builder=table.TableBuilder( table.Column(name="Epoch #"), table.NumberColumn(name="Train err", places=4), table.NumberColumn(name="Valid err", places=4), table.TimeColumn(name="Time", width=10), stdout=network.logs.write ), delay_limit=0, delay_history_length=1 ) for _ in range(3): network.training.epoch_time = 0.1 summary.show_last() terminal_output = out.getvalue() self.assertNotIn("Too many outputs", terminal_output)
def test_table_drawing(self): table_drawing = table.TableDrawer( table.Column("Col 1"), table.Column("Col 2", dtype=float), table.Column("Col 3", width=10), ) with catch_stdout() as out: table_drawing.start() table_drawing.row(['test', 33, 'val']) table_drawing.row(['test2', -3, 'val 2']) table_drawing.line() table_drawing.message("Warning message") table_drawing.line() table_drawing.row(['test3', 0, 'val 3']) table_drawing.finish() terminal_output = out.getvalue().strip() self.assertEqual(table_drawing_result, terminal_output.replace('\r', ''))
def test_logging_methods(self): with catch_stdout() as out: logs = TerminalLogger() Case = namedtuple("Case", "method msg_args expectation") test_cases = ( Case( logs.write, msg_args=["Simple text"], expectation="Simple text" ), Case( logs.message, msg_args=["TEST", "Message"], expectation=r"\[.*TEST.*\] Message", ), Case( logs.title, msg_args=["Title"], expectation=r"\n.*Title.*\n", ), Case( logs.error, msg_args=["Error message"], expectation=r"\[.*ERROR.*\] Error message", ), Case( logs.warning, msg_args=["Warning message"], expectation=r"\[.*WARN.*\] Warning message", ) ) for test_case in test_cases: test_case.method(*test_case.msg_args) terminal_output = out.getvalue() self.assertRegexpMatches(terminal_output, test_case.expectation)
def test_inline_summary_with_validation(self): with catch_stdout() as out: network = algorithms.GradientDescent((2, 3, 1), verbose=True) summary = InlineSummary(network) network.last_epoch = 12 network.training.epoch_time = 0.1 network.errors.append(10) network.validation_errors.append(20) summary.show_last() summary.finish() terminal_output = out.getvalue() # training error is 10 self.assertIn("10", terminal_output) # validation error is 20 self.assertIn("20", terminal_output) # 0.1 sec self.assertIn("0.1", terminal_output) # 12th epoch self.assertIn("12", terminal_output)
def test_inline_summary_without_validation(self): with catch_stdout() as out: network = algorithms.GradientDescent((2, 3, 1), verbose=True) summary = InlineSummary(network) network.last_epoch = 12 network.training.epoch_time = 0.1 network.errors.append(10) network.validation_errors.append(None) summary.show_last() terminal_output = out.getvalue() # training error is 10 self.assertIn("10", terminal_output) # 0.1 sec self.assertIn("0.1", terminal_output) # 12th epoch self.assertIn("12", terminal_output) # No reference to validation error in the last line output_lines = terminal_output.split('\n') last_output_line = output_lines[-2] self.assertNotIn("None", last_output_line)
def test_discrete_hn_warning(self): with catch_stdout() as out: algorithms.DiscreteHopfieldNetwork(verbose=True, n_times=100, mode="sync") terminal_output = out.getvalue() self.assertIn("only in `async` mode", terminal_output)