¡Participa de la Maratón Behind the Code, la competencia de programación más desafiante! Inscríbete aqui

Los lenguajes de la IA

La evolución de la inteligencia artificial (AI) ha crecido con la complejidad de los lenguajes disponibles para el desarrollo. En 1959, en IBM Arthur Samuel desarrolló un programa de damas que aprendía por sí mismo en una computadora IBM® 701 que utilizaba las instrucciones nativas de la máquina (un gran logro debido a los árboles de búsqueda y la poda alfa beta). Pero hoy, la IA se desarrolla utilizando diferentes lenguajes, desde Lisp a Python, pasando por R. Este artículo explora los lenguajes que evolucionaron para la IA y para el aprendizaje automático.

Los lenguajes de programación que se utilizan para construir aplicaciones de IA y de aprendizaje automático varían. Cada aplicación tiene sus propias restricciones y requisitos, y algunos lenguajes son mejores que otros en dominios de problemas específicos. También se han creado lenguajes, y han evolucionado, basándose en los requisitos únicos de las aplicaciones de IA.

Antes de los lenguajes de alto nivel

A principios de la historia de la IA, los únicos lenguajes nativos que existían eran los lenguajes nativos de las propias máquinas. Esos lenguajes, llamados lenguajes de máquinas o lenguajes ensambladores, eran complicados de utilizar porque las únicas operaciones que existían eran las operaciones sencillas (por ejemplo, mover un valor de la memoria a un registro, extraer los contenidos de una dirección de memoria del acumulador). De igual manera, los tipos de datos de la máquina eran los únicos tipos disponibles, y estaban restringidos. Sin embargo, incluso antes de que apareciesen los lenguajes de alto nivel, se estaban desarrollando aplicaciones de IA complejas.

En 1956, uno de los padres fundadores de la IA, John McCarthy, creó un esquema de poda de árboles de búsqueda llamado la poda alfa beta. Este trabajo salió en un momento en el que muchos de los problemas de la IA se consideraban problemas de las búsquedas y mientras ocurría una considerable actividad de búsqueda. La memoria y la potencia de computación también estaban limitadas, pero esta técnica permitió que los investigadores implementasen problemas más complejos en los primeros sistemas informáticos con recursos limitados. La técnica de poda alfa beta se aplicó en juegos en las primeras aplicaciones de IA.

También en 1956, Arthur Samuel desarrolló un programa para jugar a las damas en una computadora IBM 701 utilizando la búsqueda alfa-beta de McCarthy. Sin embargo, el juego de Samuel incluyó un elemento ventajoso: En vez de jugar al programa de damas por sí mismo para enseñarle a jugar, Samuel presentó la idea del autoaprendizaje y permitió que el programa jugase consigo mismo. Samuel desarrolló su programa en el conjunto de instrucciones nativas del sistema IBM 701, lo que es un logro dada la complejidad de su aplicación y el bajo nivel de instrucciones que tenía a disposición.

Eras de la evolución del lenguaje de la IA

La historia de la IA está llena de líneas cronológicas, algunas de las cuales son muy detalladas. He reducido la historia reciente de la IA en tres segmentos basados en la evolución que ocurrió en los lenguajes. Esos segmentos son: los primeros años (1954-1973), momentos turbulentos (1974-1993), y la era moderna (de 1994 hasta el presente).

Cronograma gráfico que muestra el desarrollo de los principales idiomas de IA por fecha, de 1960 a 2010

Los primeros años (1954-1973)

Los primeros años fueron un momento de descubrimientos; la presentación de máquinas nuevas y de sus capacidades y el desarrollo del lenguaje de alto nivel que podrían utilizar la potencia de esas máquinas para una mayor gama de aplicaciones.

En 1958, se desarrolló un programa llamado NSS (por sus autores, Newell, Shaw y Simon) para jugar al ajedrez en la computadora IBM 704. Este programa veía el ajedrez en términos de búsqueda y fue desarrollado en Information Processing Language (IPL) por los autores de NSS. IPL fue el primer lenguaje que se desarrolló con el fin de crear aplicaciones de IA. IPL era un lenguaje de mayor nivel que el lenguaje de las máquinas, pero solo ligeramente. Sin embargo, permitía que los desarrolladores utilizasen en lenguaje los diferentes sistemas informáticos.

