主要内容

训练生成对抗网络(GAN)进行声音合成

这个例子展示了如何训练和使用生成式对抗网络(GAN)来生成声音。

介绍

在生成对抗网络中,生成器和鉴别器相互竞争以提高生成质量。

gan在音频和语音处理领域产生了重要的兴趣。应用包括文本到语音合成、语音转换和语音增强。

这个例子训练GAN用于无监督合成音频波形。本例中的GAN生成鼓点声音。同样的方法也可以用于生成其他类型的声音,包括语音。

用预训练的GAN合成音频

在你从头开始训练氮化镓之前,你将使用一个预先训练过的氮化镓发生器来合成鼓点。

下载预训练的生成器。

matFileName =“drumGeneratorWeights.mat”如果~存在(matFileName“文件”) websave (matFileName“//www.tianjin-qmedu.com/万博1manbetxsupportfiles/audio/GanAudioSynthesis/drumGeneratorWeights.mat”);结束

这个函数synthesizeDrumBeat调用一个预先训练过的网络来合成以16千赫采样的鼓点。的synthesizeDrumBeat函数包含在本示例的最后。

合成一个鼓点,然后听它。

鼓= synthesizeDrumBeat;fs = 16 e3;声音(鼓,fs)

绘制合成鼓点。

t =(0:长度(鼓)1)/ fs;情节(t,鼓)网格xlabel(“时间(s)”)头衔(“合成鼓节拍”

您可以使用鼓点合成器和其他音频效果来创建更复杂的应用程序。例如,您可以在合成的鼓点上应用混响。

创建一个反射器(音频工具箱)对象并打开其参数调优器UI。这个UI允许您调优反射器参数作为模拟运行。

混响器(“SampleRate”fs);parameterTuner(混响);

创建时间范围对象以可视化鼓拍。

ts = timescope (“SampleRate”fs,...“TimeSpanSource”“财产”...“TimeSpanOverrunAction”“滚动”...“时间间隔”10...“BufferLength”, 10 * 256 * 64,...“ShowGrid”,真的,...“YLimits”[1]);

在循环中,合成鼓拍并应用混响。使用参数调谐器UI来调整混响。如果要运行更长时间的模拟,请增加loopCount参数

循环计数=20;ii=1:loopCount鼓=合成鼓;鼓=混响(鼓);ts(鼓(:,1));soundsc(鼓,fs)暂停(0.5)结束

火车的氮化镓

现在您已经看到了预先训练的鼓点生成器的作用,您可以详细研究训练过程。

GAN是一种深度学习网络,它生成的数据具有与训练数据相似的特征。

GAN由两个一起训练的网络组成发电机和一个鉴频器

  • 生成器——给定一个向量或随机值作为输入,该网络生成与训练数据相同结构的数据。欺骗鉴别器是生成器的工作。

  • 鉴别器——给定一批包含来自训练数据和生成数据的观测值的数据,该网络试图将这些观测值分类为真实的或生成的。

为了最大限度地提高发生器的性能,当给定生成的数据时,最大限度地降低鉴别器的损耗。也就是说,生成器的目标是生成鉴别器分类为真实的数据。为了使鉴别器的性能最大化,当给定几批真实数据和生成数据时,尽量减少鉴别器的损失。理想情况下,这些策略会产生一个生成令人信服的真实数据的生成器,以及一个学习了训练数据特征的强特征表示的鉴别器。

在本例中,您训练生成器创建鼓点的假时频短时傅立叶变换(STFT)表示。你训练鉴别器来识别真正的STFTs。您可以通过计算真实鼓点节拍的短录音的STFT来创建真正的STFT。

负荷训练数据

使用鼓声效果数据集[1]训练GAN。下载并提取数据集。

网址='http://deepyeti.ucsd.edu/cdonahue/wavegan/data/drums.tar.gz';downloadFolder = tempdir;文件名= fullfile (downloadFolder,“drums_dataset.tgz”);drumsFolder = fullfile (downloadFolder,“鼓”);如果~存在(drumsFolder“dir”) disp ('正在下载鼓声效果数据集(218MB)…') websave(文件名,url);解压(文件名,downloadFolder)结束

创建一个audioDatastore(音频工具箱)对象,该对象指向数据集。

广告= audioDatastore (drumsFolder,“IncludeSubfolders”,真正的);

定义发电机网络

定义一个网络,从1 × 1 × 100的随机值数组生成STFTs。创建一个网络,将1乘1乘100的数组升级为128乘128乘1的数组,使用的是一个完全连接层,然后是一个重塑层和一系列带有ReLU层的转置卷积层。

这个图显示了信号通过发生器时的尺寸。生成器体系结构在[1]的表4中定义。

发电机网络在中定义modelGenerator,本示例的最后将包含它。

定义鉴别器网络

定义一个对实际和生成的128×128 STFT进行分类的网络。

创建一个网络,该网络采用128 × 128的图像,并使用一系列卷积层与漏泄的ReLU层和完全连接层进行卷积,输出标量预测得分。

这张图显示了信号通过鉴别器时的尺寸。鉴别器结构定义在[1]的表5中。

中定义了鉴别器网络modelDiscriminator,本示例的最后将包含它。

生成真实的Drumbeat训练数据

从数据存储中的鼓点信号生成STFT数据。

定义STFT参数。

fftLength = 256;赢得=损害(fftLength,“周期”);overlapLength = 128;

为了加快处理速度,将特征提取分散到多个使用parfor

首先,确定数据集的分区数。如果您没有并行计算工具箱™,请使用单个分区。

如果~ isempty(版本(“平行”) pool = gcp;numPar = numpartitions(广告、池);其他的numPar = 1;结束

对于每个分区,从数据存储中读取并计算STFT。

parforii = 1:numPar subds = partition(ads,numPar,ii);应变= 0 (fftLength / 2 + 1128 1元素个数(subds.Files));idx = 1:numel(subds. files) x = read(subds);如果长度(x) > fftLength * 64如果信号太短,请延长x = x (1: fftLength * 64);结束%从双精度转换为单精度x =单(x);比例信号X = X ./ max(abs(X));%零填充以确保stft返回128个窗口。X = [X;0 (overlapLength 1“喜欢”,x)];S0=标准英尺(x,“窗口”“OverlapLength”overlapLength,“中心”、假);%从双面转换为单面。S = S0 (1:129:);S = abs(年代);应变(::,:,idx) = S;结束STrainC{2} =应变;结束

将输出转换为四维数组,并沿四维使用STFTs。

应变=猫(4,STrainC {:});

将数据转换为对数尺度,以更好地与人类感知一致。

= log(STrain + 1e-6);

将训练数据归一化,使其均值和单位标准差均为零。

计算每个频率仓的STFT均值和标准差。

SMean = mean(STrain,[2 3 4]);std = std(菌株,1,[2 3 4]);

标准化每个频率单元。

应变= (STrain-SMean)。/ SStd;

计算的STFTs具有无界值。按照[1]的方法,将光谱裁剪为3个标准差,再标度为[-1 1],使数据有界。

应变=应变/3;Y=重塑(应变,努梅尔(应变),1);Y(Y<-1)=-1;Y(Y>1)=1;应变=重塑(Y,尺寸(应变));

丢弃最后一个频率箱,以迫使STFT箱的数量为2的幂(这在卷积层中很管用)。

张力= (1:end-1,:,::);

排列尺寸,准备馈送到鉴别器。

STrain = permute(STrain,[2 1 3 4]);

指定培训选项

训练1000个纪元的64个小批量。

maxEpochs = 1000;miniBatchSize = 64;

计算使用数据所需的迭代次数。

numIterationsPerEpoch =地板(大小(压力,4)/ miniBatchSize);

指定Adam优化的选项。将生成器和鉴别器的学习速率设置为0.0002.对于两个网络,使用梯度衰减系数为0.5和平方梯度衰减系数为0.999。

learnRateGenerator=0.0002;learnRateDiscriminator=0.0002;gradientDecayFactor=0.5;squaredGradientDecayFactor=0.999;

在可用的GPU上进行训练。使用GPU需要并行计算工具箱™。

executionEnvironment =“自动”

初始化生成器和鉴别器权重initializeGeneratorWeightsinitializeDiscriminatorWeights函数返回使用gloot均匀初始化获得的随机权值。本示例的最后包含了这些函数。

generatorParameters = initializeGeneratorWeights;discriminatorParameters = initializeDiscriminatorWeights;

火车模型

使用自定义训练循环训练模型。在每次迭代时循环训练数据并更新网络参数。

对于每个纪元,洗牌训练数据,并在小批数据上循环。

为每个mini-batch:

  • 生成一个dlarray对象,该对象包含生成器网络的随机值数组。

  • 对于GPU训练,将数据转换为gpuArray(并行计算工具箱)对象。

  • 使用dlfeval辅助函数,模型鉴别梯度模型发生器半径

  • 使用adamupdate函数。

初始化Adam的参数。

trailingAvgGenerator = [];trailingAvgSqGenerator = [];trailingAvgDiscriminator = [];trailingAvgSqDiscriminator = [];

你可以设置saveCheckpoints真正的每10个纪元将更新的权重和状态保存到MAT文件中。如果训练中断,您可以使用此MAT文件恢复训练。对于本示例的目的,设置saveCheckpoints

saveCheckpoints = false;

指定发电机输入的长度。

numLatentInputs = 100;

训练甘。这可能需要几个小时来运行。

迭代= 0;历元=1:maxEpochs%洗牌数据。idx=randperm(大小(应变,4));应变=应变(:,:,:,idx);%在小批量上循环。index = 1:numIterationsPerEpoch iteration = iteration + 1;%读取小批数据。dlX =应变(:,:,:,(索引1)* miniBatchSize + 1:指数* miniBatchSize);dlX = dlarray (dlX,“SSCB”);为发电机网络产生潜在的输入。Z=2*(兰特(1,1,numLatentInputs,miniBatchSize,“单身”) - 0.5);dlZ = dlarray (Z);%如果在GPU上进行训练,则将数据转换为gpuArray。如果(b)执行环境==“自动”&& canUseGPU) || executionEnvironment ==“图形”dlZ = gpuArray (dlZ);dlX = gpuArray (dlX);结束使用dlfeval和% |modelDiscriminatorGradients| helper函数。gradientsDiscriminator =...dlfeval (@modelDiscriminatorGradients discriminatorParameters、generatorParameters dlX, dlZ);%更新鉴别器网络参数。[discriminatorParameters, trailingAvgDiscriminator trailingAvgSqDiscriminator] =...adamupdate (discriminatorParameters gradientsDiscriminator,...trailingAvgDiscriminator trailingAvgSqDiscriminator,迭代,...learnRateDiscriminator、gradientDecayFactor squaredGradientDecayFactor);为发电机网络产生潜在的输入。Z=2*(兰特(1,1,numLatentInputs,miniBatchSize,“单身”) - 0.5);dlZ = dlarray (Z);%如果在GPU上进行训练,则将数据转换为gpuArray。如果(b)执行环境==“自动”&& canUseGPU) || executionEnvironment ==“图形”dlZ = gpuArray (dlZ);结束使用dlfeval和%| modelGeneratorGradients |辅助函数。gradientsGenerator =...dlfeval (@modelGeneratorGradients discriminatorParameters generatorParameters, dlZ);%更新生成器网络参数。[generatorParameters, trailingAvgGenerator trailingAvgSqGenerator] =...adamupdate (generatorParameters gradientsGenerator,...trailingAvgGenerator,trailingAvgSqGenerator,迭代,...learnRateGenerator、gradientDecayFactor squaredGradientDecayFactor);结束%每10次迭代,将训练快照保存到MAT文件中。如果saveCheckpoints&&mod(历元,10)=0 fprintf('Epoch %d out %d complete\n'时代,maxEpochs);%在训练中断时保存检查点。保存(“audiogancheckpoint.mat”...“generatorParameters”“鉴别器参数”...“trailingAvgDiscriminator”“trailingAvgSqDiscriminator”...“trailingAvgGenerator”“trailingAvgSqGenerator”“迭代”);结束结束

合成的声音

既然您已经训练了这个网络,就可以更详细地研究合成过程了。

经过训练的鼓点发生器从随机值的输入数组中合成短时傅里叶变换(STFT)矩阵。逆STFT (ISTFT)操作将时频STFT转换为合成的时域音频信号。

加载预先训练过的发电机的重量。这些权重是通过运行前一节强调的训练1000个纪元获得的。

负载(matFileName“generatorParameters”“SMean”“SStd”);

生成器使用1 × 1 × 100的随机值向量作为输入。生成一个样本输入向量。

numLatentInputs = 100;dlZ = dlarray(2 * (rand(1,1,numLatentInputs,1, 1))“单身”) - 0.5);

