python定义fmax_浅谈pytorch中torch.max和F.softmax函数的维度解释

本文总结了torch.max和F.softmax函数设置维度的方法,给出二维和三维tensor的例子,展示不同维度设置下函数的输出结果。还介绍了多分类问题中torch.nn.Softmax的使用,通过具体案例说明如何处理语义分割预测输出特征图,最后保存处理后的图像。
部署运行你感兴趣的模型镜像

在利用torch.max函数和F.Ssoftmax函数时,对应该设置什么维度,总是有点懵,遂总结一下:

首先看看二维tensor的函数的例子:

import torch

import torch.nn.functional as F

input = torch.randn(3,4)

print(input)

tensor([[-0.5526, -0.0194, 2.1469, -0.2567],

[-0.3337, -0.9229, 0.0376, -0.0801],

[ 1.4721, 0.1181, -2.6214, 1.7721]])

b = F.softmax(input,dim=0) # 按列SoftMax,列和为1

print(b)

tensor([[0.1018, 0.3918, 0.8851, 0.1021],

[0.1268, 0.1587, 0.1074, 0.1218],

[0.7714, 0.4495, 0.0075, 0.7762]])

c = F.softmax(input,dim=1) # 按行SoftMax,行和为1

print(c)

tensor([[0.0529, 0.0901, 0.7860, 0.0710],

[0.2329, 0.1292, 0.3377, 0.3002],

[0.3810, 0.0984, 0.0064, 0.5143]])

d = torch.max(input,dim=0) # 按列取max,

print(d)

torch.return_types.max(

values=tensor([1.4721, 0.1181, 2.1469, 1.7721]),

indices=tensor([2, 2, 0, 2]))

e = torch.max(input,dim=1) # 按行取max,

print(e)

torch.return_types.max(

values=tensor([2.1469, 0.0376, 1.7721]),

indices=tensor([2, 2, 3]))

下面看看三维tensor解释例子:

函数softmax输出的是所给矩阵的概率分布;

b输出的是在dim=0维上的概率分布,b[0][5][6]+b[1][5][6]+b[2][5][6]=1

a=torch.rand(3,16,20)

b=F.softmax(a,dim=0)

c=F.softmax(a,dim=1)

d=F.softmax(a,dim=2)

In [1]: import torch as t

In [2]: import torch.nn.functional as F

In [4]: a=t.Tensor(3,4,5)

In [5]: b=F.softmax(a,dim=0)

In [6]: c=F.softmax(a,dim=1)

In [7]: d=F.softmax(a,dim=2)

In [8]: a

Out[8]:

tensor([[[-0.1581, 0.0000, 0.0000, 0.0000, -0.0344],

[ 0.0000, -0.0344, 0.0000, -0.0344, 0.0000],

[-0.0344, 0.0000, -0.0344, 0.0000, -0.0344],

[ 0.0000, -0.0344, 0.0000, -0.0344, 0.0000]],

[[-0.0344, 0.0000, -0.0344, 0.0000, -0.0344],

[ 0.0000, -0.0344, 0.0000, -0.0344, 0.0000],

[-0.0344, 0.0000, -0.0344, 0.0000, -0.0344],

[ 0.0000, -0.0344, 0.0000, -0.0344, 0.0000]],

[[-0.0344, 0.0000, -0.0344, 0.0000, -0.0344],

[ 0.0000, -0.0344, 0.0000, -0.0344, 0.0000],

[-0.0344, 0.0000, -0.0344, 0.0000, -0.0344],

[ 0.0000, -0.0344, 0.0000, -0.0344, 0.0000]]])

In [9]: b

Out[9]:

tensor([[[0.3064, 0.3333, 0.3410, 0.3333, 0.3333],

[0.3333, 0.3333, 0.3333, 0.3333, 0.3333],

[0.3333, 0.3333, 0.3333, 0.3333, 0.3333],

[0.3333, 0.3333, 0.3333, 0.3333, 0.3333]],

[[0.3468, 0.3333, 0.3295, 0.3333, 0.3333],

[0.3333, 0.3333, 0.3333, 0.3333, 0.3333],

[0.3333, 0.3333, 0.3333, 0.3333, 0.3333],

[0.3333, 0.3333, 0.3333, 0.3333, 0.3333]],

[[0.3468, 0.3333, 0.3295, 0.3333, 0.3333],

[0.3333, 0.3333, 0.3333, 0.3333, 0.3333],

[0.3333, 0.3333, 0.3333, 0.3333, 0.3333],

[0.3333, 0.3333, 0.3333, 0.3333, 0.3333]]])

