主要内容

火车生成对抗网络(GAN)合成声音

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

介绍

在生成对抗网络、发电机和鉴别器相互竞争提高一代质量。

甘斯已经产生了巨大的兴趣领域的音频和语音处理。应用包括语音合成,语音转换,语音增强。

这个例子中列车的无监督合成氮化镓音频波形。本例中的氮化镓生成敲击的声音。可以按照相同的方法生成其他类型的声音,包括演讲。

合成与Pre-Trained GAN音频

从头开始培训一个甘之前,使用pretrained GAN发电机合成敲击的声音。

下载pretrained生成器。

matFileName =“drumGeneratorWeights.mat”;loc = matlab.internal.examples.download金宝appSupportFile (“音频”,“GanAudioSynthesis /”+ matFileName);拷贝文件(loc pwd)

这个函数synthesizePercussiveSound所谓pretrained网络合成敲击的声音在16岁千赫采样。的synthesizePercussiveSound函数包含在这个例子。

合成一个敲击的声音,听它。

synthsound = synthesizePercussiveSound;fs = 16 e3;声音(synthsound fs)

画出合成敲击的声音。

t =(0:长度(synthsound) 1) / fs;情节(t, synthsound)网格包含(“时间(s)”)标题(“合成敲击的声音”)

您可以使用敲击的声音合成器与其他音频效果创建更复杂的应用程序。例如,您可以应用混响的合成敲击的声音。

创建一个反射器UI对象,并开放其参数调谐器。这个UI允许您调整反射器参数的模拟运行。

混响=反射镜(SampleRate = fs);parameterTuner(混响);

创建一个timescope对象可视化敲击的声音。

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

在一个循环中,合成敲击的声音和应用混响。使用参数调谐器UI调整混响。如果你想长时间的模拟运行,增加的价值loopCount参数。

loopCount = 20;2 = 1:loopCount synthsound = synthesizePercussiveSound;synthsound =混响(synthsound);ts (synthsound (: 1));soundsc (synthsound fs)暂停(0.5)结束

火车的氮化镓

现在您已经看到了pretrained敲击的声音发生器在行动,你可以详细调查的培训过程。

氮化镓是一种深入学习网络,与特征类似于训练数据生成数据。

GAN包含两个网络,火车在一起,发电机和一个鉴频器:

  • 发电机-向量或者随机值作为输入,该网络生成数据具有相同结构作为训练数据。发电机的工作是傻瓜鉴别器。

  • 鉴别器——鉴于批次的数据包含观察训练数据和生成的数据,这个网络尝试分类观察或生成一样真实。

发电机的性能最大化,最大化的损失时鉴别器生成的数据。,发电机的目的是生成数据,鉴别器分类是真实的。鉴频器的性能最大化,最小化损失鉴别器当批次的真实和生成数据。理想情况下,这些策略导致发电机产生令人信服的真实数据和鉴频器已经学会强大特性表征,是训练数据的特征。

在本例中,您的火车生成器来创建假的时频短时傅里叶变换(STFT)表示敲击的声音。你训练鉴别器识别是否STFT合成发生器或计算从一个真正的音频信号。您创建的真正STFTs计算短录音的STFT的敲击的声音。

负荷训练数据

火车GAN使用Freesound一次性敲击的声音数据集[2]。下载并提取数据集。删除任何文件许可,禁止商业用途。

url1 =“https://zenodo.org/record/4687854/files/one_shot_percussive_sounds.zip”;url2 =“https://zenodo.org/record/4687854/files/licenses.txt”;downloadFolder = tempdir;percussivesoundsFolder = fullfile (downloadFolder,“one_shot_percussive_sounds”);licensefilename = fullfile (percussivesoundsFolder,“licenses.txt”);如果~ datasetExists percussivesoundsFolder disp (“下载Freesound一次性敲击的声音数据集(112.6 MB)……”)解压缩(url1 downloadFolder) websave (licensefilename url2);removeRestrictiveLicence (percussivesoundsFolder licensefilename)结束

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

广告= audioDatastore (percussivesoundsFolder IncludeSubfolders = true);

定义发电机网络

