00:01 Introducción
02:44 Encuesta de necesidades predictivas
05:57 Modelos vs. Modelado
12:26 La historia hasta ahora
15:50 Un poco de teoría y un poco de práctica
17:41 Programación Diferenciable, SGD 1/6
24:56 Programación Diferenciable, autodiff 2/6
31:07 Programación Diferenciable, funciones 3/6
35:35 Programación Diferenciable, meta-parámetros 4/6
37:59 Programación Diferenciable, parámetros 5/6
40:55 Programación Diferenciable, peculiaridades 6/6
43:41 Recorrido, pronóstico de demanda minorista
45:49 Recorrido, ajuste de parámetros 1/6
53:14 Recorrido, compartición de parámetros 2/6
01:04:16 Recorrido, enmascaramiento de pérdida 3/6
01:09:34 Recorrido, integración de covariables 4/6
01:14:09 Recorrido, descomposición dispersa 5/6
01:21:17 Recorrido, escalamiento libre 6/6
01:25:14 Caja blanca
01:33:22 Regreso a la optimización experimental
01:39:53 Conclusión
01:44:40 Próxima clase y preguntas de la audiencia

Descripción

Programación Diferenciable (DP) es un paradigma generativo utilizado para diseñar una amplia clase de modelos estadísticos, que resultan ser excelentemente adecuados para los desafíos predictivos de la cadena de suministro. DP supera casi toda la literatura de pronóstico “clásica” basada en modelos paramétricos. DP también es superior a los algoritmos “clásicos” de aprendizaje automático - hasta finales de la década de 2010 - en prácticamente todas las dimensiones que importan para un uso práctico en la cadena de suministro, incluyendo la facilidad de adopción por parte de los profesionales.

Transcripción completa

Slide 1

Bienvenidos a esta serie de clases sobre la cadena de suministro. Soy Joannes Vermorel y hoy presentaré “Modelado Predictivo Estructurado con Programación Diferenciable en la Cadena de Suministro”. Elegir la acción correcta requiere una visión cuantitativa detallada sobre el futuro. De hecho, cada decisión, como comprar más o producir más, refleja una cierta anticipación del futuro. Invariablemente, la teoría convencional de la cadena de suministro enfatiza la noción de pronóstico para abordar este problema. Sin embargo, la perspectiva del pronóstico, al menos en su forma clásica, presenta deficiencias en dos aspectos.

En primer lugar, enfatiza una perspectiva estrecha de pronóstico de series de tiempo, lo cual desafortunadamente no aborda la diversidad de desafíos que se encuentran en las cadenas de suministro del mundo real. En segundo lugar, enfatiza un enfoque estrecho en la precisión del pronóstico de series de tiempo, lo cual también se aleja en gran medida del punto central. Obtener unos pocos puntos porcentuales adicionales de precisión no se traduce automáticamente en generar dólares adicionales de retorno para su cadena de suministro.

El objetivo de esta conferencia es descubrir un enfoque alternativo para el pronóstico, que es en parte una tecnología y en parte una metodología. La tecnología será la programación diferenciable y la metodología serán los modelos predictivos estructurados. Al final de esta conferencia, debería poder aplicar este enfoque a una situación de cadena de suministro. Este enfoque no es teórico; ha sido el enfoque predeterminado de Lokad durante un par de años. Además, si no ha visto las conferencias anteriores, esta conferencia no debería ser totalmente incomprensible. Sin embargo, en esta serie de conferencias, estamos llegando a un punto en el que sería de gran ayuda si realmente ve las conferencias en secuencia. En esta conferencia, revisaremos varios elementos que se han presentado en conferencias anteriores.

Slide 2

El pronóstico de demanda futura es el candidato obvio cuando se trata de las necesidades predictivas de nuestra cadena de suministro. De hecho, una mejor anticipación de la demanda es un ingrediente crítico para decisiones muy básicas, como comprar más y producir más. Sin embargo, a través de los principios de la cadena de suministro que hemos presentado a lo largo del tercer capítulo de esta serie de conferencias, hemos visto que hay un conjunto bastante diverso de expectativas que se pueden tener en términos de requisitos predictivos para impulsar su cadena de suministro.

En particular, por ejemplo, los tiempos de entrega varían y los tiempos de entrega muestran patrones estacionales. Prácticamente cada decisión relacionada con el inventario requiere una anticipación de la demanda futura, pero también una anticipación del tiempo de entrega futuro. Por lo tanto, los tiempos de entrega deben pronosticarse. Las devoluciones a veces representan hasta la mitad del flujo. Este es el caso, por ejemplo, del comercio electrónico de moda en Alemania. En esas situaciones, anticipar las devoluciones se vuelve crítico y esas devoluciones varían bastante de un producto a otro. Por lo tanto, en esas situaciones, las devoluciones deben pronosticarse.

En el lado de la oferta, la producción misma puede variar y no solo debido a los retrasos adicionales o los tiempos de entrega variables. Por ejemplo, la producción puede venir con un cierto grado de incertidumbre. Esto ocurre en sectores de baja tecnología como la agricultura, pero también puede ocurrir en sectores de alta tecnología como la industria farmacéutica. Por lo tanto, también se deben pronosticar los rendimientos de producción. Por último, el comportamiento del cliente también importa mucho. Por ejemplo, impulsar la demanda a través de productos que generan adquisición es muy importante y, a la inversa, enfrentar faltantes de stock en productos que causan una gran rotación cuando esos productos faltan precisamente debido a los faltantes de stock también es muy importante. Por lo tanto, esos comportamientos requieren análisis, predicción, en otras palabras, deben pronosticarse. La idea principal aquí es que el pronóstico de series de tiempo es solo una pieza del rompecabezas. Necesitamos un enfoque predictivo que pueda abarcar todas esas situaciones y más, ya que es una necesidad si queremos tener un enfoque que tenga alguna posibilidad de éxito al enfrentar todas las situaciones que una cadena de suministro del mundo real nos presentará.

Slide 3

El enfoque principal cuando se trata del problema predictivo es presentar un modelo. Este enfoque ha estado impulsando la literatura de pronóstico de series de tiempo durante décadas, y todavía es, diría yo, el enfoque predominante en los círculos de aprendizaje automático en la actualidad. Este enfoque centrado en el modelo, así es como voy a referirme a este enfoque, es tan omnipresente que incluso puede ser difícil retroceder por un momento para evaluar qué está sucediendo realmente con esta perspectiva centrada en el modelo.

Mi propuesta para esta conferencia es que la cadena de suministro requiere una técnica de modelado, una perspectiva centrada en el modelado, y que una serie de modelos, por extensos que sean, nunca va a ser suficiente para abordar todos nuestros requisitos tal como se encuentran en las cadenas de suministro del mundo real. Vamos a aclarar esta distinción entre el enfoque centrado en el modelo y el enfoque centrado en el modelado.

El enfoque centrado en el modelo enfatiza en primer lugar un modelo. El modelo se presenta como un paquete, un conjunto de recetas numéricas que típicamente se presentan en forma de un software que realmente se puede ejecutar. Incluso cuando no hay tal software disponible, la expectativa se establece de manera que si tienes un modelo pero no el software, entonces se espera que el modelo se describa con precisión matemática, permitiendo una reimplementación completa del modelo. Se espera que este paquete, el modelo hecho software, sea el objetivo final.

Desde una perspectiva idealizada, se supone que este modelo se comporta exactamente como una función matemática: entradas adentro, resultados afuera. Si queda alguna configurabilidad para el modelo, entonces esos elementos configurables se tratan como cabos sueltos, como problemas que aún no se han resuelto por completo. De hecho, cada opción de configuración debilita el caso del modelo. Cuando tenemos configurabilidad y demasiadas opciones desde la perspectiva centrada en el modelo, el modelo tiende a disolverse en un espacio de modelos, y de repente, ya no podemos realmente comparar nada porque no existe tal cosa como un solo modelo.

El enfoque de modelado adopta un enfoque completamente invertido en el ángulo de la configurabilidad. Maximizar la expresividad del modelo se convierte en el objetivo final. Esto no es un error; se convierte en una característica. La situación puede ser bastante confusa cuando estamos mirando desde una perspectiva centrada en el modelado, porque si estamos viendo una presentación de una perspectiva centrada en el modelado, lo que vamos a ver es una presentación de modelos. Sin embargo, esos modelos vienen con una intención muy diferente.

Si adoptas la perspectiva de modelado, el modelo que se presenta es solo una ilustración. No viene con la intención de ser completo o de ser la solución final al problema. Es solo un paso en el viaje para ilustrar la técnica de modelado en sí misma. El principal desafío con la técnica de modelado es que de repente se vuelve muy difícil evaluar el enfoque. De hecho, estamos perdiendo la opción de comparación ingenua porque, con esta perspectiva centrada en el modelado, tenemos potencialidades de modelos. No nos enfocamos específicamente en un modelo versus otro; esto ni siquiera es la mentalidad correcta. Lo que tenemos es una opinión fundamentada.

Sin embargo, me gustaría señalar de inmediato que no es porque tengas un punto de referencia y números asociados a tu punto de referencia que automáticamente califica como ciencia. Los números pueden ser simplemente absurdos, y a la inversa, no es porque sea solo una opinión fundamentada que sea menos científica. De alguna manera, es solo un enfoque diferente, y la realidad es que entre varias comunidades, los dos enfoques coexisten.

