Я делаю много симуляций, для которых мне часто нужно минимизировать сложные пользовательские функции, для которых я обычно использую numpy
и scipy.optimize.minimize()
. Однако проблема в том, что мне нужно явно записать функцию градиента, которую иногда бывает очень сложно/невозможно найти. А для векторов большой размерности числовые производные, вычисляемые scipy
, непомерно дороги.
Итак, я пытаюсь переключиться на Tensorflow
или PyTorch
, чтобы воспользоваться как их возможностями автоматической дифференциации, так и иметь возможность свободно использовать графические процессоры. Позвольте мне привести явный пример функции, производную которой довольно сложно записать (потребуется много цепных правил), и, таким образом, кажется, что она созрела для Tensorflow
или PyTorch
— вычисление двугранного угла между двумя треугольниками, образованными четырьмя точками в 3D пространство:
def dihedralAngle(xyz):
## calculate dihedral angle between 4 nodes
p1, p2, p3, p4 = 0, 1, 2, 3
## get unit normal vectors
N1 = np.cross(xyz[p1]-xyz[p3] , xyz[p2]-xyz[p3])
N2 = - np.cross(xyz[p1]-xyz[p4] , xyz[p2]-xyz[p4])
n1, n2 = N1 / np.linalg.norm(N1), N2 / np.linalg.norm(N2)
angle = np.arccos(np.dot(n1, n2))
return angle
xyz1 = np.array([[0.2 , 0. , 0. ],
[0.198358 , 0.02557543, 0. ],
[0.19345897, 0.05073092, 0. ],
[0.18538335, 0.0750534 , 0. ]]) # or any (4,3) ndarray
print(dihedralAngle(xyz1)) >> 3.141
Я мог бы легко минимизировать это, используя scipy.optimize.minimize()
, и я должен получить 0. Для такой маленькой функции мне действительно не нужен градиент (явный или числовой). Однако, если я хочу перебрать много-много узлов и минимизировать некоторую функцию, которая зависит от всех двугранных углов, то накладные расходы будут намного выше?
Тогда мои вопросы -
- Как мне реализовать эту проблему минимизации, используя
TensorFlow
илиPyTorch
? Как для одного двугранного угла, так и для списка таких углов (т.е. нам нужно учитывать зацикливание на списках). - Кроме того, могу ли я просто получить градиент с помощью автоматического дифференцирования, чтобы при желании снова подключиться к
scipy.optimize.minimize()
? Например,scipy.optimize.minimize()
позволяет легко устанавливать границы и ограничения, чего я не заметил в модулях оптимизации Tensorflow или PyToch.