我可以通过哪些方式调试此 keras 层?

What are ways I can debug this keras layer?

我是 Keras 的新手,正在尝试在 Keras 中实现 decorrelated batch Norm 论文 (https://arxiv.org/abs/1804.08450) 作为学习经验。该层与标准批规范非常相似,但有一些额外的组件。

我们现在不是将输入数据集中到每一层并按方差归一化,而是将数据集中并应用白化变换,该白化变换是通过对协方差矩阵进行特征值分解计算得出的。

论文(算法 1,第 5 页)中清楚地列出了整个过程,并且仅由大约 5 个方程组成,我在下面的代码中标记了它们的实现。我成功地重新实现了标准的批量归一化层,但是当我合并白化程序时,我得到了 NaN 损失和低准确度。

我想知道在调试这段代码时是否应该遵循任何建议。我不确定我是否犯了维度错误或不正确地实现了方程式,但我们将不胜感激。

如果您有兴趣,请查看代码(经过编辑以包括 Daniel Möller 的更正)。该层的输入是维度张量(batch_size 高度宽度通道)。

input_shape = K.int_shape(inputs) # (batch_size height width channels) 
# unroll all dimensions except feature maps dim (c X hwb)
pool_shape = (-1, input_shape[-1]) 
x = K.reshape(x,pool_shape)
x = K.permute_dimensions(x, (1,0)) #if you do want to invert the dimensions

mean = K.mean(x,1,keepdims=True)     

# standard batch norm
#stddev = K.std(x,1,keepdims=True) + self.epsilon
#normed = (x - mean) / stddev
#normed = K.reshape(normed,((-1,)+ input_shape[1:]))

# center inputs
centered_inputs = x - mean 

#vvvvvERROR SOMEWHERE IN HEREvvvvv#
# compute covariance matrix for reshaped inputs xxt
covar = K.batch_dot(K.expand_dims(x, axis=-1), K.expand_dims(x, axis=-1),axes=(2,2))
# fuzz covariance matrix to prevent singularity
covar = covar + self.epsilon 

# execute eigenvalue decomposition
#Lambda, D,_ = tf.svd(covar,compute_uv=True)
Lambda, D = tf.self_adjoint_eig(covar)
Lambda = tf.linalg.diag(Lambda)

# calculate PCA-whitening matrix 1/sqrt(L) * D^T
U = K.batch_dot(1. / K.sqrt(Lambda), D, axes=(2,2))
# calculate PCA-whitened activation x_a = U(x - \mu)
x_a = K.batch_dot(U, centered_inputs,axes=(2,1))
# calculate ZCA-whitened output Dx_a
x_whitened = K.batch_dot(D, x_a)
#^^^^^ERROR SOMEWHERE IN HERE^^^^^# 

# reshape whitened activations back to input dimension
x_normed = K.permute_dimensions(x_whitened,(1,0)) # permute back to (bhw X c)
x_normed = K.reshape(x_normed,((-1,), input_shape[1:])) # reroll dimensions

假设您的代码由 Keras 层(自定义层或 Lambda 层)执行。

我发现调试事物的最佳方法是创建一个只有该层的非常小的模型以查看它的输出。

如果问题出在代码中,那么我会逐渐将 return 语句移动到我认为错误所在的位置。

debugModel = Sequential()
debugModel.add(MyCustomLayer(...., input_shape=some_shape))

创建虚拟或有用数据:

data = loadOrCreateSomeData()

或者用子模型获取上一层的数据:

subModel = Model(oldModel.inputs, oldModel.get_layer(nameOfATargetLayer).outputs)
data = subModel.predict(inputData)

获得适合测试的数据后:

result = debugModel.predict(data)

关于您的代码的一些评论:

未分组维度

在接下来的几行中,您将反转 reshape 中的维度,这通常会完全弄乱您的数据,因为维度会失去意义。 (您没有进行适当的转置,您只是以不同的方式重新组合数字)

pool_shape = (input_shape[-1], np.prod(input_shape[1:-1])*self.batch_size) 
x = K.reshape(x,pool_shape) 

我想你应该试试这个:

pool_shape = (-1, input_shape[-1])
x = K.reshape(x,pool_shape) 

也许这样:

x = K.permute_dimensions(x, (1,0)) #if you do want to invert the dimensions