<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel>
<title><![CDATA[DSP AI]]></title> 
<atom:link href="https://dsp-ai.com/rss.php" rel="self" type="application/rss+xml" />
<description><![CDATA[主要对DSP基础算法与AI基础算法笔记]]></description>
<link>https://dsp-ai.com/</link>
<language>zh-cn</language>
<generator>emlog</generator>

<item>
    <title>GPU</title>
    <link>https://dsp-ai.com/?post=12</link>
    <description><![CDATA[<p>jetson orin nano 学习记录</p>]]></description>
    <pubDate>Mon, 09 Feb 2026 03:29:17 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://dsp-ai.com/?post=12</guid>
</item>
<item>
    <title>K230案例下载地址汇总</title>
    <link>https://dsp-ai.com/?post=11</link>
    <description><![CDATA[<p>波形识别<br />
<a href="http://dsp-ai.com/?resource_alias=XTydgxROreRrS11R&amp;resource_filename=38221770279726">波形识别.rar</a></p>]]></description>
    <pubDate>Thu, 05 Feb 2026 16:20:19 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://dsp-ai.com/?post=11</guid>
</item>
<item>
    <title>FPGA学习笔记</title>
    <link>https://dsp-ai.com/?post=10</link>
    <description><![CDATA[<p>初学 慢慢更新</p>]]></description>
    <pubDate>Mon, 02 Feb 2026 09:38:38 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://dsp-ai.com/?post=10</guid>
</item>
<item>
    <title>K230 PIN</title>
    <link>https://dsp-ai.com/?post=9</link>
    <description><![CDATA[<pre><code class="language-python">from machine import FPIOA
from machine import Pin
import time
fpioa = FPIOA()
# 设置Pin2为GPIO2
fpioa.set_function(2, FPIOA.GPIO2)
# 将 Pin2 实例化为输出模式，并配置为无上下拉（PULL_NONE），驱动能力为 7
pin = Pin(2, Pin.OUT, pull=Pin.PULL_NONE, drive=7)

# 设置 Pin2 输出高电平
while True:
    pin.value(1)
    # 设置 Pin2 输出低电平
    time.sleep_ms(10) #避免CPU满跑
    pin.value(0)
    time.sleep_ms(10) #避免CPU满跑
</code></pre>
<p><img src="https://blog.power-edge.cn/content/uploadfile/202411/93691732602241.jpg" alt="" /></p>]]></description>
    <pubDate>Sun, 25 Jan 2026 00:13:36 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://dsp-ai.com/?post=9</guid>
