Permítanme analizar aquí con algunas palabras de precaución, precedidas de una historia. Hace mucho tiempo, trabajé con un compañero cuando recién comenzaba. Tenía que resolver un problema de optimización, con un objetivo bastante desordenado. Su solución fue generar los derivados analíticos para una optimización.
El problema que vi fue que estos derivados eran desagradables. Generados usando Macsyma, convertidos a código fortran, cada uno tenía docenas de declaraciones de continuación. De hecho, el compilador de Fortran se molestó por eso, ya que excedió el número máximo de declaraciones de continuación. Si bien encontramos una bandera que nos permitió solucionar ese problema, hubo otros problemas.
En expresiones largas, como las que comúnmente generan los sistemas de CA, existe el riesgo de una cancelación sustractiva masiva. Calcule muchos números grandes, solo para descubrir que todos se cancelan entre sí para producir un número pequeño.
A menudo, los derivados generados analíticamente son en realidad más costosos de evaluar que los derivados generados numéricamente utilizando diferencias finitas. Un gradiente para n variables puede tomar más de n veces el costo de evaluar su función objetivo. (Es posible que pueda ahorrar algo de tiempo porque muchos de los términos se pueden reutilizar a través de varias derivadas, pero eso también lo obligará a realizar una codificación manual cuidadosa, en lugar de usar expresiones generadas por computadora. Y cada vez que codifique matemática desagradable expresiones, la probabilidad de un error no es trivial. Asegúrese de verificar la precisión de estos derivados).
El punto de mi historia es que estas expresiones generadas por CA tienen sus propios problemas. Lo curioso es que mi colega estaba realmente orgulloso de la complejidad del problema, que claramente estaba resolviendo un problema realmente difícil porque el álgebra era muy desagradable. Lo que no creo que haya considerado es si ese álgebra en realidad estaba calculando lo correcto, si lo estaba haciendo con precisión y si lo estaba haciendo de manera eficiente.
Si hubiera sido la persona mayor en el momento en este proyecto, le habría leído el acto antidisturbios. Su orgullo le hizo usar una solución que probablemente era innecesariamente compleja, sin siquiera comprobar que un gradiente basado en diferencias finitas era adecuado. Apuesto a que hemos pasado tal vez una semana hombre para hacer que esta optimización funcione. Por lo menos, le habría aconsejado que probara cuidadosamente el gradiente producido. ¿Fue exacto? ¿Qué tan preciso fue, en comparación con los derivados de diferencias finitas? De hecho, hoy existen herramientas que también devolverán una estimación del error en su predicción derivada. Esto es ciertamente cierto para el código de diferenciación adaptativa, (derivación) que he escrito en MATLAB.
Prueba el código. Verificar los derivados.
Pero antes de hacer CUALQUIERA de esto, considere si otros esquemas de optimización mejores son una opción. Por ejemplo, si está haciendo un ajuste exponencial, entonces hay una muy buena posibilidad de que pueda usar un mínimo cuadrado no lineal particionado (a veces llamado mínimo cuadrado separable. Creo que ese fue el término utilizado por Seber y Wild en su libro). La idea es dividir el conjunto de parámetros en conjuntos intrínsecamente lineales e intrínsecamente no lineales. Use una optimización que funcione solo en los parámetros no lineales. Dado que esos parámetros son "conocidos", entonces los parámetros intrínsecamente lineales pueden estimarse usando mínimos cuadrados lineales simples. Este esquema reducirá el espacio de parámetros en la optimización. Hace que el problema sea más robusto, ya que no necesita encontrar valores iniciales para los parámetros lineales. Reduce la dimensionalidad de su espacio de búsqueda, por lo que el problema se ejecuta más rápidamente. De nuevo he suministradouna herramienta para este propósito , pero solo en MATLAB.
Si utiliza los derivados analíticos, codifíquelos para reutilizar los términos. Esto puede ser un gran ahorro de tiempo, y en realidad puede reducir los errores, ahorrando su propio tiempo. ¡Pero luego revisa esos números!
codegen
paquete que contiene, ya que puede generar código C o Fortran compacto y eficiente para cada una o todas las expresiones automáticamente.