Por ejemplo, si observamos el artículo “Pronóstico a gran escala”, publicado por un equipo de Facebook en 2017, tenemos algo que es prácticamente el arquetipo del enfoque centrado en el modelo. En este artículo, se presenta el modelo Facebook Prophet. Y en otro artículo, “Tensor Comprehension”, publicado en 2018 por otro equipo de Facebook, tenemos esencialmente una técnica de modelado. Este artículo se puede ver como el arquetipo del enfoque centrado en el modelado. Por lo tanto, puedes ver que incluso los equipos de investigación que trabajan en la misma empresa, prácticamente al mismo tiempo, pueden abordar el problema desde un ángulo u otro, dependiendo de la situación.

Slide 4

Esta conferencia es parte de una serie de conferencias sobre la cadena de suministro. En el primer capítulo, presenté mis puntos de vista sobre la cadena de suministro tanto como campo de estudio como práctica. Desde la primera conferencia, argumenté que la teoría de la cadena de suministro convencional no está cumpliendo con sus expectativas. Sucede que la teoría convencional de la cadena de suministro se basa en gran medida en el enfoque centrado en el modelo, y creo que este aspecto único es una de las principales causas de fricción entre la teoría convencional de la cadena de suministro y las necesidades de las cadenas de suministro del mundo real.

En el segundo capítulo de esta serie de conferencias, presenté una serie de metodologías. De hecho, las metodologías ingenuas suelen ser derrotadas por la naturaleza episódica y frecuentemente adversarial de las situaciones de la cadena de suministro. En particular, la conferencia titulada “Optimización Empírica Experimental”, que formaba parte del segundo capítulo, es la perspectiva que estoy adoptando hoy en esta conferencia.

En el tercer capítulo, presenté una serie de personajes de la cadena de suministro. Los personajes representan un enfoque exclusivo en los problemas que estamos tratando de abordar, sin tener en cuenta ninguna solución candidata. Estos personajes son fundamentales para comprender la diversidad de los desafíos predictivos a los que se enfrentan las cadenas de suministro del mundo real. Creo que estos personajes son esenciales para evitar quedar atrapados en la estrecha perspectiva de series de tiempo, que es una característica distintiva de una teoría de la cadena de suministro que se ejerce prestando poca atención a los detalles más minuciosos de las cadenas de suministro del mundo real.

En el cuarto capítulo, presenté una serie de ciencias auxiliares. Estas ciencias son distintas de la cadena de suministro, pero un dominio básico de estas disciplinas es esencial para la práctica moderna de la cadena de suministro. Ya hemos tocado brevemente el tema de la programación diferenciable en este cuarto capítulo, pero volveré a presentar este paradigma de programación con mucho más detalle en unos minutos.

Finalmente, en la primera conferencia de este quinto capítulo, hemos visto un modelo simple, algunos incluso dirían simplista, que logró una precisión de pronóstico de vanguardia en una competencia de pronósticos a nivel mundial que tuvo lugar en 2020. Hoy, estoy presentando una serie de técnicas que se pueden utilizar para aprender los parámetros involucrados en este modelo que presenté en la conferencia anterior.

Slide 5

El resto de esta conferencia se dividirá en dos bloques, seguidos de algunas reflexiones finales. El primer bloque está dedicado a la programación diferenciable. Ya hemos hablado de este tema en el cuarto capítulo; sin embargo, hoy lo examinaremos mucho más de cerca. Al final de esta conferencia, casi podrás crear tu propia implementación de programación diferenciable. Digo “casi” porque puede variar dependiendo de la pila tecnológica que estés utilizando. Además, la programación diferenciable es un oficio menor en sí mismo; se necesita un poco de experiencia para que funcione sin problemas en la práctica.

El segundo bloque de esta conferencia es un recorrido por una situación de pronóstico de demanda minorista. Este recorrido es un seguimiento de la conferencia anterior, donde presentamos el modelo que obtuvo el primer lugar en la competencia de pronóstico M5 en 2020. Sin embargo, en esta presentación anterior, no detallamos cómo se calcularon efectivamente los parámetros del modelo. Este recorrido entregará exactamente eso, y también cubriremos elementos importantes como los faltantes de stock y las promociones que no se abordaron en la conferencia anterior. Finalmente, basándome en todos estos elementos, discutiré mi opinión sobre la idoneidad de la programación diferenciable para fines de la cadena de suministro.

Slide 6

El Descenso de Gradiente Estocástico (SGD) es uno de los dos pilares de la programación diferenciable. El SGD es engañosamente simple, y aún no está del todo claro por qué funciona tan bien. Es absolutamente claro por qué funciona; lo que no está muy claro es por qué funciona tan bien.

La historia del Descenso de Gradiente Estocástico se remonta a la década de 1950, por lo que tiene una historia bastante larga. Sin embargo, esta técnica solo se graduó al reconocimiento generalizado durante la última década con la aparición del deep learning. El Descenso de Gradiente Estocástico está profundamente arraigado en la perspectiva de la optimización matemática. Tenemos una función de pérdida Q que queremos minimizar, y tenemos un conjunto de parámetros reales, denotados como W, que representan todas las posibles soluciones. Lo que queremos encontrar es la combinación de parámetros W que minimice la función de pérdida Q.

Se supone que la función de pérdida Q cumple una propiedad fundamental: se puede descomponer aditivamente en una serie de términos. La existencia de esta descomposición aditiva hace que el Descenso de Gradiente Estocástico funcione en absoluto. Si tu función de pérdida no se puede descomponer aditivamente de esta manera, entonces el Descenso de Gradiente Estocástico no se aplica como técnica. En esta perspectiva, X representa el conjunto de todos los términos que contribuyen a la función de pérdida, y Qx representa una pérdida parcial que representa la pérdida para uno de los términos en esta perspectiva de tener la función de pérdida como la suma de términos parciales.

Si bien el Descenso de Gradiente Estocástico no es específico de situaciones de aprendizaje, se adapta muy bien a todos los casos de uso de aprendizaje, y cuando digo aprendizaje, me refiero a casos de uso de aprendizaje automático. De hecho, si tenemos un conjunto de datos de entrenamiento, este conjunto de datos tomará la forma de una lista de observaciones, donde cada observación es un par de características que representan la entrada del modelo y etiquetas que representan las salidas. Básicamente, lo que queremos desde una perspectiva de aprendizaje es diseñar un modelo que funcione mejor en el error empírico y otras cosas observadas a partir de este conjunto de datos de entrenamiento. Desde una perspectiva de aprendizaje, X sería en realidad la lista de observaciones, y los parámetros serían los parámetros de un modelo de aprendizaje automático que intentamos optimizar para que se ajuste mejor a este conjunto de datos.

El Descenso de Gradiente Estocástico es fundamentalmente un proceso iterativo que itera aleatoriamente a través de las observaciones, una observación a la vez. Seleccionamos una observación, una pequeña X, a la vez, y para esta observación, calculamos un gradiente local, representado como nabla de Qx. Es solo un gradiente local que se aplica solo a un término de la función de pérdida. Este no es el gradiente de la función de pérdida completa en sí, sino un gradiente local que se aplica solo a un término de la función de pérdida, puedes verlo como un gradiente parcial.

Un paso del Descenso de Gradiente Estocástico consiste en tomar este gradiente local y ajustar los parámetros W un poco basado en esta observación parcial del gradiente. Eso es exactamente lo que está sucediendo aquí, con W siendo actualizado con W menos eta veces nabla QxW. Esto simplemente dice, de una forma muy concisa, que debemos ajustar el parámetro W en la dirección del gradiente local obtenido con X, donde X es solo una de las observaciones de tu conjunto de datos, si estamos abordando un problema desde una perspectiva de aprendizaje. Luego, procedemos al azar, aplicando este gradiente local e iterando.

Intuitivamente, el Descenso de Gradiente Estocástico funciona muy bien porque muestra un equilibrio entre una iteración más rápida y gradientes más ruidosos, hasta llegar a una iteración más granular y, por lo tanto, más rápida. La esencia del Descenso de Gradiente Estocástico es que no nos importa tener mediciones muy imperfectas para nuestros gradientes siempre y cuando podamos obtener esas mediciones imperfectas súper rápido. Si podemos desplazar el equilibrio hacia una iteración más rápida, incluso a expensas de gradientes más ruidosos, hagámoslo. Es por eso que el Descenso de Gradiente Estocástico es tan efectivo para minimizar la cantidad de recursos informáticos necesarios para lograr una cierta calidad de solución para el parámetro W.

Finalmente, tenemos la variable eta, que se refiere a la tasa de aprendizaje. En la práctica, la tasa de aprendizaje no es una constante; esta variable varía mientras el Descenso de Gradiente Estocástico está en progreso. En Lokad, utilizamos el algoritmo Adam para controlar la evolución de este parámetro eta para la tasa de aprendizaje. Adam es un método publicado en 2014 y es muy popular en círculos de aprendizaje automático siempre que esté involucrado el Descenso de Gradiente Estocástico.

Slide 7

El segundo pilar para la programación diferenciable es la diferenciación automática. Ya hemos visto este concepto en una conferencia anterior. Vamos a revisitar este concepto mirando un fragmento de código. Este código está escrito en Envision, un lenguaje de programación específico del dominio desarrollado por Lokad con el propósito de optimización predictiva de cadenas de suministro. Estoy eligiendo Envision porque, como verás, los ejemplos son mucho más concisos y, con suerte, mucho más claros también, en comparación con presentaciones alternativas si usara Python, Java o C#. Sin embargo, me gustaría señalar que aunque estoy usando Envision, no hay una fórmula mágica involucrada. Podrías reimplementar completamente todos estos ejemplos en otros lenguajes de programación. Es probable que esto multiplique la cantidad de líneas de código por un factor de 10, pero en el gran esquema de las cosas, esto es un detalle. Aquí, para una conferencia, Envision nos brinda una presentación muy clara y concisa.