IPL presentó varias funciones que todavía se utilizan, como las listas, la recursividad, las funciones de orden superior, los símbolos e incluso los generadores que podrían correlacionar una lista de elementos con una función que podría iterar y procesar la lista. La primera versión de IPL nunca se implementó, pero las versiones siguientes (2 – 6) sí se implementaron y utilizaron en sistemas como el IBM 704, IBM 650 y el IBM 7090, entre otros. Algunas de las otras primeras aplicaciones de IA que se desarrollaron en IPL son Logic Theorist y General Problem Solver.

A pesar del éxito de IPL y de su amplia implementación en las arquitecturas de computación de ese momento, el IPL se reemplazó rápidamente por un lenguaje de incluso mayor nivel que todavía se utiliza casi 60 años más tarde: LISP. La sintaxis esotérica de IPL dio paso a un LISP más simple y escalable, pero la influencia de IPL se puede entrever en su contrapartida, particularmente en su enfoque en listas como una de las principales funciones del lenguaje.

LISP; -El procesador de LISt- fue creado por John McCarthy en 1958. El objetivo de McCarthy después del Dartmouth Summer Research Project de IA en 1956 era desarrollar un lenguaje para trabajos de IA que estuviese enfocado en la plataforma IBM 704. FORTRAN se presentó en 1957 en la misma plataforma, y el trabajo en IBM extendió FORTRAN para mostrar los procesos en un lenguaje llamado FORTRAN List Processing Language (FLPL). Este lenguaje se utilizó con éxito en el proyecto de geometría de aviones de IBM, pero, como extensión de FORTRAN, a FLPL le faltaban algunas de sus funciones principales.

LISP era un lenguaje de programación fundamental e implementó muchas de las principales ideas de la ciencia de la computación, como la recolección de elementos utilizados, los árboles, la escritura dinámica, la recursividad y otras funciones de mayor orden. LISP no solo representaba los datos como listas, sino que incluso definía el propio código de origen como listas. Esta función hizo que LISP pudiese manipular los datos además del propio código de LISP. LISP también es expandible, lo que permite que los programadores creen una sintaxis nueva o incluso lenguajes nuevos (llamados lenguajes específicos del dominio) para incorporarlos dentro de LISP.

El siguiente ejemplo ilustra una función de LISP para que calcule la factorial de un número. En el fragmento de código, observe el uso de la recursión para calcular la factorial (llamando a factorial dentro de la función factorial). Esta función se podía haber invocado con (factorial 9).

(defun factorial (n)
   (if (= n 0) 1
       (* n (factorial (- n 1)))))

En 1968, Terry Winograd desarrolló un programa vanguardista en LISP llamado SHRDLU que podía interactuar con un usuario en un idioma natural. El programa representaba un bloque mundial, y el usuario podría interactuar con ese mundo, dirigiendo el programa para consultar e interactuar con el mundo utilizando declaraciones como «levanta el bloque rojo» o «¿una pirámide puede estar apoyada en un bloque?» Esta demostración de la planificación y el entendimiento del idioma natural dentro de un simple mundo en bloques basados en la física proporcionaron un considerable optimismo para la IA y para el lenguaje LISP.

Momentos de turbulencia (1974-1993)

Los momentos de turbulencia representan un periodo de inestabilidad en el desarrollo y en la financiación de las aplicaciones de IA. Esta era comenzó con el primer invierno de la IA, cuando la financiación desapareció porque no se lograron los resultados esperados. En 1980, los sistemas de expertos reavivaron la emoción de la financiación de la IA (igual que los avances en las arquitecturas de conexionistas), pero en 1987, la burbuja de la IA volvió a explotar, a pesar de los avances realizados en ese tiempo, lo que dio lugar al segundo invierno de la IA.

Durante ese tiempo, el LISP se continuó utilizando en varias aplicaciones, aunque también proliferó creando varios dialectos. LISP vivió a través de Common LISP, Scheme, Clojure y Racket. Las ideas que estaban detrás de LISP continuaron desarrollándose a través de esos lenguajes y de otros de fuera del dominio funcional. LISP continúa alimentando al sistema de cálculo algebraico más antiguo, llamado Macsyma (Project MAC’s SYmbolic MAnipulator). Este entorno de computación algebraico fue desarrollado en el grupo de IA del Instituto Tecnológico de Massachusetts y es el abuelo de muchos programas, como Mathematica, Maple, y muchos otros.

