我正在研究用于音频的降噪自动编码器,将原始的时序音频输入到网络,并接收时序音频作为网络输出。 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))
训练行为是由于损失的形状引起的还是损失函数的内部结构是否存在其他问题?
答案 0 :(得分:0)
要回答我自己的问题:成本的输出形状不是问题。使用不同的(虚拟)损失测试了该假设:
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))