Veamos cómo se puede utilizar la programación diferenciable para abordar una regresión lineal. Este es un problema de juguete; no necesitamos programación diferenciable para hacer una regresión lineal. El objetivo es simplemente familiarizarse con la sintaxis de la programación diferenciable. Desde las líneas 1 a 6, estamos declarando la tabla T, que representa la tabla de observaciones. Cuando digo tabla de observaciones, simplemente recuerda el conjunto de Descenso de Gradiente Estocástico que se llamaba X. Esto es exactamente lo mismo. Esta tabla tiene dos columnas, una característica denotada X y una etiqueta denotada Y. Lo que queremos es tomar X como entrada y poder predecir Y con un modelo lineal, o más precisamente, un modelo afín. Obviamente, solo tenemos cuatro puntos de datos en esta tabla T. Este es un conjunto de datos ridículamente pequeño; es solo por el bien de la claridad de la exposición.

En la línea 8, introducimos el bloque autodiff. El bloque autodiff se puede ver como un bucle en Envision. Es un bucle que itera sobre una tabla, en este caso, la tabla T. Estas iteraciones reflejan los pasos del Descenso de Gradiente Estocástico. Por lo tanto, lo que sucede cuando la ejecución de Envision entra en este bloque autodiff es que tenemos una serie de ejecuciones repetidas donde seleccionamos líneas de la tabla de observaciones y luego aplicamos pasos del Descenso de Gradiente Estocástico. Para hacer eso, necesitamos los gradientes.

¿De dónde vienen los gradientes? Aquí, hemos escrito un programa, una pequeña expresión de nuestro modelo, Ax + B. Introducimos la función de pérdida, que es el error cuadrático medio. Queremos tener el gradiente. Para una situación tan simple como esta, podríamos escribir el gradiente manualmente. Sin embargo, la diferenciación automática es una técnica que te permite compilar un programa en dos formas: la primera forma es la ejecución hacia adelante del programa, y la segunda forma es la forma de ejecución inversa que calcula los gradientes asociados con todos los parámetros presentes en el programa.

En las líneas 9 y 10, tenemos la declaración de dos parámetros, A y B, con la palabra clave “auto” que le indica a Envision que haga una inicialización automática para los valores de estos dos parámetros. A y B son valores escalares. La diferenciación automática ocurre para todos los programas que están contenidos en este bloque autodiff. Esencialmente, es una técnica a nivel de compilador para compilar este programa dos veces: una vez para el pase hacia adelante y una segunda vez para un programa que proporcionará los valores de los gradientes. La belleza de la técnica de diferenciación automática es que garantiza que la cantidad de CPU necesaria para calcular el programa regular esté alineada con la cantidad de CPU necesaria para calcular el gradiente cuando se realiza el pase inverso. Esa es una propiedad muy importante. Finalmente, en la línea 14, imprimimos los parámetros que acabamos de aprender con el bloque autodiff anterior.

Slide 8

La programación diferenciable realmente brilla como un paradigma de programación. Es posible componer un programa arbitrariamente complejo y obtener la diferenciación automatizada de este programa. Este programa puede incluir ramificaciones y llamadas a funciones, por ejemplo. Este ejemplo de código revisa la función de pérdida pinball que presentamos en la conferencia anterior. La función de pérdida pinball se puede utilizar para derivar estimaciones de cuantiles cuando observamos desviaciones de una distribución de probabilidad empírica. Si minimizas el error cuadrático medio con tu estimación, obtienes una estimación de la media de tu distribución empírica. Si minimizas la función de pérdida pinball, obtienes una estimación de un objetivo de cuantil. Si apuntas a un cuantil del 90, significa que es el valor en tu distribución de probabilidad donde la futura valor a observar tiene un 90% de probabilidad de estar por debajo de tu estimación si tienes un objetivo del 90 o un 10% de probabilidad de estar por encima. Esto recuerda al análisis de los niveles de servicio que existen en la cadena de suministro.

En las líneas 1 y 2, estamos introduciendo una tabla de observación poblada con desviaciones muestreadas aleatoriamente de una distribución de Poisson. Los valores de la distribución de Poisson se muestrean con una media de 3 y obtenemos 10,000 desviaciones. En las líneas 4 y 5, implementamos nuestra propia función de pérdida pinball. Esta implementación es casi idéntica al código que presenté en la conferencia anterior. Sin embargo, ahora se agrega la palabra clave “autodiff” a la declaración de la función. Esta palabra clave, cuando se adjunta a la declaración de la función, asegura que el compilador Envision pueda diferenciar automáticamente esta función. Si bien, en teoría, la diferenciación automática se puede aplicar a cualquier programa, en la práctica, hay muchos programas que no tienen sentido diferenciar o muchas funciones donde no tendría sentido. Por ejemplo, considera una función que toma dos valores de texto y los concatena. Desde una perspectiva de diferenciación automática, no tiene sentido aplicar diferenciación automática a este tipo de operación. La diferenciación automática requiere que haya números presentes en la entrada y salida de las funciones que estás tratando de diferenciar.

En las líneas 7 a 9, tenemos el bloque autodiff, que calcula la estimación del cuantil objetivo para la distribución empírica recibida a través de la tabla de observación. En realidad, bajo la superficie, es una distribución de Poisson. La estimación del cuantil se declara como un parámetro llamado “quantile” en la línea 8, y en la línea 9, hacemos una llamada a nuestra propia implementación de la función de pérdida pinball. El objetivo del cuantil se establece en 0.5, por lo que en realidad estamos buscando una estimación de la mediana de la distribución. Finalmente, en la línea 11, imprimimos los resultados para el valor que hemos aprendido a través de la ejecución del bloque autodiff. Este fragmento de código ilustra cómo un programa que vamos a diferenciar automáticamente puede incluir tanto una llamada a función como una rama, y todo eso puede suceder completamente automáticamente.

Slide 9

He dicho que los bloques autodiff se pueden interpretar como un bucle que realiza una serie de pasos de descenso de gradiente estocástico (SGD) sobre la tabla de observación, seleccionando una línea de esta tabla de observación a la vez. Sin embargo, he sido bastante evasivo sobre la condición de parada para esta situación. ¿Cuándo se detiene el descenso de gradiente estocástico en Envision? Por defecto, el descenso de gradiente estocástico se detiene después de 10 épocas. Una época, en terminología de aprendizaje automático, representa un recorrido completo por la tabla de observación. En la línea 7, se puede adjuntar un atributo llamado “epochs” a los bloques autodiff. Este atributo es opcional; por defecto, el valor es 10, pero si especificas este atributo, puedes elegir un recuento diferente. Aquí, estamos especificando 100 épocas. Ten en cuenta que el tiempo total para el cálculo es casi estrictamente lineal al número de épocas. Por lo tanto, si tienes el doble de épocas, el tiempo de cálculo durará el doble.

Aún así, en la línea 7, también estamos introduciendo un segundo atributo llamado “learning_rate”. Este atributo también es opcional y, por defecto, tiene el valor 0.01, adjunto al bloque autodiff. Esta tasa de aprendizaje es un factor utilizado para inicializar el algoritmo Adam que controla la evolución de la tasa de aprendizaje. Este es el parámetro eta que hemos visto en el paso del descenso de gradiente estocástico. Controla el algoritmo Adam. Esencialmente, este es un parámetro que no necesitas ajustar con frecuencia, pero a veces ajustar este parámetro puede ahorrar una parte significativa de la potencia de procesamiento. No es inesperado que al ajustar finamente esta tasa de aprendizaje, puedas ahorrar aproximadamente un 20% del tiempo total de cálculo para tu descenso de gradiente estocástico.

Slide 10

La inicialización de los parámetros que se están aprendiendo en el bloque autodiff también requiere un examen más detenido. Hasta ahora, hemos utilizado la palabra clave “auto” y, en Envision, esto simplemente significa que Envision inicializará el parámetro dibujando aleatoriamente un valor de una distribución gaussiana con media 1 y desviación estándar 0.1. Esta inicialización difiere de la práctica habitual en el aprendizaje profundo, donde los parámetros se inicializan aleatoriamente con gaussianas centradas en cero. La razón por la que Lokad adoptó este enfoque diferente se hará más claro más adelante en esta conferencia cuando procedamos con una situación real de pronóstico de demanda minorista.

En Envision, es posible anular y controlar la inicialización de los parámetros. El parámetro “quantile”, por ejemplo, se declara en la línea 9 pero no necesita ser inicializado. De hecho, en la línea 7, justo encima del bloque autodiff, tenemos una variable “quantile” a la que se le asigna el valor 4.2, por lo que la variable ya está inicializada con un valor dado. Ya no es necesario una inicialización automática. También es posible imponer un rango de valores permitidos para los parámetros, y esto se hace con la palabra clave “in” en la línea 9. Esencialmente, estamos definiendo que “quantile” debe estar entre 1 y 10, inclusive. Con esos límites establecidos, si hay una actualización obtenida del algoritmo Adam que empujaría el valor del parámetro fuera del rango aceptable, limitamos el cambio de Adam para que se mantenga dentro de este rango. Además, también establecemos en cero los valores de impulso que típicamente se adjuntan al algoritmo Adam bajo el capó. Imponer límites a los parámetros diverge de la práctica clásica de aprendizaje profundo; sin embargo, los beneficios de esta característica se harán evidentes una vez que comencemos a discutir un ejemplo real de pronóstico de demanda minorista.

Slide 11

