in tools/utilities/pythonlibs/audio/training/train_classifier.py [0:0]
def train(config, evaluate_only=False, outdir=".", detail=False, azureml=False):
filename = config.model.filename
categories_file = config.dataset.categories
wav_directory = config.dataset.path
batch_size = config.training.batch_size
hidden_units = config.model.hidden_units
architecture = config.model.architecture
num_layers = config.model.num_layers
use_gpu = config.training.use_gpu
run = None
if azureml:
from azureml.core.run import Run
run = Run.get_context()
if run is None:
print("### Run.get_context() returned None")
else:
print("### Running in Azure Context")
valid_layers = [1, 2, 3]
if num_layers not in valid_layers:
raise Exception("--num_layers can only be one of these values {}".format(valid_layers))
if not os.path.isdir(outdir):
os.makedirs(outdir)
if not filename:
filename = "{}{}KeywordSpotter.pt".format(architecture, hidden_units)
config.model.filename = filename
# load the featurized data
if not os.path.isdir(wav_directory):
print("### Error: please specify valid --dataset folder location: {}".format(wav_directory))
sys.exit(1)
if not categories_file:
categories_file = os.path.join(wav_directory, "categories.txt")
with open(categories_file, "r") as f:
keywords = [x.strip() for x in f.readlines()]
training_file = os.path.join(wav_directory, "training_list.npz")
testing_file = os.path.join(wav_directory, "testing_list.npz")
validation_file = os.path.join(wav_directory, "validation_list.npz")
if not os.path.isfile(training_file):
print("Missing file {}".format(training_file))
print("Please run make_datasets.py")
sys.exit(1)
if not os.path.isfile(validation_file):
print("Missing file {}".format(validation_file))
print("Please run make_datasets.py")
sys.exit(1)
if not os.path.isfile(testing_file):
print("Missing file {}".format(testing_file))
print("Please run make_datasets.py")
sys.exit(1)
model = None
device = torch.device("cpu")
if use_gpu:
if torch.cuda.is_available():
device = torch.device("cuda")
else:
print("### CUDA not available!!")
print("Loading {}...".format(testing_file))
test_data = AudioDataset(testing_file, config.dataset, keywords)
log = None
if not evaluate_only:
print("Loading {}...".format(training_file))
training_data = AudioDataset(training_file, config.dataset, keywords)
print("Loading {}...".format(validation_file))
validation_data = AudioDataset(validation_file, config.dataset, keywords)
if training_data.mean is not None:
fname = os.path.join(outdir, "mean.npy")
print("Saving {}".format(fname))
np.save(fname, training_data.mean)
fname = os.path.join(outdir, "std.npy")
print("Saving {}".format(fname))
np.save(fname, training_data.std)
# use the training_data mean and std variation
test_data.mean = training_data.mean
test_data.std = training_data.std
validation_data.mean = training_data.mean
validation_data.std = training_data.std
print("Training model {}".format(filename))
model = create_model(config.model, training_data.input_size, training_data.num_keywords)
if device.type == 'cuda':
model.cuda() # move the processing to GPU
start = time.time()
log = model.fit(training_data, validation_data, config.training, config.model, device, detail, run)
end = time.time()
passed, total, rate = model.evaluate(training_data, batch_size, device)
print("Training accuracy = {:.3f} %".format(rate * 100))
torch.save(model.state_dict(), os.path.join(outdir, filename))
print("Evaluating {} keyword spotter using {} rows of featurized test audio...".format(
architecture, test_data.num_rows))
if model is None:
msg = "Loading trained model with input size {}, hidden units {} and num keywords {}"
print(msg.format(test_data.input_size, hidden_units, test_data.num_keywords))
model = create_model(config.model, test_data.input_size, test_data.num_keywords)
model.load_dict(torch.load(filename))
if model and device.type == 'cuda':
model.cuda() # move the processing to GPU
results_file = os.path.join(outdir, "results.txt")
passed, total, rate = model.evaluate(test_data, batch_size, device, results_file)
print("Testing accuracy = {:.3f} %".format(rate * 100))
if not evaluate_only:
name = os.path.splitext(filename)[0] + ".onnx"
print("saving onnx file: {}".format(name))
model.export(os.path.join(outdir, name), device)
config.dataset.sample_rate = test_data.sample_rate
config.dataset.input_size = test_data.audio_size
config.dataset.num_filters = test_data.input_size
config.dataset.window_size = test_data.window_size
config.dataset.shift = test_data.shift
logdata = {
"accuracy_val": rate,
"training_time": end - start,
"log": log
}
d = TrainingConfig.to_dict(config)
logdata.update(d)
logname = os.path.join(outdir, "train_results.json")
save_json(logdata, logname)
return rate, log