中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

網(wǎng)站運(yùn)營(yíng)淘寶關(guān)鍵詞挖掘工具

網(wǎng)站運(yùn)營(yíng),淘寶關(guān)鍵詞挖掘工具,做網(wǎng)站花了2萬(wàn)多,怎么自學(xué)室內(nèi)設(shè)計(jì)與裝修IDE: CLion MCU: STM32F407VET6 一、導(dǎo)向 以求知為導(dǎo)向,從問(wèn)題到尋求問(wèn)題解決的方法,以興趣驅(qū)動(dòng)學(xué)習(xí)。 雖從0,但不到1,剩下的那一小步將由你邁出。本篇主要目的是體驗(yàn)完整的一次簡(jiǎn)單AI模型部署流程&#x…

IDE: CLion

MCU: STM32F407VET6

一、導(dǎo)向

以求知為導(dǎo)向,從問(wèn)題到尋求問(wèn)題解決的方法,以興趣驅(qū)動(dòng)學(xué)習(xí)。

????????雖從0,但不到1,剩下的那一小步將由你邁出。本篇主要目的是體驗(yàn)完整的一次簡(jiǎn)單AI模型部署流程,從數(shù)據(jù)采集到模型創(chuàng)建與訓(xùn)練,再到部署單片機(jī)上。選定的訓(xùn)練方向也非常簡(jiǎn)單,既不是手勢(shì)識(shí)別、語(yǔ)音識(shí)別等這些較為復(fù)雜的模型,也不是使用一些第三方的預(yù)訓(xùn)練模型,而是簡(jiǎn)簡(jiǎn)單單地“調(diào)包”搭建一個(gè)判斷輸入數(shù)字大小的小模型,比如在判斷輸入數(shù)據(jù)是否小于24。最終生成的C代碼其內(nèi)存、存儲(chǔ)占用均為10KB,也可縮減至不到1KB

????????既然是“從零開始”,那么就不需要介紹太多復(fù)雜的術(shù)語(yǔ)解釋,但一些基本的概念還是需要了解的。該篇最主要的目的就是體驗(yàn),不需要知道太多為什么,真正上手實(shí)踐后,再自行學(xué)習(xí)。

? ? ? ? 此處所指的單片機(jī)是STM32系列(stm32f407vet6)

二、流程

1,STM32CubeMX的AI插件

? ? ? ? 想要觸碰一個(gè)未曾熟知的領(lǐng)域,最重要的是要搜集信息,了解要干什么、怎么干,然后簡(jiǎn)單體驗(yàn)一番。那么第一步來(lái)了,我們的問(wèn)題很簡(jiǎn)單,stm32單片機(jī)上怎么跑AI。帶著這個(gè)問(wèn)題我們使用搜索引擎可以得到一些博客,什么模型搭建、部署什么的可能也聽不大懂。

? ? ? ? 但從這些博客里我們可以找到一個(gè)共同點(diǎn),那就是都使用到了STM32CubeMX,雖然AI模型相關(guān)的不太懂,但這個(gè)工具軟件可太熟了。

? ? ? ? 從這里我們可以獲取另一個(gè)關(guān)鍵點(diǎn),就目前所獲取的信息來(lái)看stm32單片機(jī)上跑AI應(yīng)是依賴STM32CubeMX的AI插件的。至于怎么配置這個(gè)AI插件,相關(guān)的博客有很多


?

2,AI模型

? ? ? ? 當(dāng)你興沖沖地使用CubeMX上的AI插件時(shí),你可能會(huì)發(fā)現(xiàn),缺少一件東西——AI模型

? ? ? ? 回想到前面回答中,通義(通義千問(wèn))說(shuō)過(guò)導(dǎo)入模型

? ? ? ? 雖然網(wǎng)上相關(guān)博客有不少,什么手勢(shì)識(shí)別、神經(jīng)網(wǎng)絡(luò)算法等等,但幾乎沒(méi)有幾個(gè)是直接給你一個(gè)AI模型的,要么是到官網(wǎng)的github上找,要么是什么云盤??傊畬?duì)于初學(xué)者而言,是有一些麻煩的

