lnn的等式如下:
y = x * pow(lrn_k + lrn_alpha/lrn_size * sum(Xj * Xj), -lrn_beta)
cudnn的lrn落后api是
cudnnStatus_t cudnnLRNCrossChannelBackward(
cudnnHandle_t handle,
cudnnLRNDescriptor_t normDesc,
cudnnLRNMode_t lrnMode,
const void *alpha,
const cudnnTensorDescriptor_t yDesc,
const void *y,
const cudnnTensorDescriptor_t dyDesc,
const void *dy,
const cudnnTensorDescriptor_t xDesc,
const void *x,
const void *beta,
const cudnnTensorDescriptor_t dxDesc,
void *dx)
我发现没有工作空间以节省在caffe中实现的规模,即
scale = lrn_k + lrn_alpha/lrn_size * sum(Xj * Xj)
此变量对于向后计算lrn非常有用。所以我认为可能在后向内核中只计算y,x和lrn_beta以便计算这个变量,方程式如下:
y/x = pow(scale, -lrn_beta)
y/x = pow2(-lrn_beta * log2(scale))
log2(scale) = -1/lrn_beta * log2(y/x)
scale = pow2(-1/lrn_beta * log2(y/x))
当我使用这些方程计算尺度时,cuda内核生成NAN,还有其他方法可以向后计算lrn而不保存前向的缩放值吗?为什么我的方法不稳定?
检查了ptx,这个后向传递仍然需要计算在向前计算的比例。