将随机向量传递给生成器以创建STFT图像。generatorParameters是一个包含预先训练过的发电机重量的结构。

dlXGenerated = modelGenerator (dlZ generatorParameters);

把STFTdlarray到一个单精度矩阵。

S = dlXGenerated.extractdata;

转置STFT使其尺寸与伊斯特夫特函数。

=年代。”;

STFT是一个128 × 128的矩阵,其中第一个维度表示从0到8 kHz线性间隔的128个频箱。该生成器经过训练,从FFT长度256生成单侧短时傅立叶变换,省略了最后一个二进制。通过在STFT中插入一行0来重新引入那个箱子。

S = [S;0 (1128)];

还原生成用于训练的STFTs时使用的归一化和缩放步骤。

S = S * 3;S = (S *SStd) + SMean;

将STFT从日志域转换为线性域。

S = exp(年代);

将STFT从单面转换为双面。

S =[年代;S (end-1: 1:2,)];

用零填充以删除窗口边缘效果。

S = [0 (256,100) S 0 (256,100)];

STFT矩阵不包含任何相位信息。使用快速版本的Griffin-Lim算法与20次迭代估计信号相位和产生音频样本。

myAudio = stftmag2sig(年代,256,...“频率范围”双侧的...“窗口”损害(256,“周期”),...“OverlapLength”, 128,...“MaxIterations”, 20岁,...“方法”“fgla”);myAudio = myAudio. / max (abs (myAudio), [],“所有”);myAudio = myAudio(128 * 100:结束- 128 * 100);