定义一个网络,生成STFTs从1 -通过- 1 - 100随机值的数组。创建一个网络,高档1 -到- 1 - 128 - 100阵列-通过- 128 - 1阵列使用一个完全连接一层一层,后跟一个重塑和一系列的转置卷积层ReLU层。

这个图显示的尺寸信号穿过生成器。发电机架构定义在表4[1]

发电机网络中定义modelGenerator年底,包括这个例子。

定义鉴别器网络

定义一个网络,将真实的和128——- 128 STFTs生成。

创建一个网络,128 -,- 128图像和输出一个标量预测分数使用一系列的卷积层和漏ReLU层紧随其后的是一个完全连接层。

这图中显示的尺寸信号穿过鉴别器。表5中定义的鉴别器体系结构[1]

鉴频器网络中定义modelDiscriminator年底,包括这个例子。

产生真正的敲击的声音训练数据

生成STFT的敲击的声音信号数据的数据存储。

定义了STFT参数。

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

加快处理、特征提取分发到多个工人使用parfor

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

如果canUseParallelPool池=质量;numPar = numpartitions(广告、池);其他的numPar = 1;结束
开始平行池(parpool)使用“本地”概要文件…连接到平行池6工人。

为每个分区,从数据存储和读取计算STFT。

parfor2 = 1:numPar再分=分区(广告、numPar ii);应变= 0 (fftLength / 2 + 1128 1元素个数(subds.Files));idx = 1:元素个数(subds.Files)%读取音频[x, xinfo] =阅读(再分);%进行预处理x = preprocessAudio(单(x), xinfo.SampleRate);% STFTS0 = stft (x窗口=赢,OverlapLength = OverlapLength FrequencyRange =“单向的”);%级S = abs (S0);应变(::,:,idx) = S;结束STrainC{2} =应变;结束
工人们…做分析和传输文件。

输出转换为一个四维数组与STFTs沿着第四维度。

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

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

应变=日志(应变+ 1 e-6);

规范化训练数据零均值和标准差。

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

SMean =意味着(应变、[2 3 4]);SStd =性病(应变1 [2 3 4]);

每个频率本正常化。

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

计算出STFTs有无限值。以下的方法[1],使有限的数据削波频谱3个标准差和尺度改变[1]。

应变=应变/ 3;Y =重塑(应变、元素个数(应变),1);Y (Y < 1) = 1;Y (Y > 1) = 1;应变=重塑(Y,大小(应变));

丢弃过去的频率本迫使STFT垃圾箱的数量2的幂与卷积层(适用)。

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

变更的尺寸准备喂鉴别器。

应变=排列(应变、[2 1 3 4]);

指定培训选项

火车mini-batch大小为64 1000时代。

maxEpochs = 1000;miniBatchSize = 64;

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

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

指定的选项为亚当的优化。设置的学习速率生成器和鉴频器0.0002。对于网络,使用渐变衰减系数的0.5和0.999平方梯度衰减系数。

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

火车在GPU如果一个是可用的。使用GPU需要并行计算工具箱™。

executionEnvironment =“汽车”;

初始化发生器和鉴频器的重量。的initializeGeneratorWeightsinitializeDiscriminatorWeights使用Glorot均匀初始化函数返回随机获得的权重。功能都包含在这个例子。

generatorParameters = initializeGeneratorWeights;discriminatorParameters = initializeDiscriminatorWeights;

火车模型

火车模型使用自定义训练循环。循环训练数据和更新网络参数在每个迭代。

对于每一个时代,洗牌的训练数据和遍历mini-batches数据。

为每个mini-batch:

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

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

  • 评估模型梯度使用dlfeval(深度学习工具箱)和辅助功能,modelDiscriminatorGradientsmodelGeneratorGradients

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

初始化参数为亚当。

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

根据你的机器,训练该网络可以花费几个小时的时间。跳过培训,集doTraining

doTraining =真正的;

你可以设置saveCheckpoints真正的保存更新后的重量和州垫文件每十世。然后,您可以使用这个垫子文件恢复训练中断。

saveCheckpoints =真正的;

指定的长度发电机输入。

numLatentInputs = 100;

训练甘。这可以运行多个小时。