? ? ? ? 接下來(lái)繼續(xù)發(fā)揮“不會(huì)就問(wèn)”的精神

????????通義給了我們四個(gè)方案,但無(wú)論是官方給的,還是用什么第三方的,亦或者使用預(yù)訓(xùn)練模型的,總之都是有一些難度的。四種方案你可以逐一嘗試,嘗試下來(lái)后,你可能會(huì)發(fā)現(xiàn)預(yù)訓(xùn)練、官方模型庫(kù)、第三方庫(kù)這些方案太難了,因?yàn)樯婕暗酱罅磕吧R(shí)。

? ? ? ? 自己訓(xùn)練模型看著比較可行,因?yàn)閺南旅婵梢钥吹?#xff0c;自己訓(xùn)練一個(gè)簡(jiǎn)單模型就兩步,收集數(shù)據(jù)和python編程來(lái)訓(xùn)練模型。無(wú)論是收集數(shù)據(jù),還是編程,似乎都是非常清晰的過(guò)程。

????????當(dāng)然,上面的結(jié)論也是問(wèn)出來(lái)的。當(dāng)通義給你一個(gè)問(wèn)題的回答,而你對(duì)其中的一些概念又含混不清的時(shí)候,你可以把自己的猜測(cè)反問(wèn)給通義,且不必?fù)?dān)心通義出言不遜。

? ? ? ? 反問(wèn)后,無(wú)論你的猜測(cè)是否正確,你最終都會(huì)被指導(dǎo)一個(gè)正確的方向。

? ? ? ? 既然確定了步驟,不妨問(wèn)問(wèn)更細(xì)節(jié)的一些東西,這里需要自行提問(wèn),下面提供一個(gè)簡(jiǎn)單的示例

3,數(shù)據(jù)采集

? ? ? ? 前面說(shuō)過(guò),既然是初學(xué)者,那么一切從簡(jiǎn),怎么簡(jiǎn)單怎么來(lái)。這里先說(shuō)一個(gè)前置信息,AI模型訓(xùn)練需要的數(shù)據(jù)集,一般是保存在.csv文件里的,打開后你會(huì)發(fā)現(xiàn)這跟Excel表格大差不差。

? ? ? ? 使用記事本打開后,你會(huì)發(fā)現(xiàn)頭部會(huì)有一些標(biāo)簽,數(shù)據(jù)是按照列來(lái)排布的

? ? ? ? 左邊那一列是輸入的數(shù)據(jù),右邊那一列是輸出的結(jié)果,當(dāng)然也可以稱為類別

? ? ? ? 訓(xùn)練AI模型時(shí),會(huì)用你收集到的這個(gè)數(shù)據(jù)集訓(xùn)練,以圖中這個(gè)數(shù)據(jù)為例(二分類問(wèn)題),給它左邊的輸入數(shù)據(jù),讓AI模型輸出,然后與數(shù)據(jù)集中的右邊的輸出對(duì)比,來(lái)判斷AI預(yù)測(cè)的結(jié)果,之后AI再不斷調(diào)整權(quán)重、參數(shù)什么的,讓預(yù)測(cè)更加精準(zhǔn)。

? ? ? ? 這些前置信息,你自己也是可以收集的。這里,我們是需要一個(gè)數(shù)據(jù)集來(lái)幫我們訓(xùn)練,也知道數(shù)據(jù)集長(zhǎng)成什么樣子。從一些博客或者AI我們可以了解到,一般的數(shù)據(jù)集都是什么圖像相關(guān)的,什么矩陣、像素、灰度之類的,那顯然還是有些難度的。

? ? ? ? 所以接下來(lái),我們討論更簡(jiǎn)單的情況,就是給AI一個(gè)數(shù)據(jù),讓它判斷是不是小于一個(gè)數(shù),小于就輸出1,大于就輸出0。是不是簡(jiǎn)單很多了?

4、訓(xùn)練模型

? ? ? ? 我們首先要清楚,STM32上跑的這個(gè)AI模型其實(shí)是神經(jīng)網(wǎng)絡(luò)模型,它們之間的關(guān)系是這樣的:

