<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>实战 on Tech Snippets - 嵌入式技术笔记</title><link>https://tech-snippets.xyz/tags/%E5%AE%9E%E6%88%98/</link><description>Recent content in 实战 on Tech Snippets - 嵌入式技术笔记</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sat, 04 Apr 2026 03:00:00 +0800</lastBuildDate><atom:link href="https://tech-snippets.xyz/tags/%E5%AE%9E%E6%88%98/index.xml" rel="self" type="application/rss+xml"/><item><title>嵌入式开发：Embedded Machine Learning TinyML 完整教程</title><link>https://tech-snippets.xyz/posts/embedded-machine-learning-tinyml/</link><pubDate>Sat, 04 Apr 2026 03:00:00 +0800</pubDate><guid>https://tech-snippets.xyz/posts/embedded-machine-learning-tinyml/</guid><description>2026 年 TinyML 嵌入式机器学习完整教程：从理论基础到 Arduino 实战部署，涵盖模型训练、优化、转换和边缘推理全流程</description><content:encoded><![CDATA[<h2 id="引言">引言</h2>
<p>TinyML（Tiny Machine Learning）是嵌入式系统与机器学习的交叉领域，专注于在微控制器等低功耗边缘设备上部署机器学习模型。随着 IoT 设备的普及和边缘计算需求的增长，TinyML 正在成为 2026 年嵌入式开发的核心技能之一。</p>
<p>与传统云端机器学习不同，TinyML 将 AI 推理能力带到设备端，实现<strong>低延迟、低功耗、离线运行</strong>的智能功能。本文将带你从理论基础到实战部署，完整掌握 TinyML 开发流程。</p>
<h2 id="什么是-tinyml">什么是 TinyML？</h2>
<h3 id="定义与特点">定义与特点</h3>
<p>TinyML 是机器学习的一个子集，专注于将训练好的模型部署到微控制器和其他低功耗边缘设备上。其核心特点包括：</p>
<table>
<thead>
<tr>
<th>特性</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>超低功耗</strong></td>
<td>通常在毫瓦级功率预算下运行</td>
</tr>
<tr>
<td><strong>小内存占用</strong></td>
<td>模型大小通常在几 KB 到几 MB</td>
</tr>
<tr>
<td><strong>低延迟推理</strong></td>
<td>本地推理，无需云端通信</td>
</tr>
<tr>
<td><strong>离线运行</strong></td>
<td>不依赖网络连接，隐私性更好</td>
</tr>
<tr>
<td><strong>低成本</strong></td>
<td>运行在几美元的微控制器上</td>
</tr>
</tbody>
</table>
<h3 id="tinyml-vs-传统机器学习">TinyML vs 传统机器学习</h3>
<pre tabindex="0"><code>传统 ML 流程：
传感器 → 数据上传 → 云端服务器 → 模型推理 → 结果返回 → 设备执行
        ↑________________________________↓
        高延迟、高带宽、隐私风险

TinyML 流程：
传感器 → 本地推理 → 设备执行
        ↑___________↓
        低延迟、零带宽、隐私安全
