用滑動窗口與線性回歸將音頻信號轉換為“Token”序列:一種簡單的音頻特征編碼方法

在深度學習和語音處理領域,如何將原始音頻信號有效地表示為離散的“Token”序列,是語音識別、音頻生成等任務中的關鍵問題。常見的方法如Mel頻譜圖+向量量化(VQ)、wav2vec等已經非常成熟,但這些模型通常依賴復雜的神經網絡結構。

本文介紹一種輕量級、可解釋性強的音頻特征提取與“類Token化”編碼方法,僅使用余弦相似度、線性回歸和歸一化技術,即可將一段WAV音頻轉化為一個整數序列——我們稱之為“偽Token”序列。這種方法雖然不能替代現代語音模型,但非常適合用于教學、探索性數據分析或輕量級嵌入式應用。


🎯 目標

我們將實現以下功能:

  1. 讀取一段 .wav 音頻文件;
  2. 對音頻進行預處理(去均值、標準化);
  3. 使用滑動窗口對相鄰樣本做線性回歸分析;
  4. 提取回歸斜率與擬合效果(余弦相似度)作為雙特征;
  5. 將特征歸一化并量化為整數,形成“Token”序列;
  6. 可視化結果并封裝成函數。

🔧 核心工具與庫

import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile

同時為了支持中文標題顯示,設置 Matplotlib 的字體:

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False

📐 核心算法定義

1. 余弦相似度(Cosine Similarity)

衡量兩個向量方向的一致性,反映線性擬合的質量。

def cosine_similarity(a, b):return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

2. 最小二乘法線性回歸

手動實現一元線性回歸,避免依賴 sklearn

def linear_regression(x, y):n = len(x)sum_x, sum_y = np.sum(x), np.sum(y)sum_xy = np.sum(x * y)sum_x2 = np.sum(x ** 2)slope = (n * sum_xy - sum_x * sum_y) / (n * sum_x2 - sum_x ** 2)intercept = (sum_y - slope * sum_x) / nreturn slope, intercept

3. Min-Max 歸一化(防除零)

def min_max_normalize(data):min_val = np.min(data)max_val = np.max(data)return (data - min_val) / (max_val - min_val + 1e-8)

🧪 主流程解析:main() 函數

我們以文件 "sound/cat/1-47819-C-5.wav" 為例,演示整個流程。

1. 音頻讀取與預處理

_, audio = wavfile.read("sound/cat/1-47819-C-5.wav")
left = (audio - np.mean(audio)) / np.std(audio)  # 標準化

?? 注意:這里假設音頻是單聲道。如果是立體聲,請取某一通道(如 audio[:, 0])。

接著構造“左移-右移”數據對:

left = left[:left.size // 2 * 2]  # 確保長度為偶數
left = left[:-1]                  # 去最后一個元素
right = left[1:]                  # 右移一位

這相當于構建了 (x_t, x_{t+1}) 的時間序列對,可用于分析局部動態變化。


2. 滑動窗口分析

使用大小為 3200 的窗口,每步移動 1600(半重疊),進行局部線性擬合:

for i in range(0, len(left) - 1600, 1600):x, y = left[i:i + 3200], right[i:i + 3200]if len(x) > len(y): x = x[:len(y)]slope, intercept = linear_regression(x, y)sim = cosine_similarity(slope * x + intercept, y)sim_list.append(sim)slope_list.append(slope)
  • x: 當前窗口內的原始信號片段;
  • y: 對應的“下一時刻”信號(右移);
  • 使用線性模型 y ≈ slope * x + intercept 擬合;
  • 計算預測值與真實值之間的余弦相似度,評估擬合質量;
  • 記錄每個窗口的 slopesimilarity

3. 特征歸一化與“Token化”

將連續特征映射到整數空間,模擬 Token 編碼過程:

sim_list = min_max_normalize(sim_list) * 2048
slope_list = min_max_normalize(slope_list) * 2048 + 2048
  • sim_list → [0, 2048]
  • slope_list → [2048, 4096]

然后轉換為整型:

sim_list = sim_list.astype(np.int16)

最后將兩者交錯拼接成一維序列:

tokens = np.hstack([sim_list, slope_list]).reshape([2, -1]).transpose([1, 0]).reshape(-1)

這一步實現了雙通道特征的交織編碼。


4. 可視化 Token 序列

plt.plot(tokens)
plt.title("音頻生成的偽Token序列")
plt.xlabel("Token索引")
plt.ylabel("Token值")
plt.show()

💡 封裝函數:wav_to_token(path)

我們將上述邏輯封裝為通用函數,適用于任意 .wav 文件:

def wav_to_token(path):_, audio = wavfile.read(path)# 單通道處理if len(audio.shape) > 1:audio = audio[:, 0]left = (audio - np.mean(audio)) / np.std(audio)left = left[:left.size // 2 * 2][:-1]right = left[1:]sim_list = []slope_list = []# 更小的窗口:1600采樣點,每800步滑動for i in range(0, len(left) - 800, 800):x = left[i:i+1600]y = right[i:i+1600]if len(x) != len(y):min_len = min(len(x), len(y))x, y = x[:min_len], y[:min_len]slope, intercept = linear_regression(x, y)pred = slope * x + interceptsim = cosine_similarity(pred, y)sim_list.append(sim)slope_list.append(slope)# 歸一化到 0~64 范圍(2^6)sim_tokens = min_max_normalize(np.array(sim_list)) * 64slope_tokens = min_max_normalize(np.array(slope_list)) * 64sim_tokens = sim_tokens.astype(np.int16)slope_tokens = slope_tokens.astype(np.int16)# 合并為乘積特征(非零過濾)res = sim_tokens * slope_tokensreturn res[res != 0]  # 去除零值

? 返回的是一個整數數組,可視為該音頻的“特征Token序列”。


📊 方法特點總結

項目描述
優點- 不依賴深度學習框架
- 可解釋性強
- 計算開銷小
- 可用于邊緣設備
局限- 表達能力有限
- 無法捕捉高頻語義
- 對噪聲敏感
適用場景- 音頻分類初篩
- 異常聲音檢測
- 教學演示
- 低資源環境下的特征提取

🚀 拓展思路

你可以在此基礎上進一步改進:

  1. 加入頻域特征:對每個窗口做FFT,提取主頻作為第三Token維度;
  2. 向量量化(VQ):用KMeans對 (sim, slope) 向量聚類,真正生成離散Token;
  3. 滑動窗口自適應:根據能量或過零率動態調整窗口大小;
  4. 時間對齊編碼:引入DTW對齊不同長度的Token序列;
  5. 用于對比學習:計算不同音頻Token序列間的距離,做相似性匹配。

📎 完整代碼下載

你可以將以下完整代碼保存為 audio_tokenizer.py 并運行:

import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile# 中文顯示支持
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = Falsedef cosine_similarity(a, b):"""計算余弦相似度"""return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))def linear_regression(x, y):"""最小二乘法線性回歸"""n = len(x)sum_x, sum_y = np.sum(x), np.sum(y)sum_xy = np.sum(x * y)sum_x2 = np.sum(x ** 2)slope = (n * sum_xy - sum_x * sum_y) / (n * sum_x2 - sum_x ** 2)intercept = (sum_y - slope * sum_x) / nreturn slope, interceptdef min_max_normalize(data):min_val = np.min(data)max_val = np.max(data)return (data - min_val) / (max_val - min_val + 1e-8)def wav_to_token(path):_, audio = wavfile.read(path)if len(audio.shape) > 1:audio = audio[:, 0]  # 取左聲道# 標準化left = (audio - np.mean(audio)) / np.std(audio)left = left[:len(left)//2*2][:-1]right = left[1:]sim_list = []slope_list = []for i in range(0, len(left) - 800, 800):x = left[i:i+1600]y = right[i:i+1600]if len(x) != len(y):min_len = min(len(x), len(y))x, y = x[:min_len], y[:min_len]slope, intercept = linear_regression(x, y)pred = slope * x + interceptsim = cosine_similarity(pred, y)sim_list.append(sim)slope_list.append(slope)sim_arr = min_max_normalize(np.array(sim_list)) * 64slope_arr = min_max_normalize(np.array(slope_list)) * 64sim_arr = sim_arr.astype(np.int16)slope_arr = slope_arr.astype(np.int16)res = sim_arr * slope_arrreturn res[res != 0]def main():path = "sound/cat/1-47819-C-5.wav"tokens = wav_to_token(path)plt.figure(figsize=(10, 4))plt.plot(tokens)plt.title("音頻生成的偽Token序列")plt.xlabel("Token索引")plt.ylabel("Token值")plt.grid(True)plt.tight_layout()plt.show()if __name__ == "__main__":main()

📣 結語

