{"id":28223,"date":"2022-03-24T21:08:14","date_gmt":"2022-03-24T21:08:14","guid":{"rendered":"http:\/\/using-machine-learning-to-classify-user-images"},"modified":"2025-03-30T14:11:20","modified_gmt":"2025-03-30T21:11:20","slug":"using-machine-learning-to-classify-user-images","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/","title":{"rendered":"Using Machine Learning to Classify User Images"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>There are plenty of times we see something we don\u2019t recognize out in the world. So, of course, we take a picture of it. Then we might show it to several people before Googling whatever we think it is in hopes of figuring out what we\u2019re looking at.<\/p>\n<p>In this tutorial, we\u2019re going to mix a bit of machine learning with front-end and back-end development using a pre-trained model for image classification. A user will be able to upload an image on the front-end and get an image classification prediction back.<\/p>\n<h2>Setting up the Django environment<\/h2>\n<p>Let\u2019s start by setting up a Django back-end. The reason I chose this over a JavaScript back-end is that Python has some great machine learning libraries. We\u2019re not going to dive deep into training models because that could be a post of its own, but you will see how a pre-trained model can be used quickly.<\/p>\n<p>First, create a folder called <code>image-classifier<\/code>. This will hold the client-side and server-side code and will be the root directory for the project.<\/p>\n<p>We\u2019re going to start by setting up the Django REST API we\u2019ll call to classify any uploaded images. To do that, we\u2019ll need to create a virtual environment to install and run all of the Python libraries we\u2019ll work with. So open your terminal and navigate to the <code>image-classifier<\/code> directory and run the following commands:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">$ python -m venv .venv\n$ source .venv\/bin\/activate\n<\/code><\/span><\/pre>\n<p>Now that we have an active virtual environment, we can move on to creating a <code>requirements.txt<\/code> file in the root directory. This is where we\u2019ll put all of the project dependencies before we install them. Open this new file and add the following dependency names:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">django\ndjangorestframework\ndjango-cors-headers\nkeras\nnumpy\ntensorflow\n<\/code><\/span><\/pre>\n<p>Then we can install all of these dependencies with the following command:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">$ pip install -r requirements.txt\n<\/code><\/span><\/pre>\n<p>With all of the dependencies installed, let\u2019s run some commands to get this API ready to go.<\/p>\n<h3>Getting the settings in place for Django Rest Framework<\/h3>\n<p>Since all of the server-side code will be stored in its own folder, we can start by running a command to create the Django app in a new sub-folder called <code>server<\/code>:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">$ django-admin startproject server\n<\/code><\/span><\/pre>\n<p>This command creates a new Django project. Next, we can create an app inside of this project called <code>classifier<\/code>. Navigate to the new <code>server<\/code> directory in a terminal and run the following command:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">$ python manage.py startapp classifier\n<\/code><\/span><\/pre>\n<p>This gives us a new sub-directory inside the <code>server<\/code> folder with a lot of new files to handle the views and models for the image classifier functionality we\u2019ll be creating. Since this is a new app in our Django project, we need to register it in the <code>settings.py<\/code> file. Go to the inner <code>server<\/code> folder and open this <code>settings.py<\/code> file and add two apps to the end of the list of <code>INSTALLED_APPS<\/code>:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">...\nINSTALLED_APPS = &#91;\n    <span class=\"hljs-string\">'django.contrib.admin'<\/span>,\n    <span class=\"hljs-string\">'django.contrib.auth'<\/span>,\n    <span class=\"hljs-string\">'django.contrib.contenttypes'<\/span>,\n    <span class=\"hljs-string\">'django.contrib.sessions'<\/span>,\n    <span class=\"hljs-string\">'django.contrib.messages'<\/span>,\n    <span class=\"hljs-string\">'django.contrib.staticfiles'<\/span>,\n    <span class=\"hljs-string\">'rest_framework'<\/span>,\n    <span class=\"hljs-string\">'corsheaders'<\/span>,\n    <span class=\"hljs-string\">'classifier'<\/span>\n]\n...\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>This lets Django know we\u2019re using the Django Rest Framework (DRF) and that we have a custom app to use as well. We also need to update a few other things in this <code>settings.py<\/code> file so we don\u2019t run into CORS errors when we connect the front-end. So find the <code>MIDDLEWARE<\/code> array and add the last line here:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">...\nMIDDLEWARE = &#91;\n    <span class=\"hljs-string\">'django.middleware.security.SecurityMiddleware'<\/span>,\n    <span class=\"hljs-string\">'django.contrib.sessions.middleware.SessionMiddleware'<\/span>,\n    <span class=\"hljs-string\">'django.middleware.common.CommonMiddleware'<\/span>,\n    <span class=\"hljs-string\">'django.middleware.csrf.CsrfViewMiddleware'<\/span>,\n    <span class=\"hljs-string\">'django.contrib.auth.middleware.AuthenticationMiddleware'<\/span>,\n    <span class=\"hljs-string\">'django.contrib.messages.middleware.MessageMiddleware'<\/span>,\n    <span class=\"hljs-string\">'django.middleware.clickjacking.XFrameOptionsMiddleware'<\/span>,\n    <span class=\"hljs-string\">'corsheaders.middleware.CorsMiddleware'<\/span>,\n]\n...\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Then at the very bottom of the <code>settings.py<\/code> file, add this new array to allow the front-end access to the API we\u2019ll build:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">...\nCORS_ALLOWED_ORIGINS = &#91;\n    <span class=\"hljs-string\">'http:\/\/localhost:3000'<\/span>,\n]\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Now that we have all of the settings in place, we can apply a migration to initialize a SQLite database and create the superuser for the project. You can find the details for the database in the <code>settings.py<\/code> file we just modified in the <code>DATABASES<\/code> object.<\/p>\n<p>To do the migrate and create the superuser, go to the <code>server<\/code> directory in the <code>image-classifier<\/code> directory in a terminal and run the following commands:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">$ python manage.py migrate\n$ python manage.py createsuperuser\n<\/code><\/span><\/pre>\n<p>The migrate command will generate some SQLite files in your <code>server<\/code> directory. The superuser command will prompt you for a username, email address, and password. You can skip the email address and bypass the password validation if you\u2019re developing locally, but you should definitely have those set if you plan on deploying to a different environment later.<\/p>\n<p>This is a good point to stop and make sure that the Django project will run. So in your terminal, navigate to <code>image-classifier\/server<\/code> and run the following command:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">$ python manage.py runserver 8001\n<\/code><\/span><\/pre>\n<p>This will start up the project on port 8001 and you should see this default success page.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/mediadevs\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1646882210\/e-603fc55d218a650069f5228b\/ygvwbdx7lowxzhanyxd2.png\" alt=\"default success Django page\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1141\"\/><\/p>\n<p>Now that we have confirmation that the project works, let\u2019s start building the API.<\/p>\n<h3>Making the classifier data model<\/h3>\n<p>Let\u2019s start by making a model for the classifier to describe the data we\u2019re expecting. Open the <code>classifier\/models.py<\/code> file and add the following code to define the model for our classifier:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">from django.db import models\n\nclass Classifier(models.Model):\n    image_url = models.CharField(max_length=1000)\n    classification = models.CharField(max_length=50)\n<\/code><\/span><\/pre>\n<p>This model lets us include an image URL which we\u2019ll get as soon as the user uploads an image to Cloudinary through the front-end widget and it will have the predicted classification of the image.<\/p>\n<p>One of the best things about Django is the admin panel because it lets us see all of the things we\u2019ve defined in the project. To ensure that we can access this model from the admin panel, we need to register this model with Django in the <code>classifier\/admin.py<\/code> file. So open that file and add the following code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">from<\/span> django.contrib <span class=\"hljs-keyword\">import<\/span> admin\n<span class=\"hljs-keyword\">from<\/span> .models <span class=\"hljs-keyword\">import<\/span> Classifier\n\nadmin.site.register(Classifier)\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Now that this new model has been registered, we need to make a migration for this change to be reflected in the database. So we\u2019ll run a couple of commands to do this:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">$ python3 manage.py makemigrations\n$ python3 manage.py migrate\n<\/code><\/span><\/pre>\n<p>This will create a new migration file and then actually perform the migration. That means the table schema has been updated to include a <code>Classifier<\/code> table along with two columns we defined in the model.<\/p>\n<p>With a newly defined and migrated model, we can start working with the best part of DRF, serializers.<\/p>\n<h3>Adding the serializer<\/h3>\n<p>Serializers are responsible for converting Python models to JSON and taking JSON and converting it to Python models. This might sound trivial, but that can be pretty challenging with DRF when you start handling more complex requests and responses.<\/p>\n<p>We\u2019ll need to write a custom serializer for the classifier model. Inside the <code>classifier<\/code> folder, add a new file named <code>serializers.py<\/code> and write the following code in it:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">from rest_framework import serializers\nfrom .models import Classifier\n\nclass ClassifierSerializer(serializers.ModelSerializer):\n    image_url = serializers.CharField(max_length=1000)\n    classification = serializers.CharField(max_length=50)\n    \n    class Meta:\n        model = Classifier\n        fields = ('__all__')\n<\/code><\/span><\/pre>\n<p>This takes our model and serializes it in a way that can be consumed in the API. Now that we have the data concerns wrapped up, let\u2019s turn our attention to the API.<\/p>\n<h3>Writing the API<\/h3>\n<p>Let\u2019s open the <code>classifier\/views.py<\/code> file and create a class with a POST method to handle user image uploads:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">from rest_framework.views import APIView\nfrom rest_framework.response import Response\nfrom rest_framework import status\nfrom .serializers import ClassifierSerializer\n\nclass ClassifierViews(APIView):\n    def post(self, request):\n        serializer = ClassifierSerializer(data=request.data)\n        \n        if serializer.is_valid():\n        \n            # Machine learning model goes here to get the real classification label\n            \n            serializer.classification = 'puddle'\n            serializer.save()\n\n            return Response({'status': 'success', 'data': serializer.data}, status=status.HTTP_200_OK)\n        else:\n            return Response({'status': 'error', 'data': serializer.errors}, status.HTTP_BAD_REQUEST)\n<\/code><\/span><\/pre>\n<p>This is the base of what we\u2019ll add our machine learning model to. Let\u2019s walk through this code first. In the <code>post<\/code> method, we create a serializer object from the <code>request.data<\/code> that\u2019s passed from the front-end. Since the user is only uploading the image, we\u2019ll have to use our machine learning model to get the classification value to make our serializer valid. For now, we have the <code>puddle<\/code> placeholder for this.<\/p>\n<p>Next, we check if the serializer is valid and if it is, we go ahead and save this classified image and its label to the database. Once the record is saved, we return the data in a response to the front-end along with the correct status code and message. If there\u2019s something wrong with the serializer, we return an error to the front-end.<\/p>\n<p>The next step is adding an endpoint to use this <code>post<\/code> method. To do this, we need to add a new line to the <code>urlpatterns<\/code> array in the <code>server\/server\/urls.py<\/code> file. So open that file and add the last line to that <code>urlpatterns<\/code> array:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">from<\/span> django.contrib <span class=\"hljs-keyword\">import<\/span> admin\n<span class=\"hljs-keyword\">from<\/span> django.urls <span class=\"hljs-keyword\">import<\/span> path, include\n\nurlpatterns = &#91;\n    path(<span class=\"hljs-string\">'admin\/'<\/span>, admin.site.urls),\n    path(<span class=\"hljs-string\">'api\/'<\/span>, include(<span class=\"hljs-string\">'classifier.urls'<\/span>))\n]\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>With this endpoint in place, we just have a few more things to add to the <code>classifier<\/code> app. In the <code>classifier<\/code> directory, make a new file called <code>urls.py<\/code> and add this code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">from<\/span> django.urls <span class=\"hljs-keyword\">import<\/span> path\n<span class=\"hljs-keyword\">from<\/span> .views <span class=\"hljs-keyword\">import<\/span> ClassifierViews\n\nurlpatterns = &#91;\n    path(<span class=\"hljs-string\">'classifier\/'<\/span>, ClassifierViews.as_view())\n]\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The <code>path<\/code> method takes a couple of arguments to define the sub-path where this view should be accessible and it takes the class name we make in the <code>views.py<\/code> file to process requests users send.<\/p>\n<p>Alright! Now we can run the app with the following command and test out the API:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">$ python manage.py runserver 8001\n<\/code><\/span><\/pre>\n<p>Then navigate to the <code>api\/classifier<\/code> route in the browser and you should see a page like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/mediadevs\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1646885394\/e-603fc55d218a650069f5228b\/vcxhpkmfb9sfugwogyq3.png\" alt=\"classifier API page\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1152\"\/><\/p>\n<p>Don\u2019t worry about it saying the GET method isn\u2019t allowed. That just means we don\u2019t have an implementation for that at the moment. Try adding a classifier record by writing the following JSON in the <code>Content<\/code> field just to test out the API:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JSON \/ JSON with Comments\" data-shcb-language-slug=\"json\"><span><code class=\"hljs language-json shcb-wrap-lines\">{\n    <span class=\"hljs-attr\">\"image_url\"<\/span>: <span class=\"hljs-string\">\"https:\/\/test.com\/cat.jpg\"<\/span>,\n    <span class=\"hljs-attr\">\"classification\"<\/span>: <span class=\"hljs-string\">\"bowl\"<\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JSON \/ JSON with Comments<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">json<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>When you submit this post request, you should see a success message on the page like this.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/mediadevs\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1646885621\/e-603fc55d218a650069f5228b\/atklgdcx8nvpdhr1narp.png\" alt=\"successfully saved an image and its classification to the database\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1147\"\/><\/p>\n<p>We have this endpoint working so now we just have to add the machine learning model to classify the images we upload.<\/p>\n<h3>Adding the image classifier prediction model<\/h3>\n<p>Open up the <code>views.py<\/code> file in the <code>classifier<\/code> folder. We\u2019re going to replace that comment about the machine learning model now. First, we need to import a few more libraries. So add the following lines to your import statement list:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">...\nfrom keras.applications.vgg16 <span class=\"hljs-keyword\">import<\/span> VGG16, preprocess_input,decode_predictions\n<span class=\"hljs-keyword\">from<\/span> keras.preprocessing <span class=\"hljs-keyword\">import<\/span> image\n<span class=\"hljs-keyword\">import<\/span> numpy <span class=\"hljs-keyword\">as<\/span> np\n<span class=\"hljs-keyword\">import<\/span> wget\n<span class=\"hljs-keyword\">import<\/span> os\n...\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Now that we have all of the libraries we need, it\u2019s time to finally implement the classifier model. Using a pre-trained model is the easiest way to make the image classifier so we don\u2019t have to do machine learning engineering for this. We\u2019re going to do a big update to the code inside the if-statement in our file. So update your code with the following:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">if<\/span> serializer.is_valid():\n    model = VGG16(weights=<span class=\"hljs-string\">'imagenet'<\/span>)\n    \n    <span class=\"hljs-comment\"># Need to download the image file for the classifier to work<\/span>\n    image_filename = wget.download(serializer.validated_data&#91;<span class=\"hljs-string\">'image_url'<\/span>])\n    \n    <span class=\"hljs-comment\">#image loaded in PIL (Python Imaging Library)<\/span>\n    img = image.load_img(image_filename,color_mode=<span class=\"hljs-string\">'rgb'<\/span>, target_size=(<span class=\"hljs-number\">224<\/span>, <span class=\"hljs-number\">224<\/span>))\n    \n    <span class=\"hljs-comment\"># Converts a PIL Image to 3D Numy Array<\/span>\n    x = image.img_to_array(img)\n    \n    <span class=\"hljs-comment\"># Adding the fouth dimension, for number of images<\/span>\n    x = np.expand_dims(x, axis=<span class=\"hljs-number\">0<\/span>)\n    \n    x = preprocess_input(x)\n    \n    features = model.predict(x)\n    \n    predictions = decode_predictions(features)&#91;<span class=\"hljs-number\">0<\/span>]\n    predictions.sort(key = lambda x: x&#91;<span class=\"hljs-number\">2<\/span>])\n    \n    predicted_classification = predictions&#91;<span class=\"hljs-number\">-1<\/span>]&#91;<span class=\"hljs-number\">1<\/span>]\n    \n    serializer.validated_data&#91;<span class=\"hljs-string\">'classification'<\/span>] = predicted_classification\n    \n    serializer.save()\n    \n    <span class=\"hljs-comment\"># Delete the image file so we don't crowd the project directory<\/span>\n    os.remove(image_filename)\n    \n    <span class=\"hljs-keyword\">return<\/span> Response({<span class=\"hljs-string\">'status'<\/span>: <span class=\"hljs-string\">'success'<\/span>, <span class=\"hljs-string\">'data'<\/span>: serializer.data}, status=status.HTTP_200_OK)\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Let\u2019s walk through this code. First, we make our model by using the <code>VGG16<\/code> pre-trained model from the Keras library. Next, we need to download the image from the URL that users submit. This is so the model can access the raw binary data of the image. Then we do some data transformations to the image to get it into the correct format for the image to process.<\/p>\n<p>After that, we get the <code>features<\/code> from the image that the model will use to make its predictions. Then we get the top 5 potential classification labels for the image. The raw data will look something like this:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JSON \/ JSON with Comments\" data-shcb-language-slug=\"json\"><span><code class=\"hljs language-json shcb-wrap-lines\">&#91;&#91;('n02123597', 'Siamese_cat', <span class=\"hljs-number\">0.4564548<\/span>), ('n02124075', 'Egyptian_cat', <span class=\"hljs-number\">0.29191914<\/span>), ('n02123045', 'tabby', <span class=\"hljs-number\">0.045494787<\/span>), ('n02123159', 'tiger_cat', <span class=\"hljs-number\">0.018867875<\/span>), ('n02127052', 'lynx', <span class=\"hljs-number\">0.01380215<\/span>)]]\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JSON \/ JSON with Comments<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">json<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>That\u2019s why we get the array with the tuples and sort them so that we can parse out the most likely classification for the uploaded image. Next, we update the serializer data with that label and save the image and classification to the database. Lastly, we delete the downloaded image from the project and return the image and label to the front-end in the response.<\/p>\n<p>The hardest part is done now! Getting the back-end set up and making sure the image classifier works was the most tedious part. Now we can move to the front-end and create a quick image uploader in React using the Cloudinary widget.<\/p>\n<h2>Adding the React front-end<\/h2>\n<p>Go to the root <code>image-classifier<\/code> directory and run the following command to make the React project:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">$ npx create-react-app client\n<\/code><\/span><\/pre>\n<p>This will create a new sub-directory called <code>client<\/code> that will have all of the files we need to build this front-end. There are a few packages we need to install to use the Cloudinary upload widget. Navigate to the <code>client<\/code> folder in your terminal and run the following command:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">$ yarn add react-cloudinary-upload-widget axios\n<\/code><\/span><\/pre>\n<p>Now we can go to the <code>App.js<\/code> file and delete everything to start fresh. First, we\u2019ll add these imports and the component we\u2019ll export:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> { WidgetLoader, Widget } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react-cloudinary-upload-widget'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> axios <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'axios'<\/span>;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">App<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\n}\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Inside of the <code>App<\/code> component, we\u2019ll need a few states and a helper function. So go ahead and add these inside of the component:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">App<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n  <span class=\"hljs-keyword\">const<\/span> &#91;classification, setClassification] = useState(<span class=\"hljs-string\">''<\/span>)\n  <span class=\"hljs-keyword\">const<\/span> &#91;imageUrl, setImageUrl] = useState()\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getImageLabel<\/span>(<span class=\"hljs-params\">results<\/span>) <\/span>{\n    setImageUrl(results.info.url)\n\n    <span class=\"hljs-keyword\">const<\/span> data = {\n      <span class=\"hljs-attr\">image_url<\/span>: results.info.url,\n      <span class=\"hljs-attr\">classification<\/span>: <span class=\"hljs-string\">'placeholder'<\/span>,\n    }\n\n    axios.post(<span class=\"hljs-string\">'http:\/\/127.0.0.1:8001\/api\/classifier\/'<\/span>, data)\n    .then(<span class=\"hljs-function\"><span class=\"hljs-params\">response<\/span> =&gt;<\/span> {\n      setClassification(response.data.data.classification)\n    })\n  }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>First, we set a couple of states so that we can display these values to the user as they upload images and we return predictions. Next, we make the <code>getImageLabel<\/code> function which will take the results from the Cloudinary upload to get the image URL, put the required data in the right format, and then it makes the POST request to the back-end and returns the classification label.<\/p>\n<p>There are only a couple of things left for us to do now. Let\u2019s add the uploader widget to the component.<\/p>\n<h3>Uploading the image<\/h3>\n<p>You\u2019ll need a Cloudinary account to use this widget and you can sign up for one for free <a href=\"https:\/\/cloudinary.com\/users\/register\/free\">here<\/a>. Make sure you note what your <code>cloudName<\/code> and <code>uploadPreset<\/code> values are. You\u2019ll need them to upload the images and get the URL to send to the back-end. Below the <code>getImageLabel<\/code> function, let\u2019s add a return statement with the following code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">return<\/span> (\n    &lt;div style={{ margin: <span class=\"hljs-string\">'24px'<\/span> }}&gt;\n      &lt;WidgetLoader \/&gt;\n      &lt;Widget\n        sources={&#91;<span class=\"hljs-string\">'local'<\/span>, <span class=\"hljs-string\">'camera'<\/span>]}\n        cloudName={<span class=\"hljs-string\">'your_cloud_name'<\/span>}\n        uploadPreset={<span class=\"hljs-string\">'your_upload_preset'<\/span>}\n        buttonText={<span class=\"hljs-string\">'Upload Image'<\/span>}\n        style={{\n          color: <span class=\"hljs-string\">'white'<\/span>,\n          border: <span class=\"hljs-string\">'none'<\/span>,\n          width: <span class=\"hljs-string\">'120px'<\/span>,\n          backgroundColor: <span class=\"hljs-string\">'green'<\/span>,\n          borderRadius: <span class=\"hljs-string\">'4px'<\/span>,\n          height: <span class=\"hljs-string\">'25px'<\/span>,\n        }}\n        folder={<span class=\"hljs-string\">'images_to_classify'<\/span>}\n        onSuccess={getImageLabel}\n      \/&gt;\n    &lt;\/div&gt;\n)\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Navigate to the <code>client<\/code> directory in your terminal and start the app up with <code>yarn start<\/code>. You should just see a button like the one below on your page. Clicking this will bring up the whole widget where you can choose the image, whether or not to crop it, and a number of other options.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/mediadevs\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1646937276\/e-603fc55d218a650069f5228b\/yfbbwq3k6i1n9nbfsnaz.png\" alt=\"upload button\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1308\" height=\"818\"\/><\/p>\n<p>The last thing we need to do is display the image and its label once the classification is returned from the back-end.<\/p>\n<h3>Displaying the classification<\/h3>\n<p>In the return statement, just below the <code>Widget<\/code> element, add this conditional render:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">{\n    classification !== <span class=\"hljs-string\">''<\/span> &amp;&amp;\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span>&gt;<\/span>{classification}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{imageUrl}<\/span> <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">{250}<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">{250}<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">'uploaded by user'<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/&gt;<\/span><\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>We\u2019ll only display the image and classification label when there is a classification set in the state. Go ahead and upload an image and you should see the image and returned classification like below!<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/mediadevs\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1646937199\/e-603fc55d218a650069f5228b\/s8rz2uou1jzywvziwqy0.png\" alt=\"uploaded image with classification\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1706\" height=\"1168\"\/><\/p>\n<h2>Finished code<\/h2>\n<p>You can find the complete code in <a href=\"https:\/\/github.com\/flippedcoder\/media-projects\/tree\/main\/image-classifier\">this repo<\/a>. You can also check out the app in <a href=\"https:\/\/codesandbox.io\/s\/vigilant-paper-wuhood\">this Code Sandbox<\/a>.<\/p>\n<p>&lt;CodeSandBox\ntitle=\u201cvigilant-paper-wuhood\u201d\nid=\u201cvigilant-paper-wuhood\u201d\n\/&gt;<\/p>\n<h2>Conclusion<\/h2>\n<p>Machine learning gets mixed in with web development like this pretty often. Usually, there\u2019s a team of ML engineers working hard to create an accurate and fast model and we get the fun part of adding it to our existing code. Hopefully, this helped shed some light on why teams choose back-end languages other than JavaScript. Sometimes they just have the functionality you need.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28224,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,370,246,371],"class_list":["post-28223","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-image","tag-react","tag-under-review"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Using Machine Learning to Classify User Images<\/title>\n<meta name=\"description\" content=\"There are plenty of times we see something we don&#039;t recognize out in the world. So, of course, we take a picture of it. Then we might show it to several people before Googling whatever we think it is in hopes of figuring out what we&#039;re looking at.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using Machine Learning to Classify User Images\" \/>\n<meta property=\"og:description\" content=\"There are plenty of times we see something we don&#039;t recognize out in the world. So, of course, we take a picture of it. Then we might show it to several people before Googling whatever we think it is in hopes of figuring out what we&#039;re looking at.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-03-24T21:08:14+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-03-30T21:11:20+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925084\/Web_Assets\/blog\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f.jpg?_i=AA\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Using Machine Learning to Classify User Images\",\"datePublished\":\"2022-03-24T21:08:14+00:00\",\"dateModified\":\"2025-03-30T21:11:20+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/\"},\"wordCount\":7,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925084\/Web_Assets\/blog\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f.jpg?_i=AA\",\"keywords\":[\"Guest Post\",\"Image\",\"React\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/\",\"name\":\"Using Machine Learning to Classify User Images\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925084\/Web_Assets\/blog\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f.jpg?_i=AA\",\"datePublished\":\"2022-03-24T21:08:14+00:00\",\"dateModified\":\"2025-03-30T21:11:20+00:00\",\"description\":\"There are plenty of times we see something we don't recognize out in the world. So, of course, we take a picture of it. Then we might show it to several people before Googling whatever we think it is in hopes of figuring out what we're looking at.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925084\/Web_Assets\/blog\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925084\/Web_Assets\/blog\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f.jpg?_i=AA\",\"width\":3024,\"height\":4032},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using Machine Learning to Classify User Images\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Using Machine Learning to Classify User Images","description":"There are plenty of times we see something we don't recognize out in the world. So, of course, we take a picture of it. Then we might show it to several people before Googling whatever we think it is in hopes of figuring out what we're looking at.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/","og_locale":"en_US","og_type":"article","og_title":"Using Machine Learning to Classify User Images","og_description":"There are plenty of times we see something we don't recognize out in the world. So, of course, we take a picture of it. Then we might show it to several people before Googling whatever we think it is in hopes of figuring out what we're looking at.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-03-24T21:08:14+00:00","article_modified_time":"2025-03-30T21:11:20+00:00","twitter_card":"summary_large_image","twitter_image":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925084\/Web_Assets\/blog\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f.jpg?_i=AA","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/"},"author":{"name":"","@id":""},"headline":"Using Machine Learning to Classify User Images","datePublished":"2022-03-24T21:08:14+00:00","dateModified":"2025-03-30T21:11:20+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/"},"wordCount":7,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925084\/Web_Assets\/blog\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f.jpg?_i=AA","keywords":["Guest Post","Image","React","Under Review"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/","name":"Using Machine Learning to Classify User Images","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925084\/Web_Assets\/blog\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f.jpg?_i=AA","datePublished":"2022-03-24T21:08:14+00:00","dateModified":"2025-03-30T21:11:20+00:00","description":"There are plenty of times we see something we don't recognize out in the world. So, of course, we take a picture of it. Then we might show it to several people before Googling whatever we think it is in hopes of figuring out what we're looking at.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925084\/Web_Assets\/blog\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925084\/Web_Assets\/blog\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f.jpg?_i=AA","width":3024,"height":4032},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/using-machine-learning-to-classify-user-images\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Using Machine Learning to Classify User Images"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681925084\/Web_Assets\/blog\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f\/a02705a520bd83e0a45035584277df5dc53b97bd-3024x4032-1_28224a870f.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28223","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=28223"}],"version-history":[{"count":1,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28223\/revisions"}],"predecessor-version":[{"id":37332,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28223\/revisions\/37332"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28224"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28223"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28223"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28223"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}