{"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\/en\/blog\/administrirovanie\/obshhij-obzor-arhitektury-servisa-dlya-oczenki-vneshnosti-na-osnove-nejronnyh-setej","title":{"rendered":"General overview of the service architecture for evaluating appearance based on neural networks","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"General overview of the service architecture for evaluating appearance based on neural networks\" src=\"\/wp-content\/uploads\/2020\/07\/f624e995fbee3496f1f7890b98106df4.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h2>Introduction<\/h2>\n<p><\/p>\n<p>Hello!<\/p>\n<p><\/p>\n<p>In this article, I will share my experience in building a microservices architecture for a project that uses neural networks.<\/p>\n<p><\/p>\n<p>We will discuss the architecture requirements, take a look at various structural diagrams, break down each component of the completed architecture, and evaluate the technical metrics of the solution.<\/p>\n<p><\/p>\n<p>Happy reading!<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>A few words about the task and its solution<\/h2>\n<p><\/p>\n<p>The main idea is to assess a person's attractiveness based on a photo using a ten-point scale.<\/p>\n<p><\/p>\n<p>In this article, we will depart from discussing the neural networks used and the process of data preparation and training. However, in one of the upcoming publications, we will certainly return to a deeper analysis of the evaluation pipeline.<\/p>\n<p><\/p>\n<p>For now, we will outline the evaluation pipeline at a high level, focusing on the interaction of microservices within the overall architecture of the project.\u00a0<\/p>\n<p><\/p>\n<p>In working on the attractiveness evaluation pipeline, the task was decomposed into the following components:<\/p>\n<p><\/p>\n<ol>\n<li>Face detection in photos<\/li>\n<li>Evaluation of each detected face<\/li>\n<li>Rendering the result<\/li>\n<\/ol>\n<p><\/p>\n<p>The first is handled by a pre-trained <noindex><a rel=\"nofollow\" href=\"https:\/\/arxiv.org\/abs\/1604.02878\">MTCNN<\/a><\/noindex>. For the second task, a convolutional neural network was trained on PyTorch, with <noindex><a rel=\"nofollow\" href=\"https:\/\/arxiv.org\/abs\/1512.03385\">ResNet34<\/a><\/noindex> being used as the backbone to balance 'quality \/ inference speed on CPU.'<\/p>\n<p>\n<img decoding=\"async\" alt=\"General overview of the service architecture for evaluating appearance based on neural networks\" src=\"\/wp-content\/uploads\/2020\/07\/181cc89a2cf5295bdcd4b838216f96d6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Functional diagram of the evaluation pipeline<\/i><\/p>\n<p><\/p>\n<h2>Analysis of the architecture requirements for the project<\/h2>\n<p><\/p>\n<p>In the lifecycle <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Machine_learning\">ML<\/a><\/noindex> of a project, the stages of working on the architecture and automating the deployment of the model are often among the most time-consuming and resource-intensive.<\/p>\n<p>\n<img decoding=\"async\" alt=\"General overview of the service architecture for evaluating appearance based on neural networks\" src=\"\/wp-content\/uploads\/2020\/07\/4949f217d31c863176122ed87b43a88c.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>ML project lifecycle<\/i><\/p>\n<p><\/p>\n<p>This project is no exception\u2014we decided to wrap the evaluation pipeline in an online service, which required delving into the architecture. The following basic requirements were outlined:<\/p>\n<p><\/p>\n<ol>\n<li>A unified log storage\u2014 all services must write logs to a single location, which should be easy to analyze.<\/li>\n<li>The ability to horizontally scale the evaluation service\u2014as the most likely bottleneck<\/li>\n<li>Each image evaluation should allocate the same amount of CPU resources\u2014to avoid spikes in inference time distribution.<\/li>\n<li>Fast (re)deployment of both specific services and the stack as a whole.<\/li>\n<li>The ability to use shared objects in different services if necessary.<\/li>\n<\/ol>\n<p><\/p>\n<h2>Architecture<\/h2>\n<p><\/p>\n<p>After analyzing the requirements, it became clear that microservice architecture fits almost perfectly.<\/p>\n<p><\/p>\n<p>To avoid unnecessary headaches, Telegram API was chosen as the frontend.<\/p>\n<p><\/p>\n<p>First, let's look at the structural diagram of the completed architecture, then we'll move on to describing each component and formalizing the process of successful image processing.<\/p>\n<p>\n<img decoding=\"async\" alt=\"General overview of the service architecture for evaluating appearance based on neural networks\" src=\"\/wp-content\/uploads\/2020\/07\/163ec019341e9d71a1e0854c6026bd01.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Structural diagram of the completed architecture<\/i><\/p>\n<p><\/p>\n<p>Let's talk in more detail about each component of the diagram, clarifying their Single Responsibility in the image evaluation process.<\/p>\n<p><\/p>\n<h3>Microservice 'attrai-telegram-bot'<\/h3>\n<p><\/p>\n<p>This microservice encapsulates all interactions with the Telegram API. There are two main scenarios to highlight \u2013 working with the user\u2019s image and handling the results of the evaluation pipeline. We'll discuss both scenarios in general.<\/p>\n<p><\/p>\n<p>Upon receiving a user message with an image:<\/p>\n<p><\/p>\n<ol>\n<li>Filtering is performed, consisting of the following checks:\n<ul>\n<li>The optimal size of the image<\/li>\n<li>The number of user images already in the queue<\/li>\n<\/ul>\n<\/li>\n<li>If the primary filtering is passed, the image is saved in a docker volume<\/li>\n<li>A task is produced to the 'to_estimate' queue, which includes the path to the image stored in our volume<\/li>\n<li>If the above steps are successfully completed, the user will receive a message with an estimated processing time for the image, calculated based on the number of tasks in the queue. In case of an error, the user will be explicitly notified by a message with information on what might have gone wrong. <\/li>\n<\/ol>\n<p><\/p>\n<p>Additionally, this microservice, as a celery worker, listens to the 'after_estimate' queue, which is intended for tasks that have passed through the evaluation pipeline.<\/p>\n<p><\/p>\n<p>Upon receiving a new task from 'after_estimate':<\/p>\n<p><\/p>\n<ol>\n<li>If the image was processed successfully, we send the result to the user; if not, we notify them of the error.<\/li>\n<li>We delete the image that is the result of the evaluation pipeline.<\/li>\n<\/ol>\n<p><\/p>\n<h3>Evaluation microservice 'attrai-estimator'<\/h3>\n<p><\/p>\n<p>This microservice is a celery worker and encapsulates everything related to the image evaluation pipeline. The workflow here is straightforward \u2013 let's break it down.<\/p>\n<p><\/p>\n<p>Upon receiving a new task from 'to_estimate':<\/p>\n<p><\/p>\n<ol>\n<li>We run the image through the evaluation pipeline:\n<ol>\n<li>We load the image into memory.<\/li>\n<li>Resizing the image to the required dimensions<\/li>\n<li>Detecting all faces (MTCNN)<\/li>\n<li>Evaluating all faces (wrapping the faces found in the previous step into a batch and inferring with ResNet34)<\/li>\n<li>Rendering the final image\n<ol>\n<li>Drawing bounding boxes<\/li>\n<li>Drawing evaluations<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/li>\n<li>Removing the user (original) image<\/li>\n<li>Saving the output from the evaluation pipeline<\/li>\n<li>Placing the task in the queue 'after_estimate', which is listened to by the previously discussed microservice 'attrai-telegram-bot'<\/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 is a solution for centralized log management. In this project, it was used for its intended purpose.<\/p>\n<p><\/p>\n<p>The choice was made specifically for it, rather than the familiar <noindex><a rel=\"nofollow\" href=\"https:\/\/www.elastic.co\/what-is\/elk-stack\">ELK<\/a><\/noindex> stack, due to the convenience of working with it from Python. Everything needed for logging in Graylog is to add GELFTCPHandler from the <noindex><a rel=\"nofollow\" href=\"https:\/\/pypi.org\/project\/graypy\/\">graypy<\/a><\/noindex> package to the other root logger handlers of our Python microservice.<\/p>\n<p><\/p>\n<p>As someone who previously worked only with the ELK stack, I generally had a positive experience while working with Graylog. The only downside is the superiority of Kibana's features over Graylog's web interface.<\/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 is a message broker based on the AMQP protocol.<\/p>\n<p><\/p>\n<p>In this project, it was used as <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.celeryproject.org\/en\/latest\/getting-started\/brokers\/#broker-overview\">the most stable and time-tested<\/a><\/noindex> broker for Celery and operated in durable mode.<\/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 is a NoSQL DBMS working with data structures of the 'key-value' type.<\/p>\n<p><\/p>\n<p>Sometimes there is a need to use common objects across different Python microservices that implement certain data structures.<\/p>\n<p><\/p>\n<p>For example, Redis stores a hashmap of 'telegram_user_id =&gt; number of active tasks in the queue', which allows limiting the number of requests from a single user to a specific value and thus prevent DoS attacks.<\/p>\n<p><\/p>\n<h3>Formalizing the process of successfully processing the image<\/h3>\n<p><\/p>\n<ol>\n<li>The user sends an image to the Telegram bot<\/li>\n<li>\u2018attrai-telegram-bot\u2019 receives the message from the Telegram API and parses it<\/li>\n<li>The task with the image is added to the asynchronous queue \u2018to_estimate\u2019<\/li>\n<li>The user receives a message with the expected evaluation time<\/li>\n<li>\u2018attrai-estimator\u2019 takes the task from the \u2018to_estimate\u2019 queue, processes it through the evaluation pipeline, and produces a task in the \u2018after_estimate\u2019 queue<\/li>\n<li>\u2018attrai-telegram-bot\u2019, listening to the \u2018after_estimate\u2019 queue, sends the result to the user<\/li>\n<\/ol>\n<p><\/p>\n<h2>DevOps<\/h2>\n<p><\/p>\n<p>Finally, after reviewing the architecture, we can move on to the no less interesting part \u2014 DevOps<\/p>\n<p><\/p>\n<h3>the development process and in the production environment? Or use the same file for<\/h3>\n<p><\/p>\n<p>\u00a0<\/p>\n<p>\n<img decoding=\"async\" alt=\"General overview of the service architecture for evaluating appearance based on neural networks\" 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\/\">the development process and in the production environment? Or use the same file for <\/a><\/noindex>\u00a0\u2014 a clustering system whose functionality is implemented within Docker Engine and available out of the box.<\/p>\n<p><\/p>\n<p>With the help of the 'swarm', all nodes of our cluster can be divided into two types \u2013 worker and manager. Containers (stacks) are deployed on machines of the first type, while machines of the second type are responsible for scaling, balancing, and <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/swarm\/#feature-highlights\">other cool features.<\/a><\/noindex>By default, managers also act as workers.<\/p>\n<p>\n<img decoding=\"async\" alt=\"General overview of the service architecture for evaluating appearance based on neural networks\" src=\"\/wp-content\/uploads\/2020\/07\/d195e2aab6d3552652102c2b5246abfc.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>A cluster with one leader manager and three workers.<\/i><\/p>\n<p><\/p>\n<p>The minimal possible size of a cluster is one node; a single machine will act as both a leader manager and a worker. Based on the project size and minimal requirements for fault tolerance, this approach was chosen.<\/p>\n<p><\/p>\n<p>To get ahead of the story, I will say that since the first production delivery, which was in mid-June, there have been no issues related to this clustering organization (but that doesn't mean that such organization is acceptable for any medium-sized projects, which have fault tolerance requirements).<\/p>\n<p><\/p>\n<h3>Docker Stack<\/h3>\n<p><\/p>\n<p>In 'swarm' mode, the deployment of stacks (sets of Docker services) is handled by <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/stack\/\">docker stack.<\/a><\/noindex><\/p>\n<p><\/p>\n<p>It supports docker-compose configs, allowing additional use of deploy parameters.\u00a0\u00a0<\/p>\n<p><\/p>\n<p>For example, with the help of these parameters, resources were limited for each instance of the evaluation microservice (allocating N cores for N instances, and in the microservice itself limiting the number of cores used by PyTorch to one).<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">attrai_estimator:\n  image: 'erqups\/attrai_estimator:1.2'\n  deploy:\n    replicas: 4\n    resources:\n      limits:\n        cpus: '4'\n    restart_policy:\n      condition: on-failure\n      \u2026<\/code><\/pre>\n<p><\/p>\n<p>It is important to note that Redis, RabbitMQ, and Graylog are stateful services and scaling them as easily as 'attrai-estimator' is not possible.<\/p>\n<p><\/p>\n<h3>Anticipating the question \u2014 why not Kubernetes?<\/h3>\n<p><\/p>\n<p>It seems that using Kubernetes for small and medium-sized projects is overkill; all necessary functionality can be obtained from Docker Swarm, which is quite user-friendly for container orchestration and has a low entry barrier.<\/p>\n<p><\/p>\n<h3>Infrastructure<\/h3>\n<p><\/p>\n<p>This was deployed on a VDS with the following specifications:<\/p>\n<p><\/p>\n<ul>\n<li>CPU: 4 Intel\u00ae Xeon\u00ae Gold 5120 CPU cores @ 2.20GHz<\/li>\n<li>RAM: 8 GB<\/li>\n<li>SSD: 160 GB<\/li>\n<\/ul>\n<p><\/p>\n<p>After local stress testing, it seemed that this machine would be just barely enough under a significant influx of users.<\/p>\n<p><\/p>\n<p>However, right after the deployment, I posted a link to one of the most popular imageboards in the CIS (yes, that one), which sparked interest, and within a few hours, the service successfully processed tens of thousands of images. At peak moments, CPU and RAM resources were not even half utilized.<\/p>\n<p>\n<img decoding=\"async\" alt=\"General overview of the service architecture for evaluating appearance based on neural networks\" src=\"\/wp-content\/uploads\/2020\/07\/458d74dae00d455fbce1ca6a197325d7.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<img decoding=\"async\" alt=\"General overview of the service architecture for evaluating appearance based on neural networks\" src=\"\/wp-content\/uploads\/2020\/07\/e9383c47369c606d26e89a69f4d22b5a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h3>A bit more graphics<\/h3>\n<p><\/p>\n<p>The number of unique users and requests for evaluation since the deployment, depending on the day<\/p>\n<p>\n<img decoding=\"async\" alt=\"General overview of the service architecture for evaluating appearance based on neural networks\" src=\"\/wp-content\/uploads\/2020\/07\/7112c78c8400d2ac73562243b16a015b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Distribution of the inference time of the evaluation pipeline<\/p>\n<p>\n<img decoding=\"async\" alt=\"General overview of the service architecture for evaluating appearance based on neural networks\" src=\"\/wp-content\/uploads\/2020\/07\/4c892ce607c3ff3db466459729dd0876.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h2>Conclusions<\/h2>\n<p><\/p>\n<p>In summary, I can say that the architecture and approach to container orchestration have fully justified themselves \u2014 even at peak moments, there were no crashes or slowdowns in processing time.\u00a0<\/p>\n<p><\/p>\n<p>I believe that small and medium-sized projects that utilize real-time inference of neural networks on CPUs can successfully adopt the practices described in this article.<\/p>\n<p><\/p>\n<p>I should add that the article was originally longer, but to avoid posting a long read, I decided to omit certain points \u2014 we will return to them in future publications.<\/p>\n<p><\/p>\n<p>You can poke at the bot on Telegram \u2014 @AttraiBot, it will work, at least until the end of autumn 2020. I remind you \u2014 no user data is stored \u2014 neither the original images nor the results of the evaluation pipeline \u2014 everything is deleted after processing.<\/p>\n<p>Source: <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\/en\/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=\"en_US\" \/>\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\/en\/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\udd47 Overview of the architecture of the service for appearance evaluation based on neural networks | ProHoster","description":".","canonical_url":"https:\/\/prohoster.info\/en\/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":"en_US","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\/en\/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\/en\/wp-json\/wp\/v2\/posts\/89110","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/comments?post=89110"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/89110\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media\/89111"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media?parent=89110"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/categories?post=89110"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/tags?post=89110"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}