В этом примере описываются два рабочих процессов, которые могут помочь вам прийти к полностью встроенному эффективному проекту с фиксированной точкой. В этом примере показано, как:
Используйте несколько сценариев симуляции в оптимизации типа данных.
Используйте области значений, полученную из проекта областей значений для оптимизации типа данных.
Используйте различные бенчмарки численного поведения для каждого сценария, используя блоки из библиотеки Верификации модели.
Замените математические операции, которые не поддерживают типы данных с фиксированной точкой, эффективными интерполяционными таблицами.
Модель в этом примере использует алгоритм Ограниченной машины Больцмана (RBM), чтобы денонсировать изображения. Загрузите данные изображения и веса алгоритма RBM. Исходные и искаженные изображения хранятся в imgOriginal
и imgDistorted
переменные. Каждая строка каждой матрицы является тестовым изображением из набора данных MNIST.
load RBMData;
Откройте и просмотрите первый набор тестовых изображений.
singleImgDistorted = imgDistorted(1,:); singleImgOriginal = imgOriginal(1,:); imgSize = length(singleImgOriginal); subplot(1,2,1) imshow(reshape(singleImgOriginal,[28,28])') title('Original Image'); subplot(1,2,2) imshow(reshape(singleImgDistorted,[28,28])') title('Distorted Image')
Откройте модель. Модель загружает искаженное тестовое изображение, использует алгоритм RBM, чтобы обесценить изображение, а затем сравнивает деноизмененное изображение с оригинальным изображением без добавленного шума. Чтобы улучшить скорость симуляции, в этой модели отключается отображение видео. Чтобы включить отображение видео, установите DISPLAY_VIEWER
переменная - 1.
model = 'ex_rbmDenoiser01';
open_system(model);
DISPLAY_VIEWER = 0;
При преобразовании модели для использования типов данных с фиксированной точкой важно собирать области значений во время выполнения модели в полной рабочей области значений. Это можно сделать, задав несколько сценариев симуляции. В этом примере каждый из пяти сценариев симуляции задает новый набор тестовых изображений для денуилизации и сравнения с оригинальным изображением.
IMGN = 5; si = Simulink.SimulationInput.empty(0, IMGN); for indx = 1:IMGN si(indx) = Simulink.SimulationInput(model); si(indx) = si(indx).setVariable('singleImgDistorted', imgDistorted(indx,:)); si(indx) = si(indx).setVariable('singleImgOriginal', imgOriginal(indx,:)); end
В каждом сценарии симуляции проверьте, что средняя квадратная ошибка между оригинальным изображением и деноизированным изображением меньше 0,02.
si(1) = si(1).setBlockParameter([model '/CompareToOriginal/check'], 'max', '0.02'); si(2) = si(2).setBlockParameter([model '/CompareToOriginal/check'], 'max', '0.02'); si(3) = si(3).setBlockParameter([model '/CompareToOriginal/check'], 'max', '0.02'); si(4) = si(4).setBlockParameter([model '/CompareToOriginal/check'], 'max', '0.02'); si(5) = si(5).setBlockParameter([model '/CompareToOriginal/check'], 'max', '0.03');
Задайте опции, которые будут использоваться во время оптимизации. В данном примере ограничьте размеры слова в преобразованной модели в пределах от 8 до 16 бит. Можно также ограничить количество итераций, которые выполняет алгоритм оптимизации.
options = fxpOptimizationOptions(... 'AllowableWordLengths', [8 16], ... 'MaxIterations', 50, ... 'Patience', 50);
Чтобы собрать производные области значений в модели в дополнение к использованию сценариев симуляции для сбора областей значений симуляции, установите UseDerivedRangeAnalysis
опция для true
. Производный анализ области значений часто возвращает более консервативную оценку динамических областей значений в системе, чем области значений, собранные с помощью симуляций.
options.AdvancedOptions.UseDerivedRangeAnalysis = true;
Задайте сценарии симуляции, которые будут использоваться во время оптимизации.
options.AdvancedOptions.SimulationScenarios = si;
Используйте fxpopt
функция для оптимизации типов данных в подсистеме Denoiser УОКР согласно опциям, указанным в fxpOptimizationOptions
объект, options
result = fxpopt(model, [model '/RBM Denoiser'], options);
+ Starting data type optimization... + Checking for unsupported constructs. + Preprocessing + Modeling the optimization problem - Constructing decision variables + Running the optimization solver - Evaluating new solution: cost 344, does not meet the behavioral constraints. - Evaluating new solution: cost 656, meets the behavioral constraints. - Updated best found solution, cost: 656 - Evaluating new solution: cost 640, meets the behavioral constraints. - Updated best found solution, cost: 640 - Evaluating new solution: cost 624, does not meet the behavioral constraints. - Evaluating new solution: cost 632, meets the behavioral constraints. - Updated best found solution, cost: 632 - Evaluating new solution: cost 608, meets the behavioral constraints. - Updated best found solution, cost: 608 - Evaluating new solution: cost 600, meets the behavioral constraints. - Updated best found solution, cost: 600 - Evaluating new solution: cost 584, does not meet the behavioral constraints. - Evaluating new solution: cost 592, meets the behavioral constraints. - Updated best found solution, cost: 592 - Evaluating new solution: cost 568, meets the behavioral constraints. - Updated best found solution, cost: 568 - Evaluating new solution: cost 560, meets the behavioral constraints. - Updated best found solution, cost: 560 - Evaluating new solution: cost 544, meets the behavioral constraints. - Updated best found solution, cost: 544 - Evaluating new solution: cost 504, meets the behavioral constraints. - Updated best found solution, cost: 504 - Evaluating new solution: cost 440, meets the behavioral constraints. - Updated best found solution, cost: 440 - Evaluating new solution: cost 432, meets the behavioral constraints. - Updated best found solution, cost: 432 - Evaluating new solution: cost 424, meets the behavioral constraints. - Updated best found solution, cost: 424 - Evaluating new solution: cost 408, meets the behavioral constraints. - Updated best found solution, cost: 408 - Evaluating new solution: cost 400, meets the behavioral constraints. - Updated best found solution, cost: 400 - Evaluating new solution: cost 392, meets the behavioral constraints. - Updated best found solution, cost: 392 - Evaluating new solution: cost 376, meets the behavioral constraints. - Updated best found solution, cost: 376 - Evaluating new solution: cost 360, does not meet the behavioral constraints. - Evaluating new solution: cost 360, does not meet the behavioral constraints. - Evaluating new solution: cost 392, meets the behavioral constraints. - Evaluating new solution: cost 416, meets the behavioral constraints. - Evaluating new solution: cost 424, meets the behavioral constraints. - Evaluating new solution: cost 480, meets the behavioral constraints. - Evaluating new solution: cost 472, meets the behavioral constraints. - Evaluating new solution: cost 512, meets the behavioral constraints. + Optimization has finished. - Neighborhood search complete. - Maximum number of iterations completed. + Fixed-point implementation that satisfies the behavioral constraints found. The best found solution is applied on the model. - Total cost: 376 - Use the explore method of the result to explore the implementation.
Чтобы сравнить поведение базовой модели с двойной точностью с моделью, которая использует типы данных с фиксированной точкой, сохраните оптимизированную модель с фиксированной точкой с новым именем.
modelAfterFxpopt = 'ex_rbmDenoiser02';
save_system(model, modelAfterFxpopt);
Подсистемы LogisticExpression содержат операции, которые не поддерживают типы данных с фиксированной точкой. Замените эти подсистемы интерполяционными таблицами, которые тесно аппроксимируют исходное поведение.
functionToApproximate = [modelAfterFxpopt '/RBM Denoiser/Logistic/LogisticExpression'];
problem = FunctionApproximation.Problem(functionToApproximate);
problem.Options.AbsTol = 2^-6;
problem.Options.RelTol = 2^-7;
solution = solve(problem);
replaceWithApproximate(solution);
| ID | Memory (bits) | Feasible | Table Size | Breakpoints WLs | TableData WL | BreakpointSpecification | Error(Max,Current) | | 0 | 32 | 0 | 2 | 8 | 8 | EvenSpacing | 1.562500e-02, 5.000000e-01 | | 1 | 160 | 0 | 18 | 8 | 8 | EvenSpacing | 1.562500e-02, 1.562500e-01 | | 2 | 312 | 0 | 37 | 8 | 8 | EvenSpacing | 1.562500e-02, 9.375000e-02 | | 3 | 704 | 0 | 86 | 8 | 8 | EvenSpacing | 1.562500e-02, 3.125000e-02 | | 4 | 2064 | 1 | 256 | 8 | 8 | EvenSpacing | 1.562500e-02, 0.000000e+00 | | 5 | 128 | 0 | 14 | 8 | 8 | EvenSpacing | 1.562500e-02, 3.593750e-01 | | 6 | 120 | 0 | 13 | 8 | 8 | EvenSpacing | 1.562500e-02, 4.218750e-01 | | 7 | 248 | 0 | 29 | 8 | 8 | EvenSpacing | 1.562500e-02, 1.718750e-01 | | 8 | 224 | 0 | 26 | 8 | 8 | EvenSpacing | 1.562500e-02, 1.875000e-01 | | 9 | 528 | 0 | 64 | 8 | 8 | EvenSpacing | 1.562500e-02, 3.125000e-02 | | 10 | 432 | 0 | 52 | 8 | 8 | EvenSpacing | 1.562500e-02, 6.250000e-02 | | 11 | 1040 | 1 | 128 | 8 | 8 | EvenSpacing | 1.562500e-02, 1.562500e-02 | | 12 | 96 | 0 | 10 | 8 | 8 | EvenSpacing | 1.562500e-02, 3.125000e-01 | | 13 | 88 | 0 | 9 | 8 | 8 | EvenSpacing | 1.562500e-02, 5.625000e-01 | | 14 | 168 | 0 | 19 | 8 | 8 | EvenSpacing | 1.562500e-02, 3.125000e-01 | | 15 | 128 | 1 | 8 | 8 | 8 | ExplicitValues | 1.562500e-02, 1.562500e-02 | | 16 | 128 | 1 | 8 | 8 | 8 | ExplicitValues | 1.562500e-02, 1.562500e-02 | | 17 | 2064 | 1 | 256 | 8 | 8 | EvenPow2Spacing | 1.562500e-02, 0.000000e+00 | | 18 | 1040 | 1 | 128 | 8 | 8 | EvenPow2Spacing | 1.562500e-02, 1.562500e-02 | Best Solution | ID | Memory (bits) | Feasible | Table Size | Breakpoints WLs | TableData WL | BreakpointSpecification | Error(Max,Current) | | 15 | 128 | 1 | 8 | 8 | 8 | ExplicitValues | 1.562500e-02, 1.562500e-02 |
Поскольку обе подсистемы LogisticExpression реализуют один и тот же алгоритм, можно заменить вторую подсистему LogisticExpression на ту же интерполяционную таблицу, созданную на предыдущем шаге.
lutBlockPath = functionToApproximate; subsystemToReplace = [modelAfterFxpopt '/RBM Denoiser/Logistic1/LogisticExpression']; pos = get_param(subsystemToReplace, 'Position'); delete_block(subsystemToReplace); add_block(lutBlockPath, subsystemToReplace,'Position',pos); set_param(subsystemToReplace, 'Commented', 'off');
Сравните поведение симуляции модели с фиксированной точкой с приближениями интерполяционной таблицы по сравнению с исходной версией базовой линии с двойной точностью. Задайте те же сценарии симуляции для обновленной модели.
siFA = Simulink.SimulationInput.empty(0, IMGN); for indx = 1:IMGN siFA(indx) = Simulink.SimulationInput(modelAfterFxpopt); siFA(indx) = siFA(indx).setVariable('singleImgDistorted', imgDistorted(indx,:)); siFA(indx) = siFA(indx).setVariable('singleImgOriginal', imgOriginal(indx,:)); end siFA(1) = siFA(1).setBlockParameter([modelAfterFxpopt '/CompareToOriginal/check'], 'max', '0.02'); siFA(2) = siFA(2).setBlockParameter([modelAfterFxpopt '/CompareToOriginal/check'], 'max', '0.02'); siFA(3) = siFA(3).setBlockParameter([modelAfterFxpopt '/CompareToOriginal/check'], 'max', '0.02'); siFA(4) = siFA(4).setBlockParameter([modelAfterFxpopt '/CompareToOriginal/check'], 'max', '0.02'); siFA(5) = siFA(5).setBlockParameter([modelAfterFxpopt '/CompareToOriginal/check'], 'max', '0.03');
Моделируйте и наблюдайте поведение симуляции модели, которая содержит замены интерполяционной таблицы. Модель выдает ошибку, если среднеквадратическая ошибка между оригинальным изображением и деноциированным изображением больше 0,02.
simOutAfterFA = sim(siFA);
assert(all(arrayfun(@(x)(isempty(x.ErrorMessage)), simOutAfterFA)), 'Final model does not meet the behavioral constraints');
[01-Oct-2020 10:50:29] Running simulations... [01-Oct-2020 10:50:30] Completed 1 of 5 simulation runs [01-Oct-2020 10:50:31] Completed 2 of 5 simulation runs [01-Oct-2020 10:50:32] Completed 3 of 5 simulation runs [01-Oct-2020 10:50:32] Completed 4 of 5 simulation runs [01-Oct-2020 10:50:33] Completed 5 of 5 simulation runs
Сохраните модель после замены неподдерживаемых подсистем приближениями интерполяционной таблицы.
modelAfterFunctionApproximation = 'ex_rbmDenoiser03';
save_system(modelAfterFxpopt, modelAfterFunctionApproximation);