In [10]: b.sum()

Out[10]: tensor(20.0000)

In [11]: b[0][0][0]+b[1][0][0]+b[2][0][0]

Out[11]: tensor(1.0000)

In [12]: c.sum()

Out[12]: tensor(15.)

In [13]: c

Out[13]:

tensor([[[0.2235, 0.2543, 0.2521, 0.2543, 0.2457],

[0.2618, 0.2457, 0.2521, 0.2457, 0.2543],

[0.2529, 0.2543, 0.2436, 0.2543, 0.2457],

[0.2618, 0.2457, 0.2521, 0.2457, 0.2543]],

[[0.2457, 0.2543, 0.2457, 0.2543, 0.2457],

[0.2543, 0.2457, 0.2543, 0.2457, 0.2543],

[0.2457, 0.2543, 0.2457, 0.2543, 0.2457],

[0.2543, 0.2457, 0.2543, 0.2457, 0.2543]],

[[0.2457, 0.2543, 0.2457, 0.2543, 0.2457],

[0.2543, 0.2457, 0.2543, 0.2457, 0.2543],

[0.2457, 0.2543, 0.2457, 0.2543, 0.2457],

[0.2543, 0.2457, 0.2543, 0.2457, 0.2543]]])

In [14]: n=t.rand(3,4)

In [15]: n

Out[15]:

tensor([[0.2769, 0.3475, 0.8914, 0.6845],

[0.9251, 0.3976, 0.8690, 0.4510],

[0.8249, 0.1157, 0.3075, 0.3799]])

In [16]: m=t.argmax(n,dim=0)

In [17]: m

Out[17]: tensor([1, 1, 0, 0])

In [18]: p=t.argmax(n,dim=1)

In [19]: p

Out[19]: tensor([2, 0, 0])

In [20]: d.sum()

Out[20]: tensor(12.0000)

In [22]: d

Out[22]:

tensor([[[0.1771, 0.2075, 0.2075, 0.2075, 0.2005],

[0.2027, 0.1959, 0.2027, 0.1959, 0.2027],

[0.1972, 0.2041, 0.1972, 0.2041, 0.1972],

[0.2027, 0.1959, 0.2027, 0.1959, 0.2027]],

[[0.1972, 0.2041, 0.1972, 0.2041, 0.1972],

[0.2027, 0.1959, 0.2027, 0.1959, 0.2027],

[0.1972, 0.2041, 0.1972, 0.2041, 0.1972],

[0.2027, 0.1959, 0.2027, 0.1959, 0.2027]],

[[0.1972, 0.2041, 0.1972, 0.2041, 0.1972],

[0.2027, 0.1959, 0.2027, 0.1959, 0.2027],

[0.1972, 0.2041, 0.1972, 0.2041, 0.1972],

[0.2027, 0.1959, 0.2027, 0.1959, 0.2027]]])

In [23]: d[0][0].sum()

Out[23]: tensor(1.)

补充知识:多分类问题torch.nn.Softmax的使用

为什么谈论这个问题呢?是因为我在工作的过程中遇到了语义分割预测输出特征图个数为16,也就是所谓的16分类问题。

因为每个通道的像素的值的大小代表了像素属于该通道的类的大小,为了在一张图上用不同的颜色显示出来,我不得不学习了torch.nn.Softmax的使用。

首先看一个简答的例子,倘若输出为(3, 4, 4),也就是3张4x4的特征图。

import torch

img = torch.rand((3,4,4))

print(img)

输出为:

tensor([[[0.0413, 0.8728, 0.8926, 0.0693],

[0.4072, 0.0302, 0.9248, 0.6676],

[0.4699, 0.9197, 0.3333, 0.4809],

[0.3877, 0.7673, 0.6132, 0.5203]],

[[0.4940, 0.7996, 0.5513, 0.8016],

[0.1157, 0.8323, 0.9944, 0.2127],

[0.3055, 0.4343, 0.8123, 0.3184],

[0.8246, 0.6731, 0.3229, 0.1730]],

[[0.0661, 0.1905, 0.4490, 0.7484],

[0.4013, 0.1468, 0.2145, 0.8838],

[0.0083, 0.5029, 0.0141, 0.8998],

[0.8673, 0.2308, 0.8808, 0.0532]]])

