pytorch_adv_trainer.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import os
  2. import time
  3. import json
  4. import torch
  5. import torch.optim as optim
  6. from torch.utils.data import DataLoader
  7. from utils.training_interface import TrainerInterface
  8. from utils.file_utils import list_files_in_directory
  9. from utils.pytorch_utils import WakeWordDataset, CNNNetwork, preprocess_training_data, train_model, optimize_graph
  10. # Global variables for tracking progress
  11. current_progress = 0
  12. current_loss = 0.0
  13. current_accuracy = 0.0
  14. total_epochs = 0
  15. total_batches = 0
  16. class pytorch_adv_trainer(TrainerInterface):
  17. def __init__(self, learning_rate=0.001):
  18. self.model_path = None
  19. self.training_directories = []
  20. self.sample_directory = None
  21. self.background_directory = None
  22. self.dropout_rate = 0.5
  23. self.epochs = 10
  24. self.batch_size = 32
  25. self.learning_rate = learning_rate
  26. self.model = None
  27. self.optimizer = None
  28. self.criterion = torch.nn.BCEWithLogitsLoss()
  29. self.current_epoch = 0
  30. self.stop_training = False
  31. self.training_status = "Not started"
  32. self.train_loader = None
  33. self.val_loader = None
  34. def set_model_path(self, model_path):
  35. self.model_path = model_path
  36. self.model = self.load_model()
  37. self.optimizer = optim.Adam(self.model.parameters(), lr=self.learning_rate)
  38. def set_training_directories(self, directories):
  39. self.training_directories = directories
  40. def set_sample_directory(self, directory):
  41. self.sample_directory = directory
  42. def set_background_directory(self, directory):
  43. self.background_directory = directory
  44. def set_dropout_rate(self, rate):
  45. self.dropout_rate = rate
  46. def set_epochs(self, epochs):
  47. self.epochs = epochs
  48. def set_batch_size(self, batch_size):
  49. self.batch_size = batch_size
  50. def get_training_data(self):
  51. return self.training_directories
  52. def get_model_path(self):
  53. return self.model_path
  54. def get_epochs(self):
  55. return self.epochs
  56. def get_batch_size(self):
  57. return self.batch_size
  58. def get_dropout_rate(self):
  59. return self.dropout_rate
  60. def get_training_directories(self):
  61. return self.training_directories
  62. def get_sample_directory(self):
  63. return self.sample_directory
  64. def get_background_directory(self):
  65. return self.background_directory
  66. def set_training_data(self, features, labels):
  67. X_train, X_val, y_train, y_val = train_test_split(features, labels, test_size=0.2, random_state=42)
  68. self.train_loader = DataLoader(WakeWordDataset(X_train, y_train), batch_size=self.batch_size, shuffle=True)
  69. self.val_loader = DataLoader(WakeWordDataset(X_val, y_val), batch_size=self.batch_size, shuffle=False)
  70. def load_model(self):
  71. model = CNNNetwork()
  72. if os.path.exists(self.model_path + "hotword_model.pth"):
  73. model.load_state_dict(torch.load(self.model_path + "hotword_model.pth"))
  74. return model
  75. def start(self):
  76. self.training_status = "Training"
  77. self.stop_training = False
  78. self.run_training()
  79. def start_new(self):
  80. self.training_status = "Training"
  81. self.stop_training = False
  82. self.model = self.load_model()
  83. self.current_epoch = 0
  84. self.run_training()
  85. def pause(self):
  86. self.training_status = "Paused"
  87. self.stop_training = True
  88. def resume(self):
  89. self.training_status = "Training"
  90. self.stop_training = False
  91. self.run_training()
  92. def stop(self):
  93. self.training_status = "Stopped"
  94. self.stop_training = True
  95. def preprocess_training_data(self, update_progress_callback):
  96. preprocess_training_data(self.training_directories, self.background_directory, self.model_path, update_progress_callback)
  97. def run_training(self):
  98. global current_progress, current_loss, current_accuracy, total_epochs, total_batches
  99. self.preprocess_training_data(lambda progress: setattr(self, 'current_progress', progress))
  100. df = pd.read_pickle(self.model_path + "audio_data.csv")
  101. X = df["feature"].values
  102. X = np.concatenate(X, axis=0).reshape(len(X), 40)
  103. y = np.array(df["class_label"].tolist())
  104. self.set_training_data(X, y)
  105. total_batches = int(np.ceil(len(self.train_loader.dataset) / self.batch_size))
  106. total_epochs = self.epochs
  107. for epoch in range(self.current_epoch, self.epochs):
  108. if self.stop_training:
  109. break
  110. self.current_epoch = epoch
  111. train_model(self.model, self.train_loader, self.optimizer, self.criterion, epoch, self.epochs)
  112. current_progress = (epoch + 1) / self.epochs * 100
  113. print(f"Epoch {epoch + 1}/{self.epochs}")
  114. if not self.stop_training:
  115. torch.save(self.model.state_dict(), self.model_path + "hotword_model.pth")
  116. self.evaluate_model(X, y)
  117. self.training_status = "Finished"
  118. def evaluate_model(self, X_test, y_test):
  119. self.model.eval()
  120. with torch.no_grad():
  121. X_test_tensor = torch.FloatTensor(X_test)
  122. y_test_tensor = torch.LongTensor(y_test)
  123. outputs = self.model(X_test_tensor)
  124. _, predicted = torch.max(outputs, 1)
  125. accuracy = (predicted == y_test_tensor).sum().item() / len(y_test_tensor)
  126. print(f"Test Accuracy: {accuracy * 100:.2f}%")
  127. def get_training_info(self):
  128. return {
  129. "status": self.training_status,
  130. "current_epoch": self.current_epoch,
  131. "total_epochs": self.epochs,
  132. "loss": current_loss,
  133. "accuracy": current_accuracy
  134. }