? ? ? ? AI(人工智能)>? 機(jī)器學(xué)習(xí) > 深度學(xué)習(xí) >? 神經(jīng)網(wǎng)絡(luò)模型(非傳統(tǒng)神經(jīng)網(wǎng)絡(luò))

? ? ? ? 總之經(jīng)過(guò)一系列問(wèn)詢之后,我們可以選擇Keras TensorFlow Lite。這是一個(gè)神經(jīng)網(wǎng)絡(luò)框架,不要害怕陌生的術(shù)語(yǔ)名稱,它只是用于訓(xùn)練AI的工具(你也可以理解為庫(kù)或包)。

????????這里我補(bǔ)充一點(diǎn)就是,STM32CubeMX其實(shí)對(duì)Keras的支持其實(shí)并不算好,我們后續(xù)真正使用的是后者。

三、采集數(shù)據(jù)

????????正如前面所言,為了簡(jiǎn)單體驗(yàn)這個(gè)流程,我們就以那個(gè)判斷數(shù)字是否小于某個(gè)數(shù)為訓(xùn)練目的。當(dāng)體驗(yàn)過(guò)這個(gè)簡(jiǎn)單流程后,你可以放飛自我去訓(xùn)練了。

? ? ? ? 這里不說(shuō)怎么安裝Pycharm什么的,因?yàn)檫@是最基本的能力。

? ? ? ? 現(xiàn)在我們把訓(xùn)練目的具體化:在0-100內(nèi),判斷出這個(gè)數(shù)據(jù)是否小于24。那么我們就需要生成這樣的數(shù)據(jù),為了保真,還得讓數(shù)據(jù)隨機(jī)起來(lái),且小于24的和大于24的概率還不同,以增加些許難度。

? ? ? ? 這個(gè)數(shù)據(jù)可以使用python生成,那么怎么寫python腳本呢?從變量命名、標(biāo)識(shí)符開始學(xué)一遍python?那是大可不必的,不需要掌握python(因?yàn)槟阒辽僖颜莆樟薈語(yǔ)言),只需要知道怎么讓通義生成正確的代碼就行了

????????通義生成的代碼不一定可用,你把報(bào)錯(cuò)信息或者調(diào)試信息給它,提供給它需求,讓它不斷更新代碼直至生成可用的代碼。這里不展開細(xì)節(jié)了,下面就是可用的python代碼,如果你是新安裝的pycharm,那么可能會(huì)提示安裝一些庫(kù),安裝軟件包的過(guò)程可能會(huì)有些漫長(zhǎng),這都是正?,F(xiàn)象。有時(shí)間了可以自行查資料解決

import numpy as np
import pandas as pd# 參數(shù)設(shè)置
filename = 'simulated_data.csv'
num_points = 100000
threshold = 24  # 觸發(fā)閾值
low_value_frequency = 0.33  # 低于24的值的概率# 生成數(shù)據(jù)
np.random.seed(0)
data = np.random.randint(0, 101, num_points)  # 生成0到100的整型數(shù)據(jù)# 生成低于24的值
low_values = np.random.binomial(1, low_value_frequency, num_points)
data[low_values == 1] = np.random.randint(0, 24, np.sum(low_values))# 標(biāo)記是否觸發(fā)閾值
labels = (data < threshold).astype(int)# 創(chuàng)建DataFrame
df = pd.DataFrame({'value': data, 'label': labels})# 保存到CSV文件
df.to_csv(filename, index=False)print(f"數(shù)據(jù)已生成并保存到 {filename}")

? ? ? ? 正確執(zhí)行完后,當(dāng)前目錄下就會(huì)有一個(gè)simulated_data.csv文件。

四、訓(xùn)練模型

? ? ? ? 雖然聽著不明覺(jué)厲,其實(shí)這里我們只用非常簡(jiǎn)單有限的步驟,因?yàn)榭蚣芤呀?jīng)幫我們做好了絕大部分工作了。

? ? ? ? 問(wèn)詢你可以描述得更加具體

