IBM Watson y su inteligencia artificial
IBM Watson, ¿que es?
Según wikipedia:
Watson es un sistema informático de inteligencia artificial que es capaz de responder a preguntas formuladas en lenguaje natural. Esta desarrollado por la corporación estadounidense IBM y forma parte del proyecto del equipo de investigación DeepQA, liderado por el investigador principal David Ferruci. Lleva su nombre en honor del fundador y primer presidente de IBM, Thomas J. Watson.
Efectivamente, más inteligencia artificial, y ademas es una de las 7 grandes empresas que junto a Google(Alphabet), Apple, Sentient Technologies, Facebook, Microsoft y Amazon luchan por tener la más rápida y potente inteligencia artificial del mundo.
Gracias a la lucha de estas empresas, hoy tenemos acceso publico y gratuito (casi gratuito) a casi toda su potencia y/o casi todos sus servicios.
Muy bonito, ¿Por donde comienzo?
Para acceder a los servicios que ofrece IBM haremos clic aquí y nos registramos para tener acceso a nuestro panel de control.
Una vez finalizado el proceso de registro accederemos a nuestro dashboard y desde allí iniciaremos nuestro producto/servicio de IBM Cloud
La siguiente pantalla sera nuestro panel de control y es donde gestionamos todos los servicios, recursos, etc…, que ofrece IBM. La primera vez que entras no se mostrara ningún recurso ya que acabamos de iniciar y todavía no hemos creado nada.
Para continuar necesitamos Crear un recurso, así que vamos a pulsar sobre Crear recurso
En la siguiente pantalla podemos ver que IBM tiene todo tipo de servicios, pero nosotros vamos a centrarnos en la parte de inteligencia artificial: Watson
Cuando seleccionemos Watson se mostraran los diferentes servicios que IBM tiene relacionado con la inteligencia artificial, pero para este ejemplo vamos a elegir el servicio de reconocimiento visual ( visual recognition )
En la siguiente pantalla aparecerá toda la información sobre el servicio, limitaciones, versiones beta, etc…
Pulsando en el botón Crear finalizaremos el proceso.
Para entrar en profundidad y conocer todos los detalles sobre cualquier servicio, IBM ofrece una guía y la documentación API de como usar cada servicio, dentro del propio servicio.
Ahora con nuestro servicio y el api_key creado solo queda empezar a escribir un poco de código.
Probando el servicio de forma simple (solo local)
¿¡¡Pero!!?, ¿porque solo local?. Pues la respuesta es muy sencilla, el primer ejemplo es tan simple que no requiere de programación, solo es necesario realizar una llamada al API desde un formulario en HTML, y salvo que quieras que tu api_key la conozca todo el mundo, no te recomiendo esta opción.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Imagen 0</title> </head> <body> <form method="POST" enctype="multipart/form-data" action="https://gateway-a.watsonplatform.net/visual-recognition/api/v3/classify?api_key={api_key}&version=2018-03-19"> <label>Imagen</label> <input type="file" name="imagen"> <input type="submit" value="Clasificar imagen"> </form> <form method="POST" enctype="multipart/form-data" action="https://gateway-a.watsonplatform.net/visual-recognition/api/v3/detect_faces?api_key={api_key}&version=2018-03-19"> <label>Imagen</label> <input type="file" name="imagen"> <input type="submit" value="Faces"> </form> </body> </html>
{api_key} -> cambiar por vuestra api_key.
Y con esto ya tenemos un sistema de clasificación de objetos y reconocimiento facial dentro de una imagen, CHAS!!!!.
Para este ejemplo he puesto un vídeo para comprobar como funciona el servicio y el respuesta que nos devuelve, porque como decía antes, las api keys están en el propio código.
Ahora si!!, usando Node para realizar la consulta
Para probar el API de reconocimiento visual de IBM he creado una página que comprueba el fichero a subir.
Cuando abrimos la página desde un ordenador se abre el explorador de ficheros para seleccionar una imagen, pero si se usa el móvil nos permite usar también la cámara del móvil.
Si todo es correcto nos mostrara en la página la imagen que vamos a enviar para su clasificación.
Cuando pulsamos sobre el botón clasificar fotografía se realizara una petición ajax a un servidor creado en Node que sera el encargado de subir el fichero y enviarlo al API de reconocimiento visual de IBM.
Si todo el proceso es correcto tendríamos una respuesta en JSON con toda la información que ha podido extraer y clasificar el servicio de reconocimiento visual de IBM.
Finalmente desde la página web tramitaremos esa respuesta y mostrar los resultados.
Aunque voy a poner todo el código en la web siempre me gusta dejar un repositorio de todo lo que hago, así que desde aquí accedes al repositorio y en este enlace puedes probar la aplicación.
A continuación todo el código del proyecto:
[Página estática que se carga desde Node]
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>CLASIFICADOR WATSON</title> <!--<link href="style.css" rel="stylesheet">--> <link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet"> <style> body { font-family: 'Montserrat', sans-serif; } #resultado div { width: 100%; float: left; } .clasificacion b { text-transform: capitalize; } .clasificacion ul { list-style: none; padding: 0; } .loader { border: 10px solid #f3f3f3; border-radius: 50%; border-top: 10px solid #3498db; width: 60px; height: 60px; -webkit-animation: spin 2s linear infinite; animation: spin 2s linear infinite; position: absolute; left: calc(50% - 30px); top: calc(50% - 30px); display: none; } @-webkit-keyframes spin { 0% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); } } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } input { width: 100%; max-width: 300px; box-shadow: 1px 0px 10px rgba(0, 0, 0, 0.3); margin: 5px; } </style> </head> <body> <main> <form> <input type="file" name="photo" accept="image/*"><br> <input type="submit" value="Clasificar fotografía" disabled><br> </form> <div id="resultado"> <div class="imagen"><img></div> <div class="clasificacion"></div> </div> <div class="loader"></div> </main> <script> var WATSON = WATSON || {}; WATSON = { showLoading: function(status) { document.querySelector(".loader").style.display = status ? "block" : "none"; }, ajax: function(url, evt) { return new Promise(function(resolve, reject) { var request = new XMLHttpRequest(); request.open('POST', url, true); request.onreadystatechange = function(aEvt) { if (request.readyState == 4) { var html = ""; if (request.status == 200) { var responseJSON = JSON.parse(request.responseText); html += "<h3>Imagenes procesadas: " + responseJSON.images_processed + "</h3>"; var clasi = responseJSON.images[0]["classifiers"][0]["classes"]; clasi.sort(function(a, b) { return b.score - a.score; }); for (var propiedad in clasi) { if (clasi.hasOwnProperty(propiedad)) { html += "<ul>"; typeof clasi[propiedad].class !== "undefined" ? html += "<li><b>" + clasi[propiedad].class + "</b></li>" : html += ""; typeof clasi[propiedad].score !== "undefined" ? html += "<li><progress value='" + (clasi[propiedad].score * 100) + "' max='100'></progress> <b>" + clasi[propiedad].score + "</b></li>" : html += ""; //typeof clasi[propiedad].type_hierarchy !== "undefined" ? html += "<b>" + clasi[propiedad].type_hierarchy + "</b><br>" : html += "<br>"; html += "</ul>"; } } resolve(html); } else { html += "Error loading page"; reject(html); } } }; request.send(new FormData(evt.target)); }); } }; window.onload = function() { var form = document.querySelector('form'); var submit = document.querySelector("input[type='file']"); form.addEventListener('submit', function(e) { e.preventDefault(); WATSON.showLoading(true); WATSON.ajax('https://tecnops.es:17202/uploadImage', e).then(function(success) { WATSON.showLoading(false); document.querySelector(".clasificacion").innerHTML = success; }).catch(function(err) { WATSON.showLoading(false); document.querySelector(".clasificacion").innerHTML = err; }); }); submit.addEventListener("change", function(evt) { var files = evt.target.files; for (var data in files) { if (files.hasOwnProperty(data) && files[data].type.match("image.*")) { var reader = new FileReader(); reader.onload = (function(theFile) { return function(e) { var img = document.querySelector("img"); img.src = e.target.result; img.title = escape(theFile.name); img.classList.add("show"); document.querySelector("input[type='submit']").removeAttribute("disabled"); }; })(files[data]); reader.readAsDataURL(files[data]); } } }, false); }; </script> </body> </html>
Para que funcione el API de IBM de reconocimiento visual en el servidor de Node necesitaremos instalar la librería de acceso a los servicios de IBM Watson.
Como este ejemplo esta creado en Node usaremos NPM: npm install –save watson-developer-cloud
No obstante toda la documentación de uso viene especificada en cada servicio y con pequeños ejemplos de uso. Desde aquí puedes acceder a todo el API de reconocimiento visual.
[Servidor Node que carga la página estática y realiza la llamada a el servicio de IBM]
// Dependencias para usar IBM Watson var VisualRecognitionV3 = require('watson-developer-cloud/visual-recognition/v3'); // Crear servidor en Node var http = require('http'); // Obtener rutas var ruta = require("path"); // Modulo de parseo de los datos de un formulario, incluyendo la subida de ficheros (multipart/form-data). var formidable = require('formidable'); // Sistema de ficheros var fs = require('fs'); // Puerto para el servidor var port = process.env.PORT || 17202; // Creamos el servidor http.createServer(function(req, res) { if (req.url == "/") { fs.readFile('index.html', function(error, contenido_archivo) { if (error) { res.writeHead(500, 'text/plain'); res.end('Error interno.'); } else { res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(contenido_archivo); } }); } else if (req.url == "/uploadImage") { // Creamos un nuevo formulario de entrada var form = new formidable.IncomingForm(); // Analiza una solicitud entrante de node.js que contiene datos de formulario (Enviando archivos y campos) form.parse(req, function(err, fields, files) { // Error if (err) throw err; // API DE IBM Watson // 1 - Se autentica en la API de reconocimiento visual al proporcionar la clave API para la instancia de servicio que desea utilizar. var visualRecognition = new VisualRecognitionV3({ version: '2018-03-19', iam_apikey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' }); // La función fs.createReadStream () le permite abrir una secuencia legible de una manera muy simple. Todo lo que tiene que hacer es pasar la ruta del archivo para comenzar a transmitir var images_file = fs.createReadStream(files.photo.path); // La puntuación mínima que una clase debe tener para mostrarse en la respuesta 0.0 => ignora la clasificación y devuelve todo var threshold = 0.0; // Parametros (documentacion muy bien explicada) var params = { images_file: images_file, threshold: threshold, accept_language: "es" }; // Comienza la clasificación visualRecognition.classify(params, function(err, response) { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(response)); }); }); } else { var codigo_html = ''; res.writeHead(200, 'text/html'); res.end(codigo_html); } }).listen(port); console.log(`Servidor funcionando en el puerto ${port}`);
Con esta pequeña introducción y la gran documentación que ofrece IBM espero que te animes a probar todo lo que IBM pone a nuestra disposición.
ACTUALIZACIÓN [07/03/2019]
Gracias al comentario de Antonio indicando que tenia problemas para ejecutar el proyecto, he realizado algunos cambios en el código ya que IBM Watson ha cambiado la clave api_key por iam_apikey.
Para comprobar que es correcta la solución, ademas de un vídeo con el proyecto en funcionamiento también he actualizado el repositorio de github con los cambios, he añadido el package.json con las dependencias necesarias y he modificado el código de los gist de este artículo con los últimos cambios.
hola, estoy intentando crear el ejemplo con la pagina html y me da un error, a continuacion lo he creado con python y tambien me da error, aqui en python lo que he hecho es ejecutar
git clone https://github.com/kimagure44/watson-reconocimiento-visual.git
a continuación, he abierto el archivo «nodeWatsonClasificador.js» y he modificado la linea «versión» y «api_key» con los valores que me da las credenciales de ibm watson, por cierto he probado a ponerlo con comilla simple, comilla doble, sin comilla, y nada no funciona ninguna opción, me da el error «error loading page»
por favor, me podrias ayudar, ya que llevo unos días con el tema y por mas que lo intento no lo consigo ¿?
gracias y un saludo
Buenas, he probado el proyecto y cuando lo he ido ha poner en marcha me he dado cuenta que faltaban las dependencias necesarias para Node en otras cosas.
A continuación te detallo algunas cosas que han cambiado y que he actualizado en el repositorio:
1 – He incluido el package.json con las dependencias
2 – En la nueva documentación de IBM watson, antes se usaba la clave ‘api_key’ para enviar el api key a IBM Watson, pero ahora ese valor a cambiado y se usa ‘iam_apikey’.
Lo he probado con una api key y funciona, no obstante te pongo un vídeo para que veas el resultado y los cambios que he realizado.
Muchas gracias por tu comentarios, ya que me ayudan a mantener actualizado la documentación y los repositorios.