В этом примере показано, как преобразовать модель регрессии нейронной сети в 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']));
Откройте и смотрите модель.
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 | 16416 | 1 | 1024 | 16 | 16 | EvenPow2Spacing | 7.812500e-03, 1.525879e-03 | | 2 | 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) | | 2 | 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