我正在尝试从keras模型中获取经过训练的权重并尝试在numpy中实现正向模型。目前我获得的结果与我的keras模型的输出不同。
我已将差异缩小到我实现batch_normalisation的地方。只是想知道我在下面的BN实施中做错了什么:
weights = model.get_weights()
h1_w = weights[0] #no bias term
h2_w, h2_b, bn2_gamma, bn2_beta, bn2_mean, bn2_var = weights[1:7]
def relu(x, w, b):
return np.maximum(0, np.matmul(x, w) + b)
def bn(x, mean, var, gamma, beta, eps=1e-3):
return (x-mean)/(np.sqrt(var) + eps)*gamma + beta
def reconstruct_model(x, x_offset):
h1_act = np.maximum(0, np.matmul(x, h1_w))
h2_act = relu(h1_act, h2_w, h2_b)
h2 = bn(h2_act, bn2_mean, bn2_var, bn2_gamma, bn2_beta)
return h2
为了比较,我的Keras模型如下:
x_in = Input(shape=(X_train.shape[1:]))
h = Dense(20, use_bias=False, activation='relu', kernel_regularizer=l1(1e-5))(x_in)
h = Dense(10, activation='relu')(h)
out = BatchNormalization()(h)
model = Model([x_in], out)
model.compile(loss='mse', optimizer='adam')
另请注意1.我发现你没有把BN放在最后一层。我只是简化到第一层,我注意到了差异。 2.差异不是由于float64与float32问题(我最大的差异是0.6左右)。
总之,我的BN实施有什么问题。
答案 0 :(得分:1)
我还没有在python中测试实现,但是在c ++中。我将eps
放在平方根中,我的结果类似于10e-4或更好的keras实现:
def bn(x, mean, var, gamma, beta, eps=1e-3):
return (x-mean)/(np.sqrt(var + eps))*gamma + beta