В этом сообщении описывается тестирование результатов микросервисов машинного обучения. Он охватывает тестирование выходных данных ваших моделей, тестирование с использованием пустых данных, тестирование конечных точек службы и фиктивные функции.

В сообществе специалистов по машинному обучению тестирование - это тема, которой не уделяют должного внимания. Это неотъемлемая часть того, чтобы сделать ваши службы машинного обучения надежными и простыми в разработке. Это сэкономит ваше время, обеспечит безопасную разработку и обеспечит уверенность в том, что ваш микросервис работает должным образом. Например, что, если ваша модель была сохранена в старой версии Tensorflow и включает устаревшие методы или использует устаревшие библиотеки? Обновление до последней версии Tensorflow может нарушить работу вашего сервиса!

Протестируйте вывод модели

Итак, давайте представим, что ваша модель классифицирует изображения автомобилей. Ваш метод классификации может выглядеть примерно так:

def classify_image(image):
    """
    Predicts an image as a numpy array 
    """
    tf_sess = load_session()
    image_placeholder = load_image_tensor_placeholder()
    feed_dict = {image_placeholder: image}
    confidence, classification = \
        tf_sess.run(predict, feed_dict=feed_dict)
    return confidence, classification

Теперь тестовое покрытие могло выглядеть так:

def test_classify_image():
    """ A simple test of the correct classification of a car """
    car_image = load_image('path/to/car_image')
    classification = classify_image(car_image)
    
    assert classification == 'car'

Тест с пустыми данными

Часто модель может измениться при переобучении или может быть вероятностной. Это создает проблему. Тест может перестать работать, если параметры модели будут изменены. Так что, возможно, мы не хотим придерживаться одного и того же имиджа автомобиля. Без страха! Просто отправьте ему пустое изображение.

Ваш тест может выглядеть так:

def test_classify_image():
    """ A simple test of the correct function of an ML model """
    blank_image = numpy.zeros(100,100,100)
    confidence_score, classification = classify_image(blank_image)
    assert isinstance(classification, str)
    assert isinstance(confidence_score, float)

Этот тест показывает, что результат вашего метода имеет ожидаемую форму. По крайней мере, он проверяет, что ваша модель загружается без ошибок. Все под рукой.

Протестируйте конечные точки

Возможно, это более важно, чем проверка правильности работы моделей. Если в вашем коде конечной точки есть ошибка, не имеет значения, насколько эпичны ваши модели машинного обучения, ваш сервис не будет работать.

Серверные инфраструктуры часто предоставляют тестовых клиентов, чтобы убедиться, что ваши конечные точки работают. Я приведу пример для Flask (серверный фреймворк Python). Представьте, что ваша конечная точка Flask для классификации изображений содержит такую ​​конечную точку:

@app.route('/classify', methods=['POST'])
def classify_endpoint():
    """ Classify cars """
    msg = request.get_json()
    image = to_np_array(msg['encoded_image'])
    confidence, classification = classify_image(image)
    return_data = {
        'confidence': 'confidence',
        'classification': 'classification'
    }
    response = flask.jsonify(return_data)
    response.status_code = status_code
    return response

Тест, который охватывает эту конечную точку, может быть:

# Import the endpoint method
from app import classify_endpoint
def test_classify_endpoint():
    app = Flask(__name__)
    app.add_url_rule('/classify',
                     'classify',
                     classify_endpoint,
                     methods=['POST'])
    app = app.test_client()
    response = app.post('/classify',
        data=create_image_payload(),
        headers={'content-type':'application/json'})
    response_data = json.loads(response.data)
    assert response_data['classification'] == 'car'
    assert isinstance(response_data['confidence'], float)
    assert response.status_code == 200
def create_image_payload():
    """ Creates an endpoint friendly payload """
    image = load_image('path/to/car_image.jpeg')
    encoded_image = encode_image(image)
    payload = {
        'encoded_image':encoded_image,
    }
    return json.dumps(payload)

В приведенном выше коде используется тестовый клиент. Он добавляет в этот тестовый клиент метод конечной точки. Вы можете отправлять ему запросы из тестовой среды. Это действительно гарантирует, что служба работает должным образом.

Смоделируйте свои модели машинного обучения

Есть аргумент, что вы должны заглушить classify_image, чтобы ваши тесты были быстрыми. Вы можете имитировать функции следующим образом:

import mock
from app import classify_image
@mock.patch('classify_image')
def test_classify_endpoint(mocked_function): 
    classification = 'car'
    confidence = '0.8'
    mocked_function.return_value = (confidence, classification)
    
    # Rest of function.....

Таким образом, мы можем протестировать конечные точки без загрузки моделей. Если у нас есть модульный тест, который охватывает фактическую функцию модели машинного обучения, мы хорошо протестированы. Однако было бы неплохо провести полный интеграционный тест. Но выбор за вами.

Итак, это первая из серии статей о том, как создать отличный микросервис машинного обучения. Теперь вы можете легко проверить, правильно ли классифицируется модель, протестировать с использованием пустых данных, проверить фактические конечные точки и имитировать функции!