? ? ? ? 總之,多次讓AI改進(jìn)后,可以得到了一份可以訓(xùn)練剛才數(shù)據(jù)的代碼

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from keras.src.callbacks import ModelCheckpoint
from keras.src.layers import GRU
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.models import save_model
import tensorflow as tf
import subprocess# 數(shù)據(jù)加載
df = pd.read_csv('simulated_data.csv')
X = df['value'].values.reshape(-1, 1)  # 特征值需要reshape為2D數(shù)組
y = df['label'].values# 劃分訓(xùn)練集和測(cè)試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)# 創(chuàng)建模型
model = Sequential([Dense(10, input_shape=(1,), activation='relu'),  # 輸入層(同時(shí)也是隱藏層)# Dense(1, activation='sigmoid')  # 輸出層# GRU(16, input_shape=(1, 1), return_sequences=False),  # 添加GRU層,32個(gè)單元,輸入形狀為 (1, 1),不返回序列Dense(18, activation='relu'),  # 添加一個(gè)全連接層,32個(gè)神經(jīng)元,使用ReLU激活函數(shù)Dense(1, activation='sigmoid')  # 添加全連接層,輸出1個(gè)節(jié)點(diǎn),使用sigmoid激活函數(shù)
])# 編譯模型
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])# 設(shè)置 ModelCheckpoint 回調(diào)函數(shù)
checkpoint = ModelCheckpoint('best_model.keras', monitor='val_accuracy', save_best_only=True, mode='max')# 訓(xùn)練模型
history = model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=78, batch_size=60)# 繪制訓(xùn)練過(guò)程中的損失
plt.figure(figsize=(12, 6))
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Model Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()# 繪制訓(xùn)練過(guò)程中的準(zhǔn)確率
plt.figure(figsize=(12, 6))
plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title('Model Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()# 模型保存
save_model(model, 'model/stm32_model.keras')
# 將 .keras 模型轉(zhuǎn)換為 .tflite 格式
converter = tf.lite.TFLiteConverter.from_keras_model(model)# # 使用 Select TF Ops,雖然允許把Keras轉(zhuǎn)為TFLite模型,但是CubeMX的AI插件不支持
# converter.target_spec.supported_ops = [
#     tf.lite.OpsSet.TFLITE_BUILTINS,  # 支持 TFLite 內(nèi)置操作
#     tf.lite.OpsSet.SELECT_TF_OPS     # 支持 TensorFlow 原生操作
# ]
# # 禁用實(shí)驗(yàn)性降低張量列表操作
# converter._experimental_lower_tensor_list_ops = Falsetflite_model = converter.convert()# 保存 TFLite 模型
with open('model/stm32_model.tflite', 'wb') as f:f.write(tflite_model)
print("TFLite 模型已保存")# # 下面出了問(wèn)題
# # 加載最佳模型
# best_model = tf.keras.models.load_model('best_model.keras')
#
# # 保存最佳模型
# save_model(best_model, 'model/stm32_best_model.keras')
#
# # 將 .keras 模型轉(zhuǎn)換為 .tflite 格式
# # 轉(zhuǎn)換模型
# tflite_model = converter.convert()
#
# # 保存 TFLite 模型
# with open('model/stm32_best_model.tflite', 'wb') as f:
#     f.write(tflite_model)
#
# print("TFLite best模型已保存")

? ? ? ? 這個(gè)代碼,即便你安裝了所有軟件包可能還會(huì)報(bào)錯(cuò),這都是正常現(xiàn)象,可以不用管它

? ? ? ? 訓(xùn)練模型這一步,步驟非常清晰明了

①加載數(shù)據(jù)

②創(chuàng)建模型

這里面可以看到三個(gè)函數(shù),也就是三層神經(jīng)網(wǎng)絡(luò),你想要增加,就再添加一個(gè)函數(shù)即可。只不過(guò)經(jīng)過(guò)我的測(cè)試和官方文檔說(shuō)明,無(wú)法使用更加復(fù)雜的層,比如GRU層(陌生術(shù)語(yǔ)稍微過(guò)一下就行,暫時(shí)可以不必深究)

③編譯模型

????????回調(diào)函數(shù)先不用管它,可加可不加

④訓(xùn)練模型

? ? ? ? 這里只要注意這兩個(gè)參數(shù)即可,一個(gè)是epochs,另一個(gè)是batch_size。前者是訓(xùn)練輪數(shù),后者是每批次訓(xùn)練的數(shù)據(jù)量

⑤評(píng)估模型

????????這里其實(shí)就是圖形化顯示訓(xùn)練的結(jié)果,什么準(zhǔn)確率、損失什么的

⑥保存模型

? ? ? ? 這里可以看到,一開始模型格式為.keras,后面就編程了.tflite。原因就是前者格式STM32CubeMX的AI插件經(jīng)常無(wú)法正常加載,報(bào)一些奇奇怪怪的錯(cuò)。

既然這樣,我們看看運(yùn)行之后是什么樣子的

如果這是你的第一個(gè)AI模型,成就感滿滿了不是

右邊的第二張圖(還有一張?jiān)谛〈翱诶?#xff09;,可以看到隨著訓(xùn)練輪次增加,準(zhǔn)確率也逐漸增加

????????我們單看某一次的,可以發(fā)現(xiàn)正確率已經(jīng)達(dá)到0.9988了,因?yàn)閱?wèn)題比較簡(jiǎn)單嘛。有時(shí)會(huì)達(dá)到1.00

