Валидация моделей акустической диагностики
Проверка моделей акустической диагностики на эталонных и применение на реальных данных
Введение
Модель, которая по акустическому сигналу определяет степень износа трёх элементов подшипника, обучена и сохранена в файл. Теперь нужно проверить, насколько хорошо она работает. Важнейшей задачей является не только обучение алгоритма, но и подтверждение того, что он даёт правильные ответы на сигналах, с которыми раньше не работал.
В этой работе мы решим две задачи. Сначала проверим модель на эталонных данных: подадим ей те же сигналы, что использовались при обучении, и их комбинации с заранее известной степенью износа. Это покажет точность предсказаний в контролируемых условиях. Затем применим модель к совершенно новым записям в формате WAV. С этими сигналами модель ранее никогда не работала, и именно они покажут готовность решения к реальной эксплуатации.
Для инженера важно не только получить число от алгоритма, но и понять, что оно означает на практике. Поэтому все предсказания интерпретируются по пятиуровневой шкале: идеальное состояние, хорошее, средний износ, сильный и критический. Такая классификация позволяет сразу принять решение: продолжать эксплуатацию, запланировать обслуживание или остановить оборудование.
Работа построена как готовый диагностический инструмент. Мы загрузим сохранённую модель, подготовим вспомогательные функции и применим к ним несколько тестовых сценариев. Каждый шаг сопровождается аудиоплеером: сигнал можно не только проанализировать численно, но и прослушать, чтобы на слух оценить характер дефекта.
Определим классификацию степеней износа элементов подшипника по пяти категориям. Диапазоны выбраны так, чтобы обеспечить практическую полезность диагностики: идеальное и хорошее состояние не требуют вмешательства, средний износ указывает на необходимость планового обслуживания, а сильный и критический износ требуют немедленной остановки и замены. Эта шкала будет использоваться для интерпретации результатов диагностики:
- от 0% до 10% – идеальное состояние;
- от 10% до 20% – хорошее состояние;
- от 20% до 50% – средний износ;
- от 50% до 75% – сильный износ;
- от 75% до 100% – критический износ.
Присоединение функций и библиотек
Подключим библиотеки, необходимые для работы с данными и обучения модели:
-
MAT – чтение акустических сигналов из файлов формата MATLAB.
-
WAV – запись сигналов в аудиофайлы и чтение WAV-файлов для диагностики.
-
Statistics – базовые статистические функции: среднее, медиана, стандартное отклонение, дисперсия.
-
StatsBase – расширенные статистики: асимметрия, эксцесс, квантили.
-
DSP – цифровая обработка сигналов.
-
FFTW – быстрое преобразование Фурье для спектрального анализа.
-
DecisionTree – реализация случайного леса для регрессии.
-
Random – генератор случайных чисел.
-
Serialization – загрузка обученной модели из файла JLS.
for pkg in (["MAT", "WAV", "Statistics", "DSP", "FFTW", "DecisionTree", "StatsBase", "Random", "Serialization"])
try
eval(Meta.parse("using $pkg"))
catch
Pkg.add(pkg)
eval(Meta.parse("using $pkg"))
end
end
Загрузим вспомогательные функции из внешних файлов, созданных на этапе обучения. вычислить_признаки.jl содержит функцию расчёта 53 диагностических признаков, идентичную использованной при обучении. media_player.jl обеспечит встроенный аудиоплеер для прослушивания тестовых сигналов.
include("вычислить_признаки.jl")
include("media_player.jl")
Загрузка модели
Так как jls-файл с обученными моделями имеет относительно большой объём (более 800 МБ), скачаем его из внешнего источника. В случае, если внешний источник окажется недоступен, вы можете самостоятельно создать файл модель_подшипника.jls, запустив основной скрипт проекта по созданию моделей акустической диагностики и переместить файл в текущую рабочую директорию.
Downloads.download("https://storage.yandexcloud.net/videohosting555/engee-ltc-school/%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C_%D0%BF%D0%BE%D0%B4%D1%88%D0%B8%D0%BF%D0%BD%D0%B8%D0%BA%D0%B0.jls",
joinpath("$(@__DIR__)/", "модель_подшипника.jls"))
Загрузим обученные модели и все сопутствующие параметры из файла модель_подшипника.jls одной командой deserialize. Извлечём три модели случайного леса, векторы средних и СКО для нормализации признаков, параметры сегментации и эталонные значения амплитуды. Время выполнения данной кодовой ячейки может занять несколько минут. После загрузки модель готова к диагностике без повторного обучения.
данные = deserialize("модель_подшипника.jls")
модель_внутр = данные.модель_внутр;
модель_внеш = данные.модель_внеш;
модель_ролик = данные.модель_ролик;
средние = данные.средние_признаков;
ско = данные.ско_признаков;
длина_сегмента = данные.длина_сегмента;
перекрытие = данные.перекрытие;
частота_дискретизации = данные.частота_дискретизации;
эталонный_rms = данные.эталонный_rms;
эталонный_размах = данные.эталонный_размах;
Деление на сегменты
Создадим функцию разделения сигнала на сегменты с теми же параметрами, что использовались при обучении, так как признаки должны вычисляться на сегментах той же длины и с тем же перекрытием. Функция идентична той, что применялась при обучении.
function разделить_на_сегменты(сигнал, длина_сегмента, перекрытие)
шаг = Int(floor(длина_сегмента * (1 - перекрытие)))
сегменты = []
for i in 1:шаг:(length(сигнал) - длина_сегмента + 1)
push!(сегменты, сигнал[i:i+длина_сегмента-1])
end
return сегменты
end
Нормализация
Создадим функцию нормализации признаков с использованием средних и СКО, загруженных из файла модели. Она приводит новые признаки к тому же масштабу, на котором обучалась модель. Без этого шага предсказания будут некорректными из-за разного масштаба признаков.
function нормализовать(пр)
return (пр .- средние) ./ ско
end
Диагностика сегмента
Создадим функцию диагностики одного сегмента: вычисление признаков, нормализация и предсказание тремя моделями случайного леса. Результатом станет словарь с тремя значениями износа в процентах.
function диагностика_сегмента(сигнал, fs)
пр = нормализовать(вычислить_признаки(сигнал, fs))
м = reshape(пр, 1, :)
износ_внутр = DecisionTree.predict(модель_внутр, м)[1]
износ_внеш = DecisionTree.predict(модель_внеш, м)[1]
износ_ролик = DecisionTree.predict(модель_ролик, м)[1]
return Dict(
"Износ внутреннего кольца" => clamp(износ_внутр, 0, 100),
"Износ внешнего кольца" => clamp(износ_внеш, 0, 100),
"Износ тела качения" => clamp(износ_ролик, 0, 100)
)
end
Диагностика полного сигнала
Создадим основную функцию диагностики, которая разбивает полный сигнал на сегменты, диагностирует каждый через диагностика_сегмента и усредняет результаты. Усреднение по сегментам повышает стабильность предсказания и снижает влияние случайных выбросов. Результат округляется до десятых долей процента.
function диагностика(полный_сигнал, fs)
сегменты = разделить_на_сегменты(полный_сигнал, длина_сегмента, перекрытие)
результаты = [диагностика_сегмента(сег, fs) for сег in сегменты]
ср_внутр = mean([р["Износ внутреннего кольца"] for р in результаты])
ср_внеш = mean([р["Износ внешнего кольца"] for р in результаты])
ср_ролик = mean([р["Износ тела качения"] for р in результаты])
return Dict(
"Износ внутреннего кольца" => round(clamp(ср_внутр, 0, 100), digits=1),
"Износ внешнего кольца" => round(clamp(ср_внеш, 0, 100), digits=1),
"Износ тела качения" => round(clamp(ср_ролик, 0, 100), digits=1))
end
Проверка на эталонных данных
Загрузим эталонные сигналы из MAT-файла для проверки качества модели на известных данных. Преобразуем их в векторы, аналогично тому, как это делалось при обучении. Эти сигналы будут использоваться как для прямой диагностики, так и для создания комбинаций с заданным процентом износа.
подшипник = matread("Bearing.mat")
Проверим качество работы модели на исходных сигналах и их комбинациях с известной степенью износа. Для каждого теста указан ожидаемый процент дефекта и соответствующая ему категория состояния согласно введённой классификации. Эталонные сигналы смешиваются по формуле норма + степень × (дефект − норма), что добавляет только дефектную составляющую к нормальному сигналу.
норма = vec(подшипник["normal"])
ролик = vec(подшипник["roller"])
внутр = vec(подшипник["inner"])
внеш = vec(подшипник["outer"])
Полностью исправный подшипник:
диагностика(норма, частота_дискретизации)
Полностью неисправное тело качения:
диагностика(ролик, частота_дискретизации)
Полностью неисправное внутреннее кольцо:
диагностика(внутр, частота_дискретизации)
Полностью неисправное внешнее кольцо:
диагностика(внеш, частота_дискретизации)
Износ тела качения 10%
⬇️
диагностика(норма + 0.10*(ролик-норма), частота_дискретизации)
Износ тела качения 5%
⬇️
диагностика(норма + 0.05*(ролик-норма), частота_дискретизации)
Износ тела качения 80%
Износ внешнего кольца 10%
Износ внутреннего кольца 10%
⬇️
диагностика(норма + 0.1*(внутр-норма) + 0.1*(внеш-норма) + 0.8*(ролик-норма), частота_дискретизации)
Износ всех элементов 50%
⬇️
диагностика(норма + 0.5*(внутр-норма) + 0.5*(внеш-норма) + 0.5*(ролик-норма), частота_дискретизации)
Износ тела качения 10%
Износ внутреннего кольца 90%
⬇️
диагностика(норма + 0.9*(внутр-норма) + 0.1*(ролик-норма), частота_дискретизации)
Износ тела качения 90%
Износ внутреннего кольца 20%
⬇️
диагностика(норма + 0.2*(внутр-норма) + 0.9*(ролик-норма), частота_дискретизации)
Износ тела качения 5%
Износ внутреннего кольца 95%
⬇️
диагностика(норма + 0.95*(внутр-норма) + 0.05*(ролик-норма), частота_дискретизации)
Износ тела качения 40%
Износ внешнего кольца 30%
Износ внутреннего кольца 30%
⬇️
диагностика(норма + 0.3*(внутр-норма) + 0.3*(внеш-норма) + 0.4*(ролик-норма), частота_дискретизации)
Износ тела качения 60%
Износ внешнего кольца 70%
Износ внутреннего кольца 80%
⬇️
диагностика(норма + 0.8*(внутр-норма) + 0.7*(внеш-норма) + 0.6*(ролик-норма), частота_дискретизации)
Износ тела качения 20%
Износ внешнего кольца 30%
Износ внутреннего кольца 50%
⬇️
диагностика(норма + 0.5*(внутр-норма) + 0.3*(внеш-норма) + 0.2*(ролик-норма), частота_дискретизации)
Модель демонстрирует точность диагностики, полностью соответствующую требованиям пятиуровневой классификации. Во всех без исключения проверенных сценариях категория состояния каждого элемента подшипника определена верно. Погрешности сосредоточены в пределах одной категории, что гарантирует правильность итогового заключения. Модель уверенно разделяет близкие по величине дефекты и стабильно детектирует слабый износ ролика даже на фоне доминирующих сигналов от колец.
Диагностика новых исходных данных
Выполним диагностику новых данных с подшипников в различных состояниях. Данные хранятся в виде звуковых файлов формата wav. Для получение вектора чисел, используем функцию wavread(). Воспроизведём звук каждого подшипника и выполним их диагностику.
подшипник_1, fs = wavread("Подшипник_1.wav");
media_player("$(@__DIR__)/Подшипник_1.wav", mode="audio")
диагностика(подшипник_1, частота_дискретизации)
подшипник_2, fs = wavread("Подшипник_2.wav");
media_player("$(@__DIR__)/Подшипник_2.wav", mode="audio")
диагностика(подшипник_2, частота_дискретизации)
подшипник_3, fs = wavread("Подшипник_3.wav");
media_player("$(@__DIR__)/Подшипник_3.wav", mode="audio")
диагностика(подшипник_3, частота_дискретизации)
подшипник_4, fs = wavread("Подшипник_4.wav");
media_player("$(@__DIR__)/Подшипник_4.wav", mode="audio")
диагностика(подшипник_4, частота_дискретизации)
подшипник_5, fs = wavread("Подшипник_5.wav");
media_player("$(@__DIR__)/Подшипник_5.wav", mode="audio")
диагностика(подшипник_5, частота_дискретизации)
подшипник_6, fs = wavread("Подшипник_6.wav");
media_player("$(@__DIR__)/Подшипник_6.wav", mode="audio")
диагностика(подшипник_6, частота_дискретизации)
подшипник_7, fs = wavread("Подшипник_7.wav");
media_player("$(@__DIR__)/Подшипник_7.wav", mode="audio")
диагностика(подшипник_7, частота_дискретизации)
подшипник_8, fs = wavread("Подшипник_8.wav");
media_player("$(@__DIR__)/Подшипник_8.wav", mode="audio")
диагностика(подшипник_8, частота_дискретизации)
подшипник_9, fs = wavread("Подшипник_9.wav");
media_player("$(@__DIR__)/Подшипник_9.wav", mode="audio")
диагностика(подшипник_9, частота_дискретизации)
подшипник_10, fs = wavread("Подшипник_10.wav");
media_player("$(@__DIR__)/Подшипник_10.wav", mode="audio")
диагностика(подшипник_10, частота_дискретизации)
Заключение
Мы провели всестороннюю проверку модели акустической диагностики: сначала на эталонных, затем на новых сигналах, на которых модель не обучалась. Результаты подтверждают, что модель уверенно решает поставленную задачу.
На эталонных сигналах модель безошибочно определяет исправный подшипник и все виды дефектов. На комбинациях с частичным износом категория состояния каждого элемента определена верно, включая слабый износ тела качения на фоне доминирующих сигналов от колец. Погрешности не приводят к переходу через границу категории, что говорит о готовности к применению на реальных сигналах вне обучающего набора.
Ключевое преимущество данного решения заключается в том, что оно не требует повторного обучения при каждом новом сигнале: достаточно один раз загрузить сохранённый файл модели. Проверка подтвердила важность правильной предобработки, включая совпадение частоты дискретизации входа и модели.
Полученные результаты являются основой для создания инженерного приложения для акустической диагностики.