Как можно отладить этот слой keras?

Я новичок в Keras и пытаюсь реализовать в Keras оформленную пакетную документацию Norm ( https://arxiv.org/abs/1804.08450) в качестве учебного опыта. Слой очень похож на стандартную серию норм с несколькими дополнительными компонентами.

Вместо того, чтобы центрировать входные данные на каждом слое и нормализовать по дисперсии, мы теперь центрируем данные и применяем отбеливающее преобразование, которое вычисляется путем разложения по собственным значениям на ковариационной матрице.

Вся процедура четко изложена в статье (Алгоритм 1, стр. 5) и состоит только из 5 уравнений, реализацию которых я отметил в приведенном ниже коде. Я успешно повторно внедрил стандартную порцию нормального слоя, но получаю потери NaN и низкую точность, когда я включаю процедуру отбеливания.

Мне интересно, есть ли какой-нибудь совет, которому я должен следовать для отладки этого кода. Я не уверен, что сделал ошибку в размерности или неправильно реализовал уравнения, но любая помощь будет принята с благодарностью.

Вот код, если вы заинтересованы (отредактировано, чтобы включить исправления Даниэля Меллера). Входом в слой является тензор измерения (высота канала ширины канала 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

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)

Некоторые комментарии о вашем коде:

Несгруппированные размеры

В следующих строках вы инвертируете измерения при изменении их формы, что часто полностью портит ваши данные, поскольку измерения теряют смысл. (Вы не делаете правильную транспозицию, вы просто перегруппируете числа другим способом)

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    
Другие вопросы по тегам