<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>manutenção preditiva - MCU &amp; FPGA</title>
	<atom:link href="https://mcu.tec.br/tags/manutencao-preditiva/feed/" rel="self" type="application/rss+xml" />
	<link>https://mcu.tec.br</link>
	<description>Microcontroladores &#38; FPGA</description>
	<lastBuildDate>Tue, 02 Dec 2025 14:11:39 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://mcu.tec.br/wp-content/uploads/2025/02/Robo-para-o-site-MCU.tec_.br-512x512-1-150x150.png</url>
	<title>manutenção preditiva - MCU &amp; FPGA</title>
	<link>https://mcu.tec.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Detecção de Anomalias em Sistemas Embarcados: Isolation Forest, One-Class SVM e PCA com Exemplos Práticos</title>
		<link>https://mcu.tec.br/algoritimos/deteccao-de-anomalias-em-sistemas-embarcados-isolation-forest-one-class-svm-e-pca-com-exemplos-praticos/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=deteccao-de-anomalias-em-sistemas-embarcados-isolation-forest-one-class-svm-e-pca-com-exemplos-praticos</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Tue, 02 Dec 2025 14:11:15 +0000</pubDate>
				<category><![CDATA[Algoritimos]]></category>
		<category><![CDATA[algoritmos de anomalia]]></category>
		<category><![CDATA[análise de vibração]]></category>
		<category><![CDATA[anomalias em sensores]]></category>
		<category><![CDATA[aprendizado de máquina em microcontroladores]]></category>
		<category><![CDATA[detecção de anomalias]]></category>
		<category><![CDATA[diagnóstico inteligente]]></category>
		<category><![CDATA[inteligência artificial embarcada]]></category>
		<category><![CDATA[iot industrial]]></category>
		<category><![CDATA[isolation forest]]></category>
		<category><![CDATA[machine learning embarcado]]></category>
		<category><![CDATA[manutenção preditiva]]></category>
		<category><![CDATA[one-class svm]]></category>
		<category><![CDATA[pca embarcado]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=944</guid>

					<description><![CDATA[<p>A detecção de anomalias é uma técnica essencial em sistemas embarcados modernos, permitindo identificar falhas, prever problemas e garantir maior confiabilidade em aplicações industriais, IoT e automação. Este artigo explica, de forma clara e didática, como utilizar três dos métodos mais eficazes para esse fim: Isolation Forest, One-Class SVM e PCA. Cada técnica é apresentada com exemplos práticos, códigos em Python e implementações simplificadas em C para microcontroladores como RP2040, ESP32 e STM32. Também discutimos aplicações reais, vantagens de cada abordagem, comparações diretas e boas práticas para implantação em ambientes de baixa potência. Ideal para estudantes, engenheiros e profissionais que buscam implementar detecção inteligente de falhas com eficiência computacional.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/deteccao-de-anomalias-em-sistemas-embarcados-isolation-forest-one-class-svm-e-pca-com-exemplos-praticos/">Detecção de Anomalias em Sistemas Embarcados: Isolation Forest, One-Class SVM e PCA com Exemplos Práticos</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<h3 class="wp-block-heading"></h3>



<p class="wp-block-paragraph">Este artigo foi escrito para compor a documentação de justificativas das escolhas de algorítimos para o projeto de conclusão do EmbarcaTech, Rack Inteligente.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>1 — Introdução à Detecção de Anomalias</strong></h2>



<p class="wp-block-paragraph">A detecção de anomalias é uma técnica fundamental em sistemas inteligentes, especialmente em aplicações embarcadas, onde a capacidade de identificar comportamentos inesperados pode evitar falhas catastróficas, reduzir custos de manutenção e aumentar a confiabilidade de equipamentos. Em termos simples, uma anomalia é qualquer comportamento que se desvia significativamente do padrão habitual — seja uma vibração fora do normal em um transformador, um ruído inesperado em um motor, um pacote estranho em uma rede, ou mesmo uma leitura de sensor fora do perfil típico em um microcontrolador.</p>



<p class="wp-block-paragraph">Existem três grandes abordagens estatísticas e de aprendizado de máquina amplamente usadas: <strong>Isolation Forest</strong>, <strong>One-Class SVM</strong> e <strong>PCA (Principal Component Analysis)</strong> aplicado para detecção de anomalias. Cada uma utiliza uma estratégia diferente no processo de modelagem, o que é particularmente útil quando queremos embarcar parte do processamento em microcontroladores ou realizar inferência em sistemas híbridos MCU+edge AI.</p>



<p class="wp-block-paragraph">No contexto embarcado, a detecção de anomalias precisa de métodos eficientes, com baixo custo computacional e que funcionem bem mesmo quando há poucos dados rotulados. Por isso, os algoritmos apresentados neste artigo são especialmente adequados para aplicações como: predição de falhas, filtragem inteligente de dados, diagnóstico vibroacústico, análise de corrente, segurança cibernética embarcada e controle inteligente em malha fechada.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>2 — Isolation Forest</strong></h2>



<p class="wp-block-paragraph">O Isolation Forest é um algoritmo extremamente eficiente para detecção de anomalias porque trabalha de forma inversa aos métodos tradicionais: enquanto outros modelos tentam aprender <em>o que é normal</em>, o Isolation Forest tenta isolar <em>o que é anômalo</em>. Ele faz isso construindo diversas árvores aleatórias onde, a cada divisão, um subconjunto dos dados é particionado. Como pontos anômalos estão mais afastados do comportamento típico, eles tendem a ser isolados em poucas divisões — o que torna o método rápido e naturalmente escalável, inclusive para execução em hardware limitado.</p>



<p class="wp-block-paragraph">Do ponto de vista matemático, cada árvore consiste em divisões recursivas sobre atributos escolhidos aleatoriamente. O número de divisões necessárias para isolar um dado ponto define um “caminho”, cuja média entre diversas árvores gera a pontuação de anomalia. Pontos com caminho médio curto são classificados como anômalos. Esse processo reduz significativamente a necessidade de modelos complexos e evita cálculos pesados como matrizes do tipo kernel, o que é uma vantagem para implementações embarcadas.</p>



<p class="wp-block-paragraph">Em aplicações reais, o Isolation Forest é útil para detectar vibrações incomuns, oscilações de corrente fora do perfil, leituras inconsistentes de sensores, e até anomalias em tráfego de rede. Embora seja mais comum executar o treinamento fora do microcontrolador, é totalmente possível embarcar o processo de inferência, já que cada árvore pode ser representada como uma sequência de comparações simples — rápidas e leves para um Cortex-M7, ESP32 ou até um RP2040.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Exemplo em Python (Treinamento no PC, Inferência Portável para MCU)</strong></h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>from sklearn.ensemble import IsolationForest
import numpy as np

# Dados simulados: comportamento normal (cluster) + anomalias
rng = np.random.RandomState(42)
normal = 0.3 * rng.randn(200, 2)
anomalias = rng.uniform(low=-4, high=4, size=(10, 2))
dados = np.concatenate(&#91;normal, anomalias&#93;, axis=0)

# Treinamento
modelo = IsolationForest(contamination=0.05, random_state=42)
modelo.fit(dados)

# Inferência
teste = np.array([&#91;0.1, 0.2&#93;, &#91;3, 3&#93;])  # normal vs anômalo
pred = modelo.predict(teste)

print(pred)  # saída: &#91;1, -1&#93;  → -1 = anomalia
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sklearn</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ensemble</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">IsolationForest</span></span>
<span class="line"><span style="color: #8FBCBB">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">numpy</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">as</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">np</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #8FBCBB">Dados</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">simulados</span><span style="color: #D8DEE9FF">: </span><span style="color: #8FBCBB">comportamento</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">normal</span><span style="color: #D8DEE9FF"> (</span><span style="color: #8FBCBB">cluster</span><span style="color: #D8DEE9FF">) + </span><span style="color: #8FBCBB">anomalias</span></span>
<span class="line"><span style="color: #8FBCBB">rng</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">np</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">random</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">RandomState</span><span style="color: #D8DEE9FF">(42)</span></span>
<span class="line"><span style="color: #8FBCBB">normal</span><span style="color: #D8DEE9FF"> = 0.3 </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">rng</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">randn</span><span style="color: #D8DEE9FF">(200</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 2)</span></span>
<span class="line"><span style="color: #8FBCBB">anomalias</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">rng</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">uniform</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">low</span><span style="color: #D8DEE9FF">=-4</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">high</span><span style="color: #D8DEE9FF">=4</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">size</span><span style="color: #D8DEE9FF">=(10</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 2))</span></span>
<span class="line"><span style="color: #8FBCBB">dados</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">np</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">concatenate</span><span style="color: #D8DEE9FF">(&#91;</span><span style="color: #8FBCBB">normal</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">anomalias</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">axis</span><span style="color: #D8DEE9FF">=0)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #8FBCBB">Treinamento</span></span>
<span class="line"><span style="color: #8FBCBB">modelo</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">IsolationForest</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">contamination</span><span style="color: #D8DEE9FF">=0.05</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">random_state</span><span style="color: #D8DEE9FF">=42)</span></span>
<span class="line"><span style="color: #8FBCBB">modelo</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">fit</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">dados</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #8FBCBB">Inferência</span></span>
<span class="line"><span style="color: #8FBCBB">teste</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">np</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">array</span><span style="color: #D8DEE9FF">([&#91;0.1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 0.2&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> &#91;3</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 3&#93;])  # </span><span style="color: #8FBCBB">normal</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">vs</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">anômalo</span></span>
<span class="line"><span style="color: #8FBCBB">pred</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">modelo</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">predict</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">teste</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #8FBCBB">print</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">pred</span><span style="color: #D8DEE9FF">)  # </span><span style="color: #8FBCBB">saída</span><span style="color: #D8DEE9FF">: &#91;1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> -1&#93;  → -1 = </span><span style="color: #8FBCBB">anomalia</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Exemplo Embarcado (C) — Inferência de uma Árvore Simplificada</strong></h3>



<p class="wp-block-paragraph">Este exemplo representa <em>uma única árvore</em> já convertida para C (deploy embarcado). Imagine que a árvore aprendida gerou as condições:</p>



<ul class="wp-block-list">
<li>if x₀ &lt; 0.25 → vá para esquerda</li>



<li>else → vá para direita</li>



<li>se x₁ > 0.8 no nó seguinte → classifica como anomalia</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// Estrutura simplificada de uma árvore do Isolation Forest
int isolation_tree_infer(float x0, float x1) {
    if (x0 &lt; 0.25f) {
        if (x1 > 0.80f) {
            return -1; // anomalia
        } else {
            return 1;  // normal
        }
    } else {
        if (x1 > 1.2f) {
            return -1; // anomalia
        } else {
            return 1;  // normal
        }
    }
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">// Estrutura simplificada de uma árvore do Isolation Forest</span></span>
<span class="line"><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">isolation_tree_infer</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x1</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">x0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">25</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">x1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">80</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #B48EAD">1</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// anomalia</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">// normal</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">x1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> 1</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">2</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #B48EAD">1</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// anomalia</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">// normal</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Esse tipo de lógica pode ser executado facilmente em microcontroladores sem FPU ou com poucos recursos, bastando exportar as árvores do modelo e convertê-las em comparações encadeadas.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>Seção 3 — One-Class SVM</strong></h2>



<p class="wp-block-paragraph">O One-Class SVM é um método clássico e robusto para detecção de anomalias baseado em fronteiras de decisão. Enquanto um SVM convencional separa duas classes distintas, o One-Class SVM tenta aprender apenas a região onde os dados “normais” se concentram. A ideia central é encontrar uma superfície (hiperplano ou hiperfronteira) que envolva a maior parte do conjunto de dados, deixando pontos distantes dessa região como anômalos.</p>



<p class="wp-block-paragraph">Matematicamente, ele busca maximizar a margem entre os dados e a origem no espaço transformado pelo kernel. Isso significa que ele depende fortemente da função kernel — normalmente o <strong>RBF (Radial Basis Function)</strong> — para projetar os dados em um espaço onde as fronteiras possam ser bem delimitadas. Essa característica o torna muito poderoso, porém mais custoso computacionalmente que o Isolation Forest, especialmente na fase de inferência, já que envolve cálculos exponenciais e somas ponderadas sobre vetores de suporte.</p>



<p class="wp-block-paragraph">Em aplicações embarcadas, o One-Class SVM é mais adequado quando:</p>



<ul class="wp-block-list">
<li>o conjunto de dados normal é bem definido;</li>



<li>há pouco ruído;</li>



<li>a anomalia possui características sutis;</li>



<li>os dados têm baixa dimensionalidade.</li>
</ul>



<p class="wp-block-paragraph">Treinar o modelo em um computador e exportar um SVM simplificado para microcontroladores é viável, desde que a quantidade de vetores de suporte seja pequena.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Exemplo em Python — Treinamento e Teste</strong></h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>from sklearn.svm import OneClassSVM
import numpy as np

# Dados normais
rng = np.random.RandomState(10)
normal = 0.2 * rng.randn(200, 2)

# Anomalias
anom = rng.uniform(low=-3, high=3, size=(10, 2))

# Treina o modelo
model = OneClassSVM(kernel="rbf", gamma=0.1, nu=0.05)
model.fit(normal)

# Testa
test = np.vstack([normal&#91;:5&#93;, anom&#91;:2&#93;])
pred = model.predict(test)

print(pred)  # -1 indica anomalia
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sklearn</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">svm</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">OneClassSVM</span></span>
<span class="line"><span style="color: #8FBCBB">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">numpy</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">as</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">np</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #8FBCBB">Dados</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">normais</span></span>
<span class="line"><span style="color: #8FBCBB">rng</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">np</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">random</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">RandomState</span><span style="color: #D8DEE9FF">(10)</span></span>
<span class="line"><span style="color: #8FBCBB">normal</span><span style="color: #D8DEE9FF"> = 0.2 </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">rng</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">randn</span><span style="color: #D8DEE9FF">(200</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 2)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #8FBCBB">Anomalias</span></span>
<span class="line"><span style="color: #8FBCBB">anom</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">rng</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">uniform</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">low</span><span style="color: #D8DEE9FF">=-3</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">high</span><span style="color: #D8DEE9FF">=3</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">size</span><span style="color: #D8DEE9FF">=(10</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 2))</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #8FBCBB">Treina</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">o</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">modelo</span></span>
<span class="line"><span style="color: #8FBCBB">model</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">OneClassSVM</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">kernel</span><span style="color: #D8DEE9FF">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">rbf</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">gamma</span><span style="color: #D8DEE9FF">=0.1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">nu</span><span style="color: #D8DEE9FF">=0.05)</span></span>
<span class="line"><span style="color: #8FBCBB">model</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">fit</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">normal</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #8FBCBB">Testa</span></span>
<span class="line"><span style="color: #8FBCBB">test</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">np</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">vstack</span><span style="color: #D8DEE9FF">([</span><span style="color: #8FBCBB">normal</span><span style="color: #D8DEE9FF">&#91;:5&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">anom</span><span style="color: #D8DEE9FF">&#91;:2&#93;])</span></span>
<span class="line"><span style="color: #8FBCBB">pred</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">model</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">predict</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">test</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #8FBCBB">print</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">pred</span><span style="color: #D8DEE9FF">)  # -1 </span><span style="color: #8FBCBB">indica</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">anomalia</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Exemplo de Inferência Simplificada em C (Kernel RBF)</strong></h3>



<p class="wp-block-paragraph">Este é um exemplo reduzido da fórmula RBF usada na inferência:</p>



<p class="wp-block-paragraph">\[<br>K(x, v_i) = e^{-\gamma |x &#8211; v_i|^2}<br>\]



<p class="wp-block-paragraph">Onde cada \(v_i\) é um vetor de suporte.</p>



<p class="wp-block-paragraph">A soma ponderada dos kernels determina a decisão final.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>#include &lt;math.h>

#define GAMMA 0.1f

// Vetor de suporte simplificado (exemplo)
float sv[]&#91;2&#93; = {
    {0.1f,  0.2f},
    {-0.1f, 0.0f},
    {0.05f, 0.1f}
};

// Coeficientes alpha do SVM
float alpha[] = {0.5f, -0.3f, 0.8f};

float rbf(float x0, float x1, float v0, float v1) {
    float dx = x0 - v0;
    float dy = x1 - v1;
    float dist2 = dx*dx + dy*dy;
    return expf(-GAMMA * dist2);
}

int oneclass_svm_infer(float x0, float x1) {
    float sum = 0.0f;

    for (int i = 0; i &lt; 3; i++) {
        sum += alpha&#91;i&#93; * rbf(x0, x1, sv&#91;i&#93;&#91;0&#93;, sv&#91;i&#93;&#91;1&#93;);
    }

    return (sum > 0.0f) ? 1 : -1; // -1 = anomalia
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">math</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">GAMMA</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">1</span><span style="color: #D8DEE9">f</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Vetor de suporte simplificado (exemplo)</span></span>
<span class="line"><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sv</span><span style="color: #D8DEE9FF">[]&#91;</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF">0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">1</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">  0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">2</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">},</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">1</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">},</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF">0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">05</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">1</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Coeficientes alpha do SVM</span></span>
<span class="line"><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">alpha</span><span style="color: #D8DEE9FF">[] </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF">0.5</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> -0.3</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 0.8</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">rbf</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">v0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">v1</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dx</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">v0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dy</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">v1</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dist2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dx</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">dx</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dy</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">dy</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">expf</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">GAMMA</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dist2</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">oneclass_svm_infer</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x1</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sum</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">sum</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">alpha</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">rbf</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">x0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sv</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93;&#91;</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sv</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93;&#91;</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">&#93;)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">sum</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">?</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #B48EAD">1</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// -1 = anomalia</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Esse tipo de código é viável em um Cortex-M4F ou M7 com FPU; para microcontroladores mais modestos, é possível pré-computar tabelas ou usar aproximações de exponencial (como fast exp).</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>4 — PCA Embarcado para Detecção de Anomalias</strong></h2>



<p class="wp-block-paragraph">A Análise de Componentes Principais (PCA, Principal Component Analysis) é uma técnica matemática poderosa para redução de dimensionalidade e detecção de anomalias. Diferentemente do Isolation Forest e do One-Class SVM, o PCA não cria fronteiras ou árvores, mas transforma os dados originais em novas direções (componentes principais) que retêm a maior variância possível. Isso permite identificar padrões fundamentais e detectar pontos que se desviam significativamente desse padrão.</p>



<p class="wp-block-paragraph">A ideia básica é decompor os dados em uma combinação linear de componentes ortogonais. Para detectar anomalias, observamos o <strong>erro de reconstrução</strong>: quando projetamos um ponto nos componentes principais e tentamos reconstruí-lo, pontos normais tendem a ter um erro pequeno, enquanto pontos anômalos produzem erros muito maiores. Essa abordagem é extremamente eficiente para sistemas embarcados porque permite pré-calcular toda a estrutura no computador e embarcar apenas duas operações: multiplicação de matrizes e cálculo de erro.</p>



<p class="wp-block-paragraph">Matematicamente, se ( x ) é o vetor original e ( W ) é a matriz dos autovetores (componentes), o processo é:</p>



<ol class="wp-block-list">
<li><strong>Projeção no espaço PCA:</strong></li>
</ol>



<p class="wp-block-paragraph">\[<br>z = W^T (x &#8211; \mu)<br>\]



<ol start="2" class="wp-block-list">
<li><strong>Reconstrução aproximada:</strong></li>
</ol>



<p class="wp-block-paragraph">\[<br>\hat{x} = Wz + \mu<br>\]



<ol start="3" class="wp-block-list">
<li><strong>Erro de reconstrução:</strong></li>
</ol>



<p class="wp-block-paragraph">\[<br>e = | x &#8211; \hat{x} |^2<br>\]



<p class="wp-block-paragraph">Se o erro (e) ultrapassar um limiar definido, classificamos como anomalia.</p>



<p class="wp-block-paragraph">Essa abordagem é usada em vibração, acústica, qualidade de energia e em sistemas industriais embarcados com pouco poder computacional, pois envolve apenas multiplicações e somas — operações extremamente eficientes em microcontroladores.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Exemplo em Python — PCA para Identificar Anomalias</strong></h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>import numpy as np
from sklearn.decomposition import PCA

# Dados normais
rng = np.random.RandomState(1)
normal = rng.normal(0, 0.3, size=(300, 3))

# Anomalias
anom = rng.uniform(-3, 3, size=(10, 3))
dados = np.vstack(&#91;normal, anom&#93;)

# PCA com 2 componentes
pca = PCA(n_components=2)
pca.fit(normal)

# Função de erro de reconstrução
def reconstruction_error(x):
    z = pca.transform(&#91;x&#93;)
    x_hat = pca.inverse_transform(z)
    return np.linalg.norm(x - x_hat)

# Testando
for i in range(5):
    print("Erro:", reconstruction_error(dados&#91;i&#93;))
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">numpy</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">as</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">np</span></span>
<span class="line"><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">sklearn</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">decomposition</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">PCA</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #8FBCBB">Dados</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">normais</span></span>
<span class="line"><span style="color: #8FBCBB">rng</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">np</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">random</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">RandomState</span><span style="color: #D8DEE9FF">(1)</span></span>
<span class="line"><span style="color: #8FBCBB">normal</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">rng</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">normal</span><span style="color: #D8DEE9FF">(0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 0.3</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">size</span><span style="color: #D8DEE9FF">=(300</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 3))</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #8FBCBB">Anomalias</span></span>
<span class="line"><span style="color: #8FBCBB">anom</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">rng</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">uniform</span><span style="color: #D8DEE9FF">(-3</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 3</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">size</span><span style="color: #D8DEE9FF">=(10</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 3))</span></span>
<span class="line"><span style="color: #8FBCBB">dados</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">np</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">vstack</span><span style="color: #D8DEE9FF">(&#91;</span><span style="color: #8FBCBB">normal</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">anom</span><span style="color: #D8DEE9FF">&#93;)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #8FBCBB">PCA</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">com</span><span style="color: #D8DEE9FF"> 2 </span><span style="color: #8FBCBB">componentes</span></span>
<span class="line"><span style="color: #8FBCBB">pca</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">PCA</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">n_components</span><span style="color: #D8DEE9FF">=2)</span></span>
<span class="line"><span style="color: #8FBCBB">pca</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">fit</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">normal</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #8FBCBB">Função</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">erro</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">reconstrução</span></span>
<span class="line"><span style="color: #8FBCBB">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">reconstruction_error</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">x</span><span style="color: #D8DEE9FF">):</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">z</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">pca</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">transform</span><span style="color: #D8DEE9FF">(&#91;</span><span style="color: #8FBCBB">x</span><span style="color: #D8DEE9FF">&#93;)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">x_hat</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">pca</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">inverse_transform</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">z</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">np</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">linalg</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">norm</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">x</span><span style="color: #D8DEE9FF"> - </span><span style="color: #8FBCBB">x_hat</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #8FBCBB">Testando</span></span>
<span class="line"><span style="color: #8FBCBB">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">range</span><span style="color: #D8DEE9FF">(5):</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">print</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Erro:</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">reconstruction_error</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">dados</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #8FBCBB">i</span><span style="color: #D8DEE9FF">&#93;))</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Você perceberá que os erros das amostras anômalas são muito maiores.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Exemplo Embarcado (C) — Inferência PCA Simplificada</strong></h3>



<p class="wp-block-paragraph">Os autovetores e a média já foram calculados no PC. Agora, usamos apenas matrizes pequenas no microcontrolador:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>#include &lt;math.h>

// Matriz de autovetores (2 componentes, 3 dimensões)
float W&#91;2&#93;&#91;3&#93; = {
    {0.58f, 0.57f, 0.58f},
    {-0.72f, 0.01f, 0.69f}
};

// Média dos dados (calculada previamente)
float mu&#91;3&#93; = {0.02f, -0.01f, 0.03f};

float reconstruction_error(float x&#91;3&#93;) {
    float x_centered&#91;3&#93;;
    for (int i = 0; i &lt; 3; i++)
        x_centered&#91;i&#93; = x&#91;i&#93; - mu&#91;i&#93;;

    // Projeção
    float z&#91;2&#93; = {0};
    for (int i = 0; i &lt; 2; i++)
        for (int j = 0; j &lt; 3; j++)
            z&#91;i&#93; += W&#91;i&#93;&#91;j&#93; * x_centered&#91;j&#93;;

    // Reconstrução
    float x_hat&#91;3&#93; = {0};
    for (int i = 0; i &lt; 3; i++)
        for (int j = 0; j &lt; 2; j++)
            x_hat&#91;i&#93; += W&#91;j&#93;&#91;i&#93; * z&#91;j&#93;;

    for (int i = 0; i &lt; 3; i++)
        x_hat&#91;i&#93; += mu&#91;i&#93;;

    // Erro
    float e = 0;
    for (int i = 0; i &lt; 3; i++) {
        float d = x&#91;i&#93; - x_hat&#91;i&#93;;
        e += d * d;
    }

    return e;
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">math</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Matriz de autovetores (2 componentes, 3 dimensões)</span></span>
<span class="line"><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">W</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">&#93;&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF">0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">58</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">57</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">58</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">},</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">72</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">01</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">69</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Média dos dados (calculada previamente)</span></span>
<span class="line"><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mu</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF">0.02</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> -0.01</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 0.03</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">reconstruction_error</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x_centered</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">x_centered</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mu</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Projeção</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">j</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">j</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">j</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">z</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">W</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93;&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x_centered</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Reconstrução</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x_hat</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">3</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">j</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">j</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">j</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">x_hat</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">W</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #D8DEE9FF">&#93;&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">j</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">x_hat</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mu</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Erro</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">d</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x_hat</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">e</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">d</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">d</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">e</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Essa função pode ser usada diretamente em qualquer microcontrolador, bastando definir um limiar adequado de erro para classificar anomalias.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>5 — Comparação Entre Métodos e Aplicações Práticas</strong></h2>



<p class="wp-block-paragraph">A escolha entre Isolation Forest, One-Class SVM e PCA depende profundamente do tipo de aplicação, da quantidade de dados disponíveis, da complexidade do sinal e principalmente das restrições computacionais típicas de sistemas embarcados. Cada método tem pontos fortes e limitações, e compreender essas nuances permite projetar sistemas mais eficientes e robustos.</p>



<p class="wp-block-paragraph">O Isolation Forest é, em geral, o mais eficiente para dados de alta dimensionalidade e cenários onde as anomalias tendem a ser valores extremos ou isolados. Sua natureza baseada em árvores o torna leve na etapa de inferência, já que consiste em uma sequência de comparações simples — ideal em MCUs como RP2040, ESP32-C3/S3 e Cortex-M. Entretanto, sua interpretação pode ser menos intuitiva do que a de modelos lineares ou baseados em geometria. Já o One-Class SVM apresenta excelente desempenho em situações onde os dados normais são bem estruturados e a anomalia é sutil, porém o custo computacional do kernel RBF e a dependência da quantidade de vetores de suporte tornam a inferência mais cara. É um candidato natural quando a inferência ocorre em edge devices mais robustos ou quando se usa aceleradores como o NPU do ESP32-P4, HPM6xxx, STM32N6 ou NPUs externos.</p>



<p class="wp-block-paragraph">O PCA se destaca em contextos embarcados devido à sua simplicidade computacional e capacidade de reduzir drasticamente a dimensionalidade dos dados, mantendo a essência do comportamento normal. Em aplicações industriais, como vibração e acústica, onde há forte redundância entre sinais, o PCA é extremamente eficaz em capturar esse padrão e detectar desvios, principalmente quando se usa o erro de reconstrução como métrica. Seu treinamento é mais pesado, mas a inferência exige apenas multiplicações de matrizes, algo trivial para um Cortex-M7, M33, ESP32-S3 ou mesmo um RP2040.</p>



<h4 class="wp-block-heading"><strong>Aplicações práticas em sistemas embarcados</strong></h4>



<ul class="wp-block-list">
<li><strong>Manutenção preditiva de motores e transformadores</strong><br>PCA e Isolation Forest são largamente utilizados para vibrações e ruídos mecânicos. PCA detecta sutis alterações espectrais, enquanto Isolation Forest identifica comportamentos fora do padrão global.</li>



<li><strong>Segurança cibernética embarcada</strong><br>Em gateways IoT e sistemas críticos, One-Class SVM é eficiente para detectar tráfego malicioso que difere levemente do comportamento normal.</li>



<li><strong>Sensores de ambiente (temperatura, pressão, corrente, aceleração)</strong><br>Isolation Forest e PCA executam facilmente em MCUs com pouco recurso, monitorando continuamente leituras de sensores.</li>



<li><strong>Detecção de falhas em robôs, veículos autônomos e drones</strong><br>PCA pode identificar alterações no perfil de movimento; Isolation Forest detecta leituras inesperadas de IMUs, LiDARs ou encoders.</li>



<li><strong>Sistemas embarcados de análise de energia elétrica</strong><br>PCA é excelente para detectar distorções e harmônicos incomuns; SVM é útil quando há pouca variabilidade na rede elétrica monitorada.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><strong>Seção 6 — Conclusão e Boas Práticas de Implementação em Sistemas Embarcados</strong></h2>



<p class="wp-block-paragraph">A detecção de anomalias é uma peça central para sistemas embarcados modernos, especialmente aqueles voltados à manutenção preditiva, diagnóstico inteligente, proteção de equipamentos e segurança operacional. Isolation Forest, One-Class SVM e PCA representam três abordagens complementares que oferecem um conjunto sólido de ferramentas para identificar comportamentos inesperados em tempo real.</p>



<p class="wp-block-paragraph">Quando bem aplicados, esses algoritmos permitem antecipar falhas mecânicas, detectar desvios elétricos, capturar padrões incomuns em vibração/acústica, identificar leituras suspeitas de sensores ou mesmo reforçar a segurança cibernética em ambientes IoT/IIoT — tudo isso com execução eficiente em microcontroladores acessíveis.</p>



<p class="wp-block-paragraph">Do ponto de vista prático, algumas recomendações ajudam a garantir que o sistema funcione de maneira consistente:</p>



<p class="wp-block-paragraph">A primeira boa prática é sempre realizar o treinamento dos modelos fora do microcontrolador, preferencialmente em uma estação de trabalho ou servidor dedicado. Os dados coletados devem ser limpos, normalizados e analisados para garantir que representam adequadamente o “comportamento normal” do sistema. Após o treinamento, os parâmetros essenciais — árvores, vetores de suporte ou autovetores — devem ser exportados para o firmware em representações compactas.</p>



<p class="wp-block-paragraph">Outra recomendação importante é monitorar os limites numéricos. Em MCUs, operações com ponto flutuante podem gerar erros acumulados; por isso, quando possível, considere <strong>quantização</strong>, <strong>uso de ponto fixo</strong>, ou <strong>tabelas de aproximação</strong> para funções como exponencial (no caso do SVM). Em sistemas de baixa potência, evitar funções matemáticas custosas ajuda a manter a latência e o consumo energético sob controle.</p>



<p class="wp-block-paragraph">A terceira prática consiste em calibrar limiares de detecção dinamicamente. Em vez de usar um limiar fixo, o sistema pode calcular estatísticas ao longo do tempo — como média móvel ou desvio padrão — para adaptar-se a mudanças naturais no ambiente. A detecção de anomalias fica mais robusta em ambientes ruidosos ou sujeitos a variações não controladas.</p>



<p class="wp-block-paragraph">Por fim, é essencial validar o sistema com dados reais do ambiente final. Testes em bancada podem não refletir ruídos, variações térmicas, jitter dos sensores ou interferências eletromagnéticas típicas de campo. O processo de testes deve incluir cenários-limite para garantir que o sistema responde não apenas ao “anomalo ideal”, mas também a desvios graduais e quase imperceptíveis — aqueles que, na prática, causam a maior parte das falhas industriais.</p><p>The post <a href="https://mcu.tec.br/algoritimos/deteccao-de-anomalias-em-sistemas-embarcados-isolation-forest-one-class-svm-e-pca-com-exemplos-praticos/">Detecção de Anomalias em Sistemas Embarcados: Isolation Forest, One-Class SVM e PCA com Exemplos Práticos</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">944</post-id>	</item>
		<item>
		<title>CNNs na Análise de Ruídos em Transformadores com IA</title>
		<link>https://mcu.tec.br/energia/cnns-na-analise-de-ruidos-em-transformadores-com-ia/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cnns-na-analise-de-ruidos-em-transformadores-com-ia</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Sat, 21 Jun 2025 15:30:59 +0000</pubDate>
				<category><![CDATA[Energia]]></category>
		<category><![CDATA[análise de ruídos]]></category>
		<category><![CDATA[CNN]]></category>
		<category><![CDATA[deep learning]]></category>
		<category><![CDATA[diagnóstico de falhas]]></category>
		<category><![CDATA[espectrograma]]></category>
		<category><![CDATA[falha elétrica]]></category>
		<category><![CDATA[IA industrial]]></category>
		<category><![CDATA[inteligência artificial]]></category>
		<category><![CDATA[magnetostricção]]></category>
		<category><![CDATA[manutenção preditiva]]></category>
		<category><![CDATA[python keras tensorflow]]></category>
		<category><![CDATA[raspberry pi ia]]></category>
		<category><![CDATA[rede neural convolucional]]></category>
		<category><![CDATA[ruído magnético]]></category>
		<category><![CDATA[sensores acústicos]]></category>
		<category><![CDATA[simulação transformador]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[TensorFlow]]></category>
		<category><![CDATA[TensorFlow Lite]]></category>
		<category><![CDATA[tensorflow microcontrolador]]></category>
		<category><![CDATA[transformador elétrico]]></category>
		<category><![CDATA[transformers vs cnn]]></category>
		<category><![CDATA[vibração transformador]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=527</guid>

					<description><![CDATA[<p>Descubra como CNNs são aplicadas na detecção de falhas em transformadores via ruídos de magnetostricção. Do básico ao embarcado com IA.</p>
<p>The post <a href="https://mcu.tec.br/energia/cnns-na-analise-de-ruidos-em-transformadores-com-ia/">CNNs na Análise de Ruídos em Transformadores com IA</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">A crescente complexidade dos sistemas elétricos modernos demanda métodos de diagnóstico cada vez mais precisos e automatizados. No contexto da manutenção preditiva, especialmente em transformadores de potência, a análise de ruídos por magnetostricção — um fenômeno físico relacionado à vibração induzida por variações no campo magnético — tem se mostrado uma ferramenta promissora para identificar falhas incipientes sem a necessidade de desmontar ou interromper o funcionamento do equipamento.</p>



<p class="wp-block-paragraph">Neste cenário, as Redes Neurais Convolucionais (Convolutional Neural Networks – CNNs) vêm ganhando espaço como uma das abordagens mais eficazes para analisar dados complexos como imagens, espectros de frequência e séries temporais com múltiplas variáveis. Originadas no campo da visão computacional, as CNNs evoluíram para lidar com diversos tipos de sinais, incluindo os acústicos e vibracionais. Sua capacidade de extrair automaticamente características relevantes (features) do sinal as torna ideais para tarefas de classificação, detecção de padrões e diagnóstico.</p>



<p class="wp-block-paragraph">O presente artigo tem como objetivo apresentar, de forma progressiva e acessível, desde os fundamentos básicos até os conceitos avançados das CNNs, contextualizando sua aplicação na análise de sinais provenientes de sensores acústicos acoplados a transformadores. O texto também detalha como essas redes foram integradas ao simulador desenvolvido no projeto “Análise da Saúde de Transformadores com Base em Ruídos de Magnetostricção”, disponível publicamente no repositório GitHub: <a class="" href="https://github.com/rapporttecnologia/simulador_magnetostriccao">rapporttecnologia/simulador_magnetostriccao</a>.</p>



<p class="wp-block-paragraph">Ao longo do artigo, serão abordados conceitos essenciais de pré-processamento de sinais, arquiteturas de redes neurais, comparação com outros modelos de aprendizado profundo e técnicas específicas para treinar e avaliar CNNs aplicadas a dados vibracionais. A proposta é proporcionar uma compreensão sólida do papel das CNNs neste domínio, estimulando sua adoção em sistemas embarcados e aplicações industriais reais.</p>



<h2 class="wp-block-heading">O que é uma Rede Neural Convolucional (CNN)?</h2>



<p class="wp-block-paragraph">Redes Neurais Convolucionais (CNNs, do inglês <em>Convolutional Neural Networks</em>) são um tipo específico de rede neural artificial projetada para lidar com dados estruturados espacialmente ou temporalmente, como imagens, sinais de áudio e séries temporais multicanais. Elas se destacam por sua habilidade em extrair automaticamente padrões e características relevantes dos dados, dispensando a necessidade de engenharia manual de atributos — tarefa que, tradicionalmente, exigia profundo conhecimento do domínio de aplicação.</p>



<p class="wp-block-paragraph">A principal diferença entre uma CNN e uma rede neural densa (ou totalmente conectada) reside na operação de convolução. Em vez de conectar cada neurônio de uma camada a todos os neurônios da camada anterior, a CNN utiliza filtros ou <em>kernels</em> que percorrem localmente os dados de entrada, capturando padrões locais com eficiência. Essa operação simula, de certo modo, o funcionamento da visão em sistemas biológicos, onde diferentes regiões do campo visual são processadas de forma independente e combinadas em níveis superiores de abstração.</p>



<p class="wp-block-paragraph">Essas redes são compostas por blocos fundamentais: <strong>camadas convolucionais</strong>, responsáveis por aplicar os filtros e extrair <em>features</em> locais; <strong>camadas de ativação</strong>, que introduzem não linearidade no sistema (como a função ReLU); <strong>camadas de pooling</strong>, que reduzem a dimensionalidade e extraem características mais robustas; e <strong>camadas totalmente conectadas</strong>, que realizam a classificação ou regressão com base nos <em>features</em> aprendidos.</p>



<p class="wp-block-paragraph">Apesar de serem amplamente conhecidas por sua aplicação em reconhecimento de imagens, as CNNs também se mostraram extremamente eficientes na análise de sinais 1D — como os ruídos de magnetostricção captados por sensores —, desde que os dados sejam corretamente estruturados como vetores temporais ou representações espectrais (ex.: espectrogramas).</p>



<p class="wp-block-paragraph">No contexto deste artigo e do simulador em desenvolvimento, as CNNs são treinadas para identificar padrões em sinais acústicos complexos, permitindo classificar o estado de saúde dos transformadores com base na vibração que emitem. Isso representa um avanço importante frente a técnicas tradicionais de análise espectral manual ou filtros lineares, especialmente quando se trata de ruídos de baixa amplitude ou de difícil interpretação visual.</p>



<h2 class="wp-block-heading">O que é uma Rede Neural Convolucional (CNN)?</h2>



<p class="wp-block-paragraph">Redes Neurais Convolucionais (CNNs, do inglês <em>Convolutional Neural Networks</em>) são um tipo específico de rede neural artificial projetada para lidar com dados estruturados espacialmente ou temporalmente, como imagens, sinais de áudio e séries temporais multicanais. Elas se destacam por sua habilidade em extrair automaticamente padrões e características relevantes dos dados, dispensando a necessidade de engenharia manual de atributos — tarefa que, tradicionalmente, exigia profundo conhecimento do domínio de aplicação.</p>



<p class="wp-block-paragraph">A principal diferença entre uma CNN e uma rede neural densa (ou totalmente conectada) reside na operação de convolução. Em vez de conectar cada neurônio de uma camada a todos os neurônios da camada anterior, a CNN utiliza filtros ou <em>kernels</em> que percorrem localmente os dados de entrada, capturando padrões locais com eficiência. Essa operação simula, de certo modo, o funcionamento da visão em sistemas biológicos, onde diferentes regiões do campo visual são processadas de forma independente e combinadas em níveis superiores de abstração.</p>



<p class="wp-block-paragraph">Essas redes são compostas por blocos fundamentais: <strong>camadas convolucionais</strong>, responsáveis por aplicar os filtros e extrair <em>features</em> locais; <strong>camadas de ativação</strong>, que introduzem não linearidade no sistema (como a função ReLU); <strong>camadas de pooling</strong>, que reduzem a dimensionalidade e extraem características mais robustas; e <strong>camadas totalmente conectadas</strong>, que realizam a classificação ou regressão com base nos <em>features</em> aprendidos.</p>



<p class="wp-block-paragraph">Apesar de serem amplamente conhecidas por sua aplicação em reconhecimento de imagens, as CNNs também se mostraram extremamente eficientes na análise de sinais 1D — como os ruídos de magnetostricção captados por sensores —, desde que os dados sejam corretamente estruturados como vetores temporais ou representações espectrais (ex.: espectrogramas).</p>



<p class="wp-block-paragraph">No contexto deste artigo e do simulador em desenvolvimento, as CNNs são treinadas para identificar padrões em sinais acústicos complexos, permitindo classificar o estado de saúde dos transformadores com base na vibração que emitem. Isso representa um avanço importante frente a técnicas tradicionais de análise espectral manual ou filtros lineares, especialmente quando se trata de ruídos de baixa amplitude ou de difícil interpretação visual.</p>



<h2 class="wp-block-heading">Entendendo a Função ReLU</h2>



<p class="wp-block-paragraph">A função ReLU (<em>Rectified Linear Unit</em> – Unidade Linear Retificada) é uma função de ativação amplamente utilizada em redes neurais profundas, especialmente em Redes Neurais Convolucionais (CNNs). Sua popularidade se deve à simplicidade computacional e à eficácia em acelerar o treinamento e melhorar a convergência de modelos profundos.</p>



<p class="wp-block-paragraph">Matematicamente, a ReLU é definida pela seguinte equação: f(x)=max⁡(0,x)f(x) = \max(0, x)f(x)=max(0,x)</p>



<p class="wp-block-paragraph">Ou seja, se o valor de entrada xxx for positivo, ele é mantido; se for negativo, é convertido em zero. Esse comportamento cria uma espécie de filtro não linear que elimina valores negativos, preservando apenas os sinais &#8220;ativos&#8221;.</p>



<h3 class="wp-block-heading">Por que ReLU é importante?</h3>



<p class="wp-block-paragraph">Nas CNNs, cada filtro convolucional gera uma saída que representa a resposta a certos padrões locais no dado de entrada (por exemplo, bordas em uma imagem, ou frequências específicas em um espectrograma). Após essa operação, a ReLU é aplicada para reforçar a presença desses padrões (valores positivos) e suprimir sinais que não contribuem significativamente (valores negativos).</p>



<p class="wp-block-paragraph">Além disso, a ReLU evita problemas como o <em>desvanecimento do gradiente</em> (<em>vanishing gradient</em>), comum em funções sigmoides ou tanh, permitindo que os gradientes se propaguem com maior estabilidade durante o treinamento. Isso contribui para redes mais profundas e precisas.</p>



<h3 class="wp-block-heading">Exemplo prático em sinais</h3>



<p class="wp-block-paragraph">Imagine que uma CNN está processando o espectro acústico de um transformador. Algumas regiões podem apresentar padrões de vibração característicos de falhas incipientes. A convolução aplicada sobre essas regiões produzirá valores maiores, enquanto regiões sem relevância (como ruído de fundo) gerarão valores próximos ou abaixo de zero. Ao aplicar a ReLU, a rede preserva apenas os padrões significativos, facilitando a detecção de anomalias.</p>



<h3 class="wp-block-heading">Visualização</h3>



<p class="wp-block-paragraph">Gráfico da função ReLU:</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="635" src="https://mcu.tec.br/wp-content/uploads/2025/06/image-1024x635.png" alt="" class="wp-image-528" srcset="https://mcu.tec.br/wp-content/uploads/2025/06/image-1024x635.png 1024w, https://mcu.tec.br/wp-content/uploads/2025/06/image-300x186.png 300w, https://mcu.tec.br/wp-content/uploads/2025/06/image-768x476.png 768w, https://mcu.tec.br/wp-content/uploads/2025/06/image-1536x953.png 1536w, https://mcu.tec.br/wp-content/uploads/2025/06/image.png 1580w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">O gráfico mostra claramente que ReLU é zero para qualquer entrada negativa e cresce linearmente para entradas positivas, o que a torna ideal para ativar seletivamente os neurônios relevantes.</p>



<h2 class="wp-block-heading">Espectrograma: Visualizando o Sinal no Tempo e na Frequência</h2>



<p class="wp-block-paragraph">O espectrograma é uma representação visual da densidade espectral de potência de um sinal ao longo do tempo. Diferentemente da Transformada de Fourier tradicional, que mostra como a energia do sinal está distribuída em diferentes frequências, o espectrograma adiciona uma dimensão temporal, permitindo observar como essas frequências evoluem ao longo do tempo.</p>



<p class="wp-block-paragraph">Essa ferramenta é extremamente útil para análise de sinais não estacionários, como os ruídos de magnetostricção em transformadores, que podem apresentar variações abruptas ou padrões periódicos característicos de falhas mecânicas ou elétricas.</p>



<h3 class="wp-block-heading">Como é calculado um espectrograma?</h3>



<p class="wp-block-paragraph">O espectrograma é obtido por meio da <strong>Short-Time Fourier Transform (STFT)</strong> — a Transformada de Fourier de Curta Duração. A ideia é dividir o sinal original em pequenas janelas de tempo (chamadas <em>janelas de análise</em>), aplicar a Transformada de Fourier em cada uma delas e, em seguida, empilhar os espectros gerados em sequência.</p>



<p class="wp-block-paragraph">O resultado é uma matriz bidimensional onde:</p>



<ul class="wp-block-list">
<li>O eixo horizontal representa o tempo (posição da janela),</li>



<li>O eixo vertical representa as frequências,</li>



<li>As cores (ou intensidades) representam a amplitude ou energia associada a cada frequência naquele instante.</li>
</ul>



<p class="wp-block-paragraph">Matematicamente, a STFT é definida como: \[X(t, f) = \int_{-\infty}^{\infty} x(\tau) w(\tau &#8211; t) e^{-j2\pi f \tau} d\tau\]



<p class="wp-block-paragraph">onde:</p>



<ul class="wp-block-list">
<li>\(x(\tau)\) é o sinal original,</li>



<li>\(w(\tau &#8211; t)\) é a janela centrada no tempo t,</li>



<li>f é a frequência de interesse.</li>
</ul>



<h3 class="wp-block-heading">Aplicação no projeto</h3>



<p class="wp-block-paragraph">No projeto de análise da saúde de transformadores, os sinais acústicos captados pelos sensores são primeiro convertidos em espectrogramas. Esses espectrogramas são tratados como imagens, o que torna possível o uso de CNNs para detectar padrões específicos, como assinaturas de falhas, arcos elétricos, ou vibrações anormais. Essa abordagem é especialmente vantajosa, pois facilita a generalização do modelo para novos tipos de anomalias e diferentes equipamentos.</p>



<p class="wp-block-paragraph">Além disso, o espectrograma permite destacar componentes harmônicas, ruídos de fundo, variações sazonais ou transitórias — todos elementos difíceis de isolar em análises puramente temporais ou espectrais.</p>



<h2 class="wp-block-heading">Comparações entre CNNs e Outras Arquiteturas de Redes Neurais</h2>



<p class="wp-block-paragraph">Embora as Redes Neurais Convolucionais (CNNs) sejam extremamente eficazes na análise de dados com estrutura espacial ou temporal, elas não são a única opção. Outras arquiteturas, como Redes Neurais Densas (MLPs), Redes Neurais Recorrentes (RNNs), LSTM (Long Short-Term Memory) e, mais recentemente, Transformers, também são utilizadas para tarefas envolvendo séries temporais, sinais e classificação de padrões. Cada uma possui vantagens e limitações específicas, que merecem ser exploradas no contexto da análise de ruídos por magnetostricção.</p>



<h3 class="wp-block-heading">Redes Neurais Densas (MLPs)</h3>



<p class="wp-block-paragraph">As redes densas ou <em>Multilayer Perceptrons</em> conectam cada neurônio de uma camada à totalidade da camada anterior. Elas funcionam bem para dados tabulares ou vetores fixos, mas não conseguem explorar relações locais em sinais contínuos. Por exemplo, ao analisar um espectrograma, uma MLP trataria cada ponto como independente, ignorando a estrutura temporal e espectral do dado. Isso leva à perda de contexto e aumento exponencial do número de parâmetros.</p>



<h3 class="wp-block-heading">Redes Recorrentes (RNNs) e LSTM</h3>



<p class="wp-block-paragraph">As redes recorrentes, como as RNNs e suas variantes LSTM, foram projetadas para lidar com sequências temporais. Elas mantêm uma espécie de “memória” interna que permite capturar dependências ao longo do tempo. Embora sejam boas para tarefas como previsão de séries temporais ou transcrição de áudio, apresentam limitações para sinais muito longos ou com variações espaciais complexas, como os espectrogramas gerados no projeto. Além disso, seu treinamento é mais demorado e sensível a problemas como explosão ou desaparecimento do gradiente.</p>



<h3 class="wp-block-heading">Transformers</h3>



<p class="wp-block-paragraph">Arquiteturas baseadas em <em>Transformers</em> surgiram como alternativa às RNNs, utilizando mecanismos de atenção para capturar relações de longo alcance em dados sequenciais. Embora extremamente eficazes em NLP (Processamento de Linguagem Natural), sua aplicação em sinais acústicos ainda está em fase de experimentação e exige grande poder computacional. Em sistemas embarcados, seu uso é limitado devido ao alto custo de inferência.</p>



<h3 class="wp-block-heading">Vantagens das CNNs no projeto</h3>



<p class="wp-block-paragraph">Em contrapartida, as CNNs se mostram altamente adequadas para a tarefa de classificar espectrogramas de ruídos de transformadores. Elas exigem menos recursos computacionais, são mais fáceis de treinar, e capturam automaticamente padrões locais (por exemplo, harmônicos ou transientes). Essa capacidade de extração de <em>features</em> espaciais torna as CNNs ideais para transformar um problema de análise de sinal em um problema de visão computacional — um campo amplamente dominado por essa arquitetura.</p>



<p class="wp-block-paragraph">No projeto “Análise da Saúde de Transformadores com Base em Ruídos de Magnetostricção”, a CNN supera as demais abordagens pela combinação de desempenho, velocidade de inferência e facilidade de visualização dos resultados — fatores essenciais para sua aplicação em tempo real e em ambientes industriais.</p>



<h2 class="wp-block-heading">Transformers como Alternativa às CNNs na Análise de Sinais</h2>



<p class="wp-block-paragraph">Os <em>Transformers</em> representam uma arquitetura de rede neural revolucionária originalmente concebida para o processamento de linguagem natural (NLP), mas que rapidamente se estendeu para áreas como visão computacional, áudio e análise de séries temporais. Seu principal diferencial reside no mecanismo de <strong>atenção</strong> — mais especificamente, a atenção auto-regressiva (<em>self-attention</em>), que permite à rede aprender relações complexas e de longo alcance dentro de uma sequência de dados.</p>



<h3 class="wp-block-heading">Como funcionam os Transformers?</h3>



<p class="wp-block-paragraph">Diferentemente das CNNs, que processam dados de forma local (janela por janela, filtro por filtro), os Transformers consideram simultaneamente todas as partes da entrada. Isso significa que, ao analisar um espectrograma ou uma série temporal, um Transformer pode, teoricamente, correlacionar eventos distantes no tempo ou no espaço, o que é altamente vantajoso para padrões dispersos — como falhas intermitentes ou ressonâncias harmônicas sutis nos sinais de magnetostricção.</p>



<p class="wp-block-paragraph">O componente chave é o bloco de atenção: \[\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V\]



<p class="wp-block-paragraph">onde Q (queries), K (keys) e V (values) são derivados da entrada. A saída pondera as diferentes partes do sinal com base na relevância mútua entre elas.</p>



<h3 class="wp-block-heading">Vantagens no projeto</h3>



<ul class="wp-block-list">
<li><strong>Capacidade de capturar relações de longo alcance</strong> entre trechos do sinal, o que pode ser útil para detectar padrões que se repetem de forma espaçada.</li>



<li><strong>Modelagem temporal mais precisa</strong> que CNNs puras, especialmente em séries temporais não estacionárias.</li>



<li><strong>Flexibilidade multimodal</strong> — Transformers podem ser adaptados para analisar simultaneamente espectrogramas, dados de sensores e até metadados (como horário ou temperatura).</li>
</ul>



<h3 class="wp-block-heading">Desvantagens no projeto</h3>



<ul class="wp-block-list">
<li><strong>Alta demanda computacional</strong>: Transformers requerem significativamente mais poder de processamento, tanto para treinamento quanto para inferência. Isso ocorre porque o mecanismo de atenção quadrático em relação ao número de entradas exige mais memória e ciclos de CPU/GPU.</li>



<li><strong>Treinamento mais sensível</strong> a overfitting, exigindo bases de dados maiores e técnicas mais avançadas de regularização.</li>



<li><strong>Inferência mais lenta</strong>, o que compromete a aplicação embarcada em dispositivos como Raspberry Pi ou microcontroladores com TensorFlow Lite.</li>
</ul>



<h3 class="wp-block-heading">Comparativo prático com CNN</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Característica</th><th>CNN</th><th>Transformer</th></tr></thead><tbody><tr><td><strong>Tipo de dependência</strong></td><td>Local (com filtros)</td><td>Global (com atenção)</td></tr><tr><td><strong>Velocidade de inferência</strong></td><td>Alta (tempo linear)</td><td>Mais lenta (tempo quadrático)</td></tr><tr><td><strong>Requisitos de RAM</strong></td><td>Moderado</td><td>Elevado</td></tr><tr><td><strong>Necessita GPU?</strong></td><td>Não obrigatoriamente</td><td>Fortemente recomendado</td></tr><tr><td><strong>Uso em embarcados</strong></td><td>Amplo (compatível com TFLite, uTensor)</td><td>Limitado (não suportado diretamente)</td></tr><tr><td><strong>Bibliotecas recomendadas</strong></td><td><code>TensorFlow</code>, <code>Keras</code>, <code>TFLite</code></td><td><code>PyTorch</code>, <code>Transformers (HuggingFace)</code></td></tr><tr><td><strong>Facilidade de treinamento</strong></td><td>Alta</td><td>Média a baixa (depende do modelo)</td></tr><tr><td><strong>Tamanho típico do modelo</strong></td><td>Pequeno a médio</td><td>Médio a grande</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">Impacto no projeto</h3>



<p class="wp-block-paragraph">No simulador de diagnóstico por magnetostricção disponível em <a class="" href="https://github.com/rapporttecnologia/simulador_magnetostriccao">rapporttecnologia/simulador_magnetostriccao</a>, o uso de CNNs permite a execução do modelo em tempo real em sistemas com baixo consumo energético, como Raspberry Pi, Jetson Nano ou até mesmo microcontroladores avançados com suporte a inferência neural (ex.: STM32N6 com acelerador ST-NN).</p>



<p class="wp-block-paragraph">Já os Transformers, embora promissores, ainda são mais adequados para execução em estações de trabalho com GPU (ex.: Nvidia RTX, Google Colab) ou servidores em nuvem, o que limita sua aplicação em cenários de campo onde recursos são restritos. Sua adoção pode ser interessante em etapas offline do projeto, como na análise posterior de grandes volumes de dados coletados, ou em um sistema híbrido onde a CNN atua embarcada e o Transformer opera em segundo plano para casos complexos.</p>



<h2 class="wp-block-heading">Preparação do Sinal para Análise com CNNs</h2>



<p class="wp-block-paragraph">A eficácia de uma Rede Neural Convolucional depende, em grande parte, da qualidade da entrada fornecida. No caso da análise de ruídos de magnetostricção captados por sensores acústicos, é essencial transformar esses sinais brutos em representações que preservem as características relevantes para a detecção de falhas. Este processo envolve diversas etapas de pré-processamento e conversão, até que os dados estejam prontos para serem utilizados no treinamento ou inferência com CNNs.</p>



<h3 class="wp-block-heading">1. Aquisição do Sinal</h3>



<p class="wp-block-paragraph">O primeiro passo é a aquisição dos dados acústicos com amostragem adequada. No projeto, utilizam-se microfones piezoelétricos ou MEMS de alta sensibilidade, conectados a microcontroladores com ADC (Conversor Analógico-Digital) de alta resolução. A frequência de amostragem recomendada deve ser ao menos o dobro da maior frequência esperada no sinal (teorema de Nyquist), o que normalmente significa 20 kHz ou mais para ruídos industriais.</p>



<p class="wp-block-paragraph">Exemplo de código para captura com ADC + DMA no RP2040 ou STM32:</p>



<pre class="wp-block-preformatted"><code>// pseudo-código simplificado<br>adc_config();<br>dma_config();<br>start_sampling();<br></code></pre>



<h3 class="wp-block-heading">2. Filtragem e Normalização</h3>



<p class="wp-block-paragraph">Uma vez captado, o sinal pode conter ruídos externos, como interferência elétrica ou vibração ambiental. A filtragem passa-baixa, passa-banda ou notch (anti-ruído) pode ser aplicada para isolar as frequências de interesse. Além disso, a normalização do sinal para o intervalo [0,1] ou [-1,1] garante que o treinamento da rede não seja afetado por amplitudes desbalanceadas.</p>



<pre class="wp-block-preformatted"><code># Exemplo de normalização em Python<br>signal = signal / np.max(np.abs(signal))<br></code></pre>



<h3 class="wp-block-heading">3. Segmentação Temporal</h3>



<p class="wp-block-paragraph">O sinal contínuo é então dividido em janelas (segmentos) fixos de tempo, geralmente entre 0,5s a 2s. Cada janela representará uma amostra independente para o treinamento da CNN. Isso facilita a criação de datasets balanceados, inclusive com múltiplos exemplos por gravação de campo.</p>



<pre class="wp-block-preformatted"><code># Segmentação do sinal<br>window_size = 2048<br>segments = [signal[i:i+window_size] for i in range(0, len(signal)-window_size, step)]<br></code></pre>



<h3 class="wp-block-heading">4. Conversão em Espectrogramas</h3>



<p class="wp-block-paragraph">Cada segmento é transformado em um espectrograma, utilizando a STFT (Short-Time Fourier Transform) ou a escala de Mel (no caso de sinais perceptivos). O espectrograma gerado é então salvo como uma imagem (em tons de cinza ou RGB), compatível com a entrada de CNNs.</p>



<pre class="wp-block-preformatted"><code>import matplotlib.pyplot as plt<br>from scipy.signal import spectrogram<br><br>f, t, Sxx = spectrogram(segment, fs=fs)<br>plt.pcolormesh(t, f, 10 * np.log10(Sxx))<br>plt.axis('off')<br>plt.savefig("sample.png", bbox_inches='tight', pad_inches=0)<br></code></pre>



<h3 class="wp-block-heading">5. Criação dos Conjuntos de Dados</h3>



<p class="wp-block-paragraph">As imagens geradas são organizadas em diretórios por classes: por exemplo, <code>normal/</code>, <code>falha_leve/</code>, <code>falha_grave/</code>. Essa estrutura é compatível com funções de carregamento automático de imagens em bibliotecas como TensorFlow, Keras e PyTorch, que assumem um modelo de classificação supervisada.</p>



<pre class="wp-block-preformatted"><code>dataset/<br>├── normal/<br>│   ├── 001.png<br>│   ├── 002.png<br>├── falha_leve/<br>│   ├── 001.png<br>│   ├── 002.png<br></code></pre>



<h2 class="wp-block-heading">Treinando uma CNN para Diagnóstico de Transformadores</h2>



<p class="wp-block-paragraph">Após o preparo do sinal e conversão dos segmentos em espectrogramas, o próximo passo é treinar uma Rede Neural Convolucional (CNN) capaz de classificar automaticamente o estado dos transformadores com base nos padrões acústicos. Essa etapa envolve a definição da arquitetura da rede, o carregamento dos dados, o treinamento supervisionado e a validação dos resultados.</p>



<h3 class="wp-block-heading">1. Bibliotecas e Ambiente</h3>



<p class="wp-block-paragraph">Para esse processo, as bibliotecas mais indicadas são:</p>



<ul class="wp-block-list">
<li><strong>TensorFlow/Keras</strong> – para construção e treinamento do modelo;</li>



<li><strong>NumPy e Matplotlib</strong> – para manipulação de dados e visualização;</li>



<li><strong>scikit-learn</strong> – para métricas de avaliação.</li>
</ul>



<p class="wp-block-paragraph">O ambiente pode ser um Jupyter Notebook, Google Colab (com GPU ativada), ou uma estação de trabalho com Python ≥ 3.8.</p>



<pre class="wp-block-preformatted">bashCopiarEditar<code>pip install tensorflow numpy matplotlib scikit-learn
</code></pre>



<h3 class="wp-block-heading">2. Carregando os Dados de Imagem</h3>



<pre class="wp-block-preformatted">Assumindo que os espectrogramas estejam organizados em diretórios por classe, é possível utilizar <code>ImageDataGenerator</code> do Keras para leitura automática e normalização das imagens.<br><br><code>from tensorflow.keras.preprocessing.image import ImageDataGenerator<br><br>datagen = ImageDataGenerator(validation_split=0.2, rescale=1./255)<br><br>train_generator = datagen.flow_from_directory(<br>    'dataset/',<br>    target_size=(128, 128),<br>    batch_size=32,<br>    class_mode='categorical',<br>    subset='training'<br>)<br><br>val_generator = datagen.flow_from_directory(<br>    'dataset/',<br>    target_size=(128, 128),<br>    batch_size=32,<br>    class_mode='categorical',<br>    subset='validation'<br>)<br></code></pre>



<h3 class="wp-block-heading">3. Definindo a Arquitetura da CNN</h3>



<p class="wp-block-paragraph">Aqui está um exemplo básico de CNN adequada para espectrogramas monocromáticos 128×128:</p>



<pre class="wp-block-preformatted"><code>from tensorflow.keras.models import Sequential<br>from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout<br><br>model = Sequential([<br>    Conv2D(32, (3, 3), activation='relu', input_shape=(128, 128, 3)),<br>    MaxPooling2D(2, 2),<br>    Conv2D(64, (3, 3), activation='relu'),<br>    MaxPooling2D(2, 2),<br>    Flatten(),<br>    Dense(128, activation='relu'),<br>    Dropout(0.5),<br>    Dense(train_generator.num_classes, activation='softmax')<br>])<br></code></pre>



<h3 class="wp-block-heading">4. Compilando e Treinando o Modelo</h3>



<pre class="wp-block-preformatted"><code>model.compile(optimizer='adam',<br>              loss='categorical_crossentropy',<br>              metrics=['accuracy'])<br><br>history = model.fit(<br>    train_generator,<br>    epochs=20,<br>    validation_data=val_generator<br>)<br></code></pre>



<p class="wp-block-paragraph">Durante o treinamento, o modelo ajusta os filtros convolucionais para reconhecer padrões específicos de cada classe (ruído normal, falhas leves, falhas críticas), aprendendo diretamente dos dados sem necessidade de rotinas manuais de extração de <em>features</em>.</p>



<h3 class="wp-block-heading">5. Avaliação e Interpretação dos Resultados</h3>



<p class="wp-block-paragraph">Após o treinamento, os resultados podem ser avaliados com base em métricas como acurácia, matriz de confusão e curva ROC. O modelo pode ser salvo em formato <code>.h5</code> para inferência posterior, inclusive embarcada.</p>



<pre class="wp-block-preformatted"><code>model.save("modelo_transformador.h5")<br></code></pre>



<h2 class="wp-block-heading">Implementando a Inferência em Sistemas Embarcados</h2>



<p class="wp-block-paragraph">Após o treinamento da Rede Neural Convolucional (CNN) em um ambiente de alto desempenho (como uma estação com GPU ou Google Colab), o próximo desafio é implementar o modelo em dispositivos embarcados que realizam a inferência localmente, como Raspberry Pi, Jetson Nano, ESP32 com coprocessador, ou MCUs STM32 com suporte a unidades neurais. Essa etapa exige a conversão e otimização do modelo, visando reduzir seu tamanho, consumo de energia e tempo de resposta.</p>



<h3 class="wp-block-heading">1. Conversão para TensorFlow Lite</h3>



<p class="wp-block-paragraph">O TensorFlow Lite (TFLite) é uma versão compacta do TensorFlow voltada para inferência em dispositivos embarcados. Ele permite converter o modelo <code>.h5</code> treinado em um formato binário leve (<code>.tflite</code>), que pode ser carregado diretamente no dispositivo.</p>



<pre class="wp-block-preformatted"><code>import tensorflow as tf<br><br># Carregar modelo treinado<br>model = tf.keras.models.load_model('modelo_transformador.h5')<br><br># Converter para TFLite<br>converter = tf.lite.TFLiteConverter.from_keras_model(model)<br>tflite_model = converter.convert()<br><br># Salvar em disco<br>with open('modelo_transformador.tflite', 'wb') as f:<br>    f.write(tflite_model)<br></code></pre>



<p class="wp-block-paragraph">Opcionalmente, é possível aplicar técnicas de quantização (como <code>float16</code>, <code>int8</code>) para reduzir ainda mais o tamanho do modelo e acelerar sua execução:</p>



<pre class="wp-block-preformatted">pythonCopiarEditar<code>converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model_quant = converter.convert()
</code></pre>



<h3 class="wp-block-heading">2. Inferência em Raspberry Pi ou Jetson</h3>



<p class="wp-block-paragraph">Em dispositivos Linux embarcados como o Raspberry Pi 4, a inferência com TFLite pode ser feita com Python ou C++. Bibliotecas como <code>tflite_runtime</code> ou o próprio TensorFlow permitem carregar o modelo e executar a classificação.</p>



<pre class="wp-block-preformatted"><code>import numpy as np<br>import tensorflow as tf<br>from PIL import Image<br><br>interpreter = tf.lite.Interpreter(model_path="modelo_transformador.tflite")<br>interpreter.allocate_tensors()<br><br>input_details = interpreter.get_input_details()<br>output_details = interpreter.get_output_details()<br><br># Pré-processar imagem<br>img = Image.open("espectrograma.png").resize((128, 128))<br>input_data = np.expand_dims(np.array(img, dtype=np.float32) / 255.0, axis=0)<br><br># Inferência<br>interpreter.set_tensor(input_details[0]['index'], input_data)<br>interpreter.invoke()<br>output = interpreter.get_tensor(output_details[0]['index'])<br></code></pre>



<h3 class="wp-block-heading">3. Execução em Microcontroladores</h3>



<p class="wp-block-paragraph">Para MCUs como os da família <strong>STM32N6</strong> (com acelerador ST-Neural ART) ou até RP2040 com interfaces externas, é possível usar o <strong>TensorFlow Lite for Microcontrollers</strong>. Nesse caso, o modelo é convertido para um array C/C++ com <code>xxd</code> ou <code>xxd -i</code>:</p>



<pre class="wp-block-preformatted">bashCopiarEditar<code>xxd -i modelo_transformador.tflite &gt; modelo.h
</code></pre>



<p class="wp-block-paragraph">E o modelo é embutido no firmware:</p>



<pre class="wp-block-preformatted"><code>#include "modelo.h"<br>// Código para inicializar o interpretador e executar a inferência<br></code></pre>



<p class="wp-block-paragraph">A biblioteca TFLite-Micro cuida da execução do modelo mesmo sem sistema operacional, embora com algumas limitações: apenas quantização int8, sem suporte a camadas complexas (ex: convoluções dilatadas).</p>



<h3 class="wp-block-heading">4. Impactos e Otimizações</h3>



<ul class="wp-block-list">
<li><strong>Velocidade</strong>: A inferência com TFLite é rápida (tipicamente &lt; 100ms) em Raspberry Pi, e até &lt; 10ms com GPU/Coprocessador.</li>



<li><strong>Consumo</strong>: O uso local evita comunicação contínua com servidores, reduzindo energia e melhorando privacidade.</li>



<li><strong>Custo</strong>: Dispositivos baratos (&lt; R$ 300) podem rodar o modelo com precisão próxima ao ambiente de treinamento.</li>



<li><strong>Escalabilidade</strong>: A abordagem permite replicar sensores autônomos em diversos pontos da rede elétrica.</li>
</ul>



<h2 class="wp-block-heading">Conclusão</h2>



<p class="wp-block-paragraph">A aplicação de Redes Neurais Convolucionais (CNNs) à análise de ruídos de magnetostricção representa um avanço significativo no diagnóstico não invasivo da saúde de transformadores. Ao transformar sinais acústicos em representações espectrais, e posteriormente aplicar técnicas de aprendizado profundo, torna-se possível detectar padrões sutis que indicam falhas mecânicas ou elétricas incipientes, com precisão superior às abordagens tradicionais.</p>



<p class="wp-block-paragraph">Neste artigo, percorremos desde os fundamentos das CNNs até as suas aplicações práticas no projeto “Análise da Saúde de Transformadores com Base em Ruídos de Magnetostricção”. Discutimos em detalhes o processo de preparação do sinal, a construção do espectrograma, o treinamento supervisionado da rede, e sua posterior implementação em sistemas embarcados. Também comparamos, de forma crítica, as CNNs com outras arquiteturas como Transformers, destacando seus pontos fortes e limitações no contexto de execução em tempo real e em ambientes com recursos restritos.</p>



<p class="wp-block-paragraph">A integração com o simulador disponível em <a class="" href="https://github.com/rapporttecnologia/simulador_magnetostriccao">rapporttecnologia/simulador_magnetostriccao</a> permite que pesquisadores e engenheiros explorem e reproduzam os resultados obtidos, promovendo reprodutibilidade científica e abrindo espaço para otimizações contínuas.</p>



<p class="wp-block-paragraph">Ao democratizar o uso de inteligência artificial em sistemas de monitoramento industriais, especialmente em dispositivos de baixo custo, este trabalho contribui não apenas para o avanço tecnológico, mas também para a sustentabilidade e confiabilidade da infraestrutura elétrica. Com a contínua evolução das arquiteturas de redes neurais, espera-se que soluções ainda mais eficientes e precisas estejam ao alcance de projetos similares nos próximos anos.</p><p>The post <a href="https://mcu.tec.br/energia/cnns-na-analise-de-ruidos-em-transformadores-com-ia/">CNNs na Análise de Ruídos em Transformadores com IA</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">527</post-id>	</item>
	</channel>
</rss>