听合成的鼓点。

声音(myAudio fs)

绘制合成鼓点。

t =(0:长度(myAudio) 1) / fs;情节(t, myAudio)网格xlabel(“时间(s)”)头衔(“合成氮化镓的声音”

绘制合成鼓点的短时傅立叶变换图。

图stft (myAudio fs,“窗口”损害(256,“周期”),“OverlapLength”, 128);

模型生成器函数

modelGenerator函数将1乘1乘100的数组(dlX)升级为128乘128乘1的数组(dlY)。参数是一种承载生成器层重量的结构。生成器体系结构在[1]的表4中定义。

函数dlY = modelGenerator(dlX,parameters)“数据格式”“SSCB”);dlY =重塑(dlY,[1024 4 4 size(dlY,2)]);dlY = permute(dlY,[3 2 1 4]);海底= relu(海底);海底= dltranspconv(海底,parameters.Conv1.Weights parameters.Conv1.Bias,“步”2,“种植”“相同”“数据格式”“SSCB”);海底= relu(海底);海底= dltranspconv(海底,parameters.Conv2.Weights parameters.Conv2.Bias,“步”2,“种植”“相同”“数据格式”“SSCB”);海底= relu(海底);海底= dltranspconv(海底,parameters.Conv3.Weights parameters.Conv3.Bias,“步”2,“种植”“相同”“数据格式”“SSCB”);海底= relu(海底);海底= dltranspconv(海底,parameters.Conv4.Weights parameters.Conv4.Bias,“步”2,“种植”“相同”“数据格式”“SSCB”);海底= relu(海底);海底= dltranspconv(海底,parameters.Conv5.Weights parameters.Conv5.Bias,“步”2,“种植”“相同”“数据格式”“SSCB”);海底=双曲正切(海底);结束

