{"id":89110,"date":"2020-07-18T19:42:10","date_gmt":"2020-07-18T17:42:10","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/obshhij-obzor-arhitektury-servisa-dlya-oczenki-vneshnosti-na-osnove-nejronnyh-setej"},"modified":"2020-07-18T19:42:10","modified_gmt":"2020-07-18T17:42:10","slug":"obshhij-obzor-arhitektury-servisa-dlya-oczenki-vneshnosti-na-osnove-nejronnyh-setej","status":"publish","type":"post","link":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/obshhij-obzor-arhitektury-servisa-dlya-oczenki-vneshnosti-na-osnove-nejronnyh-setej","title":{"rendered":"Revisi\u00f3n general de la arquitectura del servicio para evaluar la apariencia basada en redes neuronales.","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Revisi\u00f3n general de la arquitectura del servicio para evaluar la apariencia basada en redes neuronales.\" src=\"\/wp-content\/uploads\/2020\/07\/f624e995fbee3496f1f7890b98106df4.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h2>Introducci\u00f3n<\/h2>\n<p><\/p>\n<p>\u00a1Hola!<\/p>\n<p><\/p>\n<p>En este art\u00edculo, compartir\u00e9 mi experiencia en la construcci\u00f3n de una arquitectura de microservicios para un proyecto que utiliza redes neuronales.<\/p>\n<p><\/p>\n<p>Hablaremos sobre los requisitos para la arquitectura, veremos varios diagramas estructurales, examinaremos cada uno de los componentes de la arquitectura lista, y tambi\u00e9n evaluaremos las m\u00e9tricas t\u00e9cnicas de la soluci\u00f3n.<\/p>\n<p><\/p>\n<p>\u00a1Disfruta la lectura!<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Un par de palabras sobre la tarea y su soluci\u00f3n<\/h2>\n<p><\/p>\n<p>La idea principal es evaluar la atractividad de una persona en una escala de diez puntos basada en una foto.<\/p>\n<p><\/p>\n<p>En este art\u00edculo, nos alejaremos de la descripci\u00f3n tanto de las redes neuronales utilizadas como del proceso de preparaci\u00f3n de datos y entrenamiento. Sin embargo, en una de las siguientes publicaciones, definitivamente volveremos a analizar el pipeline de evaluaci\u00f3n a un nivel m\u00e1s profundo.<\/p>\n<p><\/p>\n<p>Ahora haremos un recorrido de alto nivel por el pipeline de evaluaci\u00f3n, haciendo hincapi\u00e9 en la interacci\u00f3n de los microservicios en el contexto de la arquitectura general del proyecto.\u00a0<\/p>\n<p><\/p>\n<p>Al trabajar en el pipeline de evaluaci\u00f3n de la atractividad, la tarea se descompuso en los siguientes componentes:<\/p>\n<p><\/p>\n<ol>\n<li>Detecci\u00f3n de rostros en la foto<\/li>\n<li>Evaluaci\u00f3n de cada uno de los rostros<\/li>\n<li>Renderizaci\u00f3n del resultado<\/li>\n<\/ol>\n<p><\/p>\n<p>El primero se resuelve con la ayuda de un modelo preentrenado de <noindex><a rel=\"nofollow\" href=\"https:\/\/arxiv.org\/abs\/1604.02878\">MTCNN<\/a><\/noindex>. Para el segundo, se entren\u00f3 una red neuronal convolucional en PyTorch, utilizando como backbone <noindex><a rel=\"nofollow\" href=\"https:\/\/arxiv.org\/abs\/1512.03385\">ResNet34<\/a><\/noindex> \u2013 en un equilibrio entre \"calidad \/ velocidad de inferencia en CPU\"<\/p>\n<p>\n<img decoding=\"async\" alt=\"Revisi\u00f3n general de la arquitectura del servicio para evaluar la apariencia basada en redes neuronales.\" src=\"\/wp-content\/uploads\/2020\/07\/181cc89a2cf5295bdcd4b838216f96d6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Diagrama funcional del pipeline de evaluaci\u00f3n<\/i><\/p>\n<p><\/p>\n<h2>An\u00e1lisis de los requisitos de la arquitectura del proyecto<\/h2>\n<p><\/p>\n<p>En el ciclo de vida <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Machine_learning\">ML<\/a><\/noindex> del proyecto, las etapas de trabajo en la arquitectura y la automatizaci\u00f3n del despliegue del modelo son a menudo las m\u00e1s costosas en tiempo y recursos.<\/p>\n<p>\n<img decoding=\"async\" alt=\"Revisi\u00f3n general de la arquitectura del servicio para evaluar la apariencia basada en redes neuronales.\" src=\"\/wp-content\/uploads\/2020\/07\/4949f217d31c863176122ed87b43a88c.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Ciclo de vida del proyecto de ML<\/i><\/p>\n<p><\/p>\n<p>Este proyecto no es una excepci\u00f3n: se tom\u00f3 la decisi\u00f3n de envolver el pipeline de evaluaci\u00f3n en un servicio en l\u00ednea, para lo cual fue necesario profundizar en la arquitectura. Se definieron los siguientes requisitos b\u00e1sicos:<\/p>\n<p><\/p>\n<ol>\n<li>Almacenamiento \u00fanico de logs: todos los servicios deben escribir los logs en un solo lugar y deben ser f\u00e1ciles de analizar.<\/li>\n<li>Posibilidad de escalado horizontal del servicio de evaluaci\u00f3n \u2014 como el Bottleneck m\u00e1s probable.<\/li>\n<li>A cada imagen se debe asignar la misma cantidad de recursos del procesador \u2014 para evitar desviaciones en la distribuci\u00f3n del tiempo de inferencia.<\/li>\n<li>Despliegue r\u00e1pido (re) de servicios espec\u00edficos y del stack en general.<\/li>\n<li>Posibilidad de utilizar objetos comunes en diferentes servicios, si es necesario.<\/li>\n<\/ol>\n<p><\/p>\n<h2>Arquitectura<\/h2>\n<p><\/p>\n<p>Despu\u00e9s de analizar los requisitos, qued\u00f3 claro que la arquitectura de microservicios se adapta pr\u00e1cticamente a la perfecci\u00f3n.<\/p>\n<p><\/p>\n<p>Para evitar dolores de cabeza innecesarios, se eligi\u00f3 el API de Telegram como frontend.<\/p>\n<p><\/p>\n<p>Para empezar, revisaremos el diagrama estructural de la arquitectura final, luego pasaremos a la descripci\u00f3n de cada uno de los componentes, y adem\u00e1s formalizaremos el proceso de manejo exitoso de im\u00e1genes.<\/p>\n<p>\n<img decoding=\"async\" alt=\"Revisi\u00f3n general de la arquitectura del servicio para evaluar la apariencia basada en redes neuronales.\" src=\"\/wp-content\/uploads\/2020\/07\/163ec019341e9d71a1e0854c6026bd01.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Diagrama estructural de la arquitectura final<\/i><\/p>\n<p><\/p>\n<p>Hablemos en detalle sobre cada uno de los componentes del diagrama, se\u00f1alando su Responsabilidad \u00danica en el proceso de evaluaci\u00f3n de la imagen.<\/p>\n<p><\/p>\n<h3>Microservicio \u00abattrai-telegram-bot\u00bb<\/h3>\n<p><\/p>\n<p>Este microservicio encapsula todas las interacciones con el API de Telegram. Se pueden destacar 2 escenarios principales: trabajar con la imagen del usuario y trabajar con el resultado de la evaluaci\u00f3n del pipeline. Analizaremos ambos escenarios en t\u00e9rminos generales.<\/p>\n<p><\/p>\n<p>Al recibir un mensaje del usuario con una imagen:<\/p>\n<p><\/p>\n<ol>\n<li>Se realiza un filtrado, que consiste en las siguientes comprobaciones:\n<ul>\n<li>La existencia de un tama\u00f1o \u00f3ptimo de imagen<\/li>\n<li>La cantidad de im\u00e1genes del usuario que ya est\u00e1n en la cola<\/li>\n<\/ul>\n<\/li>\n<li>Al pasar la filtraci\u00f3n inicial, la imagen se guarda en un volumen de Docker<\/li>\n<li>Se produce una tarea en la cola \u201cto_estimate\u201d, en la que, entre otras cosas, figura la ruta de la imagen que se encuentra en nuestro volumen<\/li>\n<li>Si las etapas anteriores se superan con \u00e9xito, el usuario recibir\u00e1 un mensaje con el tiempo aproximado de procesamiento de la imagen, que se calcula en funci\u00f3n de la cantidad de tareas en la cola. En caso de error, el usuario ser\u00e1 notificado expl\u00edcitamente enviando un mensaje con informaci\u00f3n sobre qu\u00e9 pudo haber salido mal. <\/li>\n<\/ol>\n<p><\/p>\n<p>Adem\u00e1s, este microservicio, como worker de Celery, escucha la cola \u201cafter_estimate\u201d, destinada a tareas que han pasado por el pipeline de evaluaci\u00f3n.<\/p>\n<p><\/p>\n<p>Al recibir una nueva tarea de \u201cafter_estimate\u201d:<\/p>\n<p><\/p>\n<ol>\n<li>Si la imagen ha sido procesada con \u00e9xito, enviamos el resultado al usuario, si no, notificamos sobre el error.<\/li>\n<li>Eliminamos la imagen que es el resultado del pipeline de evaluaci\u00f3n.<\/li>\n<\/ol>\n<p><\/p>\n<h3>Microservicio de evaluaci\u00f3n \u00abattrai-estimator\u00bb<\/h3>\n<p><\/p>\n<p>Este microservicio es un worker de Celery y encapsula todo lo relacionado con el pipeline de evaluaci\u00f3n de im\u00e1genes. Aqu\u00ed hay un solo algoritmo de funcionamiento \u2014 lo desglosaremos.<\/p>\n<p><\/p>\n<p>Al recibir una nueva tarea de \u201cto_estimate\u201d:<\/p>\n<p><\/p>\n<ol>\n<li>Ejecutamos la imagen a trav\u00e9s del pipeline de evaluaci\u00f3n:\n<ol>\n<li>Cargamos la imagen en memoria<\/li>\n<li>Ajustamos la imagen al tama\u00f1o deseado<\/li>\n<li>Detectamos todos los rostros (MTCNN)<\/li>\n<li>Evaluamos todos los rostros (embalamos los rostros encontrados en el paso anterior en un lote y hacemos inferencia con ResNet34)<\/li>\n<li>Renderizamos la imagen final\n<ol>\n<li>Dibujamos los bounding boxes<\/li>\n<li>Dibujamos las evaluaciones<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/li>\n<li>Eliminamos la imagen del usuario (original)<\/li>\n<li>Guardamos la salida del pipeline de evaluaci\u00f3n<\/li>\n<li>Colocamos la tarea en la cola 'after_estimate', que es escuchada por el microservicio 'attrai-telegram-bot' mencionado anteriormente<\/li>\n<\/ol>\n<p><\/p>\n<h3>Graylog (+ mongoDB + Elasticsearch)<\/h3>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.graylog.org\/\">Graylog<\/a><\/noindex> \u2014 es una soluci\u00f3n para la gesti\u00f3n centralizada de logs. En este proyecto, se utiliz\u00f3 para su prop\u00f3sito directo.<\/p>\n<p><\/p>\n<p>Se eligi\u00f3 espec\u00edficamente \u00e9l, y no el habitual <noindex><a rel=\"nofollow\" href=\"https:\/\/www.elastic.co\/what-is\/elk-stack\">ELK<\/a><\/noindex> stack, por la conveniencia de trabajar con \u00e9l desde Python. Todo lo que se necesita para registrar en Graylog es a\u00f1adir GELFTCPHandler del paquete <noindex><a rel=\"nofollow\" href=\"https:\/\/pypi.org\/project\/graypy\/\">graypy<\/a><\/noindex> a los dem\u00e1s manejadores de root logger de nuestro microservicio en Python.<\/p>\n<p><\/p>\n<p>Yo, como alguien que antes solo hab\u00eda trabajado con el stack ELK, en general, tuve una experiencia positiva al trabajar con Graylog. Lo \u00fanico desalentador es la superioridad de las caracter\u00edsticas de Kibana sobre la interfaz web de Graylog.<\/p>\n<p><\/p>\n<h3>RabbitMQ<\/h3>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.rabbitmq.com\/\">RabbitMQ<\/a><\/noindex> \u2014 es un corredor de mensajes basado en el protocolo AMQP.<\/p>\n<p><\/p>\n<p>En este proyecto, se utiliz\u00f3 como <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.celeryproject.org\/en\/latest\/getting-started\/brokers\/#broker-overview\">el corredor m\u00e1s estable y probado a lo largo del tiempo<\/a><\/noindex> para Celery y funcion\u00f3 en modo durable.<\/p>\n<p><\/p>\n<h3>Redis<\/h3>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/redis.io\/\">Redis<\/a><\/noindex> \u2014 es una base de datos NoSQL que trabaja con estructuras de datos tipo 'clave-valor'.<\/p>\n<p><\/p>\n<p>A veces surge la necesidad de usar objetos comunes en diferentes microservicios de Python que implementan alguna estructura de datos.<\/p>\n<p><\/p>\n<p>Por ejemplo, en Redis se almacena un hashmap del tipo 'telegram_user_id =&gt; cantidad de tareas activas en la cola', lo que permite limitar el n\u00famero de solicitudes de un usuario a un valor espec\u00edfico y, de esta manera, prevenir ataques de DoS.<\/p>\n<p><\/p>\n<h3>Formalizamos el proceso de procesamiento exitoso de im\u00e1genes<\/h3>\n<p><\/p>\n<ol>\n<li>El usuario env\u00eda una imagen al bot de Telegram<\/li>\n<li>'attrai-telegram-bot' recibe el mensaje de la API de Telegram y lo analiza<\/li>\n<li>La tarea con la imagen se a\u00f1ade a la cola as\u00edncrona 'to_estimate'<\/li>\n<li>El usuario recibe un mensaje con el tiempo estimado para la evaluaci\u00f3n<\/li>\n<li>'attrai-estimator' toma la tarea de la cola 'to_estimate', la pasa por el pipeline de evaluaci\u00f3n y produce la tarea en la cola 'after_estimate'<\/li>\n<li>'attrai-telegram-bot', que escucha la cola 'after_estimate', env\u00eda el resultado al usuario<\/li>\n<\/ol>\n<p><\/p>\n<h2>DevOps<\/h2>\n<p><\/p>\n<p>Finalmente, tras revisar la arquitectura, podemos pasar a una parte igualmente interesante: DevOps<\/p>\n<p><\/p>\n<h3>Docker Swarm<\/h3>\n<p><\/p>\n<p>\u00a0<\/p>\n<p>\n<img decoding=\"async\" alt=\"Revisi\u00f3n general de la arquitectura del servicio para evaluar la apariencia basada en redes neuronales.\" src=\"\/wp-content\/uploads\/2020\/07\/ba539d1c8197c7961d6e5e6a5c7e83c6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/swarm\/\">Docker Swarm <\/a><\/noindex>\u00a0\u2014 sistema de cl\u00fasteres, cuya funcionalidad est\u00e1 implementada dentro de Docker Engine y est\u00e1 disponible lista para usar.<\/p>\n<p><\/p>\n<p>Con la ayuda de un \"enjambre\", todas las nodos de nuestro cl\u00faster se pueden dividir en dos tipos: worker y manager. En las m\u00e1quinas del primer tipo se despliegan grupos de contenedores (stacks), mientras que las m\u00e1quinas del segundo tipo se encargan del escalado, balanceo y <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/swarm\/#feature-highlights\">otras caracter\u00edsticas interesantes<\/a><\/noindex>. Los managers por defecto tambi\u00e9n son workers.<\/p>\n<p>\n<img decoding=\"async\" alt=\"Revisi\u00f3n general de la arquitectura del servicio para evaluar la apariencia basada en redes neuronales.\" src=\"\/wp-content\/uploads\/2020\/07\/d195e2aab6d3552652102c2b5246abfc.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Cl\u00faster con un leader manager y tres workers<\/i><\/p>\n<p><\/p>\n<p>El tama\u00f1o m\u00ednimo posible del cl\u00faster es de 1 nodo, donde una \u00fanica m\u00e1quina actuar\u00e1 simult\u00e1neamente como leader manager y worker. Seg\u00fan el tama\u00f1o del proyecto y los requisitos m\u00ednimos de resiliencia, se tom\u00f3 la decisi\u00f3n de utilizar este enfoque.<\/p>\n<p><\/p>\n<p>Para anticipar, dir\u00e9 que desde la primera entrega en producci\u00f3n, que tuvo lugar a mediados de junio, no ha habido problemas relacionados con esta organizaci\u00f3n del cl\u00faster (pero eso no significa que tal organizaci\u00f3n sea aceptable en proyectos medianos a grandes que tienen requisitos de resiliencia).<\/p>\n<p><\/p>\n<h3>Docker Stack<\/h3>\n<p><\/p>\n<p>En modo \"enjambre\", el despliegue de stacks (conjuntos de servicios Docker) es responsabilidad de <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/stack\/\">docker stack<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Soporta configuraciones de docker-compose, permitiendo utilizar par\u00e1metros de despliegue adicionales.\u00a0\u00a0<\/p>\n<p><\/p>\n<p>Por ejemplo, con estos par\u00e1metros se limitaron los recursos asignados a cada una de las instancias del microservicio de evaluaci\u00f3n (asignamos N n\u00facleos a N instancias, y en el propio microservicio limitamos la cantidad de n\u00facleos utilizados por PyTorch a uno)<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">attrai_estimator:\n\u00a0\u00a0image: 'erqups\/attrai_estimator:1.2'\n\u00a0\u00a0deploy:\n\u00a0\u00a0\u00a0\u00a0replicas: 4\n\u00a0\u00a0\u00a0\u00a0resources:\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0limits:\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cpus: '4'\n\u00a0\u00a0\u00a0\u00a0restart_policy:\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0condition: on-failure\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u2026<\/code><\/pre>\n<p><\/p>\n<p>Es importante destacar que Redis, RabbitMQ y Graylog son servicios con estado y no se pueden escalar tan f\u00e1cilmente como \"attrai-estimator\".<\/p>\n<p><\/p>\n<h3>Anticipando la pregunta: \u00bfpor qu\u00e9 no Kubernetes?<\/h3>\n<p><\/p>\n<p>Parece que usar Kubernetes en proyectos peque\u00f1os y medianos es un exceso, toda la funcionalidad necesaria se puede obtener de Docker Swarm, que es bastante amigable para un orquestador de contenedores y tiene un bajo umbral de entrada.<\/p>\n<p><\/p>\n<h3>Infraestructura<\/h3>\n<p><\/p>\n<p>Todo esto se despleg\u00f3 en un VDS con las siguientes caracter\u00edsticas:<\/p>\n<p><\/p>\n<ul>\n<li>CPU: 4 n\u00facleos Intel\u00ae Xeon\u00ae Gold 5120 CPU @ 2.20GHz<\/li>\n<li>RAM: 8 GB<\/li>\n<li>SSD: 160 GB<\/li>\n<\/ul>\n<p><\/p>\n<p>Despu\u00e9s de pruebas de carga local, parec\u00eda que con un flujo serio de usuarios, esta m\u00e1quina ser\u00eda justo suficiente.<\/p>\n<p><\/p>\n<p>Pero, justo despu\u00e9s del despliegue, publiqu\u00e9 el enlace a uno de los foros de im\u00e1genes m\u00e1s populares en la CEI (s\u00ed, ese mismo), lo que despert\u00f3 el inter\u00e9s de la gente y en pocas horas el servicio proces\u00f3 con \u00e9xito decenas de miles de im\u00e1genes. En los momentos pico, los recursos de CPU y RAM ni siquiera se utilizaron a la mitad.<\/p>\n<p>\n<img decoding=\"async\" alt=\"Revisi\u00f3n general de la arquitectura del servicio para evaluar la apariencia basada en redes neuronales.\" src=\"\/wp-content\/uploads\/2020\/07\/458d74dae00d455fbce1ca6a197325d7.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<img decoding=\"async\" alt=\"Revisi\u00f3n general de la arquitectura del servicio para evaluar la apariencia basada en redes neuronales.\" src=\"\/wp-content\/uploads\/2020\/07\/e9383c47369c606d26e89a69f4d22b5a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h3>Un poco m\u00e1s de gr\u00e1ficos<\/h3>\n<p><\/p>\n<p>Cantidad de usuarios \u00fanicos y solicitudes de evaluaci\u00f3n, desde el momento del despliegue, dependiendo del d\u00eda<\/p>\n<p>\n<img decoding=\"async\" alt=\"Revisi\u00f3n general de la arquitectura del servicio para evaluar la apariencia basada en redes neuronales.\" src=\"\/wp-content\/uploads\/2020\/07\/7112c78c8400d2ac73562243b16a015b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Distribuci\u00f3n del tiempo de inferencia del pipeline de evaluaci\u00f3n<\/p>\n<p>\n<img decoding=\"async\" alt=\"Revisi\u00f3n general de la arquitectura del servicio para evaluar la apariencia basada en redes neuronales.\" src=\"\/wp-content\/uploads\/2020\/07\/4c892ce607c3ff3db466459729dd0876.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h2>Conclusiones<\/h2>\n<p><\/p>\n<p>En resumen, puedo decir que la arquitectura y el enfoque para la orquestaci\u00f3n de contenedores se han justificado completamente: incluso en los momentos pico no hubo ca\u00eddas ni demoras en el tiempo de procesamiento.\u00a0<\/p>\n<p><\/p>\n<p>Creo que los proyectos peque\u00f1os y medianos que utilizan inferencia en tiempo real de redes neuronales en CPU pueden adoptar con \u00e9xito las pr\u00e1cticas descritas en este art\u00edculo.<\/p>\n<p><\/p>\n<p>A\u00f1adir\u00e9 que originalmente el art\u00edculo era m\u00e1s extenso, pero para no publicar un texto largo decid\u00ed omitir algunos puntos en este art\u00edculo; regresaremos a ellos en pr\u00f3ximas publicaciones.<\/p>\n<p><\/p>\n<p>Puedes probar el bot en Telegram - @AttraiBot, funcionar\u00e1, al menos, hasta finales de oto\u00f1o de 2020. Recuerda que no se almacenan datos de los usuarios: ni las im\u00e1genes originales ni los resultados del pipeline de evaluaci\u00f3n, todo se borra despu\u00e9s del procesamiento.<\/p>\n<p>Fuente: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/511332\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435 \u041f\u0440\u0438\u0432\u0435\u0442! \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u0434\u0435\u043b\u044e\u0441\u044c \u043e\u043f\u044b\u0442\u043e\u043c \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0435\u0433\u043e \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0435 \u0441\u0435\u0442\u0438. \u041f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u0445 \u043a \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u044b\u0435 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u044b, \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0433\u043e\u0442\u043e\u0432\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0446\u0435\u043d\u0438\u043c \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u041f\u0440\u0438\u044f\u0442\u043d\u043e\u0433\u043e \u0447\u0442\u0435\u043d\u0438\u044f! \u041f\u0430\u0440\u0443 \u0441\u043b\u043e\u0432 \u043e \u0437\u0430\u0434\u0430\u0447\u0435 \u0438 \u0435\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0438\u0434\u0435\u044f \u2013 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0444\u043e\u0442\u043e \u0434\u0430\u0442\u044c \u043e\u0446\u0435\u043d\u043a\u0443 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":89111,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-89110","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\".\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/obshhij-obzor-arhitektury-servisa-dlya-oczenki-vneshnosti-na-osnove-nejronnyh-setej\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041e\u0431\u0449\u0438\u0439 \u043e\u0431\u0437\u043e\u0440 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0434\u043b\u044f \u043e\u0446\u0435\u043d\u043a\u0438 \u0432\u043d\u0435\u0448\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\".\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/obshhij-obzor-arhitektury-servisa-dlya-oczenki-vneshnosti-na-osnove-nejronnyh-setej\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-07-18T17:42:10+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-07-18T17:42:10+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Resumen general de la arquitectura del servicio para evaluar la apariencia basada en redes neuronales | ProHoster","description":".","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/obshhij-obzor-arhitektury-servisa-dlya-oczenki-vneshnosti-na-osnove-nejronnyh-setej","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041e\u0431\u0449\u0438\u0439 \u043e\u0431\u0437\u043e\u0440 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0434\u043b\u044f \u043e\u0446\u0435\u043d\u043a\u0438 \u0432\u043d\u0435\u0448\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439 | ProHoster","og:description":".","og:url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/obshhij-obzor-arhitektury-servisa-dlya-oczenki-vneshnosti-na-osnove-nejronnyh-setej","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-07-18T17:42:10+00:00","article:modified_time":"2020-07-18T17:42:10+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"89110","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 13:16:27","updated":"2022-09-29 06:10:39","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/89110","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=89110"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/89110\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/89111"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=89110"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=89110"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=89110"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}