本文提出了一種新穎而直觀的方式,將音頻信號通過線性動力學建模 + 特征量化的方式轉換為離散序列。雖然它不是真正的“語音Token”,但它啟發我們思考:是否可以用更簡單的方法逼近復雜模型的部分能力?

這種“白盒”方法有助于理解音頻特征的本質,也為輕量級系統提供了一種可行的替代方案。

🔗 后續計劃:我們將嘗試用這類Token訓練一個RNN來“復現”原始音頻,敬請期待!


📌 關鍵詞:音頻處理、Token化、線性回歸、余弦相似度、滑動窗口、Python、信號處理、輕量級模型

📬 歡迎留言交流更多音頻特征工程技巧!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/95161.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/95161.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/95161.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue開發準備

vs code VSCode的下載地址https://code.visualstudio.com/Download Node.js node.js的下載地址 https://nodejs.org/zh-cn/download 注意:nodejs安裝路徑不要和vscode安裝到同一個文件夾,兩個應用分別裝到兩個不同的文件夾 npm config set cache &q…

QT6(QFileSystemModel和QTreeView)

QT6QFileSystemModel和QTreeView QFileSystemModel為本機的文件系統提供一個模型,QFileSystemModelt和QTreeView結合使用,可以用目錄樹的形式顯示本機的文件系統,如同Windows的資源管理器一樣使用QFileSystemModel提供的接口函數,…

【開題答辯全過程】以 基于Spring Boot的房屋租賃系統的設計與實現為例,包含答辯的問題和答案

個人簡介一名14年經驗的資深畢設內行人,語言擅長Java、php、微信小程序、Python、Golang、安卓Android等開發項目包括大數據、深度學習、網站、小程序、安卓、算法。平常會做一些項目定制化開發、代碼講解、答辯教學、文檔編寫、也懂一些降重方面的技巧。感謝大家的…

構建下一代智能金融基礎設施

1. 行業背景:從數字支付到可編程金融的范式躍遷全球數字支付市場正以萬億美元的規模持續擴張,但其底層系統仍受限于傳統金融的清算、結算延遲和高昂的中間成本。盡管互聯網技術提升了支付的便捷性,但其核心仍是中心化賬戶體系的延伸。Web3 技…

【C++】深入解析C++嵌套依賴類型與typename關鍵字

什么是嵌套依賴類型?嵌套依賴類型(Nested Dependent Type)是指在一個模板中,一個類型名稱依賴于模板參數,并且是該模板參數內部的嵌套類型。具體來說,當一個類型滿足以下兩個條件時,它就是嵌套依…

管網信息化監測主要的內容

管網信息化監測是指通過現代信息技術手段對管網系統進行實時監控和數據采集的管理方式。其背景源于城市化進程加快以及基礎設施建設規模不斷擴大,傳統的管網管理模式已無法滿足現代化需求。管網信息化監測主要內容包括以下幾個方面:█管網運行狀態監測&a…

數據泄露代價千萬,PII 保護你真的做對了嗎?

一、PII—數據隱私的核心概念解析 在大多數數據隱私法律中,可識別個人信息(PII, Personally Identifiable Information)是指任何可以用來識別個人身份的信息。然而,PII 的定義并非由單一法律統一規定,不同國家和地區的法律對其定義略有差異: 各國對 PII 的定義 美國 20…

【數據結構】八大排序之快速排序:分而治之的藝術

文章目錄快速排序1.hoare版本算法優化三數取中法小區間優化完整代碼如下算法分析時間復雜度空間復雜度2.前后指針法排序過程3.非遞歸(棧模擬)實現思路總結快速排序 快速排序是Hoare于1962年提出的一種二叉樹結構的交換排序方法,其基本思想為…

在ROS中獲取并發布UBS式傳感器的溫濕度

哈嘍大家好,我是鋼板獸! 今天更新一篇和ROS相關的文章,有個項目需求是在ROS中獲取并發布UBS式傳感器的溫濕度,我使用的溫濕度傳感器簡介如下:DL11- MC-S1 溫濕度傳感器通過USB 接口采用標準MODBUS RTU 協議通信&#x…

【圖論】 Graph.jl 操作匯總

文章目錄圖論的集合類操作Base.getindexBase.intersectBase.joinBase.reverseBase.reverse!Base.sizeBase.sumBase.sumBase.union圖生成與轉換Graphs.cartesian_productGraphs.complementGraphs.compute_shiftsGraphs.crosspathGraphs.differenceGraphs.egonetGraphs.induced_s…