La programación diferenciable depende en gran medida del descenso de gradiente estocástico. El enfoque estocástico es literalmente lo que hace que el descenso funcione muy rápido. Es una espada de doble filo; el ruido obtenido a través de las pérdidas parciales no es solo un error, sino también una característica. Al tener un poco de ruido, el descenso puede evitar quedarse atrapado en zonas con gradientes muy planos. Por lo tanto, tener este gradiente ruidoso no solo hace que la iteración sea mucho más rápida, sino que también ayuda a empujar la iteración para salir de áreas donde el gradiente es muy plano y causa que el descenso se ralentice. Sin embargo, una cosa a tener en cuenta es que cuando se utiliza el descenso de gradiente estocástico, la suma del gradiente no es el gradiente de la suma. Como resultado, el descenso de gradiente estocástico viene con pequeños sesgos estadísticos, especialmente cuando se trata de distribuciones de cola. Sin embargo, cuando surgen estas preocupaciones, es relativamente sencillo solucionar los problemas numéricos, incluso si la teoría sigue siendo un poco confusa.

La programación diferenciable (DP) no debe confundirse con un solucionador arbitrario de optimización matemática. El gradiente debe fluir a través del programa para que la programación diferenciable funcione en absoluto. La programación diferenciable puede funcionar con programas arbitrariamente complejos, pero esos programas deben ser diseñados teniendo en cuenta la programación diferenciable. Además, la programación diferenciable es una cultura; es un conjunto de consejos y trucos que funcionan bien con el descenso de gradiente estocástico. Teniendo en cuenta todo, la programación diferenciable se encuentra en el lado más fácil del espectro del aprendizaje automático. Es muy accesible como técnica. Sin embargo, se necesita un poco de habilidad para dominar este paradigma y utilizarlo sin problemas en la producción.

Slide 12

Ahora estamos listos para embarcarnos en el segundo bloque de esta conferencia: el recorrido. Tendremos un recorrido para nuestra tarea de pronóstico de demanda minorista. Este ejercicio de modelado está alineado con el desafío de pronóstico que presentamos en la conferencia anterior. En resumen, queremos pronosticar la demanda diaria a nivel de SKU en una red minorista. Un SKU, o unidad de mantenimiento de inventario, es técnicamente el producto cartesiano entre productos y tiendas, filtrado a lo largo de las entradas del surtido. Por ejemplo, si tenemos 100 tiendas y 10,000 productos, y si cada producto está presente en cada tienda, terminamos con 1 millón de SKU.

Hay herramientas para transformar una estimación determinista en una estimación probabilística. Hemos visto una de esas herramientas en la conferencia anterior a través de la técnica ESSM. Volveremos a visitar esta preocupación específica, convertir estimaciones en estimaciones probabilísticas, con más detalle en la próxima conferencia. Sin embargo, hoy solo nos preocupamos por estimar promedios, y todos los demás tipos de estimaciones (cuantiles, probabilísticas) vendrán más adelante como extensiones naturales del ejemplo principal que presentaré hoy. En este recorrido, vamos a aprender los parámetros de un modelo simple de pronóstico de demanda. La simplicidad de este modelo es engañosa porque esta clase de modelo logra pronósticos de vanguardia, como se ilustra en la competencia de pronóstico M5 en 2020.

Slide 13

Para nuestro modelo paramétrico de demanda, introduzcamos un solo parámetro para cada SKU. Esta es una forma absolutamente simplista de modelo; la demanda se modela como una constante para cada SKU. Sin embargo, no es la misma constante para cada SKU. Una vez que tenemos este promedio diario constante, será el mismo valor para todos los días de todo el ciclo de vida del SKU.

Veamos cómo se hace con la programación diferenciable. Desde las líneas 1 a 4, estamos introduciendo el bloque de datos simulados. En la práctica, este modelo y todas sus variantes dependerían de los datos obtenidos de los sistemas empresariales: el ERP, WMS, TMS, etc. Presentar una conferencia en la que estaría conectando un modelo matemático a una representación realista de datos, tal como se obtiene del ERP, introduciría toneladas de complicaciones accidentales que no son relevantes para el tema actual de la conferencia. Entonces, lo que estoy haciendo aquí es introducir un bloque de datos simulados que ni siquiera pretende ser realista de ninguna manera, ni el tipo de datos que se pueden observar en una situación de venta minorista real. El único objetivo de estos datos simulados es introducir las tablas y las relaciones dentro de las tablas, y asegurarse de que el ejemplo de código dado sea completo, se pueda compilar y se pueda ejecutar. Todos los ejemplos de código que has visto hasta ahora son completamente independientes; no hay partes ocultas antes o después. El único propósito del bloque de datos simulados es asegurarse de que tenemos un fragmento de código independiente.

En cada ejemplo de este recorrido, comenzamos con este bloque de datos simulados. En la línea 1, introducimos la tabla de fechas con “dates” como clave primaria. Aquí, tenemos un rango de fechas que es básicamente de dos años y un mes. Luego, en la línea 2, introducimos la tabla de SKUs, que es la lista de SKUs. En este ejemplo minimalista, solo tenemos tres SKUs. En una situación minorista real para una red minorista considerable, tendríamos millones, si no decenas de millones, de SKUs. Pero aquí, por el bien del ejemplo, tomo un número muy pequeño. En la línea 3, tenemos la tabla “T”, que es un producto cartesiano entre los SKUs y la fecha. Básicamente, lo que obtienes a través de esta tabla “T” es una matriz donde tienes cada SKU y cada día. Tiene dos dimensiones.

En la línea 6, introducimos nuestro bloque de autodiferenciación real. La tabla de observación es la tabla de SKUs, y el descenso de gradiente estocástico aquí elegirá un SKU a la vez. En la línea 7, introducimos el “level”, que será nuestro único parámetro. Es un parámetro vectorial, y hasta ahora, en nuestros bloques de autodiferenciación, solo hemos introducido parámetros escalares. Los parámetros anteriores eran solo un número; aquí, “SKU.level” es en realidad un vector. Es un vector que tiene un valor por SKU, y eso es literalmente nuestra demanda constante modelada a nivel de SKU. Especificamos un rango, y veremos por qué importa en un minuto. Debe ser al menos 0.01, y ponemos 1,000 como límite superior de la demanda diaria promedio para este parámetro. Este parámetro se inicializa automáticamente con un valor cercano a uno, que es un punto de partida razonable. En este modelo, lo que tenemos es solo un grado de libertad por SKU. Finalmente, en las líneas 8 y 9, estamos implementando el modelo en sí. En la línea 8, estamos calculando “dot.delta”, que es la demanda predicha por el modelo menos la observada, que es “T.sold”. El modelo es solo un término, una constante, y luego tenemos la observación, que es “T.sold”.

Para entender lo que está sucediendo aquí, tenemos algunos comportamientos de transmisión ocurriendo. La tabla “T” es una tabla cruzada entre SKU y fecha. El bloque autodiff es una iteración que itera sobre las líneas de la tabla de observación. En la línea 9, estamos dentro del bloque autodiff, por lo que hemos seleccionado una línea para la tabla SKU. El valor “SKUs.level” no es un vector aquí; es solo un escalar, solo un valor porque hemos seleccionado solo una línea de la tabla de observación. Luego, “T.sold” ya no es una matriz porque ya hemos seleccionado un SKU. Lo que queda es que “T.sold” es en realidad un vector, un vector que tiene la dimensión igual a la fecha. Cuando hacemos esta resta, “SKUs.level - T.sold,” obtenemos un vector que está alineado con la tabla de fechas, y lo asignamos a “D.delta,” que es un vector con una línea por día, dos años y un mes. Finalmente, en la línea 9, estamos calculando la función de pérdida, que es simplemente el error cuadrático medio. Este modelo es súper simplista. Veamos qué se puede hacer con los patrones de calendario.

Slide 14

El intercambio de parámetros es probablemente una de las técnicas de programación diferenciable más simples y útiles. Un parámetro se dice que está compartido si contribuye a múltiples líneas de observación. Al compartir parámetros entre observaciones, podemos estabilizar el descenso del gradiente y mitigar problemas de sobreajuste. Consideremos el patrón del día de la semana. Podríamos introducir siete parámetros que representen los diversos pesos para cada SKU individual. Hasta ahora, un SKU solo tiene un parámetro, que es simplemente la demanda constante. Si queremos enriquecer esta percepción de la demanda, podríamos decir que cada día de la semana viene con su propio peso, y como tenemos siete días de la semana, podemos tener siete pesos y aplicar esos pesos de manera multiplicativa.

Sin embargo, es poco probable que cada SKU tenga su propio patrón único de día de la semana. La realidad es que es mucho más razonable asumir que existe una categoría o algún tipo de jerarquía, como una familia de productos, una categoría de productos, una subcategoría de productos o incluso un departamento en la tienda que captura correctamente este patrón del día de la semana. La idea es que no queremos introducir siete parámetros por SKU; lo que queremos es introducir siete parámetros por categoría, el nivel de agrupación donde asumimos que hay un comportamiento homogéneo en términos de patrones del día de la semana.

Si decidimos introducir esos siete parámetros con un efecto multiplicativo sobre el nivel, este es exactamente el enfoque que se tomó en la conferencia anterior para este modelo, que terminó en primer lugar a nivel de SKU en la competencia M5. Tenemos un nivel y un efecto multiplicativo con el patrón del día de la semana.

