in blocksparse/norms.py [0:0]
def layer_norm(x, g, b, axis=1, segments=1, epsilon=1e-6, relu=False, atomics=True, bench=0, use_tf=False):
dev = g.op.device.lower()
if use_tf or not dev or "cpu" in dev:
if axis < 0:
axis += len(x.shape)
K = x.shape[axis].value
assert g.shape.num_elements() == K
assert b.shape.num_elements() == K
assert K % segments == 0
assert axis != 0 or segments == 1, "Segments only implemented on axis=1 for now"
K //= segments
ys = list()
for s in range(segments):
segK = slice(s*K, s*K+K)
segX = [segK if d == axis else slice(None) for d in range(x.shape.ndims)]
mean, var = tf.nn.moments(x[segX], [axis], keep_dims=True)
# mean = tf.reduce_mean(x[segX], axis=[axis], keepdims=True)
# var = tf.reduce_mean(tf.square(x[segX] - mean), axis=[axis], keepdims=True)
norm = (x[segX] - mean) * tf.rsqrt(var + epsilon)
ys.append(norm * g[segK] + b[segK])
y = tf.concat(ys, axis) if segments > 1 else ys[0]
if relu:
y = tf.nn.relu(y)
else:
y, m, v, _, _ = layer_norm_op(x, g, b, S=segments, axis=axis, epsilon=epsilon, relu=relu, atomics=atomics, bench=bench)
return y