Преобразуйте алгоритмы нейронной сети в фиксированную точку и сгенерируйте код С

Этот пример показывает, как преобразовать модель регрессии нейронной сети в Simulink к фиксированной точке с помощью Оптимизатора Fixed-Point Tool и Интерполяционной таблицы и сгенерировать код С с помощью Simulink Coder.

Обзор

Fixed-Point Designer обеспечивает рабочие процессы через Инструмент Фиксированной точки, который может преобразовать проект от типов данных с плавающей точкой до типов данных с фиксированной точкой. Оптимизатор Интерполяционной таблицы генерирует эффективные памятью замены интерполяционной таблицы для неограниченных функций, таких как exp и log2. Используя эти инструменты, этот пример демонстрирует, как преобразовать обученную модель регрессии нейронной сети с плавающей точкой, чтобы использовать встроено-эффективные типы данных с фиксированной точкой.

Сеть передачи данных и обучение нейронной сети

Neural Network Toolbox поставляется с engine_dataset, который содержит данные, представляющие отношение между топливным уровнем и скоростью механизма, и его крутящим моментом и выбросами газа.

% This dataset can be loaded using the following command:
 load engine_dataset;

% Use the Function fitting tool |nftool| from Neural Network Toolbox(TM) to
% train a neural network to estimate torque and gas emissions of an engine
% given the fuel rate and speed. Use the following commands to train
% the neural network.
x = engineInputs;
t = engineTargets;
net = fitnet(10);
net = train(net,x,t);
view(net)

Закройте все окна учебного инструмента и представление сети

nnet.guis.closeAllViews();
nntraintool('close');

Образцовая подготовка к преобразованию фиксированной точки

Если сеть обучена, используйте функцию gensim от Нейронной сети Toolbox™, чтобы сгенерировать simulink модель.

sys_name = gensim(net, 'Name', 'mTrainedNN');

Модель, сгенерированная функцией gensim, содержит нейронную сеть с обученными весами и смещениями. Чтобы подготовить эту сгенерированную модель к преобразованию фиксированной точки, выполните шаги подготовки в инструкциях по лучшым практикам. https://www.mathworks.com/help/fixedpoint/ug/best-practices-for-using-the-fixed-point-tool-to-propose-data-types-for-your-simulink-model.html

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

Скопируйте модель во временную перезаписываемую директорию.

model = 'fxpdemo_neuralnet_regression';

current_dir = pwd;
fxpnn_demo_dir = fullfile(matlabroot, 'toolbox', 'simulink', 'fixedandfloat', 'fxpdemos');
fxpnn_temp_dir = [tempdir 'fxpnn_dir'];

cd(tempdir);
[~, ~, ~] = rmdir(fxpnn_temp_dir, 's');
mkdir(fxpnn_temp_dir);
cd(fxpnn_temp_dir);

copyfile(fullfile(fxpnn_demo_dir, [model,'.slx']), fullfile(fxpnn_temp_dir, [model '_toconvert.slx']));

Открытый и модель Inspect

model = [model '_toconvert'];
system_under_design = [model '/Function Fitting Neural Network'];
baseline_output = [model '/yarr'];
open_system(model);

Чтобы открыть Fixed-Point Tool, щелкните правой кнопкой мыши по Функции, Соответствующей подсистеме Нейронной сети, и выберите Fixed-Point Tool. Также используйте интерфейс командной строки Fixed-Point Tool. Инструмент Фиксированной точки и интерфейс командной строки обеспечивают шаги рабочего процесса для образцовой подготовки к области значений преобразования фиксированной точки и инструментированию переполнения объектов через симуляцию и анализ области значений, гомогенное wordlength исследование для ввода данных о фиксированной точке и дополнительной диагностики переполнения.

converter = DataTypeWorkflow.Converter(system_under_design);

Запустите симуляцию, чтобы собрать области значений

Моделируйте модель с инструментированием, чтобы собрать области значений. Это достигается путем нажатия кнопки Collect Ranges в инструменте или следующих командах.

converter.applySettingsFromShortcut('Range collection using double override');

% Save simulation run name generated as collect_ranges. This run name is used in
% later steps to propose fixed point data types.
collect_ranges = converter.CurrentRunName;
sim_out = converter.simulateSystem();

Постройте точность регрессии перед преобразованием.

plotRegression(sim_out, baseline_output, system_under_design, 'Regression before conversion');

Предложите типы данных с фиксированной точкой

Информация об области значений, полученная из симуляции, может использоваться Fixed-Point Tool, чтобы предложить типы данных с фиксированной точкой для блоков в системе в соответствии с проектом. В этом примере, чтобы гарантировать, что инструменты предлагают подписанные типы данных для всех блоков в подсистеме, отключают опцию ProposeSignedness в объекте ProposalSettings.

ps = DataTypeWorkflow.ProposalSettings;
ps.ProposeSignedness  = false;
converter.proposeDataTypes(collect_ranges, ps);

Примените предложенные типы данных