五、部署推理

? ? ? ? 既然模型已經(jīng)訓(xùn)練完畢,接下來(lái)我們就可以在本地部署,然后進(jìn)行推理看看效果怎么樣。(加載訓(xùn)練好的模型,然后輸入數(shù)據(jù),看看AI的輸出是什么樣的)

? ? ? ? 不過(guò)在此之前我們還要生成100個(gè)模擬數(shù)據(jù),當(dāng)做實(shí)際中的數(shù)據(jù),用于驗(yàn)證模型的推理效果。

import numpy as np
import pandas as pd# 參數(shù)設(shè)置
filename = 'simulated_data1.csv'
num_points = 100
threshold = 24  # 觸發(fā)閾值
low_value_frequency = 0.33  # 低于24的值的概率# 生成數(shù)據(jù)
np.random.seed(0)
data = np.random.randint(0, 101, num_points)  # 生成0到100的整型數(shù)據(jù)# 生成低于24的值
low_values = np.random.binomial(1, low_value_frequency, num_points)
data[low_values == 1] = np.random.randint(0, 24, np.sum(low_values))# 標(biāo)記是否觸發(fā)閾值
labels = (data < threshold).astype(int)# 創(chuàng)建DataFrame
df = pd.DataFrame({'value': data, 'label': labels})# 保存到CSV文件
df.to_csv(filename, index=False)print(f"數(shù)據(jù)已生成并保存到 {filename}")

然后就是推理(預(yù)測(cè))了

import numpy as np
from tensorflow.keras.models import load_model
import pandas as pd
import matplotlib.pyplot as plt# 設(shè)置 matplotlib 使用的字體
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用來(lái)正常顯示中文標(biāo)簽
plt.rcParams['axes.unicode_minus'] = False  # 用來(lái)正常顯示負(fù)號(hào)# 加載模型
model = load_model('model/stm32_model.keras')# 加載驗(yàn)證數(shù)據(jù)集
df = pd.read_csv('simulated_data1.csv')
X_test = df['value'].values.reshape(-1, 1, 1)
y_test = df['label'].values# 進(jìn)行推理
predictions = model.predict(X_test)
predicted_labels = (predictions > 0.5).astype(int)# 輸出詳細(xì)結(jié)果
for i, value in enumerate(df['value']):print(f"輸入數(shù)據(jù): {value:.2f}, 預(yù)測(cè)結(jié)果: {predicted_labels[i][0]}, 實(shí)際標(biāo)簽: {y_test[i]}")# 計(jì)算準(zhǔn)確率
accuracy = np.mean(predicted_labels.squeeze() == y_test)
print(f"模型準(zhǔn)確率: {accuracy * 100:.2f}%")# 可視化預(yù)測(cè)結(jié)果和真實(shí)標(biāo)簽的對(duì)比
plt.figure(figsize=(12, 6))
plt.plot(y_test, label='真實(shí)標(biāo)簽', marker='o')
plt.plot(predicted_labels.squeeze(), label='預(yù)測(cè)結(jié)果', marker='x')
plt.title('真實(shí)標(biāo)簽 vs 預(yù)測(cè)結(jié)果')
plt.xlabel('樣本索引')
plt.ylabel('標(biāo)簽')
plt.legend()
plt.show()

