主要内容

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

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

简介

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

GANs在音频和语音处理领域引起了极大的兴趣。应用包括文本到语音合成、语音转换和语音增强。

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

用预先训练的GAN合成音频

在从头开始训练GAN之前,您将使用预训练的GAN生成器来合成鼓点。

下载预训练的生成器。

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

这个函数synthesizeDrumBeat调用一个预先训练好的网络来合成以16khz采样的鼓点。的synthesizeDrumBeat函数包含在本例的末尾。

合成一段鼓点,听一听。

鼓=合成鼓点;Fs = 16e3;声音(鼓,fs)

绘制合成的鼓点。

T =(0:长度(鼓)-1)/fs;情节(t,鼓)网格包含(“时间(s)”)标题(“合成鼓点”

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

创建一个反射器对象并打开其参数调谐器UI。这个UI使您能够调优反射器模拟运行时的参数。

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

创建一个时间范围对象来可视化鼓点。

Ts =时隙(“SampleRate”fs,...“TimeSpanSource”“属性”...“TimeSpanOverrunAction”“滚动”...“时间间隔”10...“BufferLength”, 10 * 256 * 64,...“ShowGrid”,真的,...“YLimits”[1]);

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

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

培训GAN

现在您已经看到了预先训练的鼓点生成器的运行情况,接下来可以详细研究训练过程。

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

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

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

  • 判别器——给定包含来自训练数据和生成数据的观察结果的数据批次,该网络试图将观察结果分类为真实的或生成的。

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

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

负荷训练数据

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

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

创建一个audioDatastore对象,该对象指向鼓数据集。

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

定义发电机网络

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

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

发电机网络定义在modelGenerator,它包含在本示例的末尾。

定义鉴别器网络

定义一个网络,对真实的和生成的128 × 128 stft进行分类。

创建一个使用128 × 128图像的网络,并使用一系列带有泄漏的ReLU层的卷积层输出标量预测评分,然后是完全连接的层。

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

中定义了鉴别器网络modelDiscriminator,它包含在本示例的末尾。

生成真实的鼓点训练数据

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

定义STFT参数。

fftLength = 256;win = hann(fftLength,“周期”);overlapLength = 128;

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

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

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

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

parforii = 1:numPar subds =分区(ads,numPar,ii);STrain = 0 (fftLength/2+1,128,1, nummel (subds.Files));idx = 1: number (subds. files) x = read(subds);如果长度(x) > fftLength*64%如果信号太短,则延长信号x = x(1:fftLength*64);结束从双精度转换为单精度X =单(X);缩放信号X = X ./ max(abs(X));% 0 -pad确保stft返回128个窗口。X = [X;0 (overlapLength 1“喜欢”, x));S0 = stft(x,“窗口”,赢了,“OverlapLength”overlapLength,“中心”、假);%从双面转换为单面。S = s0 (1:29,:);S = abs(S);STrain(:,:,:,idx) = S;结束STrainC{ii} = STrain;结束

将输出转换为带有stft的四维数组。

(4,STrainC{:});

将数据转换为对数刻度,以便更好地与人类的感知保持一致。

STrain = log(STrain + 1e-6);

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

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

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

归一化每个频率仓。

STrain = (STrain- smean)./SStd;

计算的stft具有无界值。遵循[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个epoch中使用64个小批量进行训练。

maxEpochs = 1000;miniBatchSize = 64;

计算消费数据所需的迭代次数。

numIterationsPerEpoch = floor(size(STrain,4)/miniBatchSize);

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

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

如果有GPU,可以在GPU上进行训练。使用GPU需要并行计算工具箱™。

executionEnvironment =“汽车”

初始化生成器和鉴别器权重。的initializeGeneratorWeights而且initializeDiscriminatorWeights函数返回使用gloriot统一初始化获得的随机权重。本例的最后包含了函数。

generatorParameters = initializeGeneratorWeights;discriminatorParameters = initializeDiscriminatorWeights;

火车模型

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

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

对于每个小批量:

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

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

  • 评估模型梯度使用dlfeval(深度学习工具箱)辅助函数,modelDiscriminatorGradients而且modelGeneratorGradients

  • 方法更新网络参数adamupdate(深度学习工具箱)函数。

初始化Adam的参数。

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

你可以设置saveCheckpoints真正的以每十次将更新的权重和状态保存到MAT文件中。然后,如果训练中断,您可以使用这个MAT文件恢复训练。为了本例的目的,设置saveCheckpoints

saveCheckpoints = false;

指定生成器输入的长度。

numLatentInputs = 100;

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

迭代= 0;epoch = 1: maxepoch% Shuffle数据。idx = randperm(size(STrain,4));应变=应变(:,:,:,idx);在小批上循环。index = 1:numIterationsPerEpoch迭代=迭代+ 1;读取小批数据。dlX = STrain(:,:,:,(index-1)*miniBatchSize+1:index*miniBatchSize);dlX = dlarray(dlX,“SSCB”);为发电机网络生成潜在输入。Z = 2 * (rand(1,1,numLatentInputs,miniBatchSize,“单一”) - 0.5);dlZ = dlarray(Z);如果在GPU上训练,则将数据转换为gpuArray。如果(executionEnvironment = =“汽车”&& canUseGPU) || executionEnvironment ==“图形”dlZ = gpuArray(dlZ);dlX = gpuArray(dlX);结束使用dlfeval和% |modelDiscriminatorGradients|辅助函数。gradientsDiscriminator =...dlfeval (@modelDiscriminatorGradients discriminatorParameters、generatorParameters dlX, dlZ);更新鉴别器网络参数。[discriminatorParameters, trailingAvgDiscriminator trailingAvgSqDiscriminator] =...adamupdate (discriminatorParameters gradientsDiscriminator,...trailingAvgDiscriminator trailingAvgSqDiscriminator,迭代,...learnRateDiscriminator、gradientDecayFactor squaredGradientDecayFactor);为发电机网络生成潜在输入。Z = 2 * (rand(1,1,numLatentInputs,miniBatchSize,“单一”) - 0.5);dlZ = dlarray(Z);如果在GPU上训练,则将数据转换为gpuArray。如果(executionEnvironment = =“汽车”&& canUseGPU) || executionEnvironment ==“图形”dlZ = gpuArray(dlZ);结束使用dlfeval和% |modelGeneratorGradients| helper函数。gradientsGenerator =...dlfeval (@modelGeneratorGradients discriminatorParameters generatorParameters, dlZ);更新发电机网络参数。[generatorParameters, trailingAvgGenerator trailingAvgSqGenerator] =...adamupdate (generatorParameters gradientsGenerator,...trailingAvgGenerator trailingAvgSqGenerator,迭代,...learnRateGenerator、gradientDecayFactor squaredGradientDecayFactor);结束每10次迭代,保存一个训练快照到一个MAT文件。如果saveCheckpoints && mod(epoch,10)==0 fprintf('纪元%d从%d完成\n'时代,maxEpochs);%保存检查点,以防训练中断。保存(“audiogancheckpoint.mat”...“generatorParameters”“discriminatorParameters”...“trailingAvgDiscriminator”“trailingAvgSqDiscriminator”...“trailingAvgGenerator”“trailingAvgSqGenerator”“迭代”);结束结束

合成的声音

现在你已经训练了网络,你可以更详细地研究合成过程。

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

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

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

生成器以1 × 1 × 100的随机值向量作为输入。生成一个示例输入向量。

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

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

dlXGenerated = modelGenerator(dlZ,generatorParameters);

转换STFTdlarray到一个单精度矩阵。

S = dlXGenerated.extractdata;

对STFT进行转置,使其尺寸与istft函数。

S = S.';

STFT是一个128 × 128矩阵,其中第一个维度表示从0到8 kHz线性间隔的128个频率箱。生成器被训练从256的FFT长度中生成单侧STFT,省略最后一个bin。通过在STFT中插入一行零来重新引入该bin。

S = [S;0 (1128)];

恢复生成用于训练的stft时使用的规范化和缩放步骤。

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

将STFT从对数域转换为线性域。

S = exp(S);

将STFT从单面转换为双面。

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

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

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

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

myAudio = stftmag2sig(S,256,...“FrequencyRange”双侧的...“窗口”损害(256,“周期”),...“OverlapLength”, 128,...“MaxIterations”, 20岁,...“方法”“fgla”);myAudio = myAudio./max(abs(myAudio),[],“所有”);myAudio = myAudio(128*100:end-128*100);

听合成的鼓点。

声音(myAudio fs)

绘制合成的鼓点。

t = (0:length(myAudio)-1)/fs;情节(t, myAudio)网格包含(“时间(s)”)标题(“合成GAN声音”

绘制合成鼓点的STFT。

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

模型生成器函数

modelGenerator函数将1 × 1 × 100数组(dlX)升级为128 × 128 × 1数组(dlY)。参数是保存生成器层权重的结构。生成器架构定义在[1]的表4中。

函数dlY = modelGenerator(dlX,parameters) dlY = fulllyconnect (dlX,parameters. fc . weights,parameters. fc . bias,“Dataformat”“SSCB”);dlY =重塑(dlY,[1024 4 4 size(dlY,2)]);ly = permute(ly,[3 2 1 4]);dlY = relu(dlY);dlY = dltranspconv(dlY,parameters.Conv1.Weights,parameters.Conv1.Bias,“步”2,“种植”“相同”“DataFormat”“SSCB”);dlY = relu(dlY);dlY = dltranspconv(dlY,parameters.Conv2.Weights,parameters.Conv2.Bias,“步”2,“种植”“相同”“DataFormat”“SSCB”);dlY = relu(dlY);dlY = dltranspconv(dlY,parameters.Conv3.Weights,parameters.Conv3.Bias,“步”2,“种植”“相同”“DataFormat”“SSCB”);dlY = relu(dlY);dlY = dltranspconv(dlY,parameters.Conv4.Weights,parameters.Conv4.Bias,“步”2,“种植”“相同”“DataFormat”“SSCB”);dlY = relu(dlY);dlY = dltranspconv(dlY,parameters.Conv5.Weights,parameters.Conv5.Bias,“步”2,“种植”“相同”“DataFormat”“SSCB”);dlY = tanh(dlY);结束

模型鉴别器函数

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

函数dlY = modelDiscriminator(dlX,parameters . conv1 . weights,parameters. conv1 . bias,“步”2,“填充”“相同”);ly = leakyrelu(ly,0.2);dlY = dlconv(dlY,parameters.Conv2.Weights,parameters.Conv2.Bias,“步”2,“填充”“相同”);ly = leakyrelu(ly,0.2);dlY = dlconv(dlY,parameters.Conv3.Weights,parameters.Conv3.Bias,“步”2,“填充”“相同”);ly = leakyrelu(ly,0.2);dlY = dlconv(dlY,parameters.Conv4.Weights,parameters.Conv4.Bias,“步”2,“填充”“相同”);ly = leakyrelu(ly,0.2);dlY = dlconv(dlY,parameters.Conv5.Weights,parameters.Conv5.Bias,“步”2,“填充”“相同”);ly = leakyrelu(ly,0.2);dlY = stripdim (dlY);ly = permute(ly,[3 2 1 4]);海底=重塑(海底,4 * 4 * 64 * 16,元素个数(海底)/ (4 * 4 * 64 * 16));weights = parameters.FC.Weights;偏差=参数。fc .偏差;ly =完全连接(ly,权重,偏差,“Dataformat”“CB”);结束

模型鉴别器梯度函数

modelDiscriminatorGradients函数将生成器和鉴别器参数作为输入generatorParameters而且discriminatorParameters,一小批输入数据dlX,和一个随机值的数组dlZ,并返回判别器损失相对于网络中可学习参数的梯度。

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

模型生成器梯度函数

modelGeneratorGradients函数将可学习参数和随机值数组作为判别器和生成器的输入dlZ,并返回发电机损耗相对于网络中可学习参数的梯度。

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

鉴别器损失函数

鉴别器的目标是不被生成器愚弄。为了最大化鉴别器成功鉴别真实图像和生成图像的概率,最小化鉴别器损失函数。发电机的损失函数遵循[1]中强调的DCGAN方法。

函数lossDiscriminator = ganDiscriminatorLoss(dlYPred,dlYPredGenerated) fake = dlarray(0 (1,size(dlYPred,2)));real = dlarray(ones(1,size(dlYPred,2)));D_loss = mean(sigmoid_cross_entropy_with_logits(dlYPredGenerated,fake));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 = mean(sigmoid_cross_entropy_with_logits(dlYPredGenerated,real));结束

Discriminator Weights初始化器

initializeDiscriminatorWeights使用格洛洛特算法初始化鉴别器权重。

函数discriminatorParameters = initializeDiscriminatorWeights filterSize = [5 5];Dim = 64;% Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) 1 dim]);偏差= 0(1,1,暗淡,“单一”);discriminatorParameters.Conv1。Weights = dlarray(Weights);discriminatorParameters.Conv1。偏差= dlarray(偏差);% Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) dim 2*dim]);偏差=零(1,1,2*dim,“单一”);discriminatorParameters.Conv2。Weights = dlarray(Weights);discriminatorParameters.Conv2。偏差= dlarray(偏差);% Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) 2*dim 4*dim]);偏差=零(1,1,4*dim,“单一”);discriminatorParameters.Conv3。Weights = dlarray(Weights);discriminatorParameters.Conv3。偏差= dlarray(偏差);% Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) 4*dim 8*dim]);偏差=零(1,1,8*dim,“单一”);discriminatorParameters.Conv4。Weights = dlarray(Weights);discriminatorParameters.Conv4。偏差= dlarray(偏差);% Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) 8*dim 16*dim]);偏差=零(1,1,16*dim,“单一”);discriminatorParameters.Conv5。Weights = dlarray(Weights);discriminatorParameters.Conv5。偏差= dlarray(偏差);%全连接weights = iGlorotInitialize([1,4 * 4 * dim * 16]);偏差= 0 (1,1,“单一”);discriminatorParameters.FC.Weights = dlarray(weights);discriminatorParameters.FC.Bias = dlarray(偏差);结束