【鏈表 - LeetCode】146. LRU 緩存

146. LRU 緩存 題解&#xff1a; class LRUCache {list<pair<int,int>>v;unordered_map<int,list<pair<int,int>>::iterator>idx;int capacity; public:LRUCache(int capacity):capacity(capacity){}int get(int key) {if(idx.count(key) 0) …

Elasticsearch vs Solr vs OpenSearch:搜索引擎方案對比與索引設計最佳實踐

Elasticsearch vs Solr vs OpenSearch&#xff1a;搜索引擎方案對比與索引設計最佳實踐 隨著大數據和實時分析需求的爆發&#xff0c;搜索引擎已成為許多業務系統中的核心組件。本篇文章將從“技術方案對比分析型”角度切入&#xff0c;重點比較三大主流搜索引擎&#xff1a;El…

光頡科技)Viking)的CS25FTFR009 1225 0.009R/9mR 3W電阻介紹-華年商城

“**華年商城”**小編為您介紹&#xff1a;光頡科技&#xff08;Viking&#xff09;的CS25FTFR009 1225 0.009R/9mR 3W電阻 光頡CS25FTFR009合金電阻&#xff1a;0.009Ω/9mΩ 3W 1%精密采樣電阻 光頡科技&#xff08;Viking&#xff09;的CS25FTFR009是一款高性能的電流檢測電…

港科大開放世界長時域具身導航!LOVON:足式機器人開放詞匯目標導航

作者&#xff1a;Daojie Peng1^{1}1, Jiahang Cao1,2^{1,2}1,2, Qiang Zhang1,2^{1,2}1,2, Jun Ma1,3^{1,3}1,3單位&#xff1a;1^{1}1香港科技大學&#xff08;廣州&#xff09;&#xff0c;2^{2}2北京人形機器人創新中心&#xff0c;3^{3}3香港科技大學論文標題&#xff1a;L…

【前端教程】JavaScript 數組對象遍歷與數據展示實戰

在前端開發中&#xff0c;處理數組和對象是日常工作的基礎。無論是篇文章將通過一個具體案例&#xff0c;詳細講解如何使用JavaScript遍歷包含對象的數組&#xff0c;并將數據以清晰的格式展示在頁面上。我們會從基礎語法開始&#xff0c;逐步優化代碼&#xff0c;最終實現一個…

無重復字符的最長子串,leetCode熱題100,C++實現

題目來源&#xff1a;leetCode 3. 無重復字符的最長子串 - 力扣&#xff08;LeetCode&#xff09; 給定一個字符串 s &#xff0c;請你找出其中不含有重復字符的 最長 子串 的長度。 解法 class Solution { public:int lengthOfLongestSubstring(string s) {unordered_set<…

卷積神經網絡中1×1卷積的作用

part I &#xff1a;來源part II &#xff1a;應用part III &#xff1a;作用&#xff08;降維、升維、跨通道交互、增加非線性&#xff09;part IV &#xff1a;從fully-connected layers的角度理解一、來源&#xff1a;[1312.4400] Network In Network &#xff08;如果11…

VMware設置Ubuntu虛擬機橋接模式完整教程

VMware 設置 Ubuntu 虛擬機橋接模式完整教程 下面是一個詳細的、避免出錯的 VMware Ubuntu 橋接模式設置教程&#xff0c;包含常見問題的解決方案。 準備工作 確保宿主機&#xff08;Windows 11&#xff09;已連接到網絡&#xff08;有線或無線&#xff09;確認您有管理員權限關…

淺析NVMe協議:DIF

文章目錄概述DIF數據格式盤片支持DIFFormatPILPIMSETLBAF協議命令DIF支持PRACTPRACT0PRACT1PRCHK相關參考概述 NVMe協議將DIF信息作為元數據的一部分進行攜帶。 DIF數據格式 DIF的PI由多個字段組成&#xff0c;包括&#xff1a; Guard字段&#xff1a;基于邏輯塊數據計算的C…

【觀成科技】蔓靈花User下載者加密通信分析

概述2025年5月7日&#xff0c;蔓靈花&#xff08;BITTER&#xff09;組織針對巴基斯坦電信公司工作人員發起釣魚郵件攻擊&#xff0c;投遞偽裝為安全簡報的惡意郵件&#xff0c;附件為IQY類型的Web查詢文件。該文件在用戶執行后通過HTTP協議獲取遠程CMD指令并執行&#xff0c;進…