我們可以看到推理后的結(jié)果,這根本就難不倒它嘛

六、加載模型

????????既然前面已經(jīng)把模型訓(xùn)練了出來(lái),接下來(lái)就可以把模型部署到單片機(jī)上了。下面先介紹一些分析模型時(shí)的問(wèn)題

遇到這個(gè)提示后

  • 在注冊(cè)表編輯器中,找到路徑?HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem。
  • 修改或添加 LongPathsEnabled

    • 在?FileSystem?文件夾中查找名為?LongPathsEnabled?的DWORD (32-bit) 值。
    • 如果存在,雙擊它并將其值設(shè)置為?1。
    • 如果不存在,右鍵點(diǎn)擊?FileSystem?文件夾,選擇?新建?->?DWORD (32-bit) 值,命名為?LongPathsEnabled,然后將其值設(shè)置為?1。
  • 然后重啟

????????發(fā)生下面這個(gè)問(wèn)題,比較奇葩,雖然提示說(shuō)我們引入了batch_shape,但實(shí)際上我們沒(méi)有顯式引用。但只要把模型轉(zhuǎn)為TFLite格式,同時(shí)不能直接使用GRU等高級(jí)層。

即便……你使用Select TF Ops,雖然可以轉(zhuǎn)為TFLite模型,但是Cube的AI插件不能轉(zhuǎn)換

# 模型保存
save_model(model, 'model/stm32_model.keras')
# 將 .keras 模型轉(zhuǎn)換為 .tflite 格式
converter = tf.lite.TFLiteConverter.from_keras_model(model)
# 使用 Select TF Ops
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS,  # 支持 TFLite 內(nèi)置操作tf.lite.OpsSet.SELECT_TF_OPS     # 支持 TensorFlow 原生操作
]# 禁用實(shí)驗(yàn)性降低張量列表操作
converter._experimental_lower_tensor_list_ops = False
tflite_model = converter.convert()

每次加載模型都要重新分析一遍?

1,生成C代碼?

①添加AI插件

? ? ? ? 這一步有太多博客介紹了,我就說(shuō)一點(diǎn),把下面那個(gè)Device也勾選上,選擇最后一個(gè)應(yīng)用模板即可。官方文檔里也很詳細(xì)

②添加模型

③分析模型

? ? ? ? 點(diǎn)擊分析即可,分析成功后應(yīng)如下

????????我們可以看到最后一句,由于前面訓(xùn)練模型時(shí)也是這樣,輸入和輸出只有一個(gè),這里輸入和輸出也是一個(gè)4字節(jié)(實(shí)際為float32)

????????如果你想要知道模型的詳細(xì)情況,可以選擇這個(gè)選項(xiàng),當(dāng)然這都是后面了,可以自己嘗試

④生成的文件

生成的模型代碼就是這個(gè)文件夾了

以及Middlewares下面的這個(gè)AI庫(kù)

2,移植庫(kù)

? ? ? ? 如果你移植很熟練的話,這一步也沒(méi)什么難度。不過(guò)要說(shuō)明的是,我的工程是cmake工程,移動(dòng)文件后,只需要修改CMakelists就行了。如果是Keil或者IAR的話,需要手動(dòng)圖形化添加。

????????不管是哪種,目的都一樣,先把官方提供的AI庫(kù)(是整個(gè)AI目錄而不僅僅是Lib目錄)添加到工程里,就是下面這個(gè)靜態(tài)庫(kù).a

????????在CMakelists里就是這樣,前面是什么不重要,重要的是這個(gè)庫(kù)前面要加上“:”,為什么呢?我從CubeMX生成工程的CMakelists里扒出來(lái)的就是這樣(疑惑的話可以多問(wèn)問(wèn)通義等)

