【问题标题】:What are ways I can debug this keras layer?有什么方法可以调试这个 keras 层?
【发布时间】:2018-07-23 12:17:04
【问题描述】:

我是 Keras 的新手,我正在尝试在 Keras 中实现去相关的批处理 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

【问题讨论】:

    标签: python keras keras-layer batch-normalization


    【解决方案1】:

    假设您的代码由 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)
    

    关于你的代码的一些 cmets:

    未分组的维度

    在以下几行中,您将在 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    
    

    【讨论】:

    • 非常感谢您的评论。我认为这让我走上了正确的轨道,并且您非常清楚地说明了未分组的维度问题。我按照您的建议重塑和排列 x,并在最后“取消排列”尺寸。不幸的是,损失和准确性仍然存在问题,所以我会继续寻找问题。如果其他人也有意见,我将把这个问题保持一段时间。
    • @Jake,我想说我们需要“特别注意”矩阵乘法。每个后端然后 keras 实现这些的方式非常令人困惑。我必须每次都检查。
    • 你也可以在这里和那里print(K.int_shape(something))(但这只会在编译期间出现,而不是在预测期间出现)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-27
    • 2017-03-26
    相关资源
    最近更新 更多