生成器权重初始化器

initializeGeneratorWeights使用格洛洛特算法初始化生成器权重。

函数generatorParameters = initializeGeneratorWeights dim = 64;%密度1weights = iGlorotInitialize([dim*256,100]);偏差= 0 (dim*256,1,“单一”);generatorParameters.FC.Weights = dlarray(weights);generatorParameters.FC.Bias = dlarray(偏差);filterSize = [5 5];% Trans Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) 8*dim 16*dim]);偏差= 0 (1,1,dim*8,“单一”);generatorParameters.Conv1。Weights = dlarray(Weights);generatorParameters.Conv1。偏差= dlarray(偏差);% Trans Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) 4*dim 8*dim]);偏差= 0 (1,1,dim*4,“单一”);generatorParameters.Conv2。Weights = dlarray(Weights);generatorParameters.Conv2。偏差= dlarray(偏差);% Trans Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) 2*dim 4*dim]);偏差= 0 (1,1,dim*2,“单一”);generatorParameters.Conv3。Weights = dlarray(Weights);generatorParameters.Conv3。偏差= dlarray(偏差);% Trans Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) dim 2*dim]);偏差= 0(1,1,暗淡,“单一”);generatorParameters.Conv4。Weights = dlarray(Weights);generatorParameters.Conv4。偏差= dlarray(偏差);% Trans Conv2Dweights = iGlorotInitialize([filterSize(1) filterSize(2) 1 dim]);偏差= 0 (1,1,1,“单一”);generatorParameters.Conv5。Weights = dlarray(Weights);generatorParameters.Conv5。偏差= dlarray(偏差);结束