En este período comenzaron a aparecer otros lenguajes que no estaban necesariamente centrados en la IA, pero que potenciaron su desarrollo. El lenguaje C fue diseñado como un lenguaje de sistemas para sistemas UNIX, pero rápidamente se expandió para ser uno de los lenguajes más populares (con sus variantes, como C++), desde sistemas hasta el desarrollo de dispositivos incorporados.

En ese momento en Francia se desarrolló uno de los principales lenguajes llamado Prolog (Programming in Logic). Este lenguaje implementó un subconjunto de la lógica llamado cláusulas Horn y permitió que la información se representase por hechos y por reglas, y permitiría ejecutar consultas a través de esas relaciones. El siguiente ejemplo sencillo de Prolog ilustra la definición de un hecho (Sócrates es un hombre) y una regla que define que, si alguien es un hombre, esa persona también es mortal:

man( socrates ).                    // Hecho: Sócrates es un hombre.
mortal( X ) :- man( X ).            // Regla: Todos los hombres son mortales.

Prolog sigue siendo utilizado en diferentes áreas y tiene muchas variantes que incorporan funciones como la orientación de objetivos, la habilidad de compilar en código nativo de máquina, e interfaces para lenguajes populares (como C).

Una de las principales aplicaciones de Prolog en este periodo de tiempo fue el desarrollo de sistemas expertos (también llamados sistemas de producción). Estos sistemas soportaron la codificación del conocimiento en hechos y, después, se utilizaban reglas para razonar con esa información. El problema con estos sistemas era que tendían a ser frágiles, y mantener el conocimiento dentro del sistema era algo engorroso y propenso a errores.

Un ejemplo de un sistema experto era eXpert CONfigurer (XCON), que se utilizaba para configurar sistemas de computación. XCON fue desarrollado en 1978 en OPS5 (un lenguaje de sistemas de producción escrito en LISP) que para las deducciones utilizaba encadenamiento progresivo. En 1980, XCON estaba formado por 2.500 reglas, pero su mantenimiento era demasiado caro.

Prolog y LISP no eran los únicos lenguajes que se utilizaban para desarrollar sistemas de producción. En 1985, se desarrolló C Language Integrated Production System (CLIPS) y es el sistema que más se utiliza para construir sistemas expertos. CLIPS opera en un sistema de conocimiento de reglas y de hechos, pero está escrito en C y brinda una interfaz para las extensiones de C por cuestiones de rendimiento.

El fallo de los sistemas expertos fue uno de los factores que dieron lugar al segundo invierno de la IA. Su promesa y la falta de entrega de resultados provocaron significativas reducciones en la financiación de la investigación de la IA. Sin embargo, desde ese invierno surgieron nuevos enfoques, como un renacer de los enfoques conexionistas, lo que nos ha llevado a la era moderna.

La era moderna (de 1994 hasta el presente)

La era moderna de la IA proporcionó al campo una perspectiva práctica y un éxito claro en la aplicación de métodos de IA para problemas del mundo real, lo que incluye algunos problemas de la historia previa de la IA. Los lenguajes de la IA también mostraron una tendencia interesante. Mientras se aplicaban lenguajes nuevos a los problemas de IA, los caballos de batalla de la IA (LISP y Prolog) continuaron encontrando aplicaciones y éxito. Esta era también vio el renacer del conexionismo y de enfoques nuevos para las redes neurales, como el aprendizaje profundo.

La explosión de dialectos de LISP provocó una unificación de LISP en un lenguaje nuevo llamado Common LISP, que tenía semejanzas con los dialectos populares de ese momento. En 1994, el Common LISP fue ratificado como el estándar Standard X3.226-1994 de American National Standards Institute.