我们可以看到共三张特征图,每张特征图上对应的值越大,说明属于该特征图对应类的概率越大。

import torch.nn as nn

sogtmax = nn.Softmax(dim=0)

img = sogtmax(img)

print(img)

输出为:

tensor([[[0.2780, 0.4107, 0.4251, 0.1979],

[0.3648, 0.2297, 0.3901, 0.3477],

[0.4035, 0.4396, 0.2993, 0.2967],

[0.2402, 0.4008, 0.3273, 0.4285]],

[[0.4371, 0.3817, 0.3022, 0.4117],

[0.2726, 0.5122, 0.4182, 0.2206],

[0.3423, 0.2706, 0.4832, 0.2522],

[0.3718, 0.3648, 0.2449, 0.3028]],

[[0.2849, 0.2076, 0.2728, 0.3904],

[0.3627, 0.2581, 0.1917, 0.4317],

[0.2543, 0.2898, 0.2175, 0.4511],

[0.3880, 0.2344, 0.4278, 0.2686]]])

可以看到,上面的代码对每张特征图对应位置的像素值进行Softmax函数处理, 图中标红位置加和=1,同理,标蓝位置加和=1。

我们看到Softmax函数会对原特征图每个像素的值在对应维度(这里dim=0,也就是第一维)上进行计算,将其处理到0~1之间,并且大小固定不变。

print(torch.max(img,0))

输出为:

torch.return_types.max(

values=tensor([[0.4371, 0.4107, 0.4251, 0.4117],

[0.3648, 0.5122, 0.4182, 0.4317],

[0.4035, 0.4396, 0.4832, 0.4511],

[0.3880, 0.4008, 0.4278, 0.4285]]),

indices=tensor([[1, 0, 0, 1],

[0, 1, 1, 2],

[0, 0, 1, 2],

[2, 0, 2, 0]]))

可以看到这里3x4x4变成了1x4x4,而且对应位置上的值为像素对应每个通道上的最大值,并且indices是对应的分类。

清楚理解了上面的流程,那么我们就容易处理了。

看具体案例,这里输出output的大小为:16x416x416.

output = torch.tensor(output)

sm = nn.Softmax(dim=0)

output = sm(output)

mask = torch.max(output,0).indices.numpy()

# 因为要转化为RGB彩色图,所以增加一维

rgb_img = np.zeros((output.shape[1], output.shape[2], 3))

for i in range(len(mask)):

for j in range(len(mask[0])):

if mask[i][j] == 0:

rgb_img[i][j][0] = 255

rgb_img[i][j][1] = 255

rgb_img[i][j][2] = 255

if mask[i][j] == 1:

rgb_img[i][j][0] = 255

rgb_img[i][j][1] = 180

rgb_img[i][j][2] = 0

if mask[i][j] == 2:

rgb_img[i][j][0] = 255

rgb_img[i][j][1] = 180

rgb_img[i][j][2] = 180

if mask[i][j] == 3:

rgb_img[i][j][0] = 255

rgb_img[i][j][1] = 180

rgb_img[i][j][2] = 255

if mask[i][j] == 4:

rgb_img[i][j][0] = 255

rgb_img[i][j][1] = 255

rgb_img[i][j][2] = 180

if mask[i][j] == 5:

rgb_img[i][j][0] = 255

rgb_img[i][j][1] = 255

rgb_img[i][j][2] = 0

if mask[i][j] == 6:

rgb_img[i][j][0] = 255

rgb_img[i][j][1] = 0

rgb_img[i][j][2] = 180

if mask[i][j] == 7:

rgb_img[i][j][0] = 255

rgb_img[i][j][1] = 0

rgb_img[i][j][2] = 255

if mask[i][j] == 8:

rgb_img[i][j][0] = 255

rgb_img[i][j][1] = 0

rgb_img[i][j][2] = 0

if mask[i][j] == 9:

rgb_img[i][j][0] = 180

rgb_img[i][j][1] = 0

rgb_img[i][j][2] = 0

if mask[i][j] == 10:

rgb_img[i][j][0] = 180

rgb_img[i][j][1] = 255

rgb_img[i][j][2] = 255

if mask[i][j] == 11:

rgb_img[i][j][0] = 180

rgb_img[i][j][1] = 0

rgb_img[i][j][2] = 180

if mask[i][j] == 12:

rgb_img[i][j][0] = 180

rgb_img[i][j][1] = 0

rgb_img[i][j][2] = 255

