Проверка модели после экспорта: допуски на Python

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

Программа курса «Computer Vision Engineer: от детекции и Doc-AI до продакшна».

Выходы в пределах допуска

Задание

После экспорта модель считают две разные среды, и бит-в-бит их выходы не совпадают никогда. Чтобы по такому сравнению можно было принять решение, расхождение сверяют с парой допусков: абсолютным и относительным.

Реализуйте функцию outputs_match(reference, candidate, rel, abs_). Аргументы reference и candidate — выходы эталонной и проверяемой среды, списки чисел, снятые на одном и том же входе. Число rel — относительный допуск, abs_ — абсолютный.

Правило совпадения. Значение на позиции считается совпавшим, если расхождение с эталоном укладывается хотя бы в один из двух допусков: не превышает abs_ либо не превышает rel, умноженного на модуль эталонного значения. Ровно на границе значение считается совпавшим. Выходы совпали, если совпали все позиции.

Что вернуть. Кортеж из трёх элементов: решение о совпадении, наибольшее относительное расхождение и позицию, на которой оно достигнуто. Относительное расхождение позиции — модуль разности, делённый на модуль эталонного значения. Там, где эталон равен нулю, оно не определено: такие позиции в поиске наибольшего не участвуют. По всем остальным наибольшее ищется целиком, включая те, что уложились в допуск. Если ни одной позиции с ненулевым эталоном нет, верните наибольшее расхождение 0.0 и позицию -1; решение о совпадении при этом считается по общему правилу. Когда наибольшее достигнуто сразу на нескольких позициях, возьмите наименьшую из них.

Длины разошлись. Тогда сравнивать по позициям нечего: верните решение «не совпало», расхождение 0.0 и позицию -1. Два пустых списка, наоборот, совпали.

Пример

reference = [640.0, 0.5, 0.0, -12.0]
candidate = [640.03, 0.503, 0.004, -12.6]

outputs_match(reference, candidate, 1e-3, 1e-2)
# (False, 0.05, 3)

Первая позиция разошлась на три сотых — это больше абсолютного допуска, но относительный на значении 640 разрешает почти семь десятых. Третью спасает абсолютный допуск: относительный от нуля не разрешает ничего. А на последней позиции не сработал ни один, поэтому решение отрицательное, и наибольшее относительное расхождение — как раз оттуда.

Примечание

Вход уже разобран и приходит аргументами: два списка чисел с плавающей точкой и два числа-допуска. Значения бывают отрицательными. Менять входные списки нельзя. Наибольшее расхождение сравнивается с точностью до одной миллиардной, подгонять округление не нужно: границы допусков и одинаковые расхождения заданы в проверках точными значениями, и сравнение не зависит от последнего разряда. Вызывать функцию вручную не нужно, проверка запускает её сама.

Что проверяется

Код проверок скрыт, так что вот полный список того, что в них разбирается:

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

Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.

Отправьте решение, чтобы увидеть результаты тестов.

Связанные задачи