迭代= 0;时代= 1:maxEpochs%洗牌数据。idx = randperm(大小(压力,4));张力= (:,:,:,idx);%在mini-batches循环。指数= 1:numIterationsPerEpoch迭代=迭代+ 1;% mini-batch读取的数据。dlX =应变(:,:,:,(索引1)* miniBatchSize + 1:指数* miniBatchSize);dlX = dlarray (dlX,“SSCB”);%为发电机网络生成潜在的输入。Z = 2 *(兰德(1,1,numLatentInputs miniBatchSize,“单身”)- 0.5);dlZ = dlarray (Z);%如果训练在GPU,然后将数据转换成gpuArray。如果(executionEnvironment = =“汽车”& & 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。如果(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时代,培训快照保存到垫文件。如果国防部(时代,10)= = 0 disp (“时代”+时代+“的”+ maxEpochs +“完成”。);如果saveCheckpoints%保存检查点训练中断。保存(“audiogancheckpoint.mat”,“generatorParameters”,“discriminatorParameters”,“trailingAvgDiscriminator”,“trailingAvgSqDiscriminator”,“trailingAvgGenerator”,“trailingAvgSqGenerator”,“迭代”);结束结束结束
时代的1000完成。时代20 1000完成。时代30 1000完成。时代40 1000完成。时代50 1000完成。时代60 1000完成。时代70年从1000年完成。时代80年从1000年完成。时代90年从1000年完成。时代100年从1000年完成。 Epoch 110 out of 1000 complete. Epoch 120 out of 1000 complete. Epoch 130 out of 1000 complete. Epoch 140 out of 1000 complete. Epoch 150 out of 1000 complete. Epoch 160 out of 1000 complete. Epoch 170 out of 1000 complete. Epoch 180 out of 1000 complete. Epoch 190 out of 1000 complete. Epoch 200 out of 1000 complete. Epoch 210 out of 1000 complete. Epoch 220 out of 1000 complete. Epoch 230 out of 1000 complete. Epoch 240 out of 1000 complete. Epoch 250 out of 1000 complete. Epoch 260 out of 1000 complete. Epoch 270 out of 1000 complete. Epoch 280 out of 1000 complete. Epoch 290 out of 1000 complete. Epoch 300 out of 1000 complete. Epoch 310 out of 1000 complete. Epoch 320 out of 1000 complete. Epoch 330 out of 1000 complete. Epoch 340 out of 1000 complete. Epoch 350 out of 1000 complete. Epoch 360 out of 1000 complete. Epoch 370 out of 1000 complete. Epoch 380 out of 1000 complete. Epoch 390 out of 1000 complete. Epoch 400 out of 1000 complete. Epoch 410 out of 1000 complete. Epoch 420 out of 1000 complete. Epoch 430 out of 1000 complete. Epoch 440 out of 1000 complete. Epoch 450 out of 1000 complete. Epoch 460 out of 1000 complete. Epoch 470 out of 1000 complete. Epoch 480 out of 1000 complete. Epoch 490 out of 1000 complete. Epoch 500 out of 1000 complete. Epoch 510 out of 1000 complete. Epoch 520 out of 1000 complete. Epoch 530 out of 1000 complete. Epoch 540 out of 1000 complete. Epoch 550 out of 1000 complete. Epoch 560 out of 1000 complete. Epoch 570 out of 1000 complete. Epoch 580 out of 1000 complete. Epoch 590 out of 1000 complete. Epoch 600 out of 1000 complete. Epoch 610 out of 1000 complete. Epoch 620 out of 1000 complete. Epoch 630 out of 1000 complete. Epoch 640 out of 1000 complete. Epoch 650 out of 1000 complete. Epoch 660 out of 1000 complete. Epoch 670 out of 1000 complete. Epoch 680 out of 1000 complete. Epoch 690 out of 1000 complete. Epoch 700 out of 1000 complete. Epoch 710 out of 1000 complete. Epoch 720 out of 1000 complete. Epoch 730 out of 1000 complete. Epoch 740 out of 1000 complete. Epoch 750 out of 1000 complete. Epoch 760 out of 1000 complete. Epoch 770 out of 1000 complete. Epoch 780 out of 1000 complete. Epoch 790 out of 1000 complete. Epoch 800 out of 1000 complete. Epoch 810 out of 1000 complete. Epoch 820 out of 1000 complete. Epoch 830 out of 1000 complete. Epoch 840 out of 1000 complete. Epoch 850 out of 1000 complete. Epoch 860 out of 1000 complete. Epoch 870 out of 1000 complete. Epoch 880 out of 1000 complete. Epoch 890 out of 1000 complete. Epoch 900 out of 1000 complete. Epoch 910 out of 1000 complete. Epoch 920 out of 1000 complete. Epoch 930 out of 1000 complete. Epoch 940 out of 1000 complete. Epoch 950 out of 1000 complete. Epoch 960 out of 1000 complete. Epoch 970 out of 1000 complete. Epoch 980 out of 1000 complete. Epoch 990 out of 1000 complete. Epoch 1000 out of 1000 complete.

合成的声音

现在您已经训练网络,可以更详细地研究合成工艺。

训练有素的敲击的声音发生器综合短时傅里叶变换(STFT)矩阵输入数组的随机值。逆STFT (ISTFT)操作将时频STFT合成时域音频信号。

如果你跳过训练,负载的重量pretrained生成器。

如果~ doTraining负载(matFileName“generatorParameters”,“SMean”,“SStd”);结束

发电机1 -通过- 1 - 100的随机值作为输入向量。生成一个示例输入向量。

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

通过随机向量生成器来创建一个STFT的形象。generatorParameters是一个结构,它包含pretrained生成器的权重。

dlXGenerated = modelGenerator (dlZ generatorParameters);

把STFTdlarray一个单精度矩阵。

S = dlXGenerated.extractdata;

转置的STFT其尺寸一致istft函数。

=年代。”;

STFT的128 - 128矩阵,第一个维度代表128箱线性频率间隔从0到8 kHz。发电机被训练来生成一个片面的STFT FFT长度为256,最后本省略。再次,本0到STFT的插入一行。

S =[年代;0 (1128)];

恢复正常化和扩展步骤生成STFTs时用于培训。

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

日志的STFT域转换为线性域。

S = exp(年代);

转换的STFT片面的两面。

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

垫与零删除窗口边缘效应。

S =[0(256100),年代,0 (256100)];

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

myAudio = stftmag2sig(年代,256,FrequencyRange =“双侧”,窗口=损害(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)网格包含(“时间(s)”)标题(“合成氮化镓的声音”)

情节的STFT合成敲击的声音。

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

模型生成器函数

modelGenerator函数高档1 -到- 1 - 128 - 100阵列(dlX) -由- 128 - 1阵列(海底)。参数是一个结构发电机层的权重。发电机架构定义在表4[1]

函数海底= modelGenerator (dlX参数)海底= fullyconnect (dlX、parameters.FC.Weights parameters.FC.Bias, Dataformat =“SSCB”);海底=重塑(海底,[1024 4 4大小(海底,2)]);海底=排列(海底,[3 2 1 4]);海底= relu(海底);海底= dltranspconv(海底,parameters.Conv1.Weights parameters.Conv1.Bias,跨步= 2,裁剪=“相同”DataFormat =“SSCB”);海底= relu(海底);海底= dltranspconv(海底,parameters.Conv2.Weights parameters.Conv2.Bias,跨步= 2,裁剪=“相同”DataFormat =“SSCB”);海底= relu(海底);海底= dltranspconv(海底,parameters.Conv3.Weights parameters.Conv3.Bias,跨步= 2,裁剪=“相同”DataFormat =“SSCB”);海底= relu(海底);海底= dltranspconv(海底,parameters.Conv4.Weights parameters.Conv4.Bias,跨步= 2,裁剪=“相同”DataFormat =“SSCB”);海底= relu(海底);海底= dltranspconv(海底,parameters.Conv5.Weights parameters.Conv5.Bias,跨步= 2,裁剪=“相同”DataFormat =“SSCB”);海底=双曲正切(海底);结束

模型鉴别器函数

modelDiscriminator函数接受128 -,- 128图像和输出一个标量预测分数。表5中定义的鉴别器架构[1]。

函数海底= modelDiscriminator (dlX参数)海底= dlconv (dlX、parameters.Conv1.Weights parameters.Conv1.Bias,跨步= 2,填充=“相同”);海底= leakyrelu(海底,0.2);海底= dlconv(海底,parameters.Conv2.Weights parameters.Conv2.Bias,跨步= 2,填充=“相同”);海底= leakyrelu(海底,0.2);海底= dlconv(海底,parameters.Conv3.Weights parameters.Conv3.Bias,跨步= 2,填充=“相同”);海底= leakyrelu(海底,0.2);海底= dlconv(海底,parameters.Conv4.Weights parameters.Conv4.Bias,跨步= 2,填充=“相同”);海底= leakyrelu(海底,0.2);海底= dlconv(海底,parameters.Conv5.Weights parameters.Conv5.Bias,跨步= 2,填充=“相同”);海底= leakyrelu(海底,0.2);海底= stripdims(海底);海底=排列(海底,[3 2 1 4]);海底=重塑(海底,4 * 4 * 64 * 16,元素个数(海底)/ (4 * 4 * 64 * 16));重量= parameters.FC.Weights;偏见= parameters.FC.Bias;海底= fullyconnect(海底,重量、偏见,Dataformat =“CB”);结束

模型鉴别器梯度函数

modelDiscriminatorGradients函数作为输入生成器和鉴频器参数generatorParametersdiscriminatorParametersmini-batch的输入数据X和一个随机值数组Z的梯度,并返回鉴频器的损失对可学的网络参数。

函数gradientsDiscriminator = modelDiscriminatorGradients (discriminatorParameters generatorParameters X, Z)%计算实际数据与鉴别器网络的预测。Y = modelDiscriminator (X, discriminatorParameters);%计算生成的预测数据与鉴别器网络。Xgen = modelGenerator (Z, generatorParameters);Ygen = modelDiscriminator (dlarray (Xgen“SSCB”),discriminatorParameters);甘%计算损失。lossDiscriminator = ganDiscriminatorLoss (Y, Ygen);%为每个网络,计算梯度的损失。gradientsDiscriminator = dlgradient (lossDiscriminator discriminatorParameters);结束

模型生成器梯度函数

modelGeneratorGradients函数作为输入鉴频器和生成器可学的参数和随机值的数组Z的梯度,并返回发电机损失对可学的网络参数。

函数gradientsGenerator = modelGeneratorGradients (discriminatorParameters generatorParameters, Z)%计算生成的预测数据与鉴别器网络。Xgen = modelGenerator (Z, generatorParameters);Ygen = modelDiscriminator (dlarray (Xgen“SSCB”),discriminatorParameters);甘%计算损失lossGenerator = ganGeneratorLoss (Ygen);%为每个网络,计算梯度的损失。gradientsGenerator = dlgradient (lossGenerator generatorParameters);结束

鉴频器损失函数

鉴频器的目的是不要被愚弄的发电机。的概率最大化之间的鉴别器成功地歧视真正的和生成的图像,减少鉴别器损失函数。的损失函数发生器是DCGAN方法中突出显示[1]

函数lossDiscriminator = ganDiscriminatorLoss (dlYPred dlYPredGenerated)假= dlarray(0(1、大小(dlYPred, 2)));真正的= dlarray(的(1、大小(dlYPred 2)));D_loss =意味着(sigmoid_cross_entropy_with_logits (dlYPredGenerated、假));D_loss = D_loss +的意思(sigmoid_cross_entropy_with_logits (dlYPred,实际));lossDiscriminator = D_loss / 2;结束

发电机损失函数

发电机的目的是生成数据鉴别器分类为“真正的”。最大化图像生成器的概率被归类为真正的鉴别器,减少发电机损失函数。的损失函数发生器是深卷积生成adverarial网络(DCGAN)方法中突出显示[1]

函数真正lossGenerator = ganGeneratorLoss (dlYPredGenerated) = dlarray(的(1、大小(dlYPredGenerated, 2)));lossGenerator =意味着(sigmoid_cross_entropy_with_logits (dlYPredGenerated,实际));结束

鉴频器权值初始化

initializeDiscriminatorWeights初始化使用Glorot鉴别器权重算法。

函数discriminatorParameters = initializeDiscriminatorWeights filterSize = 5 [5];昏暗的= 64;% Conv2D重量= iGlorotInitialize ([filterSize (1) filterSize(2) 1暗]);偏见= 0(1,- 1,昏暗,“单身”);discriminatorParameters.Conv1。重量= dlarray(重量);discriminatorParameters.Conv1。偏见= dlarray(偏差);% Conv2D重量= iGlorotInitialize ([filterSize (1) filterSize(2)暗2 *暗]);偏见= 0(1 1 2 *昏暗,“单身”);discriminatorParameters.Conv2。重量= dlarray(重量);discriminatorParameters.Conv2。偏见= dlarray(偏差);% Conv2D重量= iGlorotInitialize ([filterSize (1) filterSize(2) 2 *暗4 *暗]);偏见= 0(1、1、4 *昏暗,“单身”);discriminatorParameters.Conv3。重量= dlarray(重量);discriminatorParameters.Conv3。偏见= dlarray(偏差);% Conv2D重量= iGlorotInitialize ([filterSize (1) filterSize(2) 4 *昏暗的8 *暗]);偏见= 0(1 1 8 *昏暗,“单身”);discriminatorParameters.Conv4。重量= dlarray(重量);discriminatorParameters.Conv4。偏见= dlarray(偏差);% Conv2D重量= iGlorotInitialize ([filterSize (1) filterSize(2) 8 *暗16 *暗]);偏见= 0(1,1,16 *昏暗,“单身”);discriminatorParameters.Conv5。重量= dlarray(重量);discriminatorParameters.Conv5。偏见= dlarray(偏差);%完全连接重量= iGlorotInitialize([1, 4 * 4 *的* 16]);偏见= 0 (1,1,“单身”);discriminatorParameters.FC。重量= dlarray(重量);discriminatorParameters.FC。偏见= dlarray(偏差);结束

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

initializeGeneratorWeights初始化发生器使用Glorot权重算法。

函数generatorParameters = initializeGeneratorWeights昏暗= 64;%的1重量= iGlorotInitialize((暗* 256100));偏见= 0(暗* 256 1“单身”);generatorParameters.FC。重量= dlarray(重量);generatorParameters.FC。偏见= dlarray(偏差);filterSize = 5 [5];%反式Conv2D重量= iGlorotInitialize ([filterSize (1) filterSize(2) 8 *暗16 *暗]);偏见= 0(1,- 1,昏暗的* 8,“单身”);generatorParameters.Conv1。重量= dlarray(重量);generatorParameters.Conv1。偏见= dlarray(偏差);%反式Conv2D重量= iGlorotInitialize ([filterSize (1) filterSize(2) 4 *昏暗的8 *暗]);偏见= 0(1,1,暗淡的* 4“单身”);generatorParameters.Conv2。重量= dlarray(重量);generatorParameters.Conv2。偏见= dlarray(偏差);%反式Conv2D重量= iGlorotInitialize ([filterSize (1) filterSize(2) 2 *暗4 *暗]);偏见= 0(1,1,昏暗的* 2,“单身”);generatorParameters.Conv3。重量= dlarray(重量);generatorParameters.Conv3。偏见= dlarray(偏差);%反式Conv2D重量= iGlorotInitialize ([filterSize (1) filterSize(2)暗2 *暗]);偏见= 0(1,- 1,昏暗,“单身”);generatorParameters.Conv4。重量= dlarray(重量);generatorParameters.Conv4。偏见= dlarray(偏差);%反式Conv2D重量= iGlorotInitialize ([filterSize (1) filterSize(2) 1暗]);偏见= 0 (1,1,1,“单身”);generatorParameters.Conv5。重量= dlarray(重量);generatorParameters.Conv5。偏见= dlarray(偏差);结束

合成敲击的声音

synthesizePercussiveSound使用pretrained网络合成敲击的声音。

函数y = synthesizePercussiveSound持续的pGeneratorParameters pMean pSTD如果isempty (pGeneratorParameters)%如果垫文件不存在,下载它文件名=“drumGeneratorWeights.mat”;负载(文件名,“SMean”,“SStd”,“generatorParameters”);pMean = SMean;pSTD = SStd;pGeneratorParameters = generatorParameters;结束%生成随机向量dlZ = dlarray (2 * (rand (1100 1“单身”)- 0.5));%生成谱图dlXGenerated = modelGenerator (dlZ pGeneratorParameters);%从dlarray转换为单身S = dlXGenerated.extractdata;=年代。”;%在消除边缘效应S =[年代;0 (1128)];%反向从训练步骤S = S * 3;S = (S . * pSTD) + pMean;S = exp(年代);%让它两面S =[年代;S (end-1: 1:2,)];%垫与零结束和开始S = [0 (256100) 0 (256100)];%使用快速Griffin-Lim算法重构信号。myAudio = stftmag2sig(年代,256,FrequencyRange =“双侧”,窗口=损害(256“周期”),OverlapLength = 128,MaxIterations = 20,方法=“fgla”);myAudio = myAudio. / max (abs (myAudio), [],“所有”);y = myAudio(128 * 100:结束- 128 * 100);结束

效用函数

函数= sigmoid_cross_entropy_with_logits (x, z) = max (x, 0) - x。* z +日志(1 + exp (abs (x)));结束函数w = iGlorotInitialize(深圳)如果元素个数(深圳)= = 2 numInputs =深圳(2);numOutputs =深圳(1);其他的numInputs = prod(深圳(1:3));numOutputs = prod(深圳([1 2 4]));结束乘数=√2 / (numInputs + numOutputs));w =乘数* sqrt(3) *(2 *兰特(深圳,“单身”)- 1);结束函数= preprocessAudio (fs),%确保mono=意味着(2);%重新取样16赫兹x =重新取样(16 e3, fs);%削减或垫有大约秒的长度加填充物,以确保% 128分析windows的STFT窗口256点和128点%重叠。y = trimOrPad (x, 16513);%正常化出= y / max (abs (y));结束函数y = trimOrPad (x, n)% trimOrPad修剪或垫音频%% y = trimOrPad (x, n)修剪或垫输入x n沿着第一个样本%的维度。如果x是修剪,修剪同样在正面和背面。%如果x是填充,填充同样与零正面和背面。%为奇数长的削减或填充,修剪多余的样品或垫%从后面。一个=大小(x, 1);如果< n frontPad =地板((一)/ 2);挤压垫= n - - frontPad;y = [0 (frontPad、大小(x, 2),如= x); x; 0(挤压垫、大小(x, 2),如= x));elseif> n frontTrim =地板((一)/ 2)+ 1;backTrim = a - n - frontTrim;y = x (frontTrim: end-backTrim:);其他的y = x;结束结束函数removeRestrictiveLicence (percussivesoundsFolder licensefilename)% removeRestrictiveLicense消除限制性的许可%解析id映射到许可的许可文件。创建一个表来保存信息。f = fileread (licensefilename);K = jsondecode (f);fn =字段(K);T =表(大小=[元素个数(fn), 4],VariableTypes = [“字符串”,“字符串”,“字符串”,“字符串”),VariableNames = [“ID”,“文件名”,“用户名”,“许可证”]);2 = 1:元素个数(fn) fn =字符串(k . (fn {2}) . name);李=字符串(k . (fn {2}) .license);id = extractAfter(字符串(fn {2}),“x”);联合国=字符串(k . (fn {2}) .username);T (ii):) = {id、fn,李};结束%删除任何文件,禁止商业用途。发现里面的文件%合适的文件夹中,然后删除它。un金宝appsupportedLicense =“http://creativecommons.org/licenses/by-nc/3.0/”;fileToRemove = T.ID (strcmp (T.License 金宝appunsupportedLicense));2 = 1:元素个数(fileToRemove) fileInfo = dir (fullfile (percussivesoundsFolder,“* *”fileToRemove (ii) +“wav”));删除(fullfile (fileInfo.folder fileInfo.name))结束结束

参考

多纳休[1],C。,J. McAuley, and M. Puckette. 2019. "Adversarial Audio Synthesis." ICLR.

[2]拉米雷斯,安东尼奥Pritish Chandna,泽维尔Favory,伊米莉亚·戈麦斯和泽维尔塞拉。“神经冲击合成Parameterised高级场音色特性。”ICASSP 2020 - 2020年IEEE国际会议音响、演讲和信号处理(ICASSP),2020年。https://doi.org/10.1109/icassp40776.2020.9053128。

另请参阅