模型鉴别器函数

modelDiscriminator函数获取128 × 128的图像并输出标量预测得分。鉴别器结构定义在[1]的表5中。

函数dlY=modelscriminator(dlX,parameters)dlY=dlconv(dlX,parameters.Conv1.Weights,parameters.Conv1.Bias,“步”2,“填充”“相同”);dlY=leakyrelu(dlY,0.2);dlY=dlconv(dlY,parameters.Conv2.权重,parameters.Conv2.偏差,“步”2,“填充”“相同”);dlY=leakyrelu(dlY,0.2);dlY=dlconv(dlY,parameters.Conv3.权重,parameters.Conv3.Bias,“步”2,“填充”“相同”);dlY=leakyrelu(dlY,0.2);dlY=dlconv(dlY,parameters.Conv4.权重,parameters.Conv4.Bias,“步”2,“填充”“相同”);dlY=leakyrelu(dlY,0.2);dlY=dlconv(dlY,parameters.Conv5.权重,parameters.Conv5.Bias,“步”2,“填充”“相同”);海底= leakyrelu(海底,0.2);海底= stripdims(海底);dlY = permute(dlY,[3 2 1 4]);海底=重塑(海底,4 * 4 * 64 * 16,元素个数(海底)/ (4 * 4 * 64 * 16));重量= parameters.FC.Weights;偏见= parameters.FC.Bias;海底= fullyconnect(海底,重量、偏见,“数据格式”“CB”);结束