En el código, en las líneas 1 a 5, tenemos el bloque de datos simulados como antes, e introducimos una tabla adicional llamada “category”. Esta tabla es una tabla de agrupación de los SKU, y conceptualmente, para cada línea en la tabla SKU, hay una y solo una línea que coincide en la tabla de categoría. En el lenguaje Envision, decimos que la categoría está aguas arriba de la tabla SKU. La línea 7 introduce la tabla del día de la semana. Esta tabla es instrumental, y la introducimos con una forma específica que refleja el patrón cíclico que queremos capturar. En la línea 7, creamos la tabla del día de la semana agregando fechas según su valor módulo siete. Estamos creando una tabla que tendrá exactamente siete líneas, y esas siete líneas representarán cada uno de los siete días de la semana. Para cada línea en la tabla de fechas, cada línea en la base de datos tiene una y solo una contraparte en la tabla del día de la semana. Por lo tanto, siguiendo el lenguaje Envision, la tabla del día de la semana está aguas arriba de la tabla “date”.

Ahora tenemos la tabla “CD”, que es un producto cartesiano entre la categoría y el día de la semana. En términos del número de líneas, esta tabla tendrá tantas líneas como categorías por siete porque el día de la semana tiene siete líneas. En la línea 12, introducimos un nuevo parámetro llamado “CD.DOW” (DOW significa día de la semana), que es otro parámetro vector perteneciente a la tabla CD. En términos de grados de libertad, tendremos exactamente siete valores de parámetro por el número de categorías, que es lo que buscamos. Queremos un modelo que sea capaz de capturar este patrón del día de la semana pero con solo un patrón por categoría, no uno por SKU.

Declaramos este parámetro y usamos la palabra clave “in” para especificar que el valor de “CD.DOW” debe estar entre 0.1 y 100. En la línea 13, escribimos la demanda expresada por el modelo. La demanda es “SKUs.level * CD.DOW”, que representa la demanda. Tenemos la demanda menos el “T.sold” observado, y eso nos da un delta. Luego calculamos el error cuadrático medio.

En la línea 13, tenemos bastante magia de transmisión. “CD.DOW” es una tabla cruzada entre la categoría y el día de la semana. Debido a que estamos dentro del bloque de autodiferenciación, la tabla CD es una tabla cruzada entre la categoría y el día de la semana. Dado que estamos dentro del bloque de autodiferenciación, el bloque está iterando sobre la tabla SKUs. Esencialmente, cuando elegimos un SKU, hemos elegido efectivamente una categoría, ya que la tabla de categorías está aguas arriba. Esto significa que CD.DOW ya no es una matriz, sino un vector de dimensión siete. Sin embargo, está aguas arriba de la tabla “date”, por lo que esas siete líneas se pueden transmitir en la tabla de fechas. Solo hay una forma de hacer esta transmisión porque cada línea de la tabla del día de la semana tiene una afinidad con líneas específicas de la tabla de fechas. Tenemos una doble transmisión en marcha y, al final, obtenemos una demanda que es una serie de valores que es cíclica a nivel del día de la semana para el SKU. Ese es nuestro modelo en este punto, y el resto de la función de pérdida permanece sin cambios.

Vemos una forma muy elegante de abordar las ciclicidades combinando los comportamientos de transmisión obtenidos de la naturaleza relacional de Envision con sus capacidades de programación diferenciable. Podemos expresar las ciclicidades del calendario en solo tres líneas de código. Este enfoque funciona bien incluso si estamos tratando con datos muy dispersos. Funcionaría perfectamente incluso si estuviéramos viendo productos que venden solo una unidad por mes en promedio. En esos casos, el enfoque inteligente sería tener una categoría que incluya docenas, si no cientos de productos. Esta técnica también se puede utilizar para reflejar otros patrones cíclicos, como el mes del año o el día del mes.

El modelo presentado en la conferencia anterior, que logró resultados de vanguardia en la competencia M5, fue una combinación multiplicativa de tres ciclicidades: día de la semana, mes del año y día del mes. Todos estos patrones se encadenaron como una multiplicación. La implementación de las otras dos variantes queda a cargo del público atento, pero solo es cuestión de un par de líneas de código por patrón cíclico, lo que lo hace muy conciso.

Slide 15

En la conferencia anterior, presentamos un modelo de pronóstico de ventas. Sin embargo, no son las ventas las que nos interesan, sino la demanda. No debemos confundir las ventas nulas con la demanda nula. Si no quedaba stock para que el cliente compre en la tienda en un determinado día, en Lokad se utiliza la técnica de enmascaramiento de pérdidas para hacer frente a los faltantes de stock. Esta es la técnica más simple utilizada para hacer frente a los faltantes de stock, pero no es la única. Hasta donde yo sé, tenemos al menos otras dos técnicas que se utilizan en producción, cada una con sus ventajas y desventajas. Estas otras técnicas no se tratarán hoy, pero se abordarán en conferencias posteriores.

Volviendo al ejemplo de código, las líneas del 1 al 3 permanecen intactas. Veamos qué sigue. En la línea 6, estamos enriqueciendo los datos simulados con la bandera booleana de stock disponible. Para cada SKU y cada día, tenemos un valor booleano que indica si hubo un faltante de stock al final del día en la tienda. En la línea 15, estamos modificando la función de pérdida para excluir, anulándolos, los días en los que se observó un faltante de stock al final del día. Al anular esos días, nos aseguramos de que no se propague ningún gradiente en situaciones que presenten un sesgo debido a la ocurrencia del faltante de stock.

El aspecto más desconcertante de la técnica de enmascaramiento de pérdidas es que ni siquiera cambia el modelo. De hecho, si observamos el modelo expresado en la línea 14, es exactamente el mismo; no ha sido modificado. Solo se modifica la función de pérdida en sí misma. Esta técnica puede ser simple, pero diverge profundamente de una perspectiva centrada en el modelo. Es, en su esencia, una técnica centrada en la modelización. Mejoramos la situación al reconocer el sesgo causado por los faltantes de stock, reflejándolo en nuestros esfuerzos de modelización. Sin embargo, lo hacemos cambiando la métrica de precisión, no el modelo en sí. En otras palabras, estamos cambiando la pérdida que optimizamos, lo que hace que este modelo no sea comparable con otros modelos en términos de error numérico puro.

Para una situación como la de Walmart, como se discutió en la conferencia anterior, la técnica de enmascaramiento de pérdidas es adecuada para la mayoría de los productos. Como regla general, esta técnica funciona bien si la demanda no es tan dispersa como para tener solo una unidad en stock la mayor parte del tiempo. Además, se deben evitar los productos donde los faltantes de stock son muy frecuentes, ya que es la estrategia explícita del minorista terminar con un faltante de stock al final del día. Esto suele ocurrir con algunos productos ultrafrescos donde el minorista apunta a una situación de falta de stock al final del día. Técnicas alternativas solucionan estas limitaciones, pero no tenemos tiempo para cubrirlas hoy.

Slide 16

Las promociones son un aspecto importante del comercio minorista. Más en general, hay muchas formas en las que el minorista puede influir y dar forma a la demanda, como la fijación de precios o la colocación de productos en una góndola. Las variables que proporcionan información adicional con fines predictivos se suelen denominar covariables en los círculos de la cadena de suministro. Existe mucho pensamiento ilusorio sobre covariables complejas como los datos meteorológicos o los datos de las redes sociales. Sin embargo, antes de adentrarnos en temas avanzados, debemos abordar el elefante en la habitación, como la información de precios, que obviamente tiene un impacto significativo en la demanda que se observará. Por lo tanto, en la línea 7 de este ejemplo de código, introducimos para cada día individual en la línea 14, “category.ed”, donde “ed” significa elasticidad de la demanda. Este es un parámetro de vector compartido con un grado de libertad por categoría, destinado a representar la elasticidad de la demanda. En la línea 16, introducimos una forma exponencial de elasticidad precio como el exponencial de (-category.ed * t.price). Intuitivamente, con esta forma, cuando el precio aumenta, la demanda converge rápidamente a cero debido a la presencia de la función exponencial. Por el contrario, cuando el precio converge a cero, la demanda aumenta explosivamente.

Esta forma exponencial de respuesta de precios es simplista, y compartir los parámetros asegura un alto grado de estabilidad numérica incluso con esta función exponencial en el modelo. En entornos del mundo real, especialmente para situaciones como Walmart, tendríamos varias informaciones de precios, como descuentos, la diferencia en comparación con el precio normal, covariables que representan acciones de marketing ejecutadas por el proveedor o variables categóricas que introducen elementos como góndolas. Con la programación diferenciable, es fácil crear respuestas de precios arbitrariamente complejas que se ajusten estrechamente a la situación. La integración de covariables de casi cualquier tipo es muy sencilla con la programación diferenciable.

Slide 17

Los productos de rotación lenta son una realidad en el comercio minorista y en muchos otros sectores. El modelo presentado hasta ahora tiene un parámetro, un grado de libertad por SKU, con más si se cuentan los parámetros compartidos. Sin embargo, esto podría ser demasiado, especialmente para los SKU que solo rotan una vez al año o solo unas pocas veces al año. En tales situaciones, ni siquiera podemos permitirnos un grado de libertad por SKU, por lo que la solución es depender únicamente de los parámetros compartidos y eliminar todos los parámetros con grados de libertad a nivel de SKU.

En las líneas 2 y 4, introducimos dos tablas llamadas “productos” y “tiendas”, y la tabla “SKUs” se construye como una subtabla filtrada del producto cartesiano entre productos y tiendas, que es la definición misma de surtido. En las líneas 15 y 16, introducimos dos parámetros de vector compartidos: un nivel con afinidad con la tabla de productos y otro nivel que tiene afinidad con las tablas de tiendas. Estos parámetros también se definen dentro de un rango específico, de 0.01 a 100, que es el valor máximo.