En ese periodo de tiempo comenzaron a aparecer diferentes lenguajes de programación, algunos estaban basados en ideas nuevas de la ciencia de la computación, y otros se enfocaban en características clave (como el multiparadigma y en ser fáciles de aprender). Uno de los principales lenguajes que encajan en esta última categoría es Python. Python es un lenguaje interpretado con fines generalistas que incluye funciones de muchos lenguajes (como funciones orientadas objetos y funciones funcionales inspiradas por LISP). Lo que hace de Python un lenguaje útil para el desarrollo de aplicaciones inteligentes son los muchos módulos que están disponibles fuera del lenguaje. Esos módulos cubren el aprendizaje automático (scikit-learn, Numpy), el procesamiento de textos y de idiomas naturales (NLTK) y muchas librerías neurales que cubren una amplia gama de topologías.

El lenguaje R (y el entorno de software en el que se utiliza) sigue el modelo de Python. R es un entorno de código abierto para la programación estadística y la minería de datos que se ha desarrollado en el lenguaje C. Debido a que una considerable cantidad de aprendizaje automático moderno es estadístico por naturaleza, R es un lenguaje útil que ha ido aumentando de popularidad desde su versión estable de 2000. R incluye un gran conjunto de bibliotecas que cubren diferentes técnicas; también incluye la capacidad de extender el lenguaje con funciones nuevas.

El lenguaje C sigue siendo relevante. En 1996, IBM desarrolló el programa para jugar al ajedrez más rápido e inteligente del mundo, llamado Deep Blue. Deep Blue se ejecutaba en una computadora IBM RS/6000 de 32 nodos que ejecutaba el sistema operativo IBM AIX® y fue escrito en C. Deep Blue era capaz de evaluar 200 millones de posiciones por segundo. En 1997, Deep Blue se convirtió en la primera IA de ajedrez en derrotar a un gran maestro de ajedrez.

IBM volvió a dedicase a los juegos más tarde, pero esta vez menos estructurados que el ajedrez. El sistema de preguntas y respuestas IBM Watson® (llamado DeepQA) era capaz de responder a preguntas realizadas en idioma natural. La página de conocimientos de IBM Watson se rellenó con 200 millones de páginas de información, entre las cuales se incluyó todo el sitio web de Wikipedia. Para analizar las preguntas de una forma que IBM Watson pudiera entender, el equipo de IBM utilizó Prolog para transformar preguntas en idioma natural a hechos nuevos que se pudieran utilizar en el canal de IBM Watson. En 2011, el sistema compitió en el juego Jeopardy! y derrotó a los anteriores campeones del juego.

Con el retorno a las arquitecturas conexionistas, las aplicaciones nuevas parecen haber cambiado el panorama del procesamiento y del reconocimiento de imágenes y de servicios. El aprendizaje profundo (que extiende redes neurales en arquitecturas profundas y en capas) se utiliza para reconocer objetos en imágenes o en videos, brinda descripciones textuales en lenguaje natural de imágenes o de videos, e incluso prepara el camino para los vehículos de conducción autónoma a través de la detección de caminos y de objetos en tiempo real. Esas redes de aprendizaje profundo tienden a ser tan grandes que las arquitecturas de computación tradicionales no las pueden procesar de forma eficiente. Sin embargo, con la introducción de las unidades de procesamiento de gráficos (GPUs), esas redes ahora se pueden aplicar.

Para utilizar las GPU como aceleradores de redes neurales se necesitaron lenguajes nuevos para juntar las CPU tradicionales y las GPU. Un lenguaje de estándares abiertos llamado Open Computing Language (OpenCL) permite que programas de tipo C – o C++-se ejecuten en GPU (que están formadas por miles de elementos procesadores, más sencillas que las CPU). OpenCL permite el paralelismo de operaciones en GPUs que están orquestadas por CPUs.

Yendo más allá

En los últimos 60 años se han visto cambios significativos en las arquitecturas de computación junto con avances en las técnicas de IA y en sus aplicaciones. Esos años también han visto una evolución de los lenguajes, cada uno con sus propias funciones y enfoques para la resolución de problemas. Pero hoy, con la introducción del big data y de nuevas arquitecturas de procesamiento que incluyen CPU agrupadas con matrices de GPU, se han sentado las bases para un conjunto de innovaciones en la IA y en los lenguajes que las alimentan.

Aviso

El contenido aquí presentado fue traducido de la página IBM Developer US. Puede revisar el contenido original en este link.