target_link_libraries(libai INTERFACE :NetworkRuntime910_CM4_GCC.a)
target_link_libraries(libai PRIVATE libdrivers)

????????移植后,這個(gè)庫(kù)的頭文件也要包含進(jìn)來(lái),ST/AI/Inc

? ? ? ? 然后是這個(gè)X-CUBE-AI,具體過(guò)程我不描述了,移植需要多嘗試、去練,講求的是經(jīng)驗(yàn)

? ? ? ? 總之,就兩個(gè)東西,一個(gè)是官方的庫(kù),另一個(gè)是資源文件

3,使用

? ? ? ? 前面選擇軟件包時(shí),由于勾選了應(yīng)用模板,所以會(huì)給我們生成。這些文件中,我們只要考慮這兩個(gè)文件即可

????????從這個(gè)頭文件里可以看到,它提供了兩個(gè)接口,一個(gè)是初始化,另一個(gè)是AI處理。

? ? ? ? 到資源文件中,我們可以看到這兩個(gè)函數(shù)是空的,我們先補(bǔ)充初始化函數(shù),直接這樣添加就行了,不用管什么錯(cuò)誤判斷,因?yàn)閷?shí)際上這個(gè)ai_boostrap接口就已經(jīng)做好了

void MX_X_CUBE_AI_Init(void)
{ai_boostrap(data_activations0);
}

? ? ? ? 至于函數(shù)處理,我們可以不用void MX_X_CUBE_AI_Process(void);

?我們自己編寫一個(gè)簡(jiǎn)單的接口,輸入數(shù)據(jù),然后返回?cái)?shù)據(jù)。為什么前面要加上float強(qiáng)制轉(zhuǎn)換呢?因?yàn)檫@個(gè)指針類型其實(shí)就是void*

float process_data_float(float input)
{*(float *)data_ins[0]=input;ai_run();return *(float *)data_outs[0];
}

? ? ? ? 從這個(gè)函數(shù)可以清晰地看出,把接收的數(shù)據(jù)存放進(jìn)data_ins[0]指向的緩沖區(qū),然后調(diào)用ai_run進(jìn)行AI推理,之后返回data_outs[0]得到推理的結(jié)果。無(wú)論是data_ins[0]還是data_outs[0]其實(shí)都是指針,所以前面要用“*”把指針指向的緩沖區(qū)的值取出來(lái)或者修改。

????????接著,我們?cè)谀硞€(gè)按鍵處理中調(diào)用這個(gè)函數(shù),輸入的是從0累加到150的數(shù)據(jù)供它驗(yàn)證

            input = 0;for (int i = 0; i < 500; ++i){result = process_data_float(input);printf("index:%f result:%f\r\n", input, result);input += 0.3;}

? ? ? ? 按下按鍵后,串口打印的結(jié)果也符合推理結(jié)果,小于24的為1,大于24的為0。在24附近出現(xiàn)波動(dòng)的原因也很簡(jiǎn)單,因?yàn)槲姨峁┑臄?shù)據(jù)集里并沒(méi)有出現(xiàn)浮點(diǎn)數(shù),全是0-100的整數(shù),并且模型訓(xùn)練輪次和數(shù)據(jù)量都比較小。

Tips:

? ? ? ? 這三行代碼我想了好久才想出來(lái),前面定義data_ins和data_outs時(shí)不是有個(gè)int8_t,這個(gè)東西把我誤導(dǎo)了許久,問(wèn)通義,它說(shuō)什么標(biāo)準(zhǔn)化、偏移量、量化之類的,總之告訴我輸入數(shù)據(jù)和輸出數(shù)據(jù)就是一個(gè)字節(jié)(int8_t)。后來(lái)我使用CubeMX另幾個(gè)選項(xiàng)生成模板,并查看官方手冊(cè)

? ? ? ? 最終才確定轉(zhuǎn)換的模型輸入數(shù)據(jù)和輸出數(shù)據(jù)確實(shí)是float32而不是量化后的int8_t,然后大膽嘗試,強(qiáng)制把a(bǔ)i_input[0].data(也就是data_ins[0])轉(zhuǎn)換為float32,才得到正確的結(jié)果

七、跨越

