Django Rest 프레임워크를 사용하여 이미지 분류 API를 구성합니다.

개요:


머신러닝(ML)과 데이터 과학 응용에 대한 수요량이 매우 크다.ML 알고리즘이 이미 알고 있는 정보를 제공하기 전에 업무에 대한 장점이 현저하다.추리에 사용되는 머신러닝 알고리즘을 생산 시스템에 통합하는 것은 기술적 장애이기 때문에 ML모델을 API로 배치해야 한다.

소개하다.


이 단문에서 우리는 네 가지 심도 있는 학습 알고리즘인 VG16, ResNet50, Inception V3와 Exception을 사용하여 인공지능을 바탕으로 하는 모델로 흉부 X광선과 CT 스캐닝에서의 코로나를 검출했다.모델의 생성이 아니라api의 실현에 주목할 것입니다.
내 live 끝점을 테스트하려면 POST 요청을 다음 URL로 보내고 요청 본문에 x선 이미지를 추가하십시오.요청이 성공하면 다음 예제 출력이 제공됩니다.
https://alienx.tech/api/v1/xray # for the x-ray images
https://alienx.tech/api/v1/ct # for CT scans
{
    "status": "success",
    "data": {
        "asset_id": "3e978ba830fb266978af20f2bf816f5e",
        "public_id": "vacpxfywfohgfprwhrso",
        "version": 1637699139,
        "version_id": "c9017c7d3b28ce797edefec0b0d72796",
        "signature": "e9c632b832e773cbbcb8906f93aba1d9e859d4bf",
        "width": 1205,
        "height": 1395,
        "format": "png",
        "resource_type": "image",
        "created_at": "2021-11-23T20:25:39Z",
        "tags": [],
        "bytes": 1325222,
        "type": "upload",
        "etag": "86005d3c34202b10949db5569570cd16",
        "placeholder": false,
        "url": "http://res.cloudinary.com/prometheusapi/image/upload/v1637699139/vacpxfywfohgfprwhrso.png",
        "secure_url": "https://res.cloudinary.com/prometheusapi/image/upload/v1637699139/vacpxfywfohgfprwhrso.png",
        "original_filename": "covid-19-pneumonia-22",
        "api_key": "138196782467569"
    },
    "url": "http://res.cloudinary.com/prometheusapi/image/upload/v1637699139/vacpxfywfohgfprwhrso.png",
    "xception_chest_pred": "100.00% COVID",
    "inception_chest_pred": "100.00% COVID",
    "vgg_chest_pred": "100.00% COVID",
    "resnet_chest_pred": "100.00% COVID"
}

ML 모델 구성