По умолчанию Fixed-Point Tool применяет все предложенные типы данных. Используйте метод applyDataTypes, чтобы применить типы данных. Если вы хотите только применить подмножество предложений в использовании Fixed-Point Tool флажок Accept, чтобы задать предложения, что вы хотите применяться.

converter.applyDataTypes(collect_ranges);

Проверьте типы данных

Предложенные типы должны обработать все возможные входные параметры правильно. Установите модель моделировать использование недавно прикладных типов, моделировать модель и замечать, что точность регрессии нейронной сети сохраняется преобразование фиксированной точки сообщения.

converter.applySettingsFromShortcut('Range collection with specified data types');
sim_out = converter.simulateSystem();

Постройте точность регрессии модели фиксированной точки.

plotRegression(sim_out, baseline_output, system_under_design, 'Regression after conversion');

Замените функцию активации на оптимизированную интерполяционную таблицу

Функция Активации Tanh в Слое 1 может быть заменена или интерполяционной таблицей или реализацией CORDIC для более эффективной генерации фиксированной точки. В этом примере мы будем использовать Оптимизатор Интерполяционной таблицы, чтобы получить интерполяционную таблицу как замену для tanh. Мы будем использовать EvenPow2Spacing для более быстрой скорости выполнения. Для получения дополнительной информации см. https://www.mathworks.com/help/fixedpoint/ref/functionapproximation.options-class.html.

block_path = [system_under_design '/Layer 1/tansig'];
p = FunctionApproximation.Problem(block_path);
p.Options.WordLengths = 16;
p.Options.BreakpointSpecification = 'EvenPow2Spacing';
solution  = p.solve;
solution.replaceWithApproximate;
|  ID |  Memory (bits) | Feasible | Table Size | Breakpoints WLs | TableData WL | BreakpointSpecification |             Error(Max,Current) | 
|   0 |             64 |        0 |          2 |              16 |           16 |         EvenPow2Spacing |     7.812500e-03, 1.000000e+00 |
|   1 |             96 |        0 |          4 |              16 |           16 |         EvenPow2Spacing |     7.812500e-03, 9.086914e-01 |
|   2 |            160 |        0 |          8 |              16 |           16 |         EvenPow2Spacing |     7.812500e-03, 8.392944e-01 |
|   3 |            288 |        0 |         16 |              16 |           16 |         EvenPow2Spacing |     7.812500e-03, 7.229614e-01 |
|   4 |            544 |        0 |         32 |              16 |           16 |         EvenPow2Spacing |     7.812500e-03, 5.369873e-01 |
|   5 |           1056 |        0 |         64 |              16 |           16 |         EvenPow2Spacing |     7.812500e-03, 2.825317e-01 |
|   6 |           2080 |        0 |        128 |              16 |           16 |         EvenPow2Spacing |     7.812500e-03, 8.178711e-02 |
|   7 |           4128 |        0 |        256 |              16 |           16 |         EvenPow2Spacing |     7.812500e-03, 2.331543e-02 |
|   8 |           8224 |        1 |        512 |              16 |           16 |         EvenPow2Spacing |     7.812500e-03, 5.981445e-03 |

Best Solution
|  ID |  Memory (bits) | Feasible | Table Size | Breakpoints WLs | TableData WL | BreakpointSpecification |             Error(Max,Current) |
|   8 |           8224 |        1 |        512 |              16 |           16 |         EvenPow2Spacing |     7.812500e-03, 5.981445e-03 |

Проверьте точность модели после замены приближения функций

converter.applySettingsFromShortcut(converter.ShortcutsForSelectedSystem{2});
sim_out = converter.simulateSystem;

Постройте точность регрессии.

plotRegression(sim_out, baseline_output, system_under_design, 'Regression after function replacement');

Сгенерируйте код С

Чтобы сгенерировать код С, щелкните правой кнопкой по Функции, Соответствующей подсистеме Нейронной сети, выберите C/C ++ Code> Build Subsystem, затем нажмите кнопку Build, когда запрошено настраиваемые параметры. Можно также сгенерировать код при помощи следующей команды: rtwbuild('fxpdemo_neuralnet_regression_toconvert/Function Fitting Neural Network')

Очистка

close all;
clear h1 h2 h3
clear converter collect_ranges ps
clear p solution block_path
clear yarrOut y_pred actual
clear sim_out nn_out yarr_out
close_system(model, 0);
close_system(sys_name, 0);
clear system_under_design model sys_name
clear x t net engineInputs engineTargets
clear fid
cd(current_dir);
status = rmdir(fxpnn_temp_dir, 's'); %#ok
clear fxpnn_demo_dir fxpnn_temp_dir current_dir status

Функции помощника

Создайте функцию, чтобы отобразить данные о регрессии на графике

function plotRegression(sim_out, baseline_path, neural_network_output_path, plotTitle)

    nn_out = find(sim_out.logsout, 'BlockPath', neural_network_output_path);
    yarr_out = find(sim_out.logsout, 'BlockPath', baseline_path);

    ypred = nn_out{1}.Values.Data;
    actual = yarr_out{1}.Values.Data;

    figure;
    plotregression(double(ypred), actual, plotTitle);
end