</item>
<item>
    <title>理解数字信号处理系列笔记——Micropython版</title>
    <link>https://dsp-ai.com/?post=7</link>
    <description><![CDATA[<h2>理解数字信号处理</h2>
<pre><code>数字信号处理将模拟信号转换为数字信号，这样的离散值在处理时会有哪些不同于模拟量的方式呢？
模拟信号处理与数字信号处理的差异是什么呢？能够达到同样的设计结果呢？
怎么实现数字信号处理呢，理论与实现之间的如果过渡的呢？</code></pre>
<p>本系列笔记主要集中对以上问题进行学习、思考、验证的记录</p>
<h2>笔记采用的工具</h2>
<pre><code>软件：
1）信号处理软件：MATLAB、
2）硬件开发软件：CanMV K230 IDE 串口上位机（VOFA+） 

硬件：
1）传感器：ADC、DAC、串口模块、摄像头
2）数据处理单元：K230

自备：
1）数字信号处理相关书籍（因为重点会介绍算法到硬件部署的内容）
2）Micropython相关资料（将理论转换为Micropython代码）</code></pre>
<h2>前言</h2>
<p>实现数字信号处理，在硬件上运行输出结果可以更加感性直观地理解数字信号处理。同时，对于算法能否应用也有一定的认识，避免盲目一味追求高大上的算法，尽量实际应用算法。<br />
对于硬件的选择，国产、资料多、编程简单、支持AI。相对而言，AI对于大多数MCU运行一个简单的神经元是没问题的，但AI模型含有大量参数内存与计算速度往往受限，较难部署到设备端。<br />
嘉楠勘智的K230的RISC-V芯片成为了一个很好的选择，笔记使用CanMV K230相关开发板。可以在利用MicroPython快速开发DSP算法与AI算法，可以达到验证DSP效果，降低学习的时间成本。<br />
<strong>目的：将DSP理论公式转换为Micropython代码，部署到CanMV K230开发板中，实现理论并应用</strong></p>
<p>让我们开始用MicroPython（代码）在CanMV K230开发板（硬件）上实现DSP算法（理论）吧</p>
<p>笔记主要包含两个部分的内容：<br />
1）基本数字信号理论算法的实现，持续更新<br />
2）数字信号处理的简单应用，持续更新</p>
<h2>目录</h2>
<h3>1 CanMV K230的DSP框架</h3>
<p>1.1 CanMV K230的DSP框架<br />
1.2 CanMV K230 ADC案例(AD7606)<br />
1.3 CanMV DAC案例(TLV5638)<br />
1.4 CanMV UART案例</p>
<h3>2 理解傅里叶变换</h3>
<h4>2.1 傅里叶变换</h4>
<p>CanMV k230 案例2.1——DFT实现<br />
CanMV k230 案例2.2——FFT实现<br />
CanMV k230 案例2.3——ADC+DFT/FFT+UART测试<br />
CanMV k230 案例2.4——量化误差（四）<br />
CanMV k230 案例2.5——FFT加速<br />
CanMV k230 案例2.6——多种实现FFT的方式（扩展内容）</p>
<h4>2.2 傅里叶变换扩展</h4>
<p>CanMV k230 案例2.7——短时傅里叶STFT<br />
CanMV k230 案例2.8——STFT参数理解<br />
CanMV k230 案例2.9——实时STFT（ADC+STFT）（三）（预告）</p>
<h3>3 理解FIR滤波器</h3>
<p>CanMV k230 案例3.1——FIR滤波器<br />
CanMV k230 案例3.2——实时FIR滤波器原理<br />
CanMV k230 案例3.3——实时FIR（ADC+FIR+UART）</p>
<h3>4 理解IIR滤波器</h3>
<p>CanMV k230 案例4.1——IIR滤波器<br />
CanMV k230 案例4.2——实时IIR滤波器原理<br />
CanMV k230 案例4.3——实时IIR（ADC+IIR+UART）</p>
<h3>5 理解小波变换</h3>
<p>CanMV k230 案例5.1——小波变换<br />
CanMV k230 案例5.2——离散小波变换<br />
CanMV k230 案例5.3——小波奇异性检测</p>
<h3>6 理解S变换(Stockwell Transform)</h3>
<p>Canmv k230 案例6.1—— S变换(Stockwell Transform)<br />
Canmv k230 案例6.2—— S变换实现</p>
<h3>7 理解经验模态分解EMD</h3>
<p>Canmv k230 DSP案例7.1——EMD经验模态分解简介<br />
Canmv k230 DSP案例7.2——EMD基本原理<br />
Canmv k230 DSP案例7.3——EMD Canmv k230 实现</p>
<p>数字信号处理算法应用<br />
大概是一个复杂信号，采用上述的各种DSP算法处理并比较优劣</p>
<h3>8 应用案例</h3>
<p>DSP+AI综合应用案例1——三种波形识别</p>
<p>目前的内容如上所示，欢迎交流讨论</p>]]></description>
    <pubDate>Sun, 25 Jan 2026 00:09:16 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://dsp-ai.com/?post=7</guid>
