前
言
在上一篇内容中,我们介绍了 PieCloudVector 如何助力构建基于图片数据的商品推荐系统,详细描述从数据集的准备到数据向量化处理,再到向量数据的存储和相似性搜索的完整流程。本文将进一步探讨如何将 PieCloudVector 应用于音频数据,以实现音频内容的识别和分类。
音频数据是一种丰富且动态的非结构化数据形式,PieCloudVector 作为大模型时代的分析型数据库升维,其在音频数据处理上的应用,不仅能够提升音频内容识别的准确性,还能增强音频分类的效率。本文为《PieCloudVector 进阶系列》的第二篇,将以音频数据为例,详细介绍利用向量数据库助力音频数据的向量化处理、存储以及相似性搜索的过程。
(本文演示数据均来自 Hugging Face)
from datasets import load_dataset
dataset_minds = load_dataset("PolyAI/minds14", "en-US", split="train")
dataset_minds.save_to_disk('minds14_dataset')
# 读取本地数据
dataset_minds = load_from_disk('minds14_dataset')
dataset_minds.features
{ 'path': Value(dtype='string', id=None),
'audio': Audio(sampling_rate=8000, mono=True, decode=True, id=None),
'transcription': Value(dtype='string', id=None),
'english_transcription': Value(dtype='string', id=None),
'intent_class': Classlabel(names=['abroad', 'address', 'app_error', 'atm_limit', 'balance', 'business_loan', 'card_issues', 'cash_deposit', 'direct_debit', freeze', 'high_value_payment', 'joint_account', 'latest_transactions', pay_bill'], id=None),
'lang_id': ClassLabel(names=['cs-CZ', 'de-DE', 'en-AU', 'en-GB', 'en-US', 'es-ES', fr-FR', it-IT', 'ko-KR','nl- NL', 'pl-PL', 'pt-PT, 'ru-RU', 'zh-CN'], id=None)}
In: dataset_minds.['audio'][0]
Out: {'path': '/Users/arlena.wang/.cache/huggingface/datasets/downloads/extracted/fa6d050e601cf0ccf2c2b01238375a56579232af95e398fcef126ea4224e4185/en-US~JOINT_ACCOUNT/602ba55abb1e6d0fbce92065.wav',
'array': array([ 0. , 0.00024414, -0.00024414, ..., -0.00024414, 0. , 0. ]),
'sampling_rate': 8000}
from IPython.display import Audio
Audio(data=dataset_minds['audio'][0]['array'], rate=dataset_minds['audio'][0]['sampling_rate'])
print(print(dataset_minds['audio'][0]['sampling_rate']))
# 8000
print(len(dataset_minds['audio'][0]['array']))
# 86699
In: from librosa import resample
print(len(resample(dataset_minds['audio'][0]['array'], orig_sr=8000, target_sr=2000)))
print(len(resample(dataset_minds['audio'][1]['array'], orig_sr=8000, target_sr=2000)))
Out: 32513
19968
from librosa import resample
from librosa.util import fix_length
max_len = 0
for item in dataset_minds['audio']:
if len(item['array']) > max_len:
max_len = len(item['array'])
def resample_audio_fix(audio):
audio["audio_fix"] = fix_length(resample(audio['audio']['array'], orig_sr=8000, target_sr=2000, fix=True, scale=True), size=max_len)
return audio
updated_fix_dataset = dataset_minds.map(resample_audio_fix)
import torch
from IPython.display import Audio
from diffusers import DiffusionPipeline
device = "cuda" if torch.cuda.is_available() else "cpu"
pipe = DiffusionPipeline.from_pretrained("teticio/audio-diffusion-256").to(device)
output = pipe(
raw_audio=dataset_minds['audio'][0]['array'],
start_step=int(pipe.get_default_steps() / 2),
mask_start_secs=1,
mask_end_secs=1,
)
In: melspectrogram(y=dataset_minds['audio'][0]['array'], sr=8000).shape
Out: (128, 170)
from librosa.feature import melspectrogram
import PIL
def transform_audio(audio):
audio["audio_image"] = PIL.Image.fromarray(melspectrogram(y=audio['audio']['array'], sr=8000).astype('uint8'))
return audio
updated_dataset = dataset_minds.map(transform_audio)
display(updated_dataset["audio_image"][0])
from imgbeddings import imgbeddings
ibed = imgbeddings()
# 第一条音频数据
embedding_0 = ibed.to_embeddings(updated_dataset["audio_image"][0])
In: embedding_0.shape
Out: (1, 768)
embedding = ibed.to_embeddings(updated_dataset['audio_image'])
CREATE TABLE if not exists vec_test.banking_audio (id bigserial PRIMARY KEY, embedding vector(768), intent_class varchar(50), lang_id varchar(10));
truncate table vec_test.banking_audio;
import psycopg2
embeddings_lst = embedding.tolist()
conn = psycopg2.connect('postgresql://user:passwd@192.163.**.**:5432/pgvec_test')
cur = conn.cursor()
for i in range(len(embeddings_lst)):
cur.execute('INSERT INTO vec_test.banking_audio (embedding, intent_class, lang_id) values (%s,%s,%s)', (embeddings_lst[i], updated_dataset["intent_class"][i], updated_dataset["lang_id"][i]))
conn.commit()
conn.close()
from sqlalchemy import create_engine, text as sql_text
import pandas as pd
engine = create_engine('postgresql://user:passwd@192.163.**.**:5432/pgvec_test', echo=False).connect()
audio_id = pd.read_sql_query(sql=sql_text('select id, intent_class, lang_id from vec_test.banking_audio where id != 1 order by embedding <-> ' + "'" + str(embedding_0.tolist()[0]) + "'" + ' limit 10'),
con=engine)
In: updated_dataset.features["intent_class"].int2str(int(audio_id.loc[0, 'intent_class']))
Out: 'direct_debit'
In: updated_dataset.features["lang_id"].int2str(int(audio_id.loc[0, 'lang_id']))
Out: 'en-US'
在我们查询的最相近的十条记录中,所有音频皆为美式英语,对应编号 4,但意图各不相同。我们可以通过简单计算来查询出现频率最高的意图种类。
audioid_lst = audio_id['id'].to_list()
def most_common(lst):
return max(set(lst), key=lst.count)
label = most_common([updated_dataset['intent_class'][i] for i in audioid_lst])
print(updated_dataset.features["intent_class"].int2str(int(label)))
结果为'atm_limit'。
In: updated_dataset.features["intent_class"].int2str(int(label))
Out: 'atm_limit'
Audio(data=updated_dataset['audio'][354]['array'], rate=dataset_minds['audio'][354]['sampling_rate'])
在下篇文章中,我们将探索如何利用 PieCloudVector 的文本数据处理能力,打造 ChatBot。欢迎关注!
关于 PieCloudVector