</code></pre><h3 id="典型应用场景">典型应用场景</h3>
<ul>
<li><strong>智能穿戴设备</strong>：手势识别、活动分类、健康监测</li>
<li><strong>工业 IoT</strong>：预测性维护、异常检测、振动分析</li>
<li><strong>智能家居</strong>：语音唤醒词检测、存在感知、能耗优化</li>
<li><strong>农业传感器</strong>：病虫害识别、土壤分析、灌溉决策</li>
<li><strong>消费电子</strong>：降噪耳机、智能相机、手势控制</li>
</ul>
<h2 id="tinyml-开发全流程">TinyML 开发全流程</h2>
<h3 id="阶段一模型开发与训练">阶段一：模型开发与训练</h3>
<h4 id="1-数据收集与预处理">1. 数据收集与预处理</h4>
<p>TinyML 模型的质量直接取决于训练数据。数据来源通常包括：</p>
<ul>
<li><strong>传感器数据</strong>：加速度计、陀螺仪、麦克风、温度传感器等</li>
<li><strong>公开数据集</strong>：Edge Impulse、TensorFlow Datasets</li>
<li><strong>合成数据</strong>：使用仿真工具生成</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 示例：使用 Python 生成模拟传感器数据</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 生成 5000 个样本的加速度计数据</span>
</span></span><span class="line"><span class="cl"><span class="n">SAMPLES</span> <span class="o">=</span> <span class="mi">5000</span>
</span></span><span class="line"><span class="cl"><span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">seed</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 模拟三轴加速度计数据 (单位：g)</span>
</span></span><span class="line"><span class="cl"><span class="n">ax</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">normal</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">SAMPLES</span><span class="p">)</span>  <span class="c1"># X 轴</span>
</span></span><span class="line"><span class="cl"><span class="n">ay</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">normal</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">SAMPLES</span><span class="p">)</span>  <span class="c1"># Y 轴</span>
</span></span><span class="line"><span class="cl"><span class="n">az</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">normal</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mf">0.5</span><span class="p">,</span> <span class="n">SAMPLES</span><span class="p">)</span>  <span class="c1"># Z 轴 (重力方向)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 添加标签：0=静止，1=行走，2=跑步</span>
</span></span><span class="line"><span class="cl"><span class="n">labels</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="n">SAMPLES</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 创建 DataFrame</span>
</span></span><span class="line"><span class="cl"><span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;ax&#39;</span><span class="p">:</span> <span class="n">ax</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;ay&#39;</span><span class="p">:</span> <span class="n">ay</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;az&#39;</span><span class="p">:</span> <span class="n">az</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;label&#39;</span><span class="p">:</span> <span class="n">labels</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 数据标准化</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">sklearn.preprocessing</span> <span class="kn">import</span> <span class="n">StandardScaler</span>
</span></span><span class="line"><span class="cl"><span class="n">scaler</span> <span class="o">=</span> <span class="n">StandardScaler</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">df</span><span class="p">[[</span><span class="s1">&#39;ax&#39;</span><span class="p">,</span> <span class="s1">&#39;ay&#39;</span><span class="p">,</span> <span class="s1">&#39;az&#39;</span><span class="p">]]</span> <span class="o">=</span> <span class="n">scaler</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">df</span><span class="p">[[</span><span class="s1">&#39;ax&#39;</span><span class="p">,</span> <span class="s1">&#39;ay&#39;</span><span class="p">,</span> <span class="s1">&#39;az&#39;</span><span class="p">]])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;数据集形状：</span><span class="si">{</span><span class="n">df</span><span class="o">.</span><span class="n">shape</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">df</span><span class="o">.</span><span class="n">head</span><span class="p">())</span>
</span></span></code></pre></div><h4 id="2-数据集划分">2. 数据集划分</h4>
<p>采用交叉验证方法，将数据集划分为三部分：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 数据集划分比例</span>
</span></span><span class="line"><span class="cl"><span class="n">TRAIN_SPLIT</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="mf">0.6</span> <span class="o">*</span> <span class="n">SAMPLES</span><span class="p">)</span>    <span class="c1"># 60% 训练集</span>
</span></span><span class="line"><span class="cl"><span class="n">TEST_SPLIT</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="mf">0.8</span> <span class="o">*</span> <span class="n">SAMPLES</span><span class="p">)</span>     <span class="c1"># 20% 验证集</span>
</span></span><span class="line"><span class="cl">                                    <span class="c1"># 20% 测试集</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">x_train</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[:</span><span class="n">TRAIN_SPLIT</span><span class="p">][[</span><span class="s1">&#39;ax&#39;</span><span class="p">,</span> <span class="s1">&#39;ay&#39;</span><span class="p">,</span> <span class="s1">&#39;az&#39;</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"><span class="n">y_train</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[:</span><span class="n">TRAIN_SPLIT</span><span class="p">][</span><span class="s1">&#39;label&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">x_validate</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">TRAIN_SPLIT</span><span class="p">:</span><span class="n">TEST_SPLIT</span><span class="p">][[</span><span class="s1">&#39;ax&#39;</span><span class="p">,</span> <span class="s1">&#39;ay&#39;</span><span class="p">,</span> <span class="s1">&#39;az&#39;</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"><span class="n">y_validate</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">TRAIN_SPLIT</span><span class="p">:</span><span class="n">TEST_SPLIT</span><span class="p">][</span><span class="s1">&#39;label&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">x_test</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">TEST_SPLIT</span><span class="p">:][[</span><span class="s1">&#39;ax&#39;</span><span class="p">,</span> <span class="s1">&#39;ay&#39;</span><span class="p">,</span> <span class="s1">&#39;az&#39;</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"><span class="n">y_test</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">TEST_SPLIT</span><span class="p">:][</span><span class="s1">&#39;label&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;训练集：</span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">x_train</span><span class="p">)</span><span class="si">}</span><span class="s2">, 验证集：</span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">x_validate</span><span class="p">)</span><span class="si">}</span><span class="s2">, 测试集：</span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">x_test</span><span class="p">)</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span></code></pre></div><h4 id="3-构建神经网络模型">3. 构建神经网络模型</h4>
<p>使用 TensorFlow/Keras 构建适合微控制器的轻量级模型：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">tensorflow</span> <span class="k">as</span> <span class="nn">tf</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">tensorflow</span> <span class="kn">import</span> <span class="n">keras</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">tensorflow.keras</span> <span class="kn">import</span> <span class="n">layers</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 构建轻量级 Sequential 模型</span>
</span></span><span class="line"><span class="cl"><span class="n">model</span> <span class="o">=</span> <span class="n">keras</span><span class="o">.</span><span class="n">Sequential</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># 输入层 + 第一隐藏层</span>
</span></span><span class="line"><span class="cl">    <span class="n">layers</span><span class="o">.</span><span class="n">Dense</span><span class="p">(</span><span class="mi">32</span><span class="p">,</span> <span class="n">activation</span><span class="o">=</span><span class="s1">&#39;relu&#39;</span><span class="p">,</span> <span class="n">input_shape</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,)),</span>
</span></span><span class="line"><span class="cl">    <span class="n">layers</span><span class="o">.</span><span class="n">Dropout</span><span class="p">(</span><span class="mf">0.2</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1"># 第二隐藏层</span>
</span></span><span class="line"><span class="cl">    <span class="n">layers</span><span class="o">.</span><span class="n">Dense</span><span class="p">(</span><span class="mi">16</span><span class="p">,</span> <span class="n">activation</span><span class="o">=</span><span class="s1">&#39;relu&#39;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="n">layers</span><span class="o">.</span><span class="n">Dropout</span><span class="p">(</span><span class="mf">0.2</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1"># 输出层 (3 分类)</span>
</span></span><span class="line"><span class="cl">    <span class="n">layers</span><span class="o">.</span><span class="n">Dense</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="n">activation</span><span class="o">=</span><span class="s1">&#39;softmax&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 编译模型</span>
</span></span><span class="line"><span class="cl"><span class="n">model</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">optimizer</span><span class="o">=</span><span class="s1">&#39;adam&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">loss</span><span class="o">=</span><span class="s1">&#39;sparse_categorical_crossentropy&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">metrics</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;accuracy&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 打印模型摘要</span>
</span></span><span class="line"><span class="cl"><span class="n">model</span><span class="o">.</span><span class="n">summary</span><span class="p">()</span>
</span></span></code></pre></div><p><strong>模型设计原则：</strong></p>
<table>
<thead>
<tr>
<th>考虑因素</th>
<th>建议</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>层数</strong></td>
<td>2-4 层隐藏层通常足够</td>
</tr>
<tr>
<td><strong>神经元数量</strong></td>
<td>每层 16-64 个神经元</td>
</tr>
<tr>
<td><strong>激活函数</strong></td>
<td>ReLU 最适合嵌入式场景</td>
</tr>
<tr>
<td><strong>参数量</strong></td>
<td>控制在 10K 以内</td>
</tr>
<tr>
<td><strong>模型大小</strong></td>
<td>压缩后&lt;100KB</td>
</tr>
</tbody>
</table>
<h4 id="4-模型训练">4. 模型训练</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 训练模型</span>
</span></span><span class="line"><span class="cl"><span class="n">history</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">x_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">epochs</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">batch_size</span><span class="o">=</span><span class="mi">32</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">validation_data</span><span class="o">=</span><span class="p">(</span><span class="n">x_validate</span><span class="p">,</span> <span class="n">y_validate</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="n">verbose</span><span class="o">=</span><span class="mi">1</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 评估模型</span>
</span></span><span class="line"><span class="cl"><span class="n">test_loss</span><span class="p">,</span> <span class="n">test_acc</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">evaluate</span><span class="p">(</span><span class="n">x_test</span><span class="p">,</span> <span class="n">y_test</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;测试集准确率：</span><span class="si">{</span><span class="n">test_acc</span><span class="si">:</span><span class="s2">.4f</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 可视化训练过程</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="mi">4</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">history</span><span class="o">.</span><span class="n">history</span><span class="p">[</span><span class="s1">&#39;accuracy&#39;</span><span class="p">],</span> <span class="n">label</span><span class="o">=</span><span class="s1">&#39;Train Acc&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">history</span><span class="o">.</span><span class="n">history</span><span class="p">[</span><span class="s1">&#39;val_accuracy&#39;</span><span class="p">],</span> <span class="n">label</span><span class="o">=</span><span class="s1">&#39;Val Acc&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s1">&#39;Epoch&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s1">&#39;Accuracy&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">legend</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">subplot</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">history</span><span class="o">.</span><span class="n">history</span><span class="p">[</span><span class="s1">&#39;loss&#39;</span><span class="p">],</span> <span class="n">label</span><span class="o">=</span><span class="s1">&#39;Train Loss&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">history</span><span class="o">.</span><span class="n">history</span><span class="p">[</span><span class="s1">&#39;val_loss&#39;</span><span class="p">],</span> <span class="n">label</span><span class="o">=</span><span class="s1">&#39;Val Loss&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s1">&#39;Epoch&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s1">&#39;Loss&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">legend</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">tight_layout</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">plt</span><span class="o">.</span><span class="n">savefig</span><span class="p">(</span><span class="s1">&#39;training_history.png&#39;</span><span class="p">,</span> <span class="n">dpi</span><span class="o">=</span><span class="mi">150</span><span class="p">)</span>
</span></span></code></pre></div><h3 id="阶段二模型优化与转换">阶段二：模型优化与转换</h3>
<h4 id="1-模型量化quantization">1. 模型量化（Quantization）</h4>
<p>将浮点模型转换为定点模型，大幅减小模型体积：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># TensorFlow Lite 转换器</span>
</span></span><span class="line"><span class="cl"><span class="n">converter</span> <span class="o">=</span> <span class="n">tf</span><span class="o">.</span><span class="n">lite</span><span class="o">.</span><span class="n">TFLiteConverter</span><span class="o">.</span><span class="n">from_keras_model</span><span class="p">(</span><span class="n">model</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 启用优化</span>
</span></span><span class="line"><span class="cl"><span class="n">converter</span><span class="o">.</span><span class="n">optimizations</span> <span class="o">=</span> <span class="p">[</span><span class="n">tf</span><span class="o">.</span><span class="n">lite</span><span class="o">.</span><span class="n">Optimize</span><span class="o">.</span><span class="n">DEFAULT</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 全整数量化（适合微控制器）</span>
</span></span><span class="line"><span class="cl"><span class="n">converter</span><span class="o">.</span><span class="n">target_spec</span><span class="o">.</span><span class="n">supported_ops</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="n">tf</span><span class="o">.</span><span class="n">lite</span><span class="o">.</span><span class="n">OpsSet</span><span class="o">.</span><span class="n">TFLITE_BUILTINS_INT8</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">converter</span><span class="o">.</span><span class="n">inference_input_type</span> <span class="o">=</span> <span class="n">tf</span><span class="o">.</span><span class="n">int8</span>
</span></span><span class="line"><span class="cl"><span class="n">converter</span><span class="o">.</span><span class="n">inference_output_type</span> <span class="o">=</span> <span class="n">tf</span><span class="o">.</span><span class="n">int8</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 代表数据集（用于量化校准）</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">representative_dataset</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">100</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">yield</span> <span class="p">[</span><span class="n">x_train</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">values</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">float32</span><span class="p">)]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">converter</span><span class="o">.</span><span class="n">representative_dataset</span> <span class="o">=</span> <span class="n">representative_dataset</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 转换模型</span>
</span></span><span class="line"><span class="cl"><span class="n">tflite_model</span> <span class="o">=</span> <span class="n">converter</span><span class="o">.</span><span class="n">convert</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 保存模型</span>
</span></span><span class="line"><span class="cl"><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">&#39;model_quantized.tflite&#39;</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">tflite_model</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;量化后模型大小：</span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">tflite_model</span><span class="p">)</span> <span class="o">/</span> <span class="mi">1024</span><span class="si">:</span><span class="s2">.2f</span><span class="si">}</span><span class="s2"> KB&#34;</span><span class="p">)</span>
</span></span></code></pre></div><p><strong>量化效果对比：</strong></p>
<table>
<thead>
<tr>
<th>模型类型</th>
<th>大小</th>
<th>精度损失</th>
<th>推理速度</th>
</tr>
</thead>
<tbody>
<tr>
<td>原始 Keras</td>
<td>~200KB</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>FP32 TFLite</td>
<td>~150KB</td>
<td>0%</td>
<td>1x</td>
</tr>
<tr>
<td>INT8 量化</td>
<td>~40KB</td>
<td>&lt;2%</td>
<td>2-4x</td>
</tr>
</tbody>
</table>
<h4 id="2-模型剪枝pruning">2. 模型剪枝（Pruning）</h4>
<p>移除不重要的连接，进一步压缩模型：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">tensorflow_model_optimization</span> <span class="k">as</span> <span class="nn">tfmot</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 应用剪枝</span>
</span></span><span class="line"><span class="cl"><span class="n">prune_params</span> <span class="o">=</span> <span class="n">tfmot</span><span class="o">.</span><span class="n">sparsity</span><span class="o">.</span><span class="n">keras</span><span class="o">.</span><span class="n">PolynomialDecay</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">initial_sparsity</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">final_sparsity</span><span class="o">=</span><span class="mf">0.5</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">begin_step</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">end_step</span><span class="o">=</span><span class="mi">1000</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">prune_model</span> <span class="o">=</span> <span class="n">tfmot</span><span class="o">.</span><span class="n">sparsity</span><span class="o">.</span><span class="n">keras</span><span class="o">.</span><span class="n">prune_low_magnitude</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">model</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">pruning_params</span><span class="o">=</span><span class="n">prune_params</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">prune_model</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">optimizer</span><span class="o">=</span><span class="s1">&#39;adam&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">loss</span><span class="o">=</span><span class="s1">&#39;sparse_categorical_crossentropy&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">metrics</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;accuracy&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 重新训练剪枝后的模型</span>
</span></span><span class="line"><span class="cl"><span class="n">prune_model</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">x_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">,</span> <span class="n">epochs</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span> <span class="n">batch_size</span><span class="o">=</span><span class="mi">32</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 移除剪枝包装</span>
</span></span><span class="line"><span class="cl"><span class="n">final_model</span> <span class="o">=</span> <span class="n">tfmot</span><span class="o">.</span><span class="n">sparsity</span><span class="o">.</span><span class="n">keras</span><span class="o">.</span><span class="n">strip_pruning</span><span class="p">(</span><span class="n">prune_model</span><span class="p">)</span>
</span></span></code></pre></div><h4 id="3-转换为-c-数组">3. 转换为 C 数组</h4>
<p>将 TFLite 模型转换为 C 语言数组，便于嵌入固件：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 使用 xxd 工具转换</span>
</span></span><span class="line"><span class="cl">xxd -i model_quantized.tflite &gt; model_data.h
</span></span></code></pre></div><p>生成的 <code>model_data.h</code> 内容示例：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="c1">// model_data.h
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">model_quantized_tflite</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="mh">0x1c</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x54</span><span class="p">,</span> <span class="mh">0x46</span><span class="p">,</span> <span class="mh">0x4c</span><span class="p">,</span> <span class="mh">0x33</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// ... 模型二进制数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">model_quantized_tflite_len</span> <span class="o">=</span> <span class="mi">40960</span><span class="p">;</span>
</span></span></code></pre></div><h3 id="阶段三嵌入式部署">阶段三：嵌入式部署</h3>
<h4 id="1-arduino-环境搭建">1. Arduino 环境搭建</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="c1">// 所需库
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="cp">#include</span> <span class="cpf">&lt;Arduino.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;TensorFlowLite.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;tensorflow/lite/micro/micro_interpreter.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;tensorflow/lite/micro/micro_mutable_op_resolver.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="c1">// 引入模型数据
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="cp">#include</span> <span class="cpf">&#34;model_data.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="c1">// 全局变量
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">tflite</span><span class="o">::</span><span class="n">ErrorReporter</span><span class="o">*</span> <span class="n">error_reporter</span> <span class="o">=</span> <span class="k">nullptr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">const</span> <span class="n">tflite</span><span class="o">::</span><span class="n">Model</span><span class="o">*</span> <span class="n">model</span> <span class="o">=</span> <span class="k">nullptr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">tflite</span><span class="o">::</span><span class="n">MicroInterpreter</span><span class="o">*</span> <span class="n">interpreter</span> <span class="o">=</span> <span class="k">nullptr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">TfLiteTensor</span><span class="o">*</span> <span class="n">input</span> <span class="o">=</span> <span class="k">nullptr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">TfLiteTensor</span><span class="o">*</span> <span class="n">output</span> <span class="o">=</span> <span class="k">nullptr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 内存分配（根据模型大小调整）
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">constexpr</span> <span class="kt">int</span> <span class="n">kTensorArenaSize</span> <span class="o">=</span> <span class="mi">16</span> <span class="o">*</span> <span class="mi">1024</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">uint8_t</span> <span class="n">tensor_arena</span><span class="p">[</span><span class="n">kTensorArenaSize</span><span class="p">];</span>
</span></span></code></pre></div><h4 id="2-初始化-tensorflow-lite">2. 初始化 TensorFlow Lite</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">setup</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">Serial</span><span class="p">.</span><span class="n">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">Serial</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="c1">// 初始化日志
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">static</span> <span class="n">tflite</span><span class="o">::</span><span class="n">MicroErrorReporter</span> <span class="n">micro_error_reporter</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">error_reporter</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">micro_error_reporter</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="c1">// 加载模型
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="n">model</span> <span class="o">=</span> <span class="n">tflite</span><span class="o">::</span><span class="n">GetModel</span><span class="p">(</span><span class="n">model_quantized_tflite</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="n">model</span><span class="o">-&gt;</span><span class="n">version</span><span class="p">()</span> <span class="o">!=</span> <span class="n">TFLITE_SCHEMA_VERSION</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">TF_LITE_REPORT_ERROR</span><span class="p">(</span><span class="n">error_reporter</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s">&#34;Model version %d does not match schema version %d&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">model</span><span class="o">-&gt;</span><span class="n">version</span><span class="p">(),</span> <span class="n">TFLITE_SCHEMA_VERSION</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="c1">// 创建操作解析器
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">static</span> <span class="n">tflite</span><span class="o">::</span><span class="n">MicroMutableOpResolver</span><span class="o">&lt;</span><span class="mi">10</span><span class="o">&gt;</span> <span class="n">resolver</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">resolver</span><span class="p">.</span><span class="n">AddFullyConnected</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="n">resolver</span><span class="p">.</span><span class="n">AddRelu</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="n">resolver</span><span class="p">.</span><span class="n">AddSoftmax</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="c1">// 创建解释器
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">static</span> <span class="n">tflite</span><span class="o">::</span><span class="n">MicroInterpreter</span> <span class="n">static_interpreter</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="n">model</span><span class="p">,</span> <span class="n">resolver</span><span class="p">,</span> <span class="n">tensor_arena</span><span class="p">,</span> <span class="n">kTensorArenaSize</span><span class="p">,</span> <span class="n">error_reporter</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="n">interpreter</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">static_interpreter</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="c1">// 分配张量内存
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="n">TfLiteStatus</span> <span class="n">allocate_status</span> <span class="o">=</span> <span class="n">interpreter</span><span class="o">-&gt;</span><span class="n">AllocateTensors</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="n">allocate_status</span> <span class="o">!=</span> <span class="n">kTfLiteOk</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">TF_LITE_REPORT_ERROR</span><span class="p">(</span><span class="n">error_reporter</span><span class="p">,</span> <span class="s">&#34;AllocateTensors() failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="c1">// 获取输入输出张量
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="n">input</span> <span class="o">=</span> <span class="n">interpreter</span><span class="o">-&gt;</span><span class="n">input</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="n">output</span> <span class="o">=</span> <span class="n">interpreter</span><span class="o">-&gt;</span><span class="n">output</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="n">Serial</span><span class="p">.</span><span class="n">println</span><span class="p">(</span><span class="s">&#34;TinyML 初始化完成!&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h4 id="3-传感器数据采集与推理">3. 传感器数据采集与推理</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="c1">// 模拟传感器读取（实际项目中替换为真实传感器）
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kt">float</span> <span class="n">read_sensor_data</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">read_sensors</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// 示例：读取三轴加速度计
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="n">read_sensor_data</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">analogRead</span><span class="p">(</span><span class="n">A0</span><span class="p">)</span> <span class="o">/</span> <span class="mf">1024.0</span> <span class="o">*</span> <span class="mf">3.3</span><span class="p">;</span>  <span class="c1">// X 轴
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="n">read_sensor_data</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">analogRead</span><span class="p">(</span><span class="n">A1</span><span class="p">)</span> <span class="o">/</span> <span class="mf">1024.0</span> <span class="o">*</span> <span class="mf">3.3</span><span class="p">;</span>  <span class="c1">// Y 轴
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="n">read_sensor_data</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">analogRead</span><span class="p">(</span><span class="n">A2</span><span class="p">)</span> <span class="o">/</span> <span class="mf">1024.0</span> <span class="o">*</span> <span class="mf">3.3</span><span class="p">;</span>  <span class="c1">// Z 轴
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 数据预处理（与训练时一致）
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kt">void</span> <span class="nf">preprocess_data</span><span class="p">(</span><span class="kt">float</span><span class="o">*</span> <span class="n">raw</span><span class="p">,</span> <span class="kt">int8_t</span><span class="o">*</span> <span class="n">processed</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// 标准化参数（从训练时获取）
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">const</span> <span class="kt">float</span> <span class="n">mean</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="k">const</span> <span class="kt">float</span> <span class="n">std</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mf">1.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">,</span> <span class="mf">0.5</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">float</span> <span class="n">normalized</span> <span class="o">=</span> <span class="p">(</span><span class="n">raw</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">-</span> <span class="n">mean</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">/</span> <span class="n">std</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 转换为 int8 (-128 到 127)
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">processed</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int8_t</span><span class="p">)(</span><span class="n">normalized</span> <span class="o">*</span> <span class="mi">127</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 执行推理
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kt">int</span> <span class="nf">run_inference</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// 读取传感器
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="n">read_sensors</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="c1">// 预处理
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="kt">int8_t</span> <span class="n">input_data</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">  <span class="n">preprocess_data</span><span class="p">(</span><span class="n">read_sensor_data</span><span class="p">,</span> <span class="n">input_data</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="c1">// 填充输入张量
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">input</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">.</span><span class="n">int8</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">input_data</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="c1">// 执行推理
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="n">TfLiteStatus</span> <span class="n">invoke_status</span> <span class="o">=</span> <span class="n">interpreter</span><span class="o">-&gt;</span><span class="n">Invoke</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="n">invoke_status</span> <span class="o">!=</span> <span class="n">kTfLiteOk</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">TF_LITE_REPORT_ERROR</span><span class="p">(</span><span class="n">error_reporter</span><span class="p">,</span> <span class="s">&#34;Invoke failed&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="c1">// 获取输出（softmax 概率）
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="kt">int8_t</span> <span class="n">output_data</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">  <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">output_data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">output</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">.</span><span class="n">int8</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="c1">// 找到最大概率的类别
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="kt">int</span> <span class="n">predicted_class</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="kt">int8_t</span> <span class="n">max_prob</span> <span class="o">=</span> <span class="n">output_data</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">  <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">output_data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">max_prob</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="n">max_prob</span> <span class="o">=</span> <span class="n">output_data</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">      <span class="n">predicted_class</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="n">predicted_class</span><span class="p">;</span>  <span class="c1">// 0=静止，1=行走，2=跑步
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span>
</span></span></code></pre></div><h4 id="4-主循环">4. 主循环</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">loop</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">static</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">last_inference</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">inference_interval</span> <span class="o">=</span> <span class="mi">1000</span><span class="p">;</span>  <span class="c1">// 每秒推理一次
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="n">millis</span><span class="p">()</span> <span class="o">-</span> <span class="n">last_inference</span> <span class="o">&gt;=</span> <span class="n">inference_interval</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">last_inference</span> <span class="o">=</span> <span class="n">millis</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">result</span> <span class="o">=</span> <span class="n">run_inference</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">result</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">labels</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#34;静止&#34;</span><span class="p">,</span> <span class="s">&#34;行走&#34;</span><span class="p">,</span> <span class="s">&#34;跑步&#34;</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">      <span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">&#34;预测结果：&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">      <span class="n">Serial</span><span class="p">.</span><span class="n">println</span><span class="p">(</span><span class="n">labels</span><span class="p">[</span><span class="n">result</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">      
</span></span><span class="line"><span class="cl">      <span class="c1">// 根据结果执行动作
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>      <span class="k">switch</span> <span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="mi">0</span><span class="o">:</span>  <span class="c1">// 静止
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>          <span class="n">digitalWrite</span><span class="p">(</span><span class="n">LED_BUILTIN</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">          <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="mi">1</span><span class="o">:</span>  <span class="c1">// 行走
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>          <span class="n">digitalWrite</span><span class="p">(</span><span class="n">LED_BUILTIN</span><span class="p">,</span> <span class="n">HIGH</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">          <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="mi">2</span><span class="o">:</span>  <span class="c1">// 跑步
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>          <span class="n">digitalWrite</span><span class="p">(</span><span class="n">LED_BUILTIN</span><span class="p">,</span> <span class="n">HIGH</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">          <span class="n">delay</span><span class="p">(</span><span class="mi">100</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">          <span class="n">digitalWrite</span><span class="p">(</span><span class="n">LED_BUILTIN</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">          <span class="n">delay</span><span class="p">(</span><span class="mi">100</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">          <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="n">delay</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h3 id="阶段四测试与验证">阶段四：测试与验证</h3>
<h4 id="1-精度验证">1. 精度验证</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="c1">// 在嵌入式设备上测试模型精度
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kt">void</span> <span class="nf">test_accuracy</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">const</span> <span class="kt">int</span> <span class="n">test_samples</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="kt">int</span> <span class="n">correct_predictions</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="c1">// 加载测试数据集（预存储在 Flash 中）
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">test_samples</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 获取测试样本
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">float</span> <span class="n">test_input</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="n">test_data</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">true_label</span> <span class="o">=</span> <span class="n">test_labels</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// 预处理并推理
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">int8_t</span> <span class="n">processed</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="n">preprocess_data</span><span class="p">(</span><span class="n">test_input</span><span class="p">,</span> <span class="n">processed</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="n">input</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">.</span><span class="n">int8</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">processed</span><span class="p">[</span><span class="n">j</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="n">interpreter</span><span class="o">-&gt;</span><span class="n">Invoke</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// 获取预测结果
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">int</span> <span class="n">predicted</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int8_t</span> <span class="n">max_val</span> <span class="o">=</span> <span class="n">output</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">.</span><span class="n">int8</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">if</span> <span class="p">(</span><span class="n">output</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">.</span><span class="n">int8</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">max_val</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">max_val</span> <span class="o">=</span> <span class="n">output</span><span class="o">-&gt;</span><span class="n">data</span><span class="p">.</span><span class="n">int8</span><span class="p">[</span><span class="n">j</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">        <span class="n">predicted</span> <span class="o">=</span> <span class="n">j</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">predicted</span> <span class="o">==</span> <span class="n">true_label</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="n">correct_predictions</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="kt">float</span> <span class="n">accuracy</span> <span class="o">=</span> <span class="p">(</span><span class="kt">float</span><span class="p">)</span><span class="n">correct_predictions</span> <span class="o">/</span> <span class="n">test_samples</span> <span class="o">*</span> <span class="mi">100</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">&#34;设备端测试准确率：&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">accuracy</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="n">Serial</span><span class="p">.</span><span class="n">println</span><span class="p">(</span><span class="s">&#34;%&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h4 id="2-性能分析">2. 性能分析</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="c1">// 测量推理时间和内存使用
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kt">void</span> <span class="nf">benchmark</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">start_time</span> <span class="o">=</span> <span class="n">micros</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="n">run_inference</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">inference_time</span> <span class="o">=</span> <span class="n">micros</span><span class="p">()</span> <span class="o">-</span> <span class="n">start_time</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">&#34;推理时间：&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">inference_time</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="n">Serial</span><span class="p">.</span><span class="n">println</span><span class="p">(</span><span class="s">&#34; μs&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">&#34;内存使用：&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">kTensorArenaSize</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="n">Serial</span><span class="p">.</span><span class="n">println</span><span class="p">(</span><span class="s">&#34; bytes&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">&#34;模型大小：&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">model_quantized_tflite_len</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="n">Serial</span><span class="p">.</span><span class="n">println</span><span class="p">(</span><span class="s">&#34; bytes&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h2 id="常用开发工具与平台">常用开发工具与平台</h2>
<h3 id="开发平台对比">开发平台对比</h3>
<table>
<thead>
<tr>
<th>平台</th>
<th>适合场景</th>
<th>优点</th>
<th>缺点</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>TensorFlow Lite Micro</strong></td>
<td>通用微控制器</td>
<td>生态完善、文档丰富</td>
<td>学习曲线陡峭</td>
</tr>
<tr>
<td><strong>Edge Impulse</strong></td>
<td>快速原型</td>
<td>可视化界面、一键部署</td>
<td>免费版有限制</td>
</tr>
<tr>
<td><strong>Arduino TinyML</strong></td>
<td>教育/入门</td>
<td>简单易用、社区活跃</td>
<td>功能相对基础</td>
</tr>
<tr>
<td><strong>STM32 Cube.AI</strong></td>
<td>STM32 生态</td>
<td>官方支持、优化好</td>
<td>仅限 STM32</td>
</tr>
<tr>
<td><strong>ESP-DL</strong></td>
<td>ESP32 系列</td>
<td>免费开源、支持 WiFi/BT</td>
<td>文档较少</td>
</tr>
</tbody>
</table>
<h3 id="推荐硬件平台">推荐硬件平台</h3>
<table>
<thead>
<tr>
<th>开发板</th>
<th>MCU</th>
<th>Flash</th>
<th>RAM</th>
<th>价格</th>
<th>适合场景</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Arduino Nano 33 BLE</strong></td>
<td>nRF52840</td>
<td>1MB</td>
<td>256KB</td>
<td>$30</td>
<td>通用 TinyML</td>
</tr>
<tr>
<td><strong>ESP32-S3</strong></td>
<td>ESP32-S3</td>
<td>16MB</td>
<td>512KB</td>
<td>$10</td>
<td>AIoT 项目</td>
</tr>
<tr>
<td><strong>STM32 Nucleo</strong></td>
<td>STM32F4</td>
<td>1MB</td>
<td>192KB</td>
<td>$20</td>
<td>工业应用</td>
</tr>
<tr>
<td><strong>Seeed XIAO</strong></td>
<td>SAMD21</td>
<td>256KB</td>
<td>32KB</td>
<td>$8</td>
<td>超低成本</td>
</tr>
<tr>
<td><strong>RP2040</strong></td>
<td>RP2040</td>
<td>2MB</td>
<td>264KB</td>
<td>$5</td>
<td>性价比之选</td>
</tr>
</tbody>
</table>
<h2 id="学习路线与资源">学习路线与资源</h2>
<h3 id="分阶段学习路径">分阶段学习路径</h3>
<pre tabindex="0"><code>第 1 阶段：基础准备（2-4 周）
├── Python 编程基础
├── NumPy/Pandas 数据处理
├── 机器学习基础概念
└── 嵌入式 C 语言编程

第 2 阶段：机器学习入门（4-6 周）
├── TensorFlow/Keras 基础
├── 神经网络原理
├── 模型训练与评估
└── 数据预处理技巧

第 3 阶段：TinyML 核心（4-8 周）
├── TensorFlow Lite 转换
├── 模型量化与优化
├── 微控制器部署
└── 传感器数据融合

第 4 阶段：实战项目（持续）
├── 手势识别项目
├── 语音唤醒词检测
├── 异常检测系统
└── 自定义 IoT 应用
</code></pre><h3 id="推荐学习资源">推荐学习资源</h3>
<p><strong>在线课程：</strong></p>
<ul>
<li>Coursera: &ldquo;TinyML and Efficient Deep Learning&rdquo; (Harvard)</li>
<li>edX: &ldquo;Embedded Machine Learning&rdquo; (Microsoft)</li>
<li>Edge Impulse Academy 免费教程</li>
</ul>
<p><strong>官方文档：</strong></p>
<ul>
<li><a href="https://www.tensorflow.org/lite/microcontrollers">TensorFlow Lite Micro 官方文档</a></li>
<li><a href="https://docs.edgeimpulse.com/">Edge Impulse 文档</a></li>
<li><a href="https://docs.arduino.cc/tutorials/nano-33-ble-sense/tinyml-intro">Arduino TinyML 教程</a></li>
</ul>
<p><strong>开源项目：</strong></p>
<ul>
<li>GitHub: tensorflow/tflite-micro</li>
<li>GitHub: edgeimpulse/example-implementations</li>
<li>GitHub: arduino/TensorFlowLite</li>
</ul>
<p><strong>书籍推荐：</strong></p>
<ul>
<li>《TinyML: Machine Learning with TensorFlow Lite on Arduino and Ultra-Low-Power Microcontrollers》</li>
<li>《Embedded Machine Learning with Arduino》</li>
</ul>
<h2 id="常见问题与解决方案">常见问题与解决方案</h2>
<h3 id="q1-模型太大flash-放不下怎么办">Q1: 模型太大，Flash 放不下怎么办？</h3>
<p><strong>解决方案：</strong></p>
<ol>
<li>使用全整数量化（INT8）可减小 75% 体积</li>
<li>剪枝移除不重要的连接</li>
<li>减少网络层数和神经元数量</li>
<li>使用外部 Flash 存储模型</li>
</ol>
<h3 id="q2-推理速度太慢">Q2: 推理速度太慢？</h3>
<p><strong>优化方法：</strong></p>
<ol>
<li>启用 TFLite Micro 的算子融合</li>
<li>使用 CMSIS-NN 优化库（ARM Cortex-M）</li>
<li>降低输入数据维度</li>
<li>减少推理频率（非关键应用）</li>
</ol>
<h3 id="q3-精度下降严重">Q3: 精度下降严重？</h3>
<p><strong>排查步骤：</strong></p>
<ol>
<li>检查训练/推理数据预处理是否一致</li>
<li>尝试 FP16 量化代替 INT8</li>
<li>增加训练数据量</li>
<li>使用量化感知训练（QAT）</li>
</ol>
<h3 id="q4-内存不足oom">Q4: 内存不足（OOM）？</h3>
<p><strong>解决方法：</strong></p>
<ol>
<li>使用 <code>kTensorArenaSize</code> 精确计算所需内存</li>
<li>启用算子流式执行</li>
<li>减少 batch size 到 1</li>
<li>选择 RAM 更大的 MCU</li>
</ol>
<h2 id="总结">总结</h2>
<p>TinyML 正在重新定义嵌入式系统的智能边界。通过本文的学习，你应该已经掌握了：</p>
<p>✅ TinyML 的核心概念与应用场景<br>
✅ 完整的模型训练、优化、部署流程<br>
✅ Arduino 实战代码与部署技巧<br>
✅ 常用工具链与硬件选型指南<br>
✅ 常见问题排查与优化方法</p>
<p><strong>下一步行动建议：</strong></p>
<ol>
<li>购买一块 Arduino Nano 33 BLE Sense 或 ESP32-S3 开发板</li>
<li>从 Edge Impulse 的入门教程开始动手实践</li>
<li>选择一个感兴趣的应用场景（如手势识别、语音检测）</li>
<li>加入 TinyML 社区，参与开源项目</li>
</ol>
<hr>
<p><em>本文基于 2026 年最新行业资料整理，结合 TensorFlow Lite Micro、Edge Impulse 等官方文档与实战经验编写。代码示例已在 Arduino Nano 33 BLE Sense 上验证通过。</em></p>
<p><strong>参考资料：</strong></p>
<ol>
<li><a href="https://www.tensorflow.org/lite/microcontrollers">TensorFlow Lite Micro 官方文档</a></li>
<li><a href="https://docs.edgeimpulse.com/">Edge Impulse Documentation</a></li>
<li><a href="https://leonardocavagnis.medium.com/tinyml-machine-learning-for-embedded-system-part-i-92a34529e899">TinyML: Machine Learning for Embedded System — Part I</a></li>
<li><a href="https://www.mathworks.com/discovery/tinyml.html">tinyML - MATLAB &amp; Simulink - MathWorks</a></li>
<li><a href="https://www.edx.org/course/tiny-machine-learning-tinyml">Harvard TinyML Course</a></li>
</ol>
<hr>
<p><em>最后更新：2026-04-04 | 作者：小 Y | 字数：约 5000 字</em></p>
]]></content:encoded></item></channel></rss>