</item>
<item>
    <title>CanMV K230 第一个micropython案例（修正中）——单次Dense网络</title>
    <link>https://dsp-ai.com/?post=6</link>
    <description><![CDATA[<p>这是不断进行迭代的版本，因此这个过程会比较长，帖子可能也会比较长</p>
<p>官网地址：<a href="https://www.canaan-creative.com/">https://www.canaan-creative.com/</a><br />
在官网的开发者社区页面可以看到镜像、开发工具、在线文档等资料。<br />
目前K230已经存在了几种不同的开发板</p>
<p>笔记计划在两款开发板中测试</p>
<p>笔记的主要内容：<br />
CanMV K230 第一个micropython案例（修正版）——单层Dense网络<br />
简单来说就是一个一次的线性函数，形式y=ax+b</p>
<p>开发环境如下：<br />
系统:ubuntu20.04<br />
环境:jupyter、tensorflow（生成原始模型）、k230sdk (用于转换模型，版本待定)<br />
测试工具：CanMV-IDE（运行micropython）</p>
<p>k230部分的基本流程：在ubuntu安装k230sdk，用于对tensorflow模型进行转换（及后续的编译C++文件），将转换后的kmodel文件在CanMV-IDE中进行测试</p>
<p>省略ubuntu系统安装，及环境安装过程</p>
<p>在jupyter中导入tensorflow包并进行简单模型开发，需要进行拟合的函数目标为y=2x-1<br />
代码如下</p>
<p>CanMV K230开发板使用案例<br />
CanMV-IDE可以通过python变成开发，简化了开发过程，但还是涉及kmodel转换<br />
主要流程为开发模型，模型转换及测试，模型部署.</p>
<p>CanMV K230开发板Micropython开发<br />
模型转换</p>
<pre><code class="language-python">import tensorflow as tf 
import numpy as np
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
#拟合一个一次函数 Y=2X-1
Y = Dense(units=1, input_shape=[1])
model = Sequential([Y])
model.compile(optimizer='sgd', loss='mean_squared_error')
xs = np.array([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0], dtype=float)
ys = np.array([-3.0, -1.0, 1.0, 3.0, 5.0, 7.0], dtype=float)
model.fit(xs, ys, epochs=500)
#显示测试结果及参数
print(model.predict([10.0])) #测试结果
print("Here is what I learned: {}".format(Y.get_weights()))</code></pre>
<p>将模型进行保存或转换，目前的文档支持的格式为：<br />
1）tflite<br />
2）onnx<br />
可能是由于开发主要集中在图像处理领域，输入的维度一般为4维，对于1维数据转换tflite可能存在动态形状的原因转换kmodel模型失败。因此推荐采用onnx格式。</p>
<p>对tensorflow模型转换的代码如下</p>
<pre><code class="language-python">import tensorflow as tf
import os
import onnx
#需要先使用model.save方法保存模型
model.save('model')
#调用tf2onnx将上一步保存的模型导出为ONNX
os.system("python3 -m tf2onnx.convert --saved-model model --output test1.onnx --opset 11")</code></pre>
<p>转换完成需要进行校验，最好每个步骤后都进行校验</p>
<p>检测是否转换成功</p>
<pre><code class="language-python">import onnx
#载入模型
onnx_model = onnx.load("./test1.onnx")
check = onnx.checker.check_model(onnx_model)
print('Check: ', check) # 返回 Check:  None 为成功</code></pre>
<p>可视化转换的模型结构与设计的结构是否相同，可以采用netron打开原始模型与onnx模型进行比对，以确认转换无误<br />
例如转换后可能存在的输入输出维度异常问题</p>
<p>在netron上打开onnx模型，如下图所示，可以看到输入输出存在问题，需要采用下列代码进行更改</p>
<pre><code class="language-python">import onnx
onnx_model = onnx.load("./test1.onnx")
onnx_model.graph.input[0].type.tensor_type.shape.dim[0].dim_value = 1
onnx_model.graph.output[0].type.tensor_type.shape.dim[0].dim_value = 1
onnx.save(onnx_model, './test1_dim.onnx')</code></pre>
<p>修正结果如图<br />
以上完成了步骤1：原始模型开发</p>
<p>步骤2：原始模型转换——kmodel模型<br />
kmodel模型可以理解为可以被没有配置tensorflow相关环境的硬件设备中运行的文件，同时可以实现原始模型的加速</p>
<p>此处需要采用的k230sdk开发工具，将准换onnx模型转换为kmodel模型</p>
<p>转换过程如下：<br />
1）配置环境变量</p>
<pre><code class="language-python">import os
import sys
import subprocess

result = subprocess.run(["pip", "show", "nncase"], capture_output=True)

split_flag = "\n"
if sys.platform == "win32":
    split_flag = "\r\n"

location_s = [i for i in result.stdout.decode().split(split_flag) if i.startswith("Location:")]
location = location_s[0].split(": ")[1]

if "PATH" in os.environ:
    os.environ["PATH"] += os.pathsep + location
else:
    os.environ["PATH"] = location</code></pre>
<p>2）定义转换参数</p>
<pre><code class="language-python">import nncase
import numpy as np
from nncase_base_func import *

def compile_kmodel(model_path, dump_path, calib_data):
    """
    Set compile options and ptq options.
    Compile kmodel.
    Dump the compile-time result to 'compile_options.dump_dir'
    """
    print("\n----------   compile    ----------")
    print("Simplify...")
    model_file = model_simplify(model_path)

    print("Set options...")
    # import_options
    import_options = nncase.ImportOptions()

    ############################################
    # The code below, you need to modify to fit your model.
    # You can find more details about these options in docs/USAGE_v2.md.
    ############################################
    # compile_options
    compile_options = nncase.CompileOptions()
    compile_options.target = "k230" #"cpu"
    compile_options.dump_ir = False  # if False, will not dump the compile-time result.
    compile_options.dump_asm = True
    compile_options.dump_dir = dump_path
    compile_options.input_file = ""

    # preprocess args   不采用预处理过程，应用与原始数据与训练模型输入之间的差异
    compile_options.preprocess = False#True
    if compile_options.preprocess:
        compile_options.input_type = "float32" # "uint8" "float32"
        compile_options.input_shape = [1,1]
        compile_options.input_range = [-1,4]
        compile_options.input_layout = "" # "NHWC"
        compile_options.swapRB = False
        compile_options.mean = [1.5]
        compile_options.std = [1.7]
        compile_options.letterbox_value = 0
        compile_options.output_layout = "" # "NHWC"

    # quantize options
    ptq_options = nncase.PTQTensorOptions()
    ptq_options.quant_type = "uint8"    # datatype : "float32", "int8", "int16"
    ptq_options.w_quant_type = "uint8"  # datatype : "float32", "int8", "int16"
    ptq_options.calibrate_method = "NoClip" # "Kld"
    ptq_options.finetune_weights_method = "NoFineTuneWeights"
    ptq_options.dump_quant_error = True   # False 输出模型推断的误差结果，评估转换情况
    ptq_options.dump_quant_error_symmetric_for_signed = True  #False

    # mix quantize options
    # more details in docs/MixQuant.md
    ptq_options.quant_scheme = ""
    ptq_options.quant_scheme_strict_mode = False
    ptq_options.export_quant_scheme = False
    ptq_options.export_weight_range_by_channel = False
    ############################################

    ptq_options.samples_count = len(calib_data[0])
    ptq_options.set_tensor_data(calib_data)

    print("Compiling...")
    compiler = nncase.Compiler(compile_options)
    # import
    model_content = read_model_file(model_file)
    if model_path.split(".")[-1] == "onnx":
        compiler.import_onnx(model_content, import_options)
    elif model_path.split(".")[-1] == "tflite":
        compiler.import_tflite(model_content, import_options)

    compiler.use_ptq(ptq_options)

    # compile
    compiler.compile()
    kmodel = compiler.gencode_tobytes()

    kmodel_path = os.path.join(dump_path, "test1.kmodel")
    with open(kmodel_path, 'wb') as f:
        f.write(kmodel)
    print("----------------end-----------------")
    return kmodel_path</code></pre>
<p>3）模型转换</p>
<pre><code class="language-python"># compile kmodel single input  动态过程需要预先设置，
model_path = "./test1_dim.onnx"
dump_path = "./test1_onnx"
# sample_count is 2
calib_data = [[100*np.random.rand(1, 1).astype(np.float32), 100*np.random.rand(1, 1).astype(np.float32)]]  # 代表数据集
kmodel_path = compile_kmodel(model_path, dump_path, calib_data)</code></pre>
<p>4）模型测试</p>
<pre><code class="language-python"># run kmodel(simulate)
import os

kmodel_path = "./test1_onnx/test1.kmodel"

input_data=10*np.random.rand(1, 1).astype(np.float32)
print(input_data)
result = run_kmodel(kmodel_path, input_data)
# 输出被限制在代表数据集内 代表数据集的限制
print(result)</code></pre>
<p>以上完成了步骤2：原始模型转换</p>
<p>步骤3：开发板测试</p>
<p>将所需要的文件传输到开发板中的SD中<br />
方式1：scp命令<br />
方式2：读卡器或者PC的sd卡接口拷贝文件<br />
将文件放置在自己知道的路径中，例如<br />
/sdcard/app/tests/k230_test/test1.kmodel</p>
<p>插入SD并打开CanMV-IDE设置自动连接</p>
<p>在CanMV-IDE中编写测试模型的代码，整体流程如下：<br />
1）导入必要的库<br />
2）设置输入<br />
3）开启kpu载入kmodel模型<br />
4）测试模型的输入输出是否符合设计要求<br />
5）运行模型并测试结果<br />
6）释放设备</p>
<p>整体编写代码如下</p>
<pre><code class="language-python">import nncase_runtime as nn
import ulab.numpy as np
# 输入数据
a=np.array([22])
# 开启kpu
kpu = nn.kpu()
# 载入kmodel模型
kpu.load_kmodel("/sdcard/app/tests/k230_test/test1.kmodel")

print("inputs info:")
for i in range(kpu.inputs_size()):
    print(kpu.inputs_desc(i))

print("outputs info:")
for i in range(kpu.outputs_size()):
    print(kpu.outputs_desc(i))

input_data = np.frombuffer(a,dtype=np.float)
print(input_data.shape)
input_data = input_data.reshape((1,1))
print(input_data.shape)

kpu.set_input_tensor(0, nn.from_numpy(input_data))

# run kmodel
kpu.run()

print('input  is : ',a[0])
# get output
for i in range(kpu.outputs_size()):
    result = kpu.get_output_tensor(i)
    result = result.to_numpy()
    print('output is : ',result[0][0])

del kpu
del input_data
del result</code></pre>
<p>CanMV-IDE测试结果如下图所示</p>
<p>图中显示在结果与函数接近30×2-1=59，与设计的结果相近。</p>
<p>存在的问题：<br />
但300、100时其结果为192.625，当数据降为90时正常，采用的是量化模型，并量化过程中设置了输入输出的限制，同时较少的校正数据集也限制了模型的输入输出范围。<br />
尝试的解决方法：扩大范围，否则当应用的实际场景中则可能会存在问题</p>
<p>关于校正数据集的设置后续会展开讨论</p>
<p>后续，对基础模型进行扩展，例如手写数字的识别</p>
<p>以上为简单的一个模型尝试过程，欢迎讨论，后续会补充一些细节及扩展，例如传感器输入数据进行推断，如adc采集或温度传感器等采集数据进行推断等。</p>
<p>CanMV K230开发板使用感受<br />
python开发较为简单，便于模型的快速验证，但实现的功能有限，感觉C++的学习还是有必要的。同时工具链的使用还不熟练，官方的文档等也有待加强，嘻嘻</p>]]></description>
    <pubDate>Sun, 25 Jan 2026 00:03:27 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://dsp-ai.com/?post=6</guid>
