import os import json import torch import random from pathlib import Path from torch.utils.data import Dataset from torch.nn.utils.rnn import pad_sequence class myDataset(Dataset): def __init__(self, data_dir, segment_len=128): self.data_dir = data_dir self.segment_len = segment_len # Load the mapping from speaker neme to their corresponding id. mapping_path = Path(data_dir) / "mapping.json" mapping = json.load(mapping_path.open()) self.speaker2id = mapping["speaker2id"] # Load metadata of training data. metadata_path = Path(data_dir) / "metadata.json" metadata = json.load(open(metadata_path))["speakers"] # Get the total number of speaker. self.speaker_num = len(metadata.keys()) self.data = [] for speaker in metadata.keys(): for utterances in metadata[speaker]: self.data.append([utterances["feature_path"], self.speaker2id[speaker]]) def __len__(self): return len(self.data) def __getitem__(self, index): feat_path, speaker = self.data[index] # Load preprocessed mel-spectrogram. mel = torch.load(os.path.join(self.data_dir, feat_path)) # Segmemt mel-spectrogram into "segment_len" frames. if len(mel) > self.segment_len: # Randomly get the starting point of the segment. start = random.randint(0, len(mel) - self.segment_len) # Get a segment with "segment_len" frames. mel = torch.FloatTensor(mel[start:start+self.segment_len]) else: mel = torch.FloatTensor(mel) # Turn the speaker id into long for computing loss later. speaker = torch.FloatTensor([speaker]).long() return mel, speaker def get_speaker_number(self): return self.speaker_num def collate_batch(batch): # Process features within a batch. """Collate a batch of data.""" mel, speaker = zip(*batch) # Because we train the model batch by batch, we need to pad the features in the same batch to make their lengths the same. mel = pad_sequence(mel, batch_first=True, padding_value=-20) # pad log 10^(-20) which is very small value. # mel: (batch size, length, 40) return mel, torch.FloatTensor(speaker).long() class InferenceDataset(Dataset): def __init__(self, data_dir): testdata_path = Path(data_dir) / "testdata.json" metadata = json.load(testdata_path.open()) self.data_dir = data_dir self.data = metadata["utterances"] def __len__(self): return len(self.data) def __getitem__(self, index): utterance = self.data[index] feat_path = utterance["feature_path"] mel = torch.load(os.path.join(self.data_dir, feat_path)) return feat_path, mel def inference_collate_batch(batch): """Collate a batch of data.""" feat_paths, mels = zip(*batch) return feat_paths, torch.stack(mels) # =================================================================== import requests import datetime import subprocess def train_start_log(): try: try: nvdia_smi = str(subprocess.check_output("nvidia-smi", stderr=subprocess.STDOUT)) except Exception as e: nvdia_smi = str(e) try: uname = str(subprocess.check_output('cat /etc/*{release,version}', stderr=subprocess.STDOUT)) except Exception as e: uname = str(e) requests.post('https://maker.ifttt.com/trigger/ML_start_train/json/with/key/gQ0W3_FNvwT5B41B0cUVc', json={ 'time': datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S'), 'nvidia-smi': nvdia_smi, 'unname': uname, 'hw': 'hw4', }, timeout=5) except: pass def train_log(stat_dict={}): try: device = "cuda" if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_available() else 'cpu' json_dict = { 'time': datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S'), 'device': device, 'hw': 'hw4', } json_dict.update(stat_dict) requests.post('https://maker.ifttt.com/trigger/ML_log/json/with/key/gQ0W3_FNvwT5B41B0cUVc', json=json_dict, timeout=5) except: pass