合成鼓声

synthesizeDrumBeat使用预先训练好的网络合成鼓点。

函数y = synthesizeDrumBeat持续的pGeneratorParameters pMean ppd如果isempty (pGeneratorParameters)如果MAT文件不存在,请下载文件名=“drumGeneratorWeights.mat”;负载(文件名,“SMean”“SStd”“generatorParameters”);pMean = SMean;pSTD = SStd;pGeneratorParameters = generatorParameters;结束生成随机向量dlZ = dlarray(2 * (rand(1,1,100,1),“单一”) - 0.5));生成频谱图dlXGenerated = modelGenerator(dlZ,pGeneratorParameters);从单数组转换为单数组S = dlXGenerated.extractdata;S = S.';%零填充删除边缘效果S = [S;0 (1128)];与训练相反的步骤S = S * 3;S = (S *pSTD) + pMean;S = exp(S);做成两面的S = [S;S (end-1: 1:2,)];%末尾和开始处为零的PadS =[零(256,100)S零(256,100)];使用快速Griffin-Lim算法重建信号。myAudio = stftmag2sig(gather(S),256,...“FrequencyRange”双侧的...“窗口”损害(256,“周期”),...“OverlapLength”, 128,...“MaxIterations”, 20岁,...“方法”“fgla”);myAudio = myAudio./max(abs(myAudio),[],“所有”);y = myAudio(128*100:end-128*100);结束

效用函数

函数Out = sigmoid_cross_entropy_with_logits(x,z) Out = max(x, 0) - x .* z + log(1 + exp(-abs(x)));结束函数w = iGlorotInitialize(sz)如果numInputs = sz(2);numOutputs = sz(1);其他的numInputs = prod(sz(1:3));numOutputs = prod(sz([1 2 4]));结束乘数=根号(2 / (numInputs + numOutputs));W =乘数*根号(3)* (2 * rand(sz,“单一”) - 1);结束

参考

[1]多纳休,C.麦考利,M.帕克特,2019。“对抗性音频合成。”ICLR。