</item>
<item>
    <title>K230 推理全流程 以MNIST手写数字识别为例</title>
    <link>https://dsp-ai.com/?post=5</link>
    <description><![CDATA[<p>针对之前的博文有一些细节还没有更新，因此重新整理并给出全部资料</p>
<p>1 加载手写数字数据</p>
<pre><code class="language-python"># 加载手写数字数据 70000个
from tensorflow.keras.datasets import mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
print(train_images.shape)</code></pre>
<p>原始数据为（6000，28，28）构建密集连接网络时需要将数据转换为（6000，28×28）</p>
<pre><code class="language-python"># 数据形状变化转换为一维数据，采用密集连接神经网络
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype("float32") / 255
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype("float32") / 255
# 绘制训练数据
train1=train_images.reshape((60000, 28,28))
import matplotlib.pyplot as plt
for i in range(3):
    digit = train1[i]
    plt.imshow(digit, cmap=plt.cm.binary)
    plt.show()

# 绘制测试数据 共10个这是后面需要测试的数据
test1=test_images.reshape((-1, 28,28))
import matplotlib.pyplot as plt
for i in range(10):
    digit = test1[i]
    plt.imshow(digit, cmap=plt.cm.binary)
    plt.show()
    print(test_labels[i])

for i in range(10):
    print(test_labels[i])

# 不保存数据与后后续测试
import numpy as np
np.save('data.npy', test1[:10])
np.save('data1000.npy', test1[:1000])
# 载入并查看是否符合预期
data=np.load('data.npy')
data.shape
</code></pre>
<p>密集神经网络构建与训练</p>
<pre><code class="language-python">from tensorflow import keras
from tensorflow.keras import layers
model = keras.Sequential([
layers.Dense(512, activation="relu"),
layers.Dense(10, activation="softmax")
])

model.compile(optimizer="rmsprop",
loss="sparse_categorical_crossentropy",
metrics=["accuracy"])

model.fit(train_images, train_labels, epochs=5, batch_size=128)</code></pre>
<p>测试数据推理</p>
<pre><code class="language-python">test_digits = test_images[0:10]
predictions = model.predict(test_digits)
for i in range(10):
    print(predictions[i].argmax())

# 模型评估
test_loss, test_acc = model.evaluate(test_images, test_labels)
print(f"test_acc: {test_acc}")</code></pre>
<p>模型转换为ONNX用于转换为K230上可运行文件预处理</p>
<pre><code class="language-python">import tensorflow as tf
import os
import onnx
#需要先使用model.save方法保存模型
model.save('model')
#调用tf2onnx将上一步保存的模型导出为ONNX
os.system("python3 -m tf2onnx.convert --saved-model model --output test1.onnx --opset 13")
# 检测是否转换正确
import onnx
onnx_model = onnx.load("./test1.onnx")
check = onnx.checker.check_model(onnx_model)
print('Check: ', check) # 返回 Check:  None 为成功
# 修正输入输出名称及数据格式  可以用netron查看
import onnx
onnx_model = onnx.load("./test1.onnx")
check = onnx.checker.check_model(onnx_model)
print('Check: ', check) # 返回 Check:  None 为成功
</code></pre>
<p>以上完成原始数据保持与AI模型的保存</p>
<p>下面开始模型的转换，目标硬件为K230<br />
首先需要安装及下载nncase ，nncase用于转换AI模型在K230上的kmodel格式文件<br />
下载nncase压缩包，在压缩包中的案例中进行更改，简化编程<br />
<a href="https://github.com/kendryte/nncase" title="nncase">nncase</a><br />
文件路径为<br />
nncase/examples/user_guide/<br />
文件截图<br />
<img src="https://blog.power-edge.cn/content/uploadfile/202507/cc5e1753469718.png" alt="" /></p>
<pre><code class="language-python">
# 一段代码应该测试系统环境的
import os
import sys
import subprocess

result = subprocess.run(["pip", "show", "nncase"], capture_output=True)

split_flag = "\n"
if sys.platform == "win32":
    split_flag = "\r\n"

location_s = [i for i in result.stdout.decode().split(split_flag) if i.startswith("Location:")]
location = location_s[0].split(": ")[1]

if "PATH" in os.environ:
    os.environ["PATH"] += os.pathsep + location
else:
    os.environ["PATH"] = location
</code></pre>
<pre><code class="language-python"># 定义模型转换函数
import nncase
import numpy as np
from nncase_base_func import *

def compile_kmodel(model_path, dump_path, calib_data):
    """
    Set compile options and ptq options.
    Compile kmodel.
    Dump the compile-time result to 'compile_options.dump_dir'
    """
    print("\n----------   compile    ----------")
    print("Simplify...")
    model_file = model_simplify(model_path)

    print("Set options...")
    # import_options
    import_options = nncase.ImportOptions()

    ############################################
    # 你需要修改下面这段代码中的参数来适配你的模型。
    # 详细的说明可以参考docs/USAGE_v2.md.
    ############################################
    # compile_options
    compile_options = nncase.CompileOptions()
    compile_options.target = "k230" #"cpu"
    compile_options.dump_ir = True  # if False, will not dump the compile-time result.
    compile_options.dump_asm = True
    compile_options.dump_dir = dump_path
    compile_options.input_file = ""

    # preprocess args
    compile_options.preprocess = False
    if compile_options.preprocess:
        compile_options.input_type = "uint8" # "uint8" "float32"
        compile_options.overwrite_input_shapes = [1,784]
        compile_options.input_range = [0,1]
        compile_options.input_layout = "NHWC" # "NHWC"
        compile_options.swapRB = False
        compile_options.mean = [0,0,0]
        compile_options.std = [1,1,1]
        compile_options.letterbox_value = 0
        compile_options.output_layout = "NHWC" # "NHWC"

    # quantize options
    ptq_options = nncase.PTQTensorOptions()
    ptq_options.quant_type = "uint8" # datatype : "float32", "int8", "int16"
    ptq_options.w_quant_type = "uint8"  # datatype : "float32", "int8", "int16"
    ptq_options.calibrate_method = "NoClip" # "Kld"
    ptq_options.finetune_weights_method = "NoFineTuneWeights"
    ptq_options.dump_quant_error = False
    ptq_options.dump_quant_error_symmetric_for_signed = False

    # mix quantize options
    # more details in docs/MixQuant.md
    ptq_options.quant_scheme = ""
    ptq_options.quant_scheme_strict_mode = False
    ptq_options.export_quant_scheme = False
    ptq_options.export_weight_range_by_channel = False
    ############################################

    ptq_options.samples_count = len(calib_data[0])
    ptq_options.set_tensor_data(calib_data)

    print("Compiling...")
    compiler = nncase.Compiler(compile_options)
    # import
    model_content = read_model_file(model_file)
    if model_path.split(".")[-1] == "onnx":
        compiler.import_onnx(model_content, import_options)
    elif model_path.split(".")[-1] == "tflite":
        compiler.import_tflite(model_content, import_options)

    compiler.use_ptq(ptq_options)

    # compile
    compiler.compile()
    kmodel = compiler.gencode_tobytes()

    kmodel_path = os.path.join(dump_path, "test.kmodel")
    with open(kmodel_path, 'wb') as f:
        f.write(kmodel)
    print("----------------end-----------------")
    return kmodel_path
</code></pre>
<pre><code class="language-python"># 载入保存的数据 主要用于代表数据集与 模型推理输入
import numpy as np
data=np.load('data1000.npy')
data=data.reshape((-1,28 * 28))
print(data.shape)
print(data.dtype)
# len(data)
calib_data=[]
for i in range(2):
    calib_data.append(data[0].reshape(1,-1))

calib_data=[calib_data]</code></pre>
<pre><code class="language-python"># 模型转换
# compile kmodel single input
model_path = "./test1_dim.onnx"
dump_path = "./test1_dim"

# 校正集的数量为2
#calib_data = [[np.random.rand(1, 784).astype(np.float32), np.random.rand(1, 784).astype(np.float32)]]
#calib_data = [[data.astype(np.float32)]]

kmodel_path = compile_kmodel(model_path, dump_path, calib_data)
</code></pre>
<pre><code class="language-python"># 输出推理结果与原始标签对比 需要在优化下，增加原始标签准确率输出
# run kmodel(simulate)
import os

kmodel_path = "./test1_dim/test.kmodel"
for i in range(10):
    input_data = [data[i].reshape(1,-1)]
    result = run_kmodel(kmodel_path, input_data)
    print("最大值:", result[0][0].max(), "索引:", result[0][0].argmax())

for idx, i in enumerate(result):
    print(i.shape)
    i.tofile(os.path.join(dump_path,"nncase_result_{}.bin".format(idx)))</code></pre>
<p>导入输入到K230中的SD卡，现在windows可以直接显示K230文件夹，可以直接将所需文件复制到相应位置<br />
需要导入转换后的模型与需要载入的推理数据<br />
<img src="https://blog.power-edge.cn/content/uploadfile/202507/2b441753471318.png" alt="" /></p>
<p>K230中运行的代码</p>
<pre><code class="language-python">import nncase_runtime as nn
import ulab.numpy as np

# init kpu and load kmodel
kpu = nn.kpu()
kpu.load_kmodel("/sdcard/HY/test.kmodel") # 存储模型位置

data=np.load('/sdcard/HY/data.npy')
print('data.shape',data.shape)
data1=data.reshape((10,-1))
print('data1.shape',data1.shape)
# dump model input and output info
print("inputs info:")
for i in range(kpu.inputs_size()):
    print(kpu.inputs_desc(i))

print("outputs info:")
for i in range(kpu.outputs_size()):
    print(kpu.outputs_desc(i))

#input_data=np.zeros((1,784), dtype=np.float)
for i in range(10):
    kpu.set_input_tensor(0, nn.from_numpy(data1[i]))
    # run kmodel
    kpu.run()
    # get output
    result = kpu.get_output_tensor(0)
    result = result.to_numpy()
    print('mnist result is {0} scores is {1}:'.format(np.argmax(result),np.max(result)))
</code></pre>
<p>输出结果<br />
<img src="https://blog.power-edge.cn/content/uploadfile/202507/3de61753471386.png" alt="" /></p>
<p>生成的文件<br />
<a href="https://blog.power-edge.cn/content/uploadfile/202507/61511753471541.rar" title="K230_MNIST">K230_MNIST</a></p>
<p>1 数据生成<br />
直接采集或者其他设备传递<br />
摄像头<br />
ADC<br />
SPI传输等</p>
<p>2 数据预处理<br />
转换为符合输入到AI模型中的格式</p>
<p>3 数据AI模型<br />
建模，例如手写字母识别</p>
<p>4 AI模型转换 KPU加速<br />
K230加速，采用设备进行类别转换或者是原始浮点信号推理</p>
<p>5 输出结果及后处理<br />
输出数据后处理，转换或者显示 或者与其他设备通信</p>]]></description>
    <pubDate>Sun, 25 Jan 2026 00:02:00 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://dsp-ai.com/?post=5</guid>
</item>
<item>
    <title>CanMV K230</title>
    <link>https://dsp-ai.com/?post=3</link>
    <description><![CDATA[<p>目前主要采用CanMV K230进行案例分享<br />
<img src="http://dsp-ai.com/content/uploadfile/202601/b0c71769268676.jpg" alt="b0c71769268676.jpg" /></p>
<p>主要参考网址</p>]]></description>
    <pubDate>Sat, 24 Jan 2026 23:30:44 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://dsp-ai.com/?post=3</guid>
</item>
<item>
    <title>hahahah</title>
    <link>https://dsp-ai.com/?post=2</link>
    <description><![CDATA[<p>sdasfddasf a</p>]]></description>
    <pubDate>Sat, 24 Jan 2026 23:15:21 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://dsp-ai.com/?post=2</guid>
</item>
<item>
    <title>主要内容</title>
    <link>https://dsp-ai.com/?post=1</link>
    <description><![CDATA[<p>主要对DSP基础算法与AI基础算法笔记</p>
<p><a href="http://dsp-ai.com/">http://dsp-ai.com/</a></p>]]></description>
    <pubDate>Sat, 24 Jan 2026 23:08:41 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://dsp-ai.com/?post=1</guid>
</item>
</channel>
</rss>