[U] Backup unfinished changes

This commit is contained in:
Azalea (on HyDEV-Daisy)
2022-10-01 13:41:07 -04:00
parent b452d77cac
commit c39ce766af
5 changed files with 255 additions and 37 deletions
+2
View File
@@ -8,6 +8,8 @@ if __name__ == '__main__':
with open(r'C:\Datasets\CN-Celeb_flac\ina_pf_map.json', 'r', encoding='UTF-8') as f: with open(r'C:\Datasets\CN-Celeb_flac\ina_pf_map.json', 'r', encoding='UTF-8') as f:
pf = json.load(f) pf = json.load(f)
print(len(labels))
correct_f = [] correct_f = []
correct_m = [] correct_m = []
incorrect_f = [] incorrect_f = []
+47 -2
View File
@@ -38,8 +38,53 @@ class Result(NamedTuple):
file: str file: str
def segment(file) -> list[ResultFrame]: class BatchResults(NamedTuple):
return [ResultFrame(*s) for s in seg(file)] results: list[Result]
time_full: float
time_avg: float
successes: int
messages: list[tuple[str, int]]
def _process_helper(args: tuple[Segmenter, str]) -> Result:
seg, f = args
lseg = seg(f)
return Result([ResultFrame(*s) for s in lseg], f)
def process(self: Segmenter, inp: list[str], tmpdir=None, verbose=False, skip_if_exist=False,
nbtry=1, try_delay=2.) -> list[Result]:
from tqdm.contrib.concurrent import process_map
import tqdm
results = []
for i in tqdm.tqdm(inp):
results.append(_process_helper((self, i)))
return results
# return process_map(_process_helper, [(self, i) for i in inp], max_workers=2)
#
# t_batch_start = time.time()
#
# results: list[Result] = []
# lmsg = []
# fg = featGenerator(inp.copy(), inp.copy(), tmpdir, self.ffmpeg, skip_if_exist, nbtry, try_delay)
# i = 0
# for feats, msg in fg:
# lmsg += msg
# i += len(msg)
# if verbose:
# print('%d/%d' % (i, len(inp)), msg)
# if feats is None:
# break
# mspec, loge, diff_len = feats
# lseg = self.segment_feats(mspec, loge, diff_len, 0)
# results.append()
#
# t_batch_dur = time.time() - t_batch_start
# nb_processed = len([e for e in lmsg if e[1] == 0])
# avg = t_batch_dur / nb_processed if nb_processed else -1
# return BatchResults(results, t_batch_dur, avg, nb_processed, lmsg)
def to_wav(file: str, callback: Callable, start_sec: float = 0, stop_sec: float = 0): def to_wav(file: str, callback: Callable, start_sec: float = 0, stop_sec: float = 0):
+72
View File
@@ -0,0 +1,72 @@
import librosa
import librosa.display
import matplotlib.pyplot as plt
import numpy as np
import parselmouth
import sgs
if __name__ == '__main__':
librosa.filters.mel(sr=16000, n_fft=1024, htk=True)
f = 'Z:/EECS 6414/voice_cnn/test.wav'
y, sr = librosa.load(f, sr=16000)
# Plot waveform
# plt.plot(y)
# plt.title('Signal')
# plt.xlabel('Time (samples)')
# plt.ylabel('Amplitude')
# plt.show()
# plt.clf()
# Plot frequency domain graph at a single time
n_fft = 2048
ft = np.abs(librosa.stft(y[:n_fft], hop_length=n_fft + 1))
# plt.plot(ft)
# plt.title('Spectrum')
# plt.xlabel('Frequency Bin')
# plt.ylabel('Amplitude')
# plt.show()
# plt.clf()
# Plot spectrogram
spec = np.abs(librosa.stft(y, n_fft=1024, hop_length=512))
# spec = librosa.amplitude_to_db(spec, ref=np.max)
# librosa.display.specshow(spec, sr=sr, x_axis='time', y_axis='log')
# plt.colorbar(format='%+2.0f dB')
# plt.title('Spectrogram')
# plt.show()
# plt.clf()
# Mel transform
mel_spect = librosa.feature.melspectrogram(y=y, sr=sr, n_fft=2048, hop_length=512, htk=True)
mel_spect = librosa.power_to_db(mel_spect, ref=np.max)
print(len(mel_spect))
librosa.display.specshow(mel_spect, y_axis='mel', fmax=8000, x_axis='time', n_fft=1024, hop_length=512)
result, freq_array = sgs.api.calculate_feature_classification(parselmouth.Sound(f))
pitch_array = freq_array[:, 0]
# x_len = len(pitch_array) / len(mel_spect)
# x = np.arange(len(mel_spect))
# y = []
# for x in range(len(mel_spect) // 2):
# y.append(float(np.mean(pitch_array[int(x_len * x):int(x_len * (x + 1))])))
# print(len(y))
x = np.linspace(0, 4.1)
print(x)
x_len = len(pitch_array) / len(x)
y = []
for a in range(len(x)):
y.append(np.mean(pitch_array[int(x_len * a):int(x_len * (a + 1))]))
plt.plot(x, y, color='#7bff4f')
plt.plot(x, [100] * len(x), color='#7bff4f')
plt.yticks([0,100,200,300,400,500,600,700,800,900,1000,1200,1400,1600])
plt.title('Mel Spectrogram')
plt.colorbar(format='%+2.0f dB')
plt.show()
plt.clf()
+56 -35
View File
@@ -1,69 +1,81 @@
import json import json
import os import os
# os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import warnings import warnings
from pathlib import Path from pathlib import Path
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
import pygame import tensorflow as tf
from inaSpeechSegmenter import Segmenter from inaSpeechSegmenter import Segmenter
from ina_main import process, get_result_percentages from ina_main import process, get_result_percentages
from utils import color, printc from utils import color, printc
gpu_devices = tf.config.experimental.list_physical_devices('GPU')
for device in gpu_devices:
tf.config.experimental.set_memory_growth(device, True)
def segment_all(): def segment_all():
# Create segmenter # Create segmenter
seg = Segmenter() seg = Segmenter()
np.seterr(invalid='ignore') np.seterr(invalid='ignore')
# Loop through all celebrities # Loop through all celebrities
for id in ids: for id in ids[559:]:
id_dir = data_dir.joinpath(id) id_dir = data_dir / id
if (id_dir / 'total.json').is_file():
continue
# Loop through all recordings (Exclude singing for now) # Loop through all recordings (Exclude singing for now)
utters = [r for r in os.listdir(id_dir) if r.endswith('.flac') utters = audio_files[id]
and not r.startswith('singing')]
# Exclude existing # Exclude existing
utters = [id_dir.joinpath(u) for u in utters] utters = [id_dir.joinpath(u) for u in utters if u.endswith('.wav')]
utters = [u for u in utters if not u.with_suffix('.json').exists()] # utters = [u for u in utters if not u.with_suffix('.json').exists()]
if len(utters) == 0: if len(utters) == 0:
continue continue
# Analyze # Analyze
print(f'Processing {id}')
results = process(seg, [str(u) for u in utters], verbose=True) results = process(seg, [str(u) for u in utters], verbose=True)
# Write results # Write results
total = [0, 0, 0, 0, 0] # total = [0, 0, 0, 0, 0]
type_totals = {} # type_totals = {}
for result in results.results: total = []
for result in results:
file = Path(result.file).with_suffix('.json') file = Path(result.file).with_suffix('.json')
# Get results # Get results
# f: Frames, r: Ratios # f: Frames, r: Ratios
ratios = [round(r, 3) for r in get_result_percentages(result)] _, _, _, pf = get_result_percentages(result)
stored = {'f': result.frames, 'r': ratios} total.append(pf)
# Count type total (type_totals[utter_type][-1] is the count) # Count type total (type_totals[utter_type][-1] is the count)
file_name = file.name # file_name = file.name
utter_type = file_name[:file_name.index('-')] # utter_type = file_name[:file_name.index('-')]
type_totals.setdefault(utter_type, [0, 0, 0, 0, 0]) # type_totals.setdefault(utter_type, [0, 0, 0, 0, 0])
for i in range(4): # for i in range(4):
type_totals[utter_type][i] += ratios[i] # type_totals[utter_type][i] += ratios[i]
total[i] += ratios[i] # total[i] += ratios[i]
type_totals[utter_type][-1] += 1 # type_totals[utter_type][-1] += 1
total[-1] += 1 # total[-1] += 1
# Write result # Write result
file.write_text(json.dumps(stored)) # file.write_text(json.dumps(ratios))
# Write type averages # Write type averages
type_averages = {t: [r / type_totals[t][-1] for r in type_totals[t][:-1]] for t in type_totals} # type_averages = {t: [r / type_totals[t][-1] for r in type_totals[t][:-1]] for t in type_totals}
total_average = [r / total[-1] for r in total[:-1]] # total_average = [r / total[-1] for r in total[:-1]]
obj = {'type_averages': type_averages, 'total_averages': total_average} # obj = {'type_averages': type_averages, 'total_averages': total_average}
id_dir.joinpath('total.json').write_text(json.dumps(obj)) # id_dir.joinpath('total.json').write_text(json.dumps(obj))
id_dir.joinpath('total.json').write_text(json.dumps({'ratio': np.nanmean(total)}))
def graph_histogram(): def graph_histogram():
@@ -107,7 +119,7 @@ def manually_label_data():
Since CN-Celeb isn't labelled with the speaker's gender, this script is used to manually label Since CN-Celeb isn't labelled with the speaker's gender, this script is used to manually label
them. them.
""" """
pygame.mixer.init() # pygame.mixer.init()
# Load existing labels # Load existing labels
labels_json = data_dir.joinpath('id_labels.json') labels_json = data_dir.joinpath('id_labels.json')
@@ -132,13 +144,13 @@ def manually_label_data():
tracks = [f for f in os.listdir(id_dir) if f.endswith('.flac')] tracks = [f for f in os.listdir(id_dir) if f.endswith('.flac')]
for track_i, audio in enumerate(tracks): for track_i, audio in enumerate(tracks):
# Play track # Play track
sound = pygame.mixer.Sound(id_dir.joinpath(audio)) # sound = pygame.mixer.Sound(id_dir.joinpath(audio))
sound.play() # sound.play()
i = input(color( i = input(color(
f'\n&7Playing speaker {id[-3:]}/{len(ids)} - track {track_i}/{len(tracks)} - {audio}&r' f'\n&7Playing speaker {id[-3:]}/{len(ids)} - track {track_i}/{len(tracks)} - {audio}&r'
f'\n- Press f / m, or anything else to play next track: '))\ f'\n- Press f / m, or anything else to play next track: ')) \
.lower().strip() .lower().strip()
sound.stop() # sound.stop()
# Skip # Skip
if i == 's': if i == 's':
@@ -159,10 +171,19 @@ def manually_label_data():
if __name__ == '__main__': if __name__ == '__main__':
cn_celeb_root = Path('C:/Users/me/Workspace/Data/CN-Celeb_flac') cn_celeb_root = Path(r'C:\Datasets\VoxCeleb1\wav')
data_dir = cn_celeb_root.joinpath('data')
ids = [id for id in os.listdir(data_dir) if id.startswith('id0')]
# segment_all() data_dir = cn_celeb_root
ids = [id for id in os.listdir(data_dir) if id.startswith('id1')]
# Get all audio files for each id
audio_files = {}
for id in ids[559:]:
audio_files[id] = []
for dirpath, dirnames, filenames in os.walk(data_dir / id):
audio_files[id] += [os.path.join(dirpath, file) for file in filenames if file.endswith('.wav')]
# print(audio_files.keys())
segment_all()
# graph_histogram() # graph_histogram()
manually_label_data() # manually_label_data()
+78
View File
@@ -0,0 +1,78 @@
from pathlib import Path
import os
import json
import numpy as np
import pandas as pd
if __name__ == '__main__':
cn_celeb_root = Path(r'C:\Datasets\vox1_test_wav\wav')
data_dir = cn_celeb_root
ids = [id for id in os.listdir(data_dir) if id.startswith('id1')]
# ids=[data_dir / id for id in os.listdir(data_dir) if id.startswith('id1')]
appendix= Path(r'C:\Datasets\VoxCeleb1\wav')
ids += [id for id in os.listdir(appendix) if id.startswith('id1')]
# ids += [appendix / id for id in os.listdir(appendix) if id.startswith('id1')]
with open(r"C:\Datasets\vox1_label.csv") as f:
txt = f.read().strip()
map = {}
for row in txt.split('\n'):
id, gender = row.split(',')
map[id] = gender
# female-> positive, male -> negative
f_correct = 0 #tp
f_incorrect = 0 #fp
m_correct = 0 #tn
m_incorrect = 0 #fn
for id in ids[:40]:
obj = json.loads((data_dir / id / 'total.json').read_text())
label = map[id] #ground truth
if label == 'f':
if obj['ratio'] >= 0.5:
f_correct += 1
else:
# f_incorrect += 1 #fn
m_incorrect += 1
if label == 'm':
if obj['ratio'] < 0.5:
m_correct += 1
else:
# m_incorrect += 1 #fp
f_incorrect += 1
for id in ids[40:]:
obj = json.loads((appendix / id / 'total.json').read_text())
label = map[id] #ground truth
if label == 'f':
if obj['ratio'] >= 0.5:
f_correct += 1
else:
# f_incorrect += 1 #fn
m_incorrect += 1
if label == 'm':
if obj['ratio'] < 0.5:
m_correct += 1
else:
# m_incorrect += 1 #fp
f_incorrect += 1
# print(f_incorrect)
# print(m_incorrect)
f_precision = f_correct / (f_correct + f_incorrect)
f_recall = f_correct / (f_correct + m_incorrect)
m_precision = m_correct / (m_correct + m_incorrect)
m_recall = m_correct / (m_correct + f_incorrect)
print('Precision_f', f_precision)
print('Recall_f', f_recall)
print('Precision_m', m_precision)
print('Recall_m', m_recall)
print('total number: ', f_incorrect+f_correct+m_incorrect+m_correct)