if mask[i][j] == 13:

rgb_img[i][j][0] = 180

rgb_img[i][j][1] = 255

rgb_img[i][j][2] = 180

if mask[i][j] == 14:

rgb_img[i][j][0] = 0

rgb_img[i][j][1] = 180

rgb_img[i][j][2] = 255

if mask[i][j] == 15:

rgb_img[i][j][0] = 0

rgb_img[i][j][1] = 0

rgb_img[i][j][2] = 0

cv2.imwrite('output.jpg', rgb_img)

最后保存得到的图为:

以上这篇浅谈pytorch中torch.max和F.softmax函数的维度解释就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

本文标题: 浅谈pytorch中torch.max和F.softmax函数的维度解释

本文地址: http://www.cppcns.com/jiaoben/python/323756.html

您可能感兴趣的与本文相关的镜像

PyTorch 2.5

PyTorch 2.5

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

<think> 这段代码定义了一个函数`mel_spectrogram`,用于计算音频的梅尔频谱(Mel Spectrogram)。它接受多个参数,包括音频信号`y`、FFT窗口大小`n_fft`、梅尔滤波器数量`num_mels`、采样率`sampling_rate`、帧移`hop_size`、窗长`win_size`、最小频率`fmin`最大频率`fmax`,以及一个控制是否对信号进行居中的`center`标志。 以下是代码的详细解释: 1. **输入检查**:首先检查输入音频信号`y`的值是否在[-1.0, 1.0]范围内,如果超出则打印最小值最大值。这有助于确保输入音频是归一化的。 2. **全局变量**:使用全局变量`mel_basis``hann_window`来缓存梅尔滤波器汉宁窗,避免每次调用函数时都重新计算,提高效率。这两个变量是字典类型,以特定的键(由`fmax`设备类型组成)存储对应的梅尔滤波器汉宁窗。 3. **梅尔滤波器构建**:如果当前`fmax`设备组合的梅尔滤波器未创建,则调用`librosa_mel_fn`(该函数未在此代码中定义,但通常来自librosa库)生成梅尔滤波器组,并将其转换为PyTorch张量,存储到`mel_basis`字典中。同时,为当前设备创建汉宁窗并存储到`hann_window`字典中。 4. **音频填充**:为了在STFT(短时傅里叶变换)处理边缘时保持帧数,使用反射填充对音频进行填充。填充的长度为`(n_fft - hop_size) // 2`。 5. **STFT计算**:使用`torch.stft`计算音频的STFT。参数说明: - `y`: 输入音频 - `n_fft`: FFT窗口大小 - `hop_length`: 帧移(即`hop_size`) - `win_length`: 窗长(即`win_size`) - `window`: 汉宁窗 - `center`: 是否居中,如果为True,则在信号两端填充以使帧居中 - `pad_mode`: 填充模式,这里用反射填充 - `normalized`: 是否归一化,这里不归一化 - `onesided`: 只返回正频率部分(因为音频信号是实数) - `return_complex`: 返回复数张量(实部虚部) `torch.stft`返回一个复数张量(实部虚部),然后使用`torch.view_as_real`将其转换为实数的张量(实部虚部分开作为最后一维)。 6. **幅度谱计算**:计算复数频谱的幅度谱(模),公式为`sqrt(real^2 + imag^2)`,并加上一个很小的数(1e-9)避免数值问题。 7. **梅尔谱计算**:将幅度谱通过梅尔滤波器组(`mel_basis`)进行滤波,得到梅尔频谱。这一步通过矩阵乘法实现。 8. **频谱归一化**:调用`spectral_normalize_torch`(该函数未在此代码中定义)对梅尔频谱进行归一化处理(通常是对数压缩)。 最后返回梅尔频谱。 注意:该代码依赖于外部函数`librosa_mel_fn``spectral_normalize_torch`,以及全局字典`mel_basis``hann_window`(需要在函数外部初始化)。 下面是一个完整的示例,包括必要的全局变量初始化辅助函数(为了可运行,我们实现了`librosa_mel_fn`的替代版本`spectral_normalize_torch`): ```python import torch import numpy as np from scipy.signal import get_window # 初始化全局变量 mel_basis = {} hann_window = {} def librosa_mel_fn(sr, n_fft, n_mels, fmin, fmax): """创建梅尔滤波器组(替代版本)""" # 使用librosa的梅尔滤波器组公式 import librosa return librosa.filters.mel(sr=sr, n_fft=n_fft, n_mels=n_mels, fmin=fmin, fmax=fmax) def spectral_normalize_torch(magnitudes): """对幅度谱进行归一化(对数压缩)""" # 动态范围压缩,这里使用对数压缩:log(1 + magnitude) return torch.log(torch.clamp(magnitudes, min=1e-5)) def mel_spectrogram(y, n_fft, num_mels, sampling_rate, hop_size, win_size, fmin, fmax, center=False): # 检查输入范围 if torch.min(y) < -1.0: print("min value is ", torch.min(y)) if torch.max(y) > 1.0: print("max value is ", torch.max(y)) global mel_basis, hann_window # pylint: disable=global-statement # 为当前fmax设备创建唯一的键 key = f"{str(fmax)}_{str(y.device)}" if key not in mel_basis: # 生成梅尔滤波器组 mel = librosa_mel_fn(sr=sampling_rate, n_fft=n_fft, n_mels=num_mels, fmin=fmin, fmax=fmax) mel_basis[key] = torch.from_numpy(mel).float().to(y.device) # 创建汉宁窗 hann_window[str(y.device)] = torch.hann_window(win_size).to(y.device) # 对音频进行填充 y = torch.nn.functional.pad( y.unsqueeze(1), (int((n_fft - hop_size) / 2), int((n_fft - hop_size) / 2)), mode="reflect" ) y = y.squeeze(1) # 计算STFT spec = torch.stft( y, n_fft, hop_length=hop_size, win_length=win_size, window=hann_window.get(str(y.device), torch.hann_window(win_size).to(y.device)), center=center, pad_mode="reflect", normalized=False, onesided=True, return_complex=True ) # 将复数STFT转换为幅度谱 spec = torch.abs(spec) # 应用梅尔滤波器组 mel_spec = torch.matmul(mel_basis[key], spec) # 归一化 mel_spec = spectral_normalize_torch(mel_spec) return mel_spec # 示例使用 if __name__ == "__main__": # 生成测试音频(1秒,采样率22050) sample_rate = 22050 duration = 1.0 t = torch.linspace(0, duration, int(sample_rate * duration)) audio = torch.sin(2 * np.pi * 440 * t) # 440Hz正弦波 # 参数设置 n_fft = 1024 num_mels = 80 hop_size = 256 win_size = 1024 fmin = 0 fmax = 8000 # 计算梅尔频谱 mel_spec = mel_spectrogram( audio.unsqueeze(0), # 添加批次维度 n_fft, num_mels, sample_rate, hop_size, win_size, fmin, fmax ) print("梅尔频谱形状:", mel_spec.shape) # 应为 [1, 80, 帧数] ``` 注意:上面的代码中,我们使用了`torch.stft`的`return_complex=True`选项,然后直接取绝对值得到幅度谱。原代码中使用了`torch.view_as_real`,然后计算复数的模,但新版本的PyTorch推荐直接使用`torch.abs`。 另外,原代码中`spectral_normalize_torch`函数定义,这里我们实现了一个简单的对数压缩版本。 §§相关问题§§: 1. 梅尔频谱在语音处理中有什么应用? 2. 为什么在STFT之前需要对音频信号进行填充? 3. 梅尔滤波器组的作用是什么,它是如何构建的? 4. 如何将梅尔频谱转换回音频(即梅尔频谱的逆变换)? </think>以下是对您提供的代码的详细解释分析: ```python def mel_spectrogram(y, n_fft, num_mels, sampling_rate, hop_size, win_size, fmin, fmax, center=False): # 1. 输入音频范围检查 if torch.min(y) < -1.0: print("min value is ", torch.min(y)) if torch.max(y) > 1.0: print("max value is ", torch.max(y)) # 2. 全局缓存初始化 global mel_basis, hann_window # pylint: disable=global-statement # 3. 梅尔滤波器组缓存检查与创建 if f"{str(fmax)}_{str(y.device)}" not in mel_basis: # 使用librosa创建梅尔滤波器组 mel = librosa_mel_fn(sr=sampling_rate, n_fft=n_fft, n_mels=num_mels, fmin=fmin, fmax=fmax) # 将梅尔滤波器组转换为PyTorch张量并存储到缓存 mel_basis[str(fmax) + "_" + str(y.device)] = torch.from_numpy(mel).float().to(y.device) # 创建汉宁窗并缓存 hann_window[str(y.device)] = torch.hann_window(win_size).to(y.device) # 4. 音频填充(边界处理) y = torch.nn.functional.pad( y.unsqueeze(1), (int((n_fft - hop_size) / 2), int((n_fft - hop_size) / 2)), mode="reflect" ) y = y.squeeze(1) # 5. 短时傅里叶变换(STFT) spec = torch.view_as_real( torch.stft( y, n_fft, hop_length=hop_size, win_length=win_size, window=hann_window[str(y.device)], center=center, pad_mode="reflect", normalized=False, onesided=True, return_complex=True ) ) # 6. 计算幅度谱 spec = torch.sqrt(spec.pow(2).sum(-1) + (1e-9)) # 计算复数幅度(模) # 7. 应用梅尔滤波器组 spec = torch.matmul(mel_basis[str(fmax) + "_" + str(y.device)], spec) # 8. 频谱归一化 spec = spectral_normalize_torch(spec) return spec ``` ### 代码作用详解: 1. **输入音频检查**: ```python if torch.min(y) < -1.0: ... if torch.max(y) > 1.0: ... ``` - 检查输入音频值是否在[-1.0, 1.0]范围内 - 超出范围时打印警告信息(但不中断处理) 2. **全局缓存初始化**: ```python global mel_basis, hann_window ``` - 使用全局变量缓存梅尔滤波器组汉宁窗 - 避免每次调用时重复计算,提高效率 3. **梅尔滤波器组创建与缓存**: ```python if f"{str(fmax)}_{str(y.device)}" not in mel_basis: mel = librosa_mel_fn(...) mel_basis[...] = torch.from_numpy(mel).float().to(y.device) hann_window[...] = torch.hann_window(...).to(y.device) ``` - 为每个(fmax, 设备)组合创建唯一的梅尔滤波器组 - 使用librosa的梅尔滤波器实现 - 缓存结果避免重复计算 4. **音频填充**: ```python y = torch.nn.functional.pad(...) ``` - 在音频两端添加反射填充 - 填充长度:`(n_fft - hop_size)/2` - 确保STFT处理边界时的稳定性 5. **短时傅里叶变换(STFT)**: ```python spec = torch.view_as_real(torch.stft(...)) ``` - 使用汉宁窗进行窗口化 - 参数说明: - `n_fft`: FFT窗口大小 - `hop_size`: 帧移 - `win_size`: 窗口长度 - `center=False`: 不居中处理 - `return_complex=True`: 返回复数频谱 - `torch.view_as_real`:将复数转换为实部+虚部形式 6. **幅度谱计算**: ```python spec = torch.sqrt(spec.pow(2).sum(-1) + (1e-9)) ``` - 计算复数频谱的幅度:$\sqrt{\text{real}^2 + \text{imag}^2}$ - 添加小值(1e-9)避免数值不稳定 7. **梅尔谱转换**: ```python spec = torch.matmul(mel_basis[...], spec) ``` - 将线性频率谱转换为梅尔频率谱 - 通过矩阵乘法应用梅尔滤波器组 8. **频谱归一化**: ```python spec = spectral_normalize_torch(spec) ``` - 应用自定义的频谱归一化函数 - 通常是对数压缩(如log(1 + amplitude)) ### 整体功能总结: 该函数实现了**从时域音频到梅尔频谱的完整转换流程**,包含以下关键步骤: 1. **输入检查**:验证音频范围 2. **资源缓存**:高效管理梅尔滤波器函数 3. **信号预处理**:反射填充边界 4. **频谱分析**:STFT计算复数频谱 5. **幅度计算**:获取能量信息 6. **频率转换**:线性频率→梅尔频率 7. **归一化处理**:压缩动态范围 ### 典型应用场景: 1. **语音识别前端处理**:将原始音频转换为梅尔频谱作为模型输入 2. **语音合成**:在Tacotron等模型中作为声学特征表示 3. **音乐信息检索**:提取音频的感知相关特征 4. **音频分类**:作为深度学习模型的输入特征 ### 注意事项: 1. **依赖项**: - 需要预先定义 `librosa_mel_fn` `spectral_normalize_torch` - `mel_basis` `hann_window` 需在函数外部初始化(全局字典) 2. **性能优化**: - 使用设备感知的缓存(不同设备创建不同张量) - 避免重复计算滤波器组 3. **参数选择**: - `n_fft`、`hop_size` 影响时间/频率分辨率 - `fmin`/`fmax` 决定关注的频率范围 - `num_mels` 控制梅尔带数量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值