? ? ? ? AI模型轉(zhuǎn)為C代碼可以不使用CubeMX的這個(gè)插件,但那樣占用可能會(huì)很高,對(duì)于STM32平臺(tái),無(wú)論是操作的便捷性還是針對(duì)STM32的性能優(yōu)化,都是使用官方的比較合適。如果是其他單片機(jī),那么直接使用由TensorFlow Lite訓(xùn)練的模型轉(zhuǎn)換的C代碼,占用也不會(huì)很高,因?yàn)樗鼘iT用于嵌入式平臺(tái)。

????????至于神經(jīng)網(wǎng)絡(luò)、CNN、LVTM、圖像識(shí)別什么的,從0.9到,需要靠自己主動(dòng)學(xué)習(xí)了。

http://www.risenshineclean.com/news/5539.html

相關(guān)文章:

  • 石家莊有哪些公司可以做網(wǎng)站電子商務(wù)營(yíng)銷方法
  • 怎樣做音視頻宣傳網(wǎng)站正規(guī)網(wǎng)站建設(shè)公司
  • 上海商城網(wǎng)站站內(nèi)免費(fèi)推廣有哪些
  • java做網(wǎng)站的要求推廣普通話的意義50字
  • 手機(jī)開發(fā)網(wǎng)站教程如何做好一個(gè)品牌推廣
  • 尉氏做網(wǎng)站網(wǎng)絡(luò)營(yíng)銷logo
  • 網(wǎng)站建設(shè)全網(wǎng)推廣網(wǎng)絡(luò)seo優(yōu)化
  • 區(qū)塊鏈開發(fā)書籍推薦搜索引擎優(yōu)化課程
  • 高新區(qū)網(wǎng)站建設(shè)的建議免費(fèi)網(wǎng)上申請(qǐng)注冊(cè)
  • 深圳做小程序的公司排名關(guān)鍵詞seo排名怎么做的
  • 網(wǎng)站維護(hù)與建設(shè)內(nèi)容公司網(wǎng)站設(shè)計(jì)圖
  • 高端網(wǎng)站開發(fā)找哪家好企業(yè)官方網(wǎng)站怎么申請(qǐng)
  • title 鎮(zhèn)江網(wǎng)站建設(shè)免費(fèi)推廣軟件
  • 鐘表珠寶商城網(wǎng)站建設(shè)百度經(jīng)驗(yàn)官網(wǎng)
  • 惠州網(wǎng)站建設(shè)學(xué)校百度學(xué)術(shù)論文官網(wǎng)入口
  • 網(wǎng)站開發(fā)文檔包括長(zhǎng)春網(wǎng)站建設(shè)方案咨詢
  • 江蘇省建設(shè)廳網(wǎng)站施工員證查詢營(yíng)銷比較好的知名公司有哪些
  • 免費(fèi)php網(wǎng)站源碼信息流推廣渠道有哪些
  • 網(wǎng)站建設(shè)中 模版模板建站哪里有
  • 網(wǎng)站做任務(wù)賺錢優(yōu)化設(shè)計(jì)六年級(jí)下冊(cè)語(yǔ)文答案
  • 淄博團(tuán)購(gòu)網(wǎng)站建設(shè)紋身網(wǎng)站設(shè)計(jì)
  • 旅游酒店網(wǎng)站建設(shè)公司網(wǎng)站建設(shè)多少錢
  • 本地建設(shè)網(wǎng)站寧波網(wǎng)站制作優(yōu)化服務(wù)
  • 怎么用ps切片在dw里做網(wǎng)站百度收錄時(shí)間
  • 家具網(wǎng)站模板百度客戶電話
  • 做服裝加工哪個(gè)網(wǎng)站比較好溫州seo推廣外包
  • 黑龍江進(jìn)入疫情緊急狀態(tài)seo需要什么技術(shù)
  • 外包公司做的網(wǎng)站怎么改密碼站長(zhǎng)之家app下載
  • 1688網(wǎng)站上自己做模版專業(yè)營(yíng)銷團(tuán)隊(duì)公司
  • 阿里云網(wǎng)站如何建設(shè)視頻新浪微博指數(shù)查詢