模型鉴别梯度函数

模型鉴别梯度函数接受生成器和鉴别器参数作为输入generatorParametersdiscriminatorParameters,一小批输入数据dlX,以及一个随机值数组dlZ,并返回鉴别器损失相对于网络中可学习参数的梯度。

函数gradientsDiscriminator = modelDiscriminatorGradients(discriminatorParameters, generatorParameters, dlX, dlZ)%用鉴别器网络计算真实数据的预测。dlYPred = modelDiscriminator (dlX discriminatorParameters);%使用鉴别器网络计算生成数据的预测。dlXGenerated = modelGenerator (dlZ generatorParameters);dlYPredGenerated = modelDiscriminator (dlarray (dlXGenerated“SSCB”), discriminatorParameters);%计算氮化镓损耗lossDiscriminator = ganDiscriminatorLoss (dlYPred dlYPredGenerated);%对于每个网络,计算相对于损失的梯度。gradientsDiscriminator = dlgradient (lossDiscriminator discriminatorParameters);结束

模型生成器梯度函数

模型发生器半径函数将鉴别器和生成器可学习的参数以及一组随机值作为输入dlZ,并返回发电机损耗相对于网络中可学习参数的梯度。

函数gradientsGenerator = modelGeneratorGradients(discriminatorParameters, generatorParameters, dlZ)%使用鉴别器网络计算生成数据的预测。dlXGenerated = modelGenerator (dlZ generatorParameters);dlYPredGenerated = modelDiscriminator (dlarray (dlXGenerated“SSCB”), discriminatorParameters);%计算氮化镓损耗lossGenerator = ganGeneratorLoss (dlYPredGenerated);%对于每个网络,计算相对于损失的梯度。梯度发生器=dlgradient(损耗发生器、发生器参数);结束

鉴频器损失函数

鉴别器的目的是不被生成器愚弄。为了最大限度地提高鉴别器在真实图像和生成图像之间成功鉴别的概率,最小化鉴别器损失函数。生成器的损失函数遵循[1]中突出显示的DCGAN方法。

函数lossDiscriminator = ganDiscriminatorLoss(dlYPred,dlYPredGenerated) fake = dlarray(zeros(1,size(dlYPred,2))));真正的= dlarray(的(1、大小(dlYPred 2)));D_loss =意味着(sigmoid_cross_entropy_with_logits (dlYPredGenerated、假));D_loss = D_loss + mean(sigmoid_cross_entropy_with_logits(dlYPred,real));lossDiscriminator = D_loss / 2;结束

发电机损失函数

生成器的目标是生成鉴别器分类为“真实”的数据。为了最大限度地提高来自发生器的图像被鉴别器分类为真实图像的概率,最小化发生器损失函数。生成器的损失函数遵循[1]中强调的深度卷积生成对抗网络(DCGAN)方法。

函数lossGenerator = ganGeneratorLoss(dlYPredGenerated) real = dlarray(ones(1,size(dlYPredGenerated,2)));lossGenerator =意味着(sigmoid_cross_entropy_with_logits (dlYPredGenerated,实际));结束

鉴频器权值初始化

initializeDiscriminatorWeights使用gloria算法初始化鉴别器权值。

函数鉴别器参数=初始化描述器权重过滤器大小=[5];尺寸=64;% Conv2D权重= iGlorotInitialize([filterSize(1) filterSize(2) 1 dim]); / /初始化偏见= 0(1,- 1,昏暗,“单身”);discriminatorParameters.Conv1。重量= dlarray(重量);discriminatorParameters.Conv1。偏见= dlarray(偏差);% Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) dim 2*dim]); / /指定权重偏见= 0(1 1 2 *昏暗,“单身”);discriminatorParameters.Conv2。重量= dlarray(重量);discriminatorParameters.Conv2。偏见= dlarray(偏差);% Conv2D权重=iGlorotInitialize([filterSize(1)filterSize(2)2*尺寸4*尺寸];偏差=零(1,1,4*dim,“单身”);discriminatorParameters.Conv3。重量= dlarray(重量);discriminatorParameters.Conv3。偏见= dlarray(偏差);% Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) 4*dim 8*dim]); / /设置权重偏见= 0(1 1 8 *昏暗,“单身”);discriminatorParameters.Conv4.Weights=dlarray(Weights);discriminatorParameters.Conv4.Bias=dlarray(Bias);% Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) 8*dim 16*dim]); / /设置权重偏见= 0(1,1,16 *昏暗,“单身”);discriminatorParameters.Conv5。重量= dlarray(重量);discriminatorParameters.Conv5。偏见= dlarray(偏差);%完全连接weights = iGlorotInitialize([1,4 * 4 * dim * 16]);偏见= 0 (1,1,“单身”);discriminatorParameters.FC.Weights = dlarray(重量);discriminatorParameters.FC.Bias = dlarray(偏差);结束

