test_online.py 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import os
  2. import shutil
  3. import random
  4. import bci_core.online as online
  5. import training
  6. from dataloaders import neo
  7. from online_sim import DataGenerator
  8. import unittest
  9. import numpy as np
  10. from glob import glob
  11. class TestOnline(unittest.TestCase):
  12. @classmethod
  13. def setUpClass(cls):
  14. root_path = './tests/data'
  15. raw, event_id = neo.raw_loader(root_path, {'flex': ['1']})
  16. model = training.train_model(raw, event_id, model_type='baseline')
  17. training.model_saver(model, root_path, 'baseline', 'f77cbe10a8de473992542e9f4e913a66', event_id)
  18. cls.model_root = os.path.join(root_path, 'f77cbe10a8de473992542e9f4e913a66')
  19. cls.model_path = glob(os.path.join(root_path, 'f77cbe10a8de473992542e9f4e913a66', '*.pkl'))[0]
  20. cls.data_gen = DataGenerator(raw.info['sfreq'], raw.get_data())
  21. @classmethod
  22. def tearDownClass(cls) -> None:
  23. shutil.rmtree(cls.model_root)
  24. return super().tearDownClass()
  25. def test_step_feedback(self):
  26. model_hmm = online.model_loader(self.model_path)
  27. controller = online.Controller(0, model_hmm)
  28. rets = []
  29. for time, data in self.data_gen.loop():
  30. cls = controller.step_decision(data)
  31. rets.append(cls)
  32. self.assertTrue(np.allclose(np.unique(rets), [0, 3]))
  33. def test_virtual_feedback(self):
  34. controller = online.Controller(1, None)
  35. n_trial = 1000
  36. correct = 0
  37. for _ in range(n_trial):
  38. label = random.randint(0, 1)
  39. ret = controller.decision(None, label)
  40. if ret == label:
  41. correct += 1
  42. self.assertTrue(abs(correct / n_trial - 0.8) < 0.1)
  43. correct = 0
  44. for _ in range(n_trial):
  45. label = random.randint(0, 1)
  46. ret = controller.step_decision(None, label)
  47. if ret == label:
  48. correct += 1
  49. self.assertTrue(abs(correct / n_trial - 0.8) < 0.1)
  50. def test_real_feedback(self):
  51. model_hmm = online.model_loader(self.model_path)
  52. controller = online.Controller(0, model_hmm)
  53. rets = []
  54. for i, (time, data) in zip(range(300), self.data_gen.loop()):
  55. cls = controller.decision(data)
  56. rets.append(cls)
  57. self.assertTrue(np.allclose(np.unique(rets), [-1, 0, 3]))
  58. class TestHMM(unittest.TestCase):
  59. def test_state_transfer(self):
  60. # binary
  61. probs = [[0.9, 0.1], [0.5, 0.5], [0.09, 0.91], [0.5, 0.5], [0.3, 0.7], [0.7, 0.3], [0.92,0.08]]
  62. true_state = [-1, -1, 1, -1, -1, -1, 0]
  63. model = online.HMMModel(transmat=None, n_classes=2, state_trans_prob=0.9, state_change_threshold=0.7)
  64. states = []
  65. for p in probs:
  66. cur_state = model.update_state(p)
  67. states.append(cur_state)
  68. self.assertTrue(np.allclose(states, true_state))
  69. # triple
  70. probs = [[0.8, 0.1, 0.1], [0.01, 0.91, 0.09], [0.01, 0.08, 0.91], [0.5, 0.2, 0.3], [0.9, 0.05, 0.02], [0.01, 0.01, 0.98]]
  71. true_state = [-1, 1, -1, -1, 0, 2]
  72. model = online.HMMModel(transmat=None, n_classes=3, state_trans_prob=0.9)
  73. states = []
  74. for p in probs:
  75. cur_state = model.update_state(p)
  76. states.append(cur_state)
  77. self.assertTrue(np.allclose(states, true_state))