Ahora, en la línea 18, el nivel por SKU se compone como la multiplicación del nivel de producto y el nivel de tienda. El resto del script permanece sin cambios. ¿Cómo funciona esto? En la línea 19, SKU.level es un escalar. Tenemos el bloque autodesk que itera sobre la tabla SKUs, que es la tabla de observación. Por lo tanto, SKUs.level en la línea 18 es solo un valor escalar. Luego tenemos products.level. Dado que la tabla de productos está aguas arriba de la tabla SKUs, para cada SKU individual, hay un solo producto. Por lo tanto, products.level es solo un número escalar. Lo mismo se aplica a la tabla de tiendas, que también está aguas arriba de la tabla SKUs. En la línea 18, solo hay una tienda asociada a este SKU específico. Por lo tanto, lo que tenemos es la multiplicación de dos valores escalares, que nos da SKU.level. El resto del modelo permanece sin cambios.

Estas técnicas arrojan una nueva luz sobre la afirmación de que a veces no hay suficientes datos o que a veces los datos son demasiado dispersos. De hecho, desde la perspectiva diferenciable, esas afirmaciones ni siquiera tienen mucho sentido. No hay tal cosa como demasiados pocos datos o que los datos sean demasiado dispersos, al menos no en términos absolutos. Solo hay modelos que se pueden modificar hacia la dispersión y posiblemente hacia la dispersión extrema. La estructura impuesta es como rieles guía que hacen que el proceso de aprendizaje no solo sea posible, sino numéricamente estable.

En comparación con otras técnicas de aprendizaje automático que intentan que el modelo de aprendizaje automático descubra todos los patrones ex nihilo, este enfoque estructurado establece la estructura misma que debemos aprender. Por lo tanto, el mecanismo estadístico en juego aquí tiene una libertad limitada en lo que se refiere a aprender. En consecuencia, en términos de eficiencia de datos, puede ser increíblemente eficiente. Naturalmente, todo esto se basa en el hecho de que hemos elegido la estructura correcta.

Como puede ver, hacer experimentos es muy sencillo. Ya estamos haciendo algo muy complicado, y en menos de 50 líneas, podríamos lidiar con una situación bastante compleja similar a la de Walmart. Esto es todo un logro. Hay un poco de proceso empírico, pero la realidad es que no es tanto. Estamos hablando de unas pocas docenas de líneas. Tenga en cuenta que un ERP como el que ejecuta una empresa, una gran red minorista, típicamente tiene mil tablas y 100 campos por tabla. Por lo tanto, claramente, la complejidad de los sistemas empresariales es absolutamente gigantesca en comparación con la complejidad de este modelo predictivo estructurado. Si tenemos que pasar un poco de tiempo iterando, casi no es nada.

Además, como se demostró en la competencia de pronóstico M5, la realidad es que los profesionales de la cadena de suministro ya conocen los patrones. Cuando el equipo de M5 utilizó tres patrones de calendario, que eran el día de la semana, el mes del año y el día del mes, todos estos patrones eran evidentes para cualquier profesional experimentado en cadena de suministro. La realidad en la cadena de suministro es que no estamos tratando de descubrir algún patrón oculto. El hecho de que, por ejemplo, si se reduce masivamente el precio, la demanda aumentará masivamente, no sorprenderá a nadie. La única pregunta que queda es cuál es exactamente la magnitud del efecto y cuál es la forma exacta de la respuesta. Estos son detalles relativamente técnicos y, si nos permitimos la oportunidad de hacer un poco de experimentos, podemos abordar estos problemas de manera relativamente fácil.

Slide 18

Como último paso de este recorrido, me gustaría señalar una peculiaridad menor de la programación diferenciable. La programación diferenciable no debe confundirse con un solucionador genérico de optimización matemática. Debemos tener en cuenta que se está llevando a cabo un descenso de gradiente. Más específicamente, el algoritmo utilizado para optimizar y actualizar los parámetros tiene una velocidad máxima de descenso que es igual a la tasa de aprendizaje que viene con el algoritmo ADAM. En Envision, la tasa de aprendizaje predeterminada es 0.01.

Si observamos el código, en la línea 4, introdujimos una inicialización donde las cantidades vendidas se muestrean de una distribución de Poisson con una media de 50. Si queremos aprender un nivel, técnicamente, necesitaríamos tener un nivel que sea del orden de 50. Sin embargo, cuando hacemos una inicialización automática del parámetro, comenzamos con un valor que está alrededor de uno, y solo podemos ir en incrementos de 0.01. Tomaría alrededor de 5,000 épocas alcanzar realmente este valor de 50. Dado que tenemos un parámetro no compartido, SKU.level, este parámetro por época solo se modifica una vez. Por lo tanto, necesitaríamos 5,000 épocas, lo que ralentizaría innecesariamente el cálculo.

Podríamos aumentar la tasa de aprendizaje para acelerar el descenso, lo cual sería una solución. Sin embargo, no aconsejaría inflar la tasa de aprendizaje, ya que esto generalmente no es la forma correcta de abordar el problema. En una situación real, tendríamos parámetros compartidos además de este parámetro no compartido. Esos parámetros compartidos serán modificados por el descenso de gradiente estocástico muchas veces a lo largo de cada época. Si aumentas en gran medida la tasa de aprendizaje, corres el riesgo de crear inestabilidades numéricas para tus parámetros compartidos. Podrías aumentar la velocidad de movimiento del nivel SKU pero crear problemas de estabilidad numérica para los otros parámetros.

Una mejor técnica sería utilizar un truco de reescalado y envolver el parámetro en una función exponencial, que es exactamente lo que se hace en la línea 8. Con este envoltorio, ahora podemos alcanzar valores de parámetros para el nivel que pueden ser muy bajos o muy altos con un número mucho menor de épocas. Esta peculiaridad es básicamente la única peculiaridad que necesitaría introducir para tener un ejemplo realista para este recorrido de la situación de pronóstico de demanda minorista. Considerando todo, es una peculiaridad menor. Sin embargo, es un recordatorio de que la programación diferenciable requiere prestar atención al flujo de gradientes. La programación diferenciable ofrece una experiencia de diseño fluida en general, pero no es magia.

Slide 19

Algunas reflexiones finales: los modelos estructurados logran una precisión de pronóstico de vanguardia. Este punto se mencionó extensamente en la conferencia anterior. Sin embargo, basándonos en los elementos presentados hoy, argumentaría que la precisión ni siquiera es el factor decisivo a favor de la programación diferenciable con un modelo paramétrico estructurado. Lo que obtenemos es comprensión; no solo obtenemos un software capaz de hacer predicciones, sino que también obtenemos información directa sobre los patrones mismos que estamos tratando de capturar. Por ejemplo, el modelo presentado hoy nos daría directamente un pronóstico de demanda que viene con pesos explícitos para los días de la semana y una elasticidad explícita de la demanda. Si quisiéramos ampliar esta demanda, por ejemplo, para introducir un aumento asociado con el Black Friday, un evento cuasi-estacional que no ocurre en el mismo momento todos los años, podríamos hacerlo. Solo agregaríamos un factor y luego tendríamos una estimación del aumento del Black Friday aislado de todos los demás patrones, como el patrón de los días de la semana. Esto es de gran interés.

Lo que obtenemos a través del enfoque estructurado es comprensión, y es mucho más que solo el modelo en bruto. Por ejemplo, si terminamos con una elasticidad negativa, una situación en la que el modelo te dice que cuando aumentas el precio, aumentas la demanda, en una situación similar a Walmart, este es un resultado muy dudoso. Lo más probable es que refleje que la implementación de tu modelo está defectuosa o que hay problemas profundos en marcha. No importa lo que te diga la métrica de precisión, si terminas en una situación similar a Walmart con algo que te dice que al hacer que un producto sea más caro, la gente compra más, realmente deberías cuestionar toda tu cadena de datos porque lo más probable es que haya algo muy mal. De eso se trata la comprensión.

Además, el modelo está abierto al cambio. La programación diferenciable es increíblemente expresiva. El modelo que tenemos es solo una iteración en un viaje. Si el mercado se transforma o si la propia empresa se transforma, podemos estar seguros de que el modelo que tenemos será capaz de capturar esta evolución de manera natural. No existe tal cosa como una evolución automática; requerirá esfuerzo de un Supply Chain Scientist para capturar esta evolución. Sin embargo, se espera que este esfuerzo sea relativamente mínimo. Se reduce al hecho de que si tienes un modelo muy pequeño y ordenado, cuando necesites revisar este modelo más adelante para ajustar su estructura, será una tarea relativamente pequeña en comparación con una situación en la que tu modelo sería una bestia de ingeniería.

Cuando se diseñan cuidadosamente, los modelos producidos con programación diferenciable son muy estables. La estabilidad se reduce a la elección de la estructura. La estabilidad no es algo garantizado para cualquier programa que se optimice a través de la programación diferenciable; es algo que se obtiene cuando se tiene una estructura muy clara en la que los parámetros tienen un significado específico. Por ejemplo, si tienes un modelo en el que, cada vez que vuelvas a entrenar tu modelo, obtienes pesos completamente diferentes para el día de la semana, entonces la realidad en tu negocio no está cambiando tan rápido. Si ejecutas tu modelo dos veces, deberías obtener valores para el día de la semana que sean bastante estables. Si no es así, entonces hay algo muy mal en la forma en que has modelado tu demanda. Por lo tanto, si haces una elección sabia para la estructura de tu modelo, puedes obtener resultados numéricos increíblemente estables. Al hacerlo, evitamos los problemas que suelen afectar a los modelos de aprendizaje automático complejos cuando intentamos utilizarlos en un contexto de cadena de suministro. De hecho, desde una perspectiva de cadena de suministro, las inestabilidades numéricas son mortales porque tenemos efectos de trinquete en todas partes. Si tienes una estimación de la demanda que fluctúa, significa que al azar vas a desencadenar una orden de compra o una orden de producción sin motivo alguno. Una vez que hayas desencadenado tu orden de producción, no puedes decidir la próxima semana que fue un error y que no deberías haberlo hecho. Estás atrapado con la decisión que acabas de tomar. Si tienes un estimador de la demanda futura que sigue fluctuando, terminarás con un reabastecimiento inflado y órdenes de producción infladas. Este problema se puede resolver asegurando la estabilidad, que es una cuestión de diseño.

