我正在为音频的Denoising AutoCoder工作,将原始的时间序列音频馈送到网络,并接收时间序列的音频作为网络输出。mean_square_error
损耗目标函数返回形状(batch_size, audio_sequence_length)
的值,Keras在内部进一步处理(我希望我正确理解),以通过计算均值随时间箱和批次来达到最终的单值损失。
我目前的工作重点是使用信号功率而不是单个样本的错误创建自定义损失函数,从而返回形状(batch_size, )
的值。该模型很好地编译,但在训练时只能返回NAN损失。尝试使用此类模型预测任何内容都会导致由NAN组成的输出向量。
这是损失函数:
def SI_SNR(yTrue,yPred):
yTarget = K.batch_dot(yTrue,yPred,axes=0)
yTarget = K.batch_dot(yTrue,yTarget,axes=None)
yNorm = K.batch_dot(yTrue,yTrue, axes = 0)
yTarget = yTarget/yNorm
eNoise = yPred - yTarget
losses = -(10.*K.log(K.batch_dot(yTarget,yTarget,axes=0)/
K.batch_dot(eNoise,eNoise,axes=0))/K.log(10.))
return K.reshape(losses,([-1]))
在实际数字上使用该函数时(使用训练数据的子集或随机填充的数组),我确实会得到非NAN结果:
x=K.variable(np.random.rand(8,1024,1))
y=K.variable(np.random.rand(8,1024,1))
K.eval(SI_SNR(y,x))
是由于损失的形状而引起的训练行为,还是损失函数的内部结构也可能存在其他问题?
回答我自己的问题:成本的输出形状不是问题。使用不同的(虚拟)损失检验了这一假设:
def meanMSE(yTrue,yPred):
return K.mean(mean_squared_error(yTrue,yPred),axis=1)
如果yPred
是零的向量,则先前的成本函数使用DIV0问题,使用backend.clip
并稍微修改该函数,该问题已解决:
def SDR(yTrue,yPred):
return(K.batch_dot(yPred,yPred,axes=1)/
K.clip(K.square(K.batch_dot(yPred,yTrue,axes=1)),1e-7,1e12))