发电机权重的初始值设定项

initializeGeneratorWeights使用gloria算法初始化生成器权重。

函数dim = 64;%稠密1重量= iGlorotInitialize((暗* 256100));偏见= 0(暗* 256 1“单身”);generatorParameters.FC.Weights = dlarray(重量);generatorParameters.FC.Bias = dlarray(偏差);filterSize = [5 5];%Trans-Conv2D权重=IGLOROTILIZE([filterSize(1)filterSize(2)8*dim 16*dim]);偏差=零(1,1,dim*8,“单身”);generatorParameters.Conv1.Weights=dlarray(权重);generatorParameters.Conv1.Bias=dlarray(偏差);%Trans-Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) 4*dim 8*dim]); / /设置权重偏见= 0(1,1,暗淡的* 4“单身”);generatorParameters.Conv2。重量= dlarray(重量);generatorParameters.Conv2。偏见= dlarray(偏差);%Trans-Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) 2*dim 4*dim]); / /指定权重偏见= 0(1,1,昏暗的* 2,“单身”);generatorParameters.Conv3。重量= dlarray(重量);generatorParameters.Conv3。偏见= dlarray(偏差);%Trans-Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) dim 2*dim]); / /指定权重偏见= 0(1,- 1,昏暗,“单身”);generatorParameters.Conv4。重量= dlarray(重量);generatorParameters.Conv4。偏见= dlarray(偏差);%Trans-Conv2D权重= iGlorotInitialize([filterSize(1) filterSize(2) 1 dim]); / /初始化偏见= 0 (1,1,1,“单身”);generatorParameters.Conv5。重量= dlarray(重量);generatorParameters.Conv5。偏见= dlarray(偏差);结束

合成鼓声

synthesizeDrumBeat使用预训练网络来合成鼓拍。

函数y = synthesizeDrumBeat持续的pGeneratorParameters pMean pSTD如果isempty (pGeneratorParameters)%如果MAT文件不存在,请下载文件名=“drumGeneratorWeights.mat”;负载(文件名,“SMean”“SStd”“generatorParameters”);pMean = SMean;pSTD = SStd;pGeneratorParameters = generatorParameters;结束生成随机向量dlZ=dlarray(2*(兰特(1,1100,1,“单身”) - 0.5);%生成谱图dlXGenerated = modelGenerator (dlZ pGeneratorParameters);%转换从美元到单一S = dlXGenerated.extractdata;=年代。”;%零填充以删除边缘效果S = [S;0 (1128)];将训练步骤倒过来S = S * 3;S = (S *pSTD) + pMean;S = exp(年代);%要双面的S = [S;S (end-1: 1:2,)];起始和结束都为零的% PadS = [0 (256,100) S 0 (256,100)];%使用快速Griffin-Lim算法重建信号。myAudio=stftmag2sig(聚集),256,...“频率范围”双侧的...“窗口”损害(256,“周期”),...“OverlapLength”, 128,...“MaxIterations”, 20岁,...“方法”“fgla”);myAudio = myAudio. / max (abs (myAudio), [],“所有”);y=myAudio(128*100:end-128*100);结束

效用函数

函数max(x, 0) - x .* z + log(1 + exp(-abs(x)));结束函数w = iGlorotInitialize(深圳)如果numel(sz)=2 numinput=sz(2);numoutput=sz(1);其他的numinput=prod(sz(1:3));numOutputs=prod(sz([1,2,4]);结束乘法器=√(2 / (numInputs + numOutputs));W =乘数*根号(3)* (2 * rand(sz),“单身”) - 1);结束

参考文献

[1] Donahue, C., J. McAuley, M. puckett . 2019。“敌对的音频合成。”ICLR。