Uno de los mayores obstáculos para implementar el aprendizaje automático en producción es la confianza. Cuando operas con millones de euros o dólares, entender lo que está sucediendo en tu receta numérica es fundamental. Los errores en la cadena de suministro pueden ser extremadamente costosos, y hay muchos ejemplos de desastres en la cadena de suministro causados por una mala aplicación de algoritmos mal comprendidos. Si bien la programación diferenciable es muy poderosa, los modelos que se pueden diseñar son increíblemente simples. Estos modelos podrían ejecutarse en una hoja de cálculo de Excel, ya que suelen ser modelos multiplicativos sencillos con ramificaciones y funciones. El único aspecto que no se puede ejecutar en una hoja de cálculo de Excel es la diferenciación automática, y obviamente, si tienes millones de SKU, no intentes hacer eso en una hoja de cálculo. Sin embargo, en cuanto a simplicidad, es muy compatible con algo que pondrías en una hoja de cálculo. Esta simplicidad contribuye en gran medida a establecer la confianza y a llevar el aprendizaje automático a la producción, en lugar de mantenerlo como prototipos sofisticados en los que la gente nunca llega a confiar completamente.

Por último, cuando juntamos todas estas propiedades, obtenemos una tecnología muy precisa. Este enfoque se discutió en el primer capítulo de esta serie de conferencias. Queremos convertir todos los esfuerzos invertidos en la cadena de suministro en inversiones capitalistas, en lugar de tratar a los expertos y profesionales de la cadena de suministro como consumibles que necesitan hacer las mismas cosas una y otra vez. Con este enfoque, podemos considerar todos estos esfuerzos como inversiones que generarán y seguirán generando retorno de la inversión con el tiempo. La programación diferenciable se adapta muy bien a esta perspectiva capitalista de la cadena de suministro.

Slide 20

En el segundo capítulo, presentamos una conferencia importante titulada “Optimización Experimental”, que proporcionó una posible respuesta a la pregunta simple pero fundamental: ¿Qué significa realmente mejorar o hacerlo mejor en una cadena de suministro? La perspectiva de la programación diferenciable proporciona una visión muy específica de las muchas dificultades que enfrentan los profesionales de la cadena de suministro. Los proveedores de software empresarial a menudo culpan a los datos incorrectos por los fracasos en la cadena de suministro. Sin embargo, creo que esta es simplemente la forma incorrecta de ver el problema. Los datos son simplemente lo que son. Su ERP nunca ha sido diseñado para la ciencia de datos, pero ha estado funcionando sin problemas durante años, si no décadas, y las personas en la empresa logran ejecutar la cadena de suministro de todos modos. Incluso si su ERP que captura datos sobre su cadena de suministro no es perfecto, está bien. Si espera que se disponga de datos perfectos, esto es simplemente un pensamiento ilusorio. Estamos hablando de cadenas de suministro; el mundo es muy complejo, por lo que los sistemas son imperfectos. Realísticamente, no tiene un sistema empresarial; tiene como media docena, y no son completamente consistentes entre sí. Esto es simplemente un hecho de la vida. Sin embargo, cuando los proveedores empresariales culpan a los datos incorrectos, la realidad es que se utiliza un modelo de pronóstico muy específico por parte del proveedor, y este modelo se ha diseñado con un conjunto específico de suposiciones sobre la empresa. El problema es que si su empresa viola alguna de esas suposiciones, la tecnología se desmorona por completo. En esta situación, tiene un modelo de pronóstico que viene con suposiciones irrazonables, alimenta los datos, no es perfecto y, por lo tanto, la tecnología se desmorona. Es completamente irrazonable decir que la empresa es culpable. La tecnología culpable es la que impulsa el proveedor y que hace suposiciones completamente irrealistas sobre qué datos pueden estar incluso en un contexto de cadena de suministro.

Hoy no he presentado ningún punto de referencia para ninguna métrica de precisión. Sin embargo, mi propuesta es que esas métricas de precisión son en su mayoría inconsecuentes. Un modelo predictivo es una herramienta para tomar decisiones. Lo que importa es si esas decisiones, qué comprar, qué producir, si subir o bajar el precio, son buenas o malas. Las malas decisiones se pueden rastrear hasta el modelo predictivo, eso es cierto. Sin embargo, la mayoría de las veces, no es un problema de precisión. Por ejemplo, teníamos un modelo de pronóstico de ventas y solucionamos el problema de faltante de stock que no se manejaba adecuadamente. Sin embargo, cuando solucionamos el problema de faltante de stock, lo que hicimos fue solucionar la métrica de precisión en sí misma. Entonces, solucionar el modelo predictivo no significa mejorar la precisión; con mucha frecuencia, significa literalmente revisar el problema y la perspectiva en la que operas y, por lo tanto, modificar la métrica de precisión o algo aún más profundo. El problema con la perspectiva clásica es que asume que la métrica de precisión es un objetivo valioso. Esto no es del todo cierto.

Las cadenas de suministro operan en un mundo real y hay muchos eventos inesperados e incluso extraños. Por ejemplo, puede haber una obstrucción del Canal de Suez debido a un barco; este es un evento completamente extraño. En una situación así, inmediatamente invalidaría todos los modelos de pronóstico de tiempo de entrega existentes que estaban mirando esta parte del mundo. Obviamente, esto es algo que realmente no había sucedido antes, por lo que no podemos hacer una prueba retrospectiva en una situación así. Sin embargo, incluso si tenemos esta situación completamente excepcional con un barco bloqueando el Canal de Suez, aún podemos solucionar el modelo, al menos si tenemos este tipo de enfoque de caja blanca que estoy proponiendo hoy. Esta solución implicará un grado de conjetura, lo cual está bien. Es mejor estar aproximadamente en lo correcto que estar exactamente equivocado. Por ejemplo, si estamos considerando que el Canal de Suez está bloqueado, simplemente podemos decir: “agreguemos un mes al tiempo de entrega para todos los suministros que se suponía que iban a pasar por esta ruta”. Esto es muy aproximado, pero es mejor asumir que no habrá retraso en absoluto, aunque ya tengas la información. Además, el cambio frecuentemente proviene desde adentro. Por ejemplo, consideremos una red minorista que tiene un centro de distribución antiguo y un centro de distribución nuevo que abastece a varias docenas de tiendas. Digamos que hay una migración en curso, donde básicamente los suministros para las tiendas se están migrando del centro de distribución antiguo al nuevo. Esta situación ocurre casi solo una vez en la historia de este minorista específico y no se puede probar retrospectivamente. Sin embargo, con un enfoque como la programación diferenciable, es completamente sencillo implementar un modelo que se ajuste a esta migración gradual.

Slide 21

En conclusión, la programación diferenciable es una tecnología que nos brinda un enfoque para estructurar nuestras ideas sobre el futuro. La programación diferenciable nos permite dar forma, literalmente, a la forma en que vemos el futuro. La programación diferenciable se encuentra en el lado de la percepción de esta imagen. Basándonos en esta percepción, podemos tomar mejores decisiones para las cadenas de suministro, y esas decisiones impulsan las acciones que se encuentran en el otro lado de la imagen. Uno de los mayores malentendidos de la teoría convencional de las cadenas de suministro es que se puede tratar la percepción y la acción de forma aislada como componentes estrictamente aislados. Esto toma la forma, por ejemplo, de tener un equipo a cargo de la planificación (que es la percepción) y un equipo independiente a cargo del abastecimiento (que es la acción).

Sin embargo, el bucle de retroalimentación percepción-acción es muy importante; es de suma importancia. Este es literalmente el mecanismo que te guía hacia una forma correcta de percepción. Si no tienes este bucle de retroalimentación, ni siquiera está claro si estás mirando lo correcto, o si lo que estás mirando es realmente lo que crees que es. Necesitas este mecanismo de retroalimentación, y es a través de este bucle de retroalimentación que realmente puedes dirigir tus modelos hacia una evaluación cuantitativa correcta del futuro que sea relevante para el curso de acción de tu cadena de suministro. Los enfoques convencionales de las cadenas de suministro están desestimando este caso casi por completo porque, esencialmente, creo que están atrapados en una forma muy rígida de pronóstico. Esta forma de pronóstico centrada en el modelo puede ser un modelo antiguo, como el modelo de pronóstico de Holt-Winters, o uno reciente como Facebook Prophet. La situación es la misma: si estás atrapado con un modelo de pronóstico, entonces toda la retroalimentación que puedes obtener desde el lado de la acción de la imagen no tiene sentido porque no puedes hacer nada al respecto, excepto ignorarla por completo.

Si estás atrapado con un modelo de pronóstico dado, no puedes reformatear o reestructurar tu modelo a medida que obtienes información desde el lado de la acción. Por otro lado, la programación diferenciable, con su enfoque de modelado estructurado, te brinda un paradigma completamente diferente. El modelo predictivo es completamente desechable, todo él. Si la retroalimentación que obtienes de tus acciones requiere cambios radicales en tu perspectiva predictiva, simplemente implementa esos cambios radicales. No hay una conexión específica con una iteración dada del modelo. Mantener el modelo muy simple es una forma de asegurarse de que una vez en producción, conserves la opción de seguir cambiando este modelo. Porque, nuevamente, si lo que has diseñado es como una bestia, un monstruo de ingeniería, entonces una vez en producción, se vuelve increíblemente difícil cambiarlo. Uno de los aspectos clave es que si quieres poder seguir cambiando, necesitas tener un modelo que sea muy parsimonioso en términos de líneas de código y complejidad interna. Aquí es donde brilla la programación diferenciable. No se trata de lograr una mayor precisión, se trata de lograr una mayor relevancia. Sin relevancia, todas las métricas de precisión no tienen sentido. La programación diferenciable y el modelado estructurado te brindan el camino para lograr relevancia y luego mantenerla a lo largo del tiempo.

Slide 22

Esto concluye la conferencia de hoy. La próxima vez, el 2 de marzo, a la misma hora, a las 3 PM hora de París, presentaré el modelado probabilístico para la cadena de suministro. Analizaremos de cerca las implicaciones técnicas de mirar todos los futuros posibles en lugar de simplemente elegir un futuro y declararlo como el correcto. De hecho, mirar todos los futuros posibles es muy importante si quieres que tu cadena de suministro sea efectivamente resiliente contra el riesgo. Si solo eliges un futuro, es una receta para terminar con algo que es increíblemente frágil si tu pronóstico no resulta ser perfectamente correcto. Y adivina qué, el pronóstico nunca es completamente correcto. Por eso es muy importante aceptar la idea de que necesitas mirar todos los futuros posibles, y veremos cómo hacerlo con recetas numéricas modernas.

Pregunta: Se agrega ruido estocástico para evitar mínimos locales, pero ¿cómo se aprovecha o se escala para evitar grandes desviaciones para que el descenso de gradiente no se aleje mucho de su objetivo?

Esa es una pregunta muy interesante, y hay dos partes en esta respuesta.

Primero, esto es por qué el algoritmo Adam es muy conservador en términos de la magnitud de los movimientos. El gradiente es fundamentalmente ilimitado; puedes tener un gradiente que valga miles o millones. Sin embargo, con Adam, el paso máximo está limitado por la tasa de aprendizaje. Entonces, efectivamente, Adam viene con una receta numérica que literalmente impone un paso máximo, y con suerte, eso evita una inestabilidad numérica masiva.

Ahora, si al azar, a pesar de tener esta tasa de aprendizaje, podríamos decir que solo por fluctuaciones puras vamos a movernos de forma iterativa, un paso a la vez, pero muchas veces en una dirección incorrecta, esta es una posibilidad. Es por eso que digo que el descenso de gradiente estocástico aún no se comprende completamente. Funciona increíblemente bien en la práctica, pero por qué funciona tan bien, por qué converge tan rápido y por qué no tenemos más problemas que pueden ocurrir, no se comprende completamente, especialmente si consideramos que el descenso de gradiente estocástico ocurre en dimensiones altas. Por lo general, tienes literalmente decenas, si no cientos, de parámetros que se están modificando en cada paso. La intuición que puedes tener en dos o tres dimensiones es muy engañosa; las cosas se comportan de manera muy diferente cuando estás mirando dimensiones más altas.

Entonces, la conclusión para esta pregunta: es muy relevante. Hay una parte donde está la magia de Adam de ser muy conservador con la escala de los pasos del gradiente, y la otra parte, que se entiende poco pero aún funciona muy bien en la práctica. Por cierto, creo que el hecho de que el descenso de gradiente estocástico no sea completamente intuitivo también es la razón por la cual durante casi 70 años esta técnica se conocía pero no se reconocía como efectiva. Durante casi 70 años, las personas sabían que existía, pero eran muy escépticas. Se necesitó el gran éxito del deep learning para que la comunidad reconociera y admitiera que en realidad funciona muy bien, incluso si realmente no entendemos por qué.

Pregunta: ¿Cómo se sabe cuándo un cierto patrón es débil y, por lo tanto, debe eliminarse del modelo?

Nuevamente, una muy buena pregunta. No hay criterios estrictos; es literalmente una decisión del supply chain scientist. La razón es que si el patrón que introduces te brinda beneficios mínimos, pero en términos de modelado es solo dos líneas de código y el impacto en términos de tiempo de cálculo es insignificante, y si alguna vez quieres eliminar el patrón más adelante, es semi-trivial, podrías decir: “Bueno, puedo dejarlo. No parece hacer daño, no hace mucho bien. Puedo ver situaciones en las que este patrón que es débil ahora podría volverse fuerte”. En términos de mantenibilidad, está bien.

Sin embargo, también puedes ver el otro lado de la imagen donde tienes un patrón que no captura mucho y agrega mucho cálculo al modelo. Entonces no es gratuito; cada vez que agregas un parámetro o lógica, vas a inflar la cantidad de recursos informáticos necesarios para tu modelo, haciéndolo más lento y más difícil de manejar. Si piensas que este patrón que es débil podría volverse fuerte, pero de una manera negativa, generando inestabilidad y creando caos en tu modelado predictivo, esta es típicamente la situación en la que pensarías: “No, probablemente debería eliminarlo”.

Ves, realmente es una cuestión de juicio. La programación diferenciable es una cultura; no estás solo. Tienes colegas y compañeros que tal vez hayan probado diferentes cosas en Lokad. Esta es la especie de cultura que tratamos de cultivar. Sé que puede ser un poco decepcionante en comparación con la perspectiva de la inteligencia artificial todopoderosa, la idea de que podríamos tener una inteligencia artificial todopoderosa que resuelva todos esos problemas por nosotros. Pero la realidad es que las cadenas de suministro son tan complejas y nuestras técnicas de inteligencia artificial son tan rudimentarias que no tenemos ningún sustituto realista para la inteligencia humana. Cuando digo juicio, solo quiero decir que necesitas una buena dosis de inteligencia humana aplicada al caso, porque todos los trucos algorítmicos ni siquiera se acercan a brindar una respuesta satisfactoria.

Sin embargo, eso no significa que no puedas diseñar algún tipo de herramienta. Ese sería otro tema; veré si realmente cubro el tipo de herramientas que proporcionamos en Lokad para facilitar el diseño. Un patrón tangencial sería, si tenemos que tomar una decisión, tratemos de proporcionar toda la instrumentación para que esta decisión se pueda tomar rápidamente, minimizando la cantidad de dolor que conlleva este tipo de indecisión donde el científico de la cadena de suministro necesita decidir algo sobre el destino del estado actual del modelo.

Pregunta: ¿Cuál es el umbral de complejidad de una cadena de suministro después del cual el aprendizaje automático y la programación diferenciable brindan resultados considerablemente mejores?

En Lokad, generalmente logramos obtener resultados sustanciales para empresas que tienen un volumen de negocios de $10 millones al año o más. Diría que realmente comienza a destacar si tienes una empresa con un volumen de negocios anual de $50 millones o más.

La razón es que, fundamentalmente, necesitas establecer un flujo de datos muy confiable. Debes poder extraer todos los datos relevantes del ERP diariamente. No quiero decir que sean buenos datos o malos datos, simplemente los datos que tienes pueden tener muchos defectos. Sin embargo, significa que hay bastante trabajo solo para poder extraer las transacciones básicas diariamente. Si la empresa es demasiado pequeña, generalmente ni siquiera tienen un departamento de TI dedicado y no pueden lograr una extracción diaria confiable, lo que realmente compromete los resultados.

Ahora, en términos de verticales o complejidad, la cuestión es que, en la mayoría de las empresas y la mayoría de las cadenas de suministro, en mi opinión, ni siquiera han comenzado a optimizar todavía. Como dije, la teoría de la cadena de suministro predominante enfatiza que debes buscar pronósticos más precisos. Tener un porcentaje reducido de error de pronóstico es un objetivo, y muchas empresas, por ejemplo, lo abordarían teniendo un equipo de planificación o un equipo de pronóstico. En mi opinión, todo eso no agrega nada de valor al negocio porque fundamentalmente proporciona respuestas muy sofisticadas al conjunto incorrecto de preguntas.

Puede sorprender, pero la programación diferenciable realmente destaca no porque sea fundamentalmente súper poderosa, que lo es, sino porque generalmente es la primera vez que hay algo que es realmente relevante para el negocio implementado en la empresa. Si solo quieres tener un ejemplo, la mayoría de lo que se implementa en la cadena de suministro son modelos como el modelo de existencias de seguridad, que no tienen absolutamente ninguna relevancia para ninguna cadena de suministro del mundo real. Por ejemplo, en el modelo de existencias de seguridad, se asume que es posible tener un tiempo de espera negativo, lo que significa que ordenas ahora y te entregaron ayer. No tiene ningún sentido y, como consecuencia, los resultados operativos para las existencias de seguridad suelen ser insatisfactorios.

La programación diferenciable brilla al lograr relevancia, no al lograr algún tipo de superioridad numérica grandiosa o al ser mejor que otras técnicas alternativas de aprendizaje automático. El punto es lograr relevancia en un mundo que es muy complejo, caótico, adversarial, que cambia todo el tiempo y donde tienes que lidiar con un paisaje aplicativo seminocturno que representa los datos que tienes que procesar.

Parece que no hay más preguntas. En este caso, supongo que nos veremos el próximo mes para la conferencia de modelado probabilístico para la cadena de suministro.