이 프로젝트의 데이터 세트는
  • 흉부 엑스레이 이미지(1000장 이미지) 출처: https://github.com/ieee8023/covid-chestxray-dataset
  • CT 스캔 이미지(이미지 750장): https://github.com/UCSD-AI4H/COVID-CT/tree/master/Data-split
  • 흉부 엑스레이와 CT 스캐닝에서 각각 VGG16, ResNet50, InceptionV3, Exception 네 가지 알고리즘을 훈련해 총 8개의 심도 있는 학습 모델을 제공했다.80%의 이미지는 훈련 모델에 사용되고 나머지 20%는 모델의 정확성을 측정하는 데 사용된다.
    저의githubrepository에서 이 8개 모델을 교육하는 코드를 제공했습니다.이 프로젝트의 모델은 아래 구글drive에서 찾을 수 있습니다.

    모델을 RESTFUL API로 변환


    파이썬의 최선의 실천에 따라 프로젝트를 위한 가상 환경을 만들고 필요한 패키지를 설치할 것입니다.
    먼저 프로젝트 디렉토리를 만듭니다.
    $ mkdir djangoapp
    $ cd djangoapp
    
    
    이제 가상 환경을 만들고 필요한 패키지를 설치합니다.
    macOS 및 Unix 시스템의 경우:
    $ python3 -m venv myenv
    $ source myenv/bin/activate
    (myenv) $ pip install django requests djangorestframework tensorflow cloudinary opencv-python
    
    
    Windows의 경우:
    $ python3 -m venv myenv
    $ myenv\Scripts\activate
    (myenv) $ pip install django requests djangorestframework tensorflow cloudinary opencv-python
    

    Django 응용 프로그램 설정


    우선, 우리가 만든 디렉터리djangoapp로 이동하여 Django 프로젝트를 만듭니다.
    (myenv) $ django-admin startproject mainapp
    
    
    이렇게 하면 프로젝트 프레임에 대한 파일이 자동으로 생성됩니다.
    mainapp/
        manage.py
        mainapp/
            __init__.py
            settings.py
            urls.py
            asgi.py
            wsgi.py
    
    현재, 새로 만든 디렉터리 (관리자.py와 같은 디렉터리에 있는지 확인하기) 로 이동하여 프로그램 디렉터리를 만듭니다.
    (myenv) $ python manage.py startapp monitor
    
    이렇게 하면 다음이 작성됩니다.
    monitor/
        __init__.py
        admin.py
        apps.py
        migrations/
            __init__.py
        models.py
        tests.py
        views.py
    
    주 프로그램/설정에 있습니다.py 파일, 다음 줄을 찾아서 우리가 방금 만든 프로그램을 추가합니다.
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'rest_framework',#new line
        'monitor', #new line
    ]
    
    
    모니터 디렉터리에 있는 다음templates라는 새 디렉터리와 URL이라는 새 파일을 만듭니다.피야.모니터 프로그램의 디렉터리 구조는 다음과 같아야 한다
    monitor/
        __init__.py
        admin.py
        apps.py
        migrations/
        templates/
            __init__.py
        models.py
        tests.py
        urls.py
        views.py
    
    mainapp/URL을 확인하십시오.py 파일, 모니터링 응용 프로그램 URL을 추가하여 다음 모니터링 응용 프로그램에서 작성할 URL을 포함합니다.
    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        #path('admin/', admin.site.urls),
        path('', include('monitor.urls')),#monitor app url
    ]
    
    
    이제 모니터/URL에 있습니다.py 파일, 거기에 우리 사이트를 추가:
    from django.urls import path
    from .views import *
    
    urlpatterns = [
        path('api/upload/xray', UploadView.as_view(), name = 'prediction'),
        path('api/upload/ct', CTUploadView.as_view(), name = 'ct_prediction'),
    ]
    
    기계 학습 모형을 저장하기 위해 다른 디렉터리를 만듭니다.나는 또한 전체 데이터 집합을 실현하고자 하는 사람들을 위해 데이터 집합을 프로젝트에 추가할 것이다.데이터 폴더를 강제로 만들지 않습니다.
    (venv)$ mkdir ml
    (venv)$ mkdir ml/models
    (venv)$ mkdir ml/data
    
    우리는 Django에게 우리의 기계 학습 모형이 어디에 있는지 알려주고 거기에cloudinary 설정을 추가해야 한다.이러한 행을 설정에 추가합니다.py 파일:
    import os
    import cloudinary
    
    cloudinary.config( 
      cloud_name = "prometheusapi", 
      api_key = "GETYOURAPIKEY", 
      api_secret = "GETYOURAPIKEY" 
    )
    
    MODELS = os.path.join(BASE_DIR, 'ml/models')
    

    적용을 통해 Keras 모델을 로드합니다.py


    응용 프로그램에 기계 학습 모형을 불러옵니다.따라서 프로그램이 시작될 때 훈련을 받은 모델을 한 번만 불러옵니다.그렇지 않으면 노드를 호출할 때마다 훈련된 모델을 불러오고 응답 시간이 느려집니다.
    응용 프로그램을 업데이트합시다.py
    import os
    from django.apps import AppConfig
    from django.conf import settings
    from tensorflow.keras.models import load_model
    from tensorflow import keras
    
    
    class ResNetModelConfig(AppConfig):
        name = 'resnetAPI'
        MODEL_FILE = os.path.join(settings.MODELS, "resnet_chest.h5")
        model = keras.models.load_model(MODEL_FILE)
    
    class ResNetCTModelConfig(AppConfig):
        name = 'resnetCTAPI'
        MODEL_FILE = os.path.join(settings.MODELS, "resnet_ct.h5")
        model = keras.models.load_model(MODEL_FILE)
    
    class VGGModelConfig(AppConfig):
        name = 'vggAPI'
        MODEL_FILE = os.path.join(settings.MODELS, "vgg_chest.h5")
        model = keras.models.load_model(MODEL_FILE)
    
    class VGGCTModelConfig(AppConfig):
        name = 'vggCTAPI'
        MODEL_FILE = os.path.join(settings.MODELS, "vgg_ct.h5")
        model = keras.models.load_model(MODEL_FILE)    
    
    class InceptionModelConfig(AppConfig):
        name = 'inceptionv3_chestAPI'
        MODEL_FILE = os.path.join(settings.MODELS, "inceptionv3_chest.h5")    
        model = keras.models.load_model(MODEL_FILE)
    
    class InceptionCTModelConfig(AppConfig):
        name = 'inceptionv3_chestCTAPI'
        MODEL_FILE = os.path.join(settings.MODELS, "inception_ct.h5")    
        model = keras.models.load_model(MODEL_FILE)    
    
    class ExceptionModelConfig(AppConfig):
        name = 'xception_chestAPI'
        MODEL_FILE = os.path.join(settings.MODELS, "xception_chest.h5")    
        model = keras.models.load_model(MODEL_FILE)
    
    class ExceptionCTModelConfig(AppConfig):
        name = 'xception_chestCTAPI'
        MODEL_FILE = os.path.join(settings.MODELS, "xception_ct.h5")    
        model = keras.models.load_model(MODEL_FILE)    
    

    뷰를 편집합니다.py


    마지막 단계는 보기를 업데이트하는 것입니다.피야.이러한 관점은 주로 두 가지 임무를 맡을 것이다.
  • 들어오는 POST 요청을 처리합니다.
  • 입력 데이터로 예측하고 결과를 응답으로 제시한다.
  • import urllib
    from django.shortcuts import render
    import numpy as np
    from .apps import *
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework.parsers import MultiPartParser, JSONParser
    import cloudinary.uploader
    import matplotlib.pyplot as plt
    import cv2
    
    # Create your views here.
    class UploadView(APIView):
        parser_classes = (
            MultiPartParser,
            JSONParser,
        )
    
        @staticmethod
        def post(request):
            file = request.data.get('picture')
            upload_data = cloudinary.uploader.upload(file)
            #print(upload_data)
            img = upload_data['url']
    
    
            #load models
            resnet_chest = ResNetModelConfig.model
            vgg_chest = VGGModelConfig.model
            inception_chest = InceptionModelConfig.model
            xception_chest = ExceptionModelConfig.model
    
            req = urllib.request.urlopen(img)
            arr = np.asarray(bytearray(req.read()), dtype=np.uint8)
            image = cv2.imdecode(arr, -1) # 'Load it as it is'
            #image = cv2.imread('upload_chest.jpg') # read file 
            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # arrange format as per keras
            image = cv2.resize(image,(224,224))
            image = np.array(image) / 255
            image = np.expand_dims(image, axis=0)
    
            resnet_pred = resnet_chest.predict(image)
            probability = resnet_pred[0]
            #print("Resnet Predictions:")
            if probability[0] > 0.5:
                resnet_chest_pred = str('%.2f' % (probability[0]*100) + '% COVID') 
            else:
                resnet_chest_pred = str('%.2f' % ((1-probability[0])*100) + '% NonCOVID')
            #print(resnet_chest_pred)
    
            vgg_pred = vgg_chest.predict(image)
            probability = vgg_pred[0]
            #print("VGG Predictions:")
            if probability[0] > 0.5:
                vgg_chest_pred = str('%.2f' % (probability[0]*100) + '% COVID') 
            else:
                vgg_chest_pred = str('%.2f' % ((1-probability[0])*100) + '% NonCOVID')
            #print(vgg_chest_pred)
    
            inception_pred = inception_chest.predict(image)
            probability = inception_pred[0]
            #print("Inception Predictions:")
            if probability[0] > 0.5:
                inception_chest_pred = str('%.2f' % (probability[0]*100) + '% COVID') 
            else:
                inception_chest_pred = str('%.2f' % ((1-probability[0])*100) + '% NonCOVID')
            #print(inception_chest_pred)
    
            xception_pred = xception_chest.predict(image)
            probability = xception_pred[0]
            #print("Xception Predictions:")
            if probability[0] > 0.5:
                xception_chest_pred = str('%.2f' % (probability[0]*100) + '% COVID') 
            else:
                xception_chest_pred = str('%.2f' % ((1-probability[0])*100) + '% NonCOVID')
            #print(xception_chest_pred)
            return Response({
                'status': 'success',
                'data': upload_data,
                'url':img,
                'xception_chest_pred':xception_chest_pred,
                'inception_chest_pred':inception_chest_pred,
                'vgg_chest_pred':vgg_chest_pred,
                'resnet_chest_pred':resnet_chest_pred,
            }, status=201)
    
    
    class CTUploadView(APIView):
        parser_classes = (
            MultiPartParser,
            JSONParser,
        )
    
        @staticmethod
        def post(request):
            file = request.data.get('picture')
            upload_data = cloudinary.uploader.upload(file)
            #print(upload_data)
            img = upload_data['url']
    
    
            #load models
            resnet_chest = ResNetCTModelConfig.model
            vgg_chest = VGGCTModelConfig.model
            inception_chest = InceptionCTModelConfig.model
            xception_chest = ExceptionCTModelConfig.model
    
            req = urllib.request.urlopen(img)
            arr = np.asarray(bytearray(req.read()), dtype=np.uint8)
            image = cv2.imdecode(arr, -1) # 'Load it as it is'
            #image = cv2.imread('upload_chest.jpg') # read file 
            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # arrange format as per keras
            image = cv2.resize(image,(224,224))
            image = np.array(image) / 255
            image = np.expand_dims(image, axis=0)
    
            resnet_pred = resnet_chest.predict(image)
            probability = resnet_pred[0]
            #print("Resnet Predictions:")
            if probability[0] > 0.5:
                resnet_chest_pred = str('%.2f' % (probability[0]*100) + '% COVID') 
            else:
                resnet_chest_pred = str('%.2f' % ((1-probability[0])*100) + '% NonCOVID')
            #print(resnet_chest_pred)
    
            vgg_pred = vgg_chest.predict(image)
            probability = vgg_pred[0]
            #print("VGG Predictions:")
            if probability[0] > 0.5:
                vgg_chest_pred = str('%.2f' % (probability[0]*100) + '% COVID') 
            else:
                vgg_chest_pred = str('%.2f' % ((1-probability[0])*100) + '% NonCOVID')
            #print(vgg_chest_pred)
    
            inception_pred = inception_chest.predict(image)
            probability = inception_pred[0]
            #print("Inception Predictions:")
            if probability[0] > 0.5:
                inception_chest_pred = str('%.2f' % (probability[0]*100) + '% COVID') 
            else:
                inception_chest_pred = str('%.2f' % ((1-probability[0])*100) + '% NonCOVID')
            #print(inception_chest_pred)
    
            xception_pred = xception_chest.predict(image)
            probability = xception_pred[0]
            #print("Xception Predictions:")
            if probability[0] > 0.5:
                xception_chest_pred = str('%.2f' % (probability[0]*100) + '% COVID') 
            else:
                xception_chest_pred = str('%.2f' % ((1-probability[0])*100) + '% NonCOVID')
            #print(xception_chest_pred)
            return Response({
                'status': 'success',
                'data': upload_data,
                'url':img,
                'xceptionCT_chest_pred':xception_chest_pred,
                'inceptionCT_chest_pred':inception_chest_pred,
                'vggCT_chest_pred':vgg_chest_pred,
                'resnetCT_chest_pred':resnet_chest_pred,
            }, status=201)
    
    
    

    API 테스트


    필요한 마이그레이션을 만들고 서버를 실행합니다.
    (myenv) $ python manage.py makemigrations
    (myenv) $ python manage.py migrate
    (myenv) $ python manage.py runserver
    
    우체부를 가동시키고 시체에 사진 한 장을 첨부해 포스터 요청을 한다.

    시청해 주셔서 감사합니다!

    좋은 웹페이지 즐겨찾기