Использование гессиана TensorFlow для второго теста частной производной
Второй тест с частной производной - это простой способ определить, является ли критическая точка минимумом, максимумом или седлом. В настоящее время я занимаюсь идеей реализации такого теста для простой нейронной сети в тензорном потоке. Следующий набор весов используется для моделирования нейронной сети XOR с 2 входами, 1 скрытым слоем с 2 скрытыми единицами и 1 единицей вывода:
weights = {
'h1': tf.Variable(np.empty([2, 2]), name="h1", dtype=tf.float64),
'b1': tf.Variable(np.empty([2]), name="b1", dtype=tf.float64),
'h2': tf.Variable(np.empty([2, 1]), name="h2", dtype=tf.float64),
'b2': tf.Variable(np.empty([1]), name="b2", dtype=tf.float64)
}
Теперь и градиенты, и гессианы могут быть получены следующим образом:
gradients = tf.gradients(mse_op, [weights['h1'], weights['b1'], weights['h2'], weights['b2']])
hessians = tf.hessians(mse_op, [weights['h1'], weights['b1'], weights['h2'], weights['b2']])
куда mse_op
это ошибка MSE сети.
И градиенты, и гессианы вычисляются просто отлично. Размерность градиентов равна размерности исходных входных данных. Размерность гессиан явно отличается.
Вопрос: это хорошая идея, и возможно ли вообще вычислить собственные значения гессиан, генерируемые tf.hessian
применяется к данному набору весов? Будут ли собственные значения отражать то, что, я думаю, они представляют, то есть смогу ли я сказать, что если в целом присутствуют как положительные, так и отрицательные значения, то мы можем заключить, что эта точка является седловой?
До сих пор я пробовал следующий нестандартный подход для вычисления собственных значений каждого из гессиан:
eigenvals1 = tf.self_adjoint_eigvals(hessians[0])
eigenvals2 = tf.self_adjoint_eigvals(hessians[1])
eigenvals3 = tf.self_adjoint_eigvals(hessians[2])
eigenvals4 = tf.self_adjoint_eigvals(hessians[3])
1,2 и 4 работают, но третий взрывает, жалуясь, что Dimensions must be equal, but are 2 and 1 for 'SelfAdjointEigV2_2' (op: 'SelfAdjointEigV2') with input shapes: [2,1,2,1].
Должен ли я как-то изменить форму гессиана и продолжить, или я полностью на неправильном пути?
1 ответ
После некоторого возни я понял, что, учитывая n*m
матрица входных переменных, TensorFlow's tf.hessians
производит [n,m,n,m]
тензор, который может быть преобразован в квадрат [n*m, n*m]
Гессенская матрица выглядит следующим образом:
sq_hess = tf.reshape(hessians[0], [tf.size(weights['h1']), tf.size(weights['h1'])])
Далее можно вычислить собственные значения результирующего квадратного гессиана:
eigenvals = tf.self_adjoint_eigvals(sq_hess)
Это может быть тривиально, но мне понадобилось некоторое время, чтобы обдумать это. Я считаю поведение tf.hessians
не очень хорошо задокументировано. Однако, как только вы соберете размерности, все будет иметь смысл!