最新版本TensorFlow训练模型TinyML部署到ESP32入门实操

最新版本TensorFlow训练模型TinyML入门实操

1.概述

这篇文章介绍微型嵌入式设备的机器学习TinyML,它们的特点就是将训练好的模型部署到单片机上运行。

2.TensorFlow深度学习原理

TensorFlow开源项目是由google研发的一个嵌入式机器学习工具,通过调用该工具的API可以实现训练模型,部署模型等。
下面介绍下使用 TensorFlow 训练模型的工作流程,掌握了流程后就可以进行实操,训练一个模型然后部署到单片机上运行。

  1. 选择一个目标:他决定了使用什么模型架构和收集什么数据
  2. 收集训练数据
  3. 设计模型架构
  4. 训练模型:给模型输入一组数据产生正确的输出
  5. 转换模型:我们训练的模型不能在MCU微控制器上运行,需要将他们转换为TensorFlowLite然后保存在硬盘上。
  6. 运行推断:将模型部署到微控制器上,通过测试数据判断它的运行质量。
  7. 评估和故障排除

3.TensorFlow深度学习实操

3.1.搭建开发环境

目标

今天要做的一个项目是训练一个可以对给定输入值X,然后预测输出正弦值Y的模型,通过输出的Y值控制微控制器的LED灯闪烁频率。

1.项目使用工具版本清单
工具包版本
python3.10
tensorflow2.16.2
numpy1.26.4
matplotlib3.7.1
arduinoIDE2.3.2
ESP32固件3.0.3
ESP32开发板ESP32WROOM32
EloquentTinyML0.0.10
2.colab介绍

福利:如果不能访问colab平台,所有在colab平台操作的内容都可以在本地电脑操作,只需要有个python环境和代码编辑器即可。

colab平台是google提供的一个免费模型训练的云端计算机,他有两个作用可以写笔记,还可以运行代码训练模型。

注册一个google账号就会得到一个云端的硬盘,访问下面的地址进入硬盘。
https://drive.google.com/

在google云盘的首页点击我的云盘硬盘,然后点击上面的新建,选择新建文件夹
在这里插入图片描述
为新建的文件夹命名,例如TinyML ,在这个文件夹中存放机器学习的笔记。
在这里插入图片描述
双击tinyml文件夹,然后点击新建,选择google Colabratory
在这里插入图片描述
如果没有找google Colabratory,就点击下面的关联更多应用并添加colab
在这里插入图片描述
新创建的colab和我们平时用的jutyper一样,不但可以写笔记还可以运行代码。
左上角是笔记名称,可以修改。
在这里插入图片描述
在colab右上角点击连接google就会自动为我们分配一个云端的计算机运行我们的代码。

到这一步我们的colab平台就准备好了,下面就可以开始训练我们的第一个模型啦。
在这里插入图片描述

3.2.安装工具包

1.安装tensorflow

鼠标hover在输入框上边,就会出现添加文本代码 两个选项,点击文本就可以写笔记。

在这里插入图片描述
输入笔记内容
在这里插入图片描述

网上给出的教程都是安装的tensorflow2.0版本,该版本太老了,现在已经不能使用了,我们这里安装最新的版本。
在下一行代码框输入tensorflow,然后点击左边的三角图标就可以运行代码。

!pip install tensorflow==2.17.0

在这里插入图片描述
查看安装包版本号,新建一行代码,输入下面的代码运行。

# 查看 tensorflow版本
!pip show tensorflow
# 查看python版本
import platform
print(platform.python_version())
2.导入依赖包

新建一行文本,输入2.导入依赖包

新建一行代码,并运行下面的代码

import tensorflow as tf
# Numpy is a math library
import numpy as np
# Matplotlib is a graphing library
import matplotlib.pyplot as plt
# math is Python's math library
import math

在这里插入图片描述

3.2.准备训练数据

嵌入式机器学习,通常训练数据来自于传感器采集的数据。这里我们用numpy生成我们要用到的训练数据。

1.生成数据

新建一行文本3.生成数据
新建一行代码,输入如下内容点击运行代码。

# We'll generate this many sample datapoints/设置数据总量
SAMPLES = 1000# Set a "seed" value, so we get the same random numbers each time we run this
# notebook. Any number can be used here.
SEED = 1337
np.random.seed(SEED)
tf.random.set_seed(SEED)# Generate a uniformly distributed set of random numbers in the range from
# 0 to 2π, which covers a complete sine wave oscillation/设置生成数据格式
x_values = np.random.uniform(low=0, high=2*math.pi, size=SAMPLES)# Shuffle the values to guarantee they're not in order/打乱数据的顺序
np.random.shuffle(x_values)# Calculate the corresponding sine values/使用sin方法计算正弦值
y_values = np.sin(x_values)# Add a small random number to each y value
y_values += 0.1 * np.random.randn(*y_values.shape)# Plot our data/使用matplotlib绘制图形
plt.plot(x_values, y_values, 'b.')
plt.show()

在这里插入图片描述
运行上面的代码,生成数据图如下。
在这里插入图片描述

2.拆分数据

我们的数据会分为三个部分,训练数据、验证数据、测试数据。
为了评估模型的训练准确率,我们需要将模型预测的数据与实际数据进行比较,评估会发生在训练期间(称为验证)和训练之后(称为测试)。
为了确保有数据可以被用于评估,我们将在开始训练之前预留出一些数据。让我们保留20%数据用于验证,另外20%数据用于测试。剩余的60%数据用于训练模型,这是训练模型经典拆分比例。

新建一行文本,输入4.拆分数据
新建一行代码,输入如下内容,运行代码

# We'll use 60% of our data for training and 20% for testing. The remaining 20%
# will be used for validation. Calculate the indices of each section.
TRAIN_SPLIT =  int(0.6 * SAMPLES)
TEST_SPLIT = int(0.2 * SAMPLES + TRAIN_SPLIT)
# 通过split方法拆分数据
x_train, x_validate, x_test = np.split(x_values, [TRAIN_SPLIT, TEST_SPLIT])
y_train, y_validate, y_test = np.split(y_values, [TRAIN_SPLIT, TEST_SPLIT])plt.plot(x_train, y_train, 'b.', label="Train")
plt.plot(x_validate, y_validate, 'y.', label="Validate")
plt.plot(x_test, y_test, 'r.', label="Test")
plt.legend()
plt.show()

在这里插入图片描述
使用不同的颜色显示拆分后的数据
在这里插入图片描述

3.3.设计训练模型

新建一行文本输入5.创建模型
新建一行代码,输入内容如下

from tensorflow.keras import layers
# 使用keras创建一个序列模型Sequential
model_2 = tf.keras.Sequential()# First layer takes a scalar input and feeds it through 16 "neurons". The
# neurons decide whether to activate based on the 'relu' activation function.
# 第一层使用16个神经元;activation:激活函数,选择relu策略,他返回两个数中较大的值。
model_2.add(layers.Dense(16, activation='relu', input_shape=(1,)))# The new second layer may help the network learn more complex representations
# 第二层神经元模型
model_2.add(layers.Dense(16, activation='relu'))# Final layer is a single neuron, since we want to output a single value
#第三层神经元模型
model_2.add(layers.Dense(1))# Compile the model using a standard optimizer and loss function for regression
# 设置训练过程中的参数 optimizer:优化器在训练期间用于调整网络对其输入进行建模的算法。
# loss:损失值在训练期间计算模型预测值与真实值之间的差距,mse代表均方误差(Mean Squared Error),
# 它是预测值与真实值之差的平方的平均值。
# metrics:用于评估模型性能的指标列表model_2.compile(optimizer='rmsprop', loss='mse', metrics=['mae'])# Show a summary of the model
# 输出设计的模型架构摘要
model_2.summary()

运行结果显示了模型设计概要信息
在这里插入图片描述

3.4.训练模型

新建一行文本输入 6.训练模型
新建一行代码,输入启动训练的参数,然后运行代码开始训练模型。

# 调用fit方法训练模型
# history_2:接收训练返回的数据
# x_train, y_train:训练数据x和y值
# epochs:训练次数
# batch_size:每次训练输入多少个数据,每一轮训练完成就会更新一次神经元模型,如果设置1就要更新600次,增加训练时间,
# 如果设置600,则每轮训练包含所有数据这样是快了,但是准确度降低了。因此设置为每论随机取16个数据训练。
# validation_data:验证数据,验证在训练过程中模型的预测和实际正确值是否一致。
history_2 = model_2.fit(x_train, y_train, epochs=600, batch_size=16,validation_data=(x_validate, y_validate))

查看运算结果

  • loss:损失值越小越好,比较第一轮和最后一轮,观察损失值从大到小在变化,说明是好事。
  • mae:平均绝对误差,显示神经元网络模型预测值和训练数据中y值的平均差
  • val_loss: 验证数据损失值输出
  • val_mae: 验证数据平均误差

第一轮和最后一轮训练结果
在这里插入图片描述

在这里插入图片描述

3.5.分析运算结果

我们可以通过绘制数据图来了解模型训练的情况,掌握提高模型训练准确度的依据。

1.绘制训练损失和验证损失图

新建一行文本输入7.分析模型数据
新建一行代码,输入下面的代码。

#绘制训练损失和验证损失图
# Draw a graph of the loss, which is the distance between
# the predicted and actual values during training and validation.
# 分别从历史数据中提取出损失数据loss和验证数据val_loss
loss = history_2.history['loss']
val_loss = history_2.history['val_loss']epochs = range(1, len(loss) + 1)plt.plot(epochs, loss, 'g.', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

从图中可以看出训练损失和验证损失值趋势都在减小,意味着模型正在改进并产生准确值。
在这里插入图片描述

2.绘制训练损失和验证损失详情图

通过减少查看训练轮次的次数,将训练数据放大,能够观察到训练的更多细节,发现模型训练的问题。

在colab中新建一行代码,输入下面的代码。

# 跳过前100次,查看后面500次训练损失和验证损失详细数据
# Exclude the first few epochs so the graph is easier to read
#设置跳过的次数
SKIP = 100plt.clf()plt.plot(epochs[SKIP:], loss[SKIP:], 'g.', label='Training loss')
plt.plot(epochs[SKIP:], val_loss[SKIP:], 'b.', label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

从这个图中可以看出损失减小的很平缓,最小损失在0.15,这个值还是高。另外验证损失值高于训练损失值,可能出现了过拟合现象。
在这里插入图片描述

3.绘制平均绝对误差

为了更好的了解模型的表现,绘制更多的数据进行分析。例如绘制平均绝对误差看下情况。
在colab中新建一行代码,输入下面的代码。

#使用上面相同轮次,绘制下面的图形。
plt.clf()# Draw a graph of mean absolute error, which is another way of
# measuring the amount of error in the prediction.
mae = history_2.history['mae']
val_mae = history_2.history['val_mae']plt.plot(epochs[SKIP:], mae[SKIP:], 'g.', label='Training MAE')
plt.plot(epochs[SKIP:], val_mae[SKIP:], 'b.', label='Validation MAE')
plt.title('Training and validation mean absolute error')
plt.xlabel('Epochs')
plt.ylabel('MAE')
plt.legend()
plt.show()

这个图中可以看出,训练的误差低于验证的误差。可能出现了过拟合,对训练数据学习过度,无法对新数据做出有效的预测。平均绝对误差值非常高,由于我们期望输出范围在-1~+1之间,因此0.31误差离精确建模正弦波很远。
在这里插入图片描述

4.绘制训练数据的预期值和期望值

我们通过绘制神经网络模型在训练过程中训练数据的预测值和预期值情况,了解他识别精确度情况。
在colab中新建一行代码,输入下面的代码。

# 训练数据的预测值和期望值
# Make predictions based on our test dataset
predictions = model_2.predict(x_test)# Graph the predictions against the actual values
plt.clf()
plt.title('Comparison of predictions and actual values')
plt.plot(x_test, y_test, 'b.', label='Actual')
plt.plot(x_test, predictions, 'r.', label='Predicted')
plt.legend()
plt.show()

通过调用predict方法,将训练数据中所有x值进行推断,返回一个预测数组。将数组中的值与训练集中实际的y值绘制在一张图上。

这张图表明,模型只能粗略的拟合数据,实际值不能完全匹配我们的预期值
在这里插入图片描述
通过对模型训练结果分析,我们得出这次训练的结果不是很好,需要扩大模型(增加模型的层数)或者调整训练数据,以及调整训练参数等方式改善训练结果。

3.6.测试模型

当模型训练的精确度达到我们的要求后,就可以使用测试数据测试下它的实际运行情况。

我们预留了20%的数据用于测试模型
在colab中新建一行代码,输入下面的代码。

# Calculate and print the loss on our test dataset 
#使用测试数据调用evaluate方法计算损失值和平均绝对误差值,
loss = model_2.evaluate(x_test, y_test)# Make predictions based on our test dataset
#使用测试数据计算预测值
predictions = model_2.predict(x_test)# Graph the predictions against the actual values
plt.clf()plt.title('Comparison of predictions and actual values')
# 绘制测试数据直接结果
plt.plot(x_test, y_test, 'b.', label='Actual')
# 绘制测试数据预测结果
plt.plot(x_test, predictions, 'r.', label='Predicted')
plt.legend()
plt.show()

从图中可以看出损失值为0.1639,这个值高于验证损失0.1577,平均绝对误差0.3213和验证的平均绝对误差一样。
图中的实际值和预测值不在一条线上,说明和训练模型的结果相同,不能精确的识别出预期值。
这个测试结果和训练结果没有太大差异,说明测试结果和训练结果基本吻合。
在这里插入图片描述

3.7.转换模型(导出模型)

我们使用TensorFlow训练的模型不能直接部署到微控制器上,需要将它转换为更小的模型。TensorFlow Lite转换器由两个部分构成

  • 转换器
    • 将tensorflow模型转换成一种特殊的更节省空间的文件格式,以便在小型微控制器上运行。
  • 解释器
    • 在微控制器上运行转换后的TensorFlow Lite模型
1.转化模型

使用tensorflowLite 转化器将模型转化为适合微控制器运行的小模型,它除了转化还可以对模型进行优化,使它的体积更小,这个优化是不会降低模型精度的。 为了验证使用优化压缩模型是否会影响模型识别精度,下面的代码创建了两个版本。 普通转化和使用了优化策略的转化。

在colab中新建一行代码,输入下面的代码。
运行下面的代码得到转化后的模型

# Convert the model to the TensorFlow Lite format without quantization
# 只将模型转化,不做优化。
converter = tf.lite.TFLiteConverter.from_keras_model(model_2)
tflite_model = converter.convert()# Save the model to disk
open("sine_model.tflite", "wb").write(tflite_model)# Convert the model to the TensorFlow Lite format with quantization
# 对模型转化并使用了优化压缩模型体积
converter = tf.lite.TFLiteConverter.from_keras_model(model_2)
# Indicate that we want to perform the default optimizations,
# which includes quantization
# 使用优化器
converter.optimizations = [tf.lite.Optimize.DEFAULT]
# Define a generator function that provides our test data's x values
# as a representative dataset, and tell the converter to use it
def representative_dataset_generator():for value in x_test:# Each scalar value must be inside of a 2D array that is wrapped in a listyield [np.array(value, dtype=np.float32, ndmin=2)]
converter.representative_dataset = representative_dataset_generator
# Convert the model
tflite_model = converter.convert()# Save the model to disk
open("sine_model_quantized.tflite", "wb").write(tflite_model)
2.验证普通转化和优化器转化后模型识别精度差距

由于TensorFlowLite解释器主要是用来提高效率的,所以它的使用就比较复杂,需要经过如下几个步骤

  • 实例化一个Interpreter对象
  • 调用一些为模型分配内存的方法
  • 将输入写入输入张量
  • 调用模型
  • 读取输出张量的输出

在colab中新建一行代码,输入下面的代码。运行代码

# Instantiate an interpreter for each model
sine_model = tf.lite.Interpreter('sine_model.tflite')
sine_model_quantized = tf.lite.Interpreter('sine_model_quantized.tflite')# Allocate memory for each model
sine_model.allocate_tensors()
sine_model_quantized.allocate_tensors()# Get indexes of the input and output tensors
sine_model_input_index = sine_model.get_input_details()[0]["index"]
sine_model_output_index = sine_model.get_output_details()[0]["index"]
sine_model_quantized_input_index = sine_model_quantized.get_input_details()[0]["index"]
sine_model_quantized_output_index = sine_model_quantized.get_output_details()[0]["index"]# Create arrays to store the results
sine_model_predictions = []
sine_model_quantized_predictions = []# Run each model's interpreter for each value and store the results in arrays
for x_value in x_test:# Create a 2D tensor wrapping the current x valuex_value_tensor = tf.convert_to_tensor([[x_value]], dtype=np.float32)# Write the value to the input tensorsine_model.set_tensor(sine_model_input_index, x_value_tensor)# Run inferencesine_model.invoke()# Read the prediction from the output tensorsine_model_predictions.append(sine_model.get_tensor(sine_model_output_index)[0])# Do the same for the quantized modelsine_model_quantized.set_tensor(sine_model_quantized_input_index, x_value_tensor)sine_model_quantized.invoke()sine_model_quantized_predictions.append(sine_model_quantized.get_tensor(sine_model_quantized_output_index)[0])# See how they line up with the data
plt.clf()
plt.title('Comparison of various models against actual values')
plt.plot(x_test, y_test, 'bo', label='Actual')
plt.plot(x_test, predictions, 'ro', label='Original predictions')
plt.plot(x_test, sine_model_predictions, 'bx', label='Lite predictions')
plt.plot(x_test, sine_model_quantized_predictions, 'gx', label='Lite quantized predictions')
plt.legend()
plt.show()

从图中可以看出无论是原始模型、转换模型、优化转换模型,几乎没有区别。普通的转化和使用优化的转化模型预测值基本是吻合的,说明使用优化方式转换模型没有带来精度的损失。
在这里插入图片描述

3.8.标准化模型

我们转化后的模型还不能直接部署到微控制器上,因为它使用的是python语言,我们使用工具将它C语言源文件,才可以部署。
使用xxd工具可以将模型转化为c语言文件。

# Install xxd if it is not available
!apt-get -qq install xxd
# Save the file as a C source file
# 将模型格式化为C语言文件
!xxd -i sine_model_quantized.tflite > sine_model_quantized.cc
# Print the source file
# 查看C语言文件模型内容
!cat sine_model_quantized.cc

格式化结果如下
他是一个数组文件
在这里插入图片描述
在colab左侧工具栏点击文件夹,就可以看到创建的模型文件。在这里可以下载模型文件。
在这里插入图片描述

4.部署项目

我们的目标是将训练好的模型部署到esp32开发板上,然后根据模型的输出控制LED灯的亮和灭.

在微控制器上运行模型有两个支持的库

  • EloquentTinyML库
    它是eloquentarduino开发的,https://github.com/eloquentarduino
    这个Arduino库简化使用Arduino IDE将Tensorflow Lite for Micro控制器模型部署到Arduino板的过程,操作起来非常的简单。

  • TensorFlowLite_ESP32库
    它是TensorFlow官方项目下TensorFlowLite解释器运行模型,里面的类比较多操作较为复杂。

4.1.安装依赖库

我们选择简单方式来运行我们的模型,首先搜索EloquentTinyML库选择0.0.10版本并安装它
在这里插入图片描述

4.2.下载模型文件

使用前面介绍的方法将模型转为.h文件,运行代码如下。然后将模型文件下载到本地。

# 将模型格式化为C语言的.h文件
!xxd -i sine_model_quantized.tflite > sine_model.h
# Print the source file
# 查看C语言文件模型内容
!cat sine_model.h

下载到本地模型文件sine_model.h的内容如下:

unsigned char sine_model_tflite[] = {0x20, 0x00, 0x00, 0x00, 0x54, 0x46, 0x4c, 0x33, 0x00, 0x00, 0x00, 0x00,0x14, 0x00, 0x20, 0x00, 0x1c, 0x00, 0x18, 0x00, 0x14, 0x00, 0x10, 0x00,0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00,0x1c, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00,0x00, 0x04, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x2c, 0x0e, 0x00, 0x00,0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,0xae, 0xfb, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,0x3c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x73, 0x65, 0x72, 0x76,0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00,0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x68, 0xff, 0xff, 0xff,0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x30, 0x00, 0x00, 0x00, 0x00,0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x86, 0xfc, 0xff, 0xff,0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x6b, 0x65, 0x72, 0x61,0x73, 0x5f, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00,0x03, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,0x04, 0x00, 0x00, 0x00, 0xb8, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00,0x04, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x43, 0x4f, 0x4e, 0x56,0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x41, 0x44,0x41, 0x54, 0x41, 0x00, 0xdc, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00,0x04, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x6d, 0x69, 0x6e, 0x5f,0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73,0x69, 0x6f, 0x6e, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00,0x08, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,0x13, 0x00, 0x00, 0x00, 0x6d, 0x69, 0x6e, 0x5f, 0x72, 0x75, 0x6e, 0x74,0x69, 0x6d, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00,0x10, 0x00, 0x00, 0x00, 0xf0, 0x02, 0x00, 0x00, 0xe8, 0x02, 0x00, 0x00,0xd4, 0x02, 0x00, 0x00, 0xac, 0x02, 0x00, 0x00, 0x5c, 0x02, 0x00, 0x00,0x4c, 0x01, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00,0xd4, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00,0xbc, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,0x74, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6a, 0xfd, 0xff, 0xff,0x04, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,0x08, 0x00, 0x0e, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,0x10, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,0x01, 0x00, 0x00, 0x00, 0xeb, 0x03, 0x00, 0x00, 0x0c, 0x00, 0x18, 0x00,0x14, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00,0x81, 0x33, 0x62, 0xc9, 0x4d, 0x63, 0x8a, 0x73, 0x02, 0x00, 0x00, 0x00,0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,0x32, 0x2e, 0x31, 0x37, 0x2e, 0x30, 0x00, 0x00, 0xd6, 0xfd, 0xff, 0xff,0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0xf2, 0xfd, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,0x31, 0x2e, 0x31, 0x34, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0xf4, 0xf3, 0xff, 0xff, 0xf8, 0xf3, 0xff, 0xff,0xfc, 0xf3, 0xff, 0xff, 0x00, 0xf4, 0xff, 0xff, 0x04, 0xf4, 0xff, 0xff,0x22, 0xfe, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,0x7f, 0x7f, 0x81, 0x7f, 0x81, 0x7f, 0x7f, 0x7f, 0x81, 0x81, 0x7f, 0x7f,0x7f, 0x7f, 0x7f, 0x81, 0x3e, 0xfe, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00,0x40, 0x00, 0x00, 0x00, 0x3a, 0xe6, 0xff, 0xff, 0xc9, 0x0b, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x1b, 0xef, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,0xa4, 0xe6, 0xff, 0xff, 0x47, 0x07, 0x00, 0x00, 0x8b, 0xe6, 0xff, 0xff,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x77, 0xff, 0xff,0xed, 0xe5, 0xff, 0xff, 0x9e, 0xe6, 0xff, 0xff, 0x9c, 0xe6, 0xff, 0xff,0xd5, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0xfe, 0xff, 0xff,0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x7f, 0x95, 0xdd, 0x2e,0xb8, 0xd3, 0x9d, 0x05, 0x42, 0xfe, 0xff, 0x21, 0x91, 0x9b, 0x79, 0x64,0x7f, 0x9a, 0x44, 0xb1, 0x3d, 0xad, 0xa9, 0x20, 0xac, 0x8c, 0xe0, 0xe6,0xca, 0x84, 0x9f, 0xe9, 0x3a, 0xbb, 0xe8, 0x81, 0xa7, 0xd6, 0x0b, 0xb8,0xe1, 0xd5, 0xcc, 0x38, 0xfd, 0x13, 0x46, 0xac, 0x8a, 0x45, 0xdc, 0xd9,0x44, 0x15, 0x57, 0xb9, 0x24, 0x5d, 0x58, 0x13, 0x81, 0x0d, 0x09, 0x06,0x5b, 0x7f, 0x1a, 0xce, 0x9f, 0x9d, 0x42, 0x39, 0xb2, 0xcc, 0x0d, 0x5b,0xc0, 0xad, 0xe9, 0x53, 0x40, 0x8d, 0x35, 0x91, 0x42, 0xba, 0x29, 0xbc,0x36, 0xa5, 0x38, 0xd5, 0xe8, 0xf0, 0x88, 0x81, 0x67, 0x3e, 0xc7, 0x5f,0xa9, 0x24, 0x81, 0x8f, 0xe2, 0x0c, 0x13, 0x0a, 0x52, 0x9e, 0xe9, 0x7b,0x1f, 0x3d, 0x46, 0x58, 0xdd, 0x7f, 0xf5, 0x2c, 0x52, 0xf6, 0x0e, 0x5a,0x42, 0xb2, 0x22, 0xdf, 0xde, 0x87, 0x0b, 0x04, 0xb3, 0x7f, 0x41, 0x88,0xca, 0x4d, 0x47, 0x89, 0xc0, 0x42, 0xf7, 0xc1, 0x7d, 0xd7, 0x32, 0xb6,0x49, 0x3c, 0x66, 0x3b, 0x66, 0xf5, 0x25, 0x7f, 0xec, 0x76, 0x69, 0xec,0x8a, 0x81, 0xa6, 0x8e, 0x0c, 0x3f, 0x0b, 0xc8, 0xca, 0x6f, 0x9a, 0x78,0x3d, 0xe6, 0x24, 0xb8, 0x97, 0xb7, 0xfc, 0xef, 0xf2, 0xd6, 0xcb, 0x2e,0xb6, 0x2f, 0xd1, 0x65, 0x6b, 0xe6, 0x0c, 0x7f, 0xd0, 0x15, 0x0c, 0x21,0x00, 0xd1, 0xfe, 0xe3, 0xcc, 0x0c, 0x4e, 0xf3, 0xcf, 0xeb, 0x81, 0xf0,0xd6, 0x19, 0x57, 0x0f, 0x85, 0x32, 0xc6, 0x68, 0xb8, 0x7f, 0xe3, 0x96,0x51, 0xa8, 0xaf, 0x37, 0x81, 0xdc, 0xde, 0x89, 0x6d, 0xce, 0xf3, 0x02,0x20, 0x33, 0x04, 0x66, 0x66, 0xb0, 0x06, 0xbc, 0xbb, 0xe1, 0x91, 0xef,0x77, 0x7f, 0x2b, 0x34, 0x1e, 0x90, 0xdc, 0xd2, 0x88, 0x90, 0xa0, 0x20,0x96, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,0xd3, 0xfd, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xfc, 0xff, 0xff,0x3c, 0x1a, 0x00, 0x00, 0xec, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0xe4, 0xfe, 0xff, 0xff, 0x83, 0xea, 0xff, 0xff, 0x42, 0xff, 0xff, 0xff,0xf3, 0xe7, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00,0x88, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0xe2, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00,0x10, 0x00, 0x00, 0x00, 0xf0, 0xd5, 0x27, 0x17, 0x27, 0xde, 0x1a, 0xd5,0x31, 0xdd, 0x18, 0x23, 0x81, 0xed, 0xf4, 0xe0, 0x00, 0x00, 0x06, 0x00,0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,0x04, 0x00, 0x00, 0x00, 0x04, 0x0e, 0x00, 0x00, 0xfc, 0xf5, 0xff, 0xff,0x00, 0xf6, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x4d, 0x4c, 0x49, 0x52,0x20, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x2e, 0x00,0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00,0x18, 0x00, 0x14, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00,0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,0x40, 0x01, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, 0x48, 0x01, 0x00, 0x00,0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,0x05, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00,0x6c, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x04, 0x00,0x0a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x92, 0xff, 0xff, 0xff,0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00,0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xb0, 0xf6, 0xff, 0xff,0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,0xc6, 0xff, 0xff, 0xff, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,0xb6, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00,0x1a, 0x00, 0x14, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x04, 0x00,0x0e, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,0x1c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x00, 0x00,0x08, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x0c, 0x00, 0x00, 0x00, 0x48, 0x08, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00,0x40, 0x07, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00,0xfc, 0x03, 0x00, 0x00, 0xe0, 0x02, 0x00, 0x00, 0x6c, 0x02, 0x00, 0x00,0xa0, 0x01, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,0x04, 0x00, 0x00, 0x00, 0xfe, 0xf7, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,0x14, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,0x0c, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0xe8, 0xf7, 0xff, 0xff,0x1b, 0x00, 0x00, 0x00, 0x53, 0x74, 0x61, 0x74, 0x65, 0x66, 0x75, 0x6c,0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x43,0x61, 0x6c, 0x6c, 0x5f, 0x31, 0x3a, 0x30, 0x00, 0x02, 0x00, 0x00, 0x00,0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0xfe, 0xff, 0xff,0x00, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,0x40, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,0x01, 0x00, 0x00, 0x00, 0xd4, 0xf8, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00,0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,0x74, 0x91, 0xff, 0x3b, 0x1c, 0x00, 0x00, 0x00, 0x53, 0x74, 0x61, 0x74,0x65, 0x66, 0x75, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f,0x6e, 0x65, 0x64, 0x43, 0x61, 0x6c, 0x6c, 0x5f, 0x31, 0x3a, 0x30, 0x31,0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,0x01, 0x00, 0x00, 0x00, 0x96, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x90, 0x00, 0x00, 0x00,0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00,0x54, 0xf9, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xbf, 0x90, 0x3a, 0x3c,0x54, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69,0x61, 0x6c, 0x5f, 0x31, 0x2f, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x31,0x5f, 0x32, 0x2f, 0x4d, 0x61, 0x74, 0x4d, 0x75, 0x6c, 0x3b, 0x73, 0x65,0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x31, 0x2f, 0x64,0x65, 0x6e, 0x73, 0x65, 0x5f, 0x31, 0x5f, 0x32, 0x2f, 0x52, 0x65, 0x6c,0x75, 0x3b, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c,0x5f, 0x31, 0x2f, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x31, 0x5f, 0x32,0x2f, 0x41, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x4e, 0xff, 0xff, 0xff,0x00, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,0x40, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,0x88, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,0x10, 0x00, 0x00, 0x00, 0x0c, 0xfa, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00,0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff,0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,0x62, 0xb1, 0x81, 0x3c, 0x4e, 0x00, 0x00, 0x00, 0x73, 0x65, 0x71, 0x75,0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x31, 0x2f, 0x64, 0x65, 0x6e,0x73, 0x65, 0x5f, 0x31, 0x2f, 0x4d, 0x61, 0x74, 0x4d, 0x75, 0x6c, 0x3b,0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x31,0x2f, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x31, 0x2f, 0x52, 0x65, 0x6c,0x75, 0x3b, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c,0x5f, 0x31, 0x2f, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x31, 0x2f, 0x41,0x64, 0x64, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x20, 0x00, 0x1c, 0x00,0x1b, 0x00, 0x14, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,0x08, 0x00, 0x07, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x48, 0x00, 0x00, 0x00,0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,0xd4, 0xfa, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,0x01, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc9, 0x80, 0xc9, 0x3c,0x0c, 0x00, 0x00, 0x00, 0x74, 0x66, 0x6c, 0x2e, 0x71, 0x75, 0x61, 0x6e,0x74, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4a, 0xfb, 0xff, 0xff,0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00,0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf4, 0x00, 0x00, 0x00,0x34, 0xfb, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00,0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xb5, 0x5b, 0x89, 0x3a,0xfc, 0x3e, 0x67, 0x3b, 0x55, 0x6e, 0x4d, 0x3a, 0xda, 0x5a, 0x49, 0x3b,0x5d, 0x53, 0x97, 0x3b, 0x60, 0x4d, 0xb2, 0x3a, 0x54, 0x2a, 0xf6, 0x3a,0x03, 0x6c, 0x17, 0x3b, 0x18, 0x5e, 0x2e, 0x3b, 0x36, 0xd5, 0x4e, 0x3a,0xf1, 0x6c, 0xb5, 0x37, 0x0e, 0xb3, 0xe7, 0x3a, 0x9f, 0x2d, 0xa8, 0x3a,0xb7, 0x69, 0x46, 0x3b, 0x74, 0x17, 0x9a, 0x3b, 0x71, 0xf9, 0x68, 0x3b,0x12, 0x00, 0x00, 0x00, 0x74, 0x66, 0x6c, 0x2e, 0x70, 0x73, 0x65, 0x75,0x64, 0x6f, 0x5f, 0x71, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x35, 0x00, 0x00,0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,0x62, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00,0xe4, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,0xf0, 0x00, 0x00, 0x00, 0x4c, 0xfc, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00,0x88, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x36, 0x3c, 0xd8, 0x37,0xc9, 0x04, 0xb6, 0x38, 0xf9, 0xb2, 0xa1, 0x37, 0xa1, 0x7d, 0x9e, 0x38,0x29, 0x39, 0xee, 0x38, 0x73, 0x58, 0x0c, 0x38, 0x12, 0xc3, 0x41, 0x38,0xf7, 0x5f, 0x6e, 0x38, 0x99, 0x3f, 0x89, 0x38, 0x74, 0xcd, 0xa2, 0x37,0xce, 0xcd, 0x0e, 0x35, 0x25, 0x60, 0x36, 0x38, 0x6d, 0x60, 0x04, 0x38,0xd1, 0x2c, 0x9c, 0x38, 0xde, 0x93, 0xf2, 0x38, 0x0d, 0x61, 0xb7, 0x38,0x12, 0x00, 0x00, 0x00, 0x74, 0x66, 0x6c, 0x2e, 0x70, 0x73, 0x65, 0x75,0x64, 0x6f, 0x5f, 0x71, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x34, 0x00, 0x00,0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x72, 0xfd, 0xff, 0xff,0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00,0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf4, 0x00, 0x00, 0x00,0x5c, 0xfd, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00,0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xcb, 0x98, 0x3e, 0x3b,0xa2, 0x2a, 0x51, 0x3b, 0x71, 0x35, 0x9a, 0x3b, 0xd1, 0x6d, 0x73, 0x3b,0x79, 0xc9, 0x3f, 0x3b, 0xfe, 0x6d, 0x5a, 0x3b, 0xc6, 0xad, 0x58, 0x3b,0xb7, 0x66, 0x89, 0x3b, 0x7e, 0x67, 0x4e, 0x3b, 0x56, 0x04, 0x74, 0x3b,0x67, 0x3f, 0x44, 0x3b, 0xb4, 0xd7, 0x5d, 0x3b, 0x0c, 0xad, 0x07, 0x3c,0x11, 0xde, 0x5e, 0x3b, 0x63, 0x13, 0x58, 0x3b, 0xe3, 0xea, 0x5d, 0x3b,0x12, 0x00, 0x00, 0x00, 0x74, 0x66, 0x6c, 0x2e, 0x70, 0x73, 0x65, 0x75,0x64, 0x6f, 0x5f, 0x71, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x33, 0x00, 0x00,0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,0x8a, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00,0xe4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,0xf0, 0x00, 0x00, 0x00, 0x74, 0xfe, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00,0x88, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1e, 0x1e, 0x41, 0x38,0xd4, 0xee, 0x53, 0x38, 0x90, 0x3f, 0x9c, 0x38, 0x05, 0xa6, 0x76, 0x38,0xd3, 0x52, 0x42, 0x38, 0x8d, 0x51, 0x5d, 0x38, 0x68, 0x8b, 0x5b, 0x38,0xee, 0x37, 0x8b, 0x38, 0x56, 0x22, 0x51, 0x38, 0x87, 0x3e, 0x77, 0x38,0xdc, 0xd7, 0x46, 0x38, 0xd2, 0xc6, 0x60, 0x38, 0x6b, 0x78, 0x09, 0x39,0xa7, 0xd0, 0x61, 0x38, 0xfa, 0xee, 0x5a, 0x38, 0x41, 0xda, 0x60, 0x38,0x12, 0x00, 0x00, 0x00, 0x74, 0x66, 0x6c, 0x2e, 0x70, 0x73, 0x65, 0x75,0x64, 0x6f, 0x5f, 0x71, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x32, 0x00, 0x00,0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x9a, 0xff, 0xff, 0xff,0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x40, 0x00, 0x00, 0x00,0x84, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x34, 0xcf, 0x28, 0x3c,0x12, 0x00, 0x00, 0x00, 0x74, 0x66, 0x6c, 0x2e, 0x70, 0x73, 0x65, 0x75,0x64, 0x6f, 0x5f, 0x71, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x31, 0x00, 0x00,0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,0x00, 0x00, 0x16, 0x00, 0x1c, 0x00, 0x18, 0x00, 0x17, 0x00, 0x10, 0x00,0x0c, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00,0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,0x4c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,0x08, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,0xfd, 0x0b, 0xf6, 0x38, 0x11, 0x00, 0x00, 0x00, 0x74, 0x66, 0x6c, 0x2e,0x70, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x5f, 0x71, 0x63, 0x6f, 0x6e, 0x73,0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,0x00, 0x00, 0x16, 0x00, 0x1c, 0x00, 0x18, 0x00, 0x00, 0x00, 0x14, 0x00,0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0x00,0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00,0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,0x3c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,0x1e, 0x00, 0x00, 0x00, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x5f,0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x6b, 0x65, 0x72, 0x61,0x73, 0x5f, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x3a, 0x30, 0x00, 0x00,0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,0x03, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,0x04, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x06, 0x00, 0x00, 0x00,0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x00, 0x10, 0x00,0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00,0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,0x0c, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,0x0c, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72
};
unsigned int sine_model_tflite_len = 3768;

4.3.开发应用程序(控制LED灯逻辑)

1.在ArduinoIDE软件新建一个文件helloworld_tinyml 将下面的程序复制到该文件中保存该文件。
2.将下载的sine_model.h模型文件移动到helloworld_tinyml 所在的目录下,这样运行主程序时候就能读取到该模型的文件内容。

#include <Arduino.h>// https://github.com/eloquentarduino/EloquentTinyML  Version:0.0.10
#include <EloquentTinyML.h>
// sine_model.h contains the array you exported from the previous step with xxd or tinymlgen
// 导入模型文件
#include "sine_model.h"// 设置ESP32 灯pwm参数
#define PIN 2
#define BASE_FREQ 5000
#define LEDC_TIMER_12_BIT 12// 设置Eloquent参数
#define NUMBER_OF_INPUTS 1
#define NUMBER_OF_OUTPUTS 1
// in future projects you may need to tweek this value: it's a trial and error process
#define TENSOR_ARENA_SIZE 3 * 1024// 实例化对象ml
Eloquent::TinyML::TfLite<NUMBER_OF_INPUTS, NUMBER_OF_OUTPUTS, TENSOR_ARENA_SIZE> ml;void setup() {// put your setup code here, to run once:Serial.begin(115200);// LED灯pwm参数ledcAttach(PIN, BASE_FREQ, LEDC_TIMER_12_BIT);// 启动模型ml.begin(sine_model_tflite);
}void loop() {// 生成随机测试数据// pick up a random x and predict its sinefloat x = 3.14 * random(100) / 100;// 通过sin函数对输入值输出正确的预期值yfloat y = sin(x);// 将x值输入模型得到预测值,这个值就是执行模型后输出的值float input[1] = { x };float predicted = ml.predict(input);// 下面是设置pwm浮动算法,根据模型输出的结果改变LED灯亮度// Calculate the brightness of the LED such that y=-1 is fully off// and y=1 is fully on. The LED's brightness can range from 0-255.int brightness = (int)(127.5f * (predicted + 1));// Set the brightness of the LED. If the specified pin does not support PWM,// this will result in the LED being on when y > 127, off otherwise.//analogWrite(led, brightness);uint32_t duty = (8191 / 255) * min(brightness, 255);ledcWrite(PIN, duty);// 输出Serial.print("duty(");Serial.print(duty);Serial.println(")");Serial.print("sin(");Serial.print(x);Serial.print(") = ");Serial.print(y);Serial.print("\t predicted: ");Serial.println(predicted);delay(200);
}

4.4.主程序代码介绍

1.引入必要的库和头文件
#include <Arduino.h>
#include <EloquentTinyML.h>
#include "sine_model.h"
2.定义运行模型输入和输出参数
# 定义输入和输出的数量
#define NUMBER_OF_INPUTS 1
#define NUMBER_OF_OUTPUTS 1# 定义Tensor Arena的大小,用于分配内存空间给模型,这个值需要根据具体开发板内存大小进行尝试调整
#define TENSOR_ARENA_SIZE 3 * 1024# 创建TinyML对象并设置模型数据
Eloquent::TinyML::TfLite<NUMBER_OF_INPUTS, NUMBER_OF_OUTPUTS, TENSOR_ARENA_SIZE> ml;
3.初始化模型
void setup() {// put your setup code here, to run once:Serial.begin(115200);// LED灯pwm参数ledcAttach(PIN, BASE_FREQ, LEDC_TIMER_12_BIT);// 启动模型,输入的参数必须是模型文件中数组的名称,否则会找不到模型的入口。ml.begin(sine_model_tflite);
}
4.在loop()函数中运行模型控制LED灯亮灭

生成测试数据

// 生成随机测试数据
// pick up a random x and predict its sine
float x = 3.14 * random(100) / 100;
// 通过sin函数对输入值输出正确的预期值y
float y = sin(x);

运行模型输出预测结果

// 将x值输入模型得到预测值,这个值就是执行模型后输出的值float input[1] = { x };float predicted = ml.predict(input);

使用pwm方式控制灯的亮度

  //使用模型输出的预测值作为条件改变pwm值int brightness = (int)(127.5f * (predicted + 1));uint32_t duty = (8191 / 255) * min(brightness, 255);ledcWrite(PIN, duty);

输出结果

  // 输出信息Serial.print("duty(");Serial.print(duty);Serial.println(")");Serial.print("sin(");Serial.print(x);Serial.print(") = ");Serial.print(y);Serial.print("\t predicted: ");Serial.println(predicted);delay(200);
}

5.上传程序到ESP32

将ESP32开发板和电脑连接然后上传程序,运行结果如下。
从运行的结果可以看出模型运行结果和sin函数计算处的值差距很大,说明模型训练的时候精度不够。
在这里插入图片描述
通过模型运行,控制LED灯实现了闪烁功能。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/145978.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Compose动画

一、Compose动画种类和选择 1.1 选择动画API 1.采用SVG&#xff1a;AnimatedVectorDrawable 是否第三方动画框架&#xff1a;Lottie动画 2.是否需要永久播放&#xff1a;rememberInfiniteTransition 3.布局动画 在内容不同的多个可组合项之间切换 3.1 导航过渡动画&#…

154-钓鱼篇Offfice-CVE漏洞RLO隐藏压缩包释放免杀打包捆绑

#知识点&#xff1a; 1、文件名-RLO 伪装-后缀 2、压缩文件-自解压-运行 3、捆绑文件-打包加载-运行 4、Office 套件-漏洞钓鱼-CVE #文件后缀-钓鱼伪装-RLO cs生成一个exe后门 重命名为一个png反过来或者jpg反过来的名字 然后再g前面输入其他字符在g字符前面右键选择这个插入…

CUDA-事件计时方法cudaEventElapsedTime

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 实现原理 事件计时方法是CUDA编程中一种用于测量GPU内核执行时间的高效手段。其基本步骤包括&#xff1a; 创建事件&#xff1a;…

Python模拟鼠标轨迹[Python]

一.鼠标轨迹模拟简介 传统的鼠标轨迹模拟依赖于简单的数学模型&#xff0c;如直线或曲线路径。然而&#xff0c;这种方法难以捕捉到人类操作的复杂性和多样性。AI大模型的出现&#xff0c;能够通过深度学习技术&#xff0c;学习并模拟更自然的鼠标移动行为。 二.鼠标轨迹算法实…

echarts柱图

样式如下 关键代码 // html部分<div class"echarts-container" :id"echartDiv id"></div>// js部分 data() {return {myChart: null,xAxisData: [云南, 浙江, 山东, 广东, 四川, 河南, 广西, 河南, 广西],yAxisData: [{value: 230,num: {r…

超实用线程调度方法!

文章目录 前言一、实现思路二、实现实例三、实现效果 前言 你有想过这样一个问题吗&#xff1f;线程之间是如何调度的&#xff1f; 更具体点说是这样&#xff0c;有两个线程&#xff1a;线程A和线程B&#xff0c;线程B要先于线程A运行&#xff0c;或者是线程B运行了多次之后在…

2024年华为杯中国研究生数学建模竞赛F题保姆级教程思路分析

2024年中国研究生数学建模竞赛F题保姆级教程思路分析 F题题目&#xff1a;X射线脉冲星光子到达时间建模 本题目围绕脉冲星导航与X射线光子到达时间建模展开。脉冲星由于其自转稳定性和规律性&#xff0c;被认为是宇宙中精确的时钟&#xff0c;并可以用作航天器的定位和导航基…

Ubuntu 22.04 源码下载、编译

Kernel/BuildYourOwnKernel - Ubuntu Wikihttps://wiki.ubuntu.com/Kernel/BuildYourOwnKernel 一、查询当前系统内核版本 rootubuntu22:~# uname -r 5.15.0-118-generic 二、查询本地软件包数据库中的内核源码信息 rootubuntu22:~# apt search linux-source Sorting... Do…

使用Maven创建一个Java项目并在repository中使用

JDK环境&#xff1a;1.8.0_371 Maven环境 &#xff1a;Apache Maven 3.6.3 配置完成jdk和mvn后&#xff0c;进入到指定文件夹下执行如下语句&#xff1a; mvn archetype:generate -DgroupIdtop.chengrongyu -DartifactIdCyberSpace -DarchetypeArtifactIdmaven-archetype-quic…

(20)Shell脚本的书写

linux中的shell脚本&#xff0c;其实是系统中真正的命令。Shell语言写的程序不需编译.定义各种参数和变量、使用条件命令、控制结构以及其他高级特性。 一、shell脚本基本元素 1.1变量 定义&#xff1a;定义一个名称&#xff0c;将参数赋予给这个名称。就叫变量。变量名可以…

C++【类和对象】(一)

文章目录 前言1.类的定义1.1类定义格式1.2 访问限定符1.3 类域 2. 实例化2.1 实例化的概念2.2 对象大小 3.this指针结语 前言 在前文我们讲解了C基础语法知识。本文将会讲解C的类和对象。 1.类的定义 1.1类定义格式 class name {}&#xff1b;class为定义类的关键字&#x…

Linux进阶命令-rsync

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 经过上一章Linux日志的讲解&#xff0c;我们对Linux系统自带的日志服务已经有了一些了解。我们接下来将讲解一些进阶命令&am…

erlang学习:Linux常用命令2

目录操作命令 对目录进行基本操作 相关cd切换目录之类的就直接省去了&#xff0c;以下操作中都会用到 查看当前目录下的所有目录和文件 ls 列表查看当前目录下的所有目录和文件&#xff08;列表查看&#xff0c;显示更多信息&#xff09; ls -l 或 ll 在当前目录下创建一个…

高性能并发计数器的比较

参考文档&#xff1a;https://baijiahao.baidu.com/s?id1742540809477784106&wfrspider&forpc 一、常用的并发计数方法 1、synchronized synchronized早期是一个重量级锁&#xff0c;因为线程竞争锁会引起操作系统用户态和内核态切换&#xff0c;浪费资源&#xff…

Element Plus中button按钮相关大全

一、基本用法 使用 type、plain、round 和 circle 来定义按钮的样式。 样式代码如下&#xff1a; <template><div class"mb-4"><el-button>Default</el-button><el-button type"primary">Primary</el-button><el…

C语言常见字符串函数模拟实现一

strlen模拟实现 重点&#xff1a;1.字符串已经\0作为结束标志&#xff0c;strlen返回的是字符串\0前面出现的字符个数&#xff08;不包含\0&#xff09; 2.参数指向的字符串必须要以\0结束。 3.注意函数的返回值是size_t&#xff0c;是无符号的&#xff0c;加减是无法对比的。…

卡西欧相机SD卡格式化后数据恢复指南

在数字摄影时代&#xff0c;卡西欧相机以其卓越的性能和便携性成为了众多摄影爱好者的首选。然而&#xff0c;随着拍摄量的增加&#xff0c;SD卡中的数据管理变得尤为重要。不幸的是&#xff0c;有时我们可能会因为操作失误或系统故障而将SD卡格式化&#xff0c;导致珍贵的照片…

数据类型转换中存在的问题分析

隐式类型转换&#xff08;implicit type conversion&#xff09; 隐式类型转换&#xff08;implicit type conversion&#xff09;包括整型提升&#xff08;integer promotion&#xff09;和标准算数转换&#xff08;usual arithmetic conversions&#xff09; 遵循较大范围优…

堡垒机(Bastion Host)概述

Bastion Host 堡垒机 一、什么是堡垒机&#xff1f; A bastion host is a computer specially designed to mitigate cyberattacks and manage access rights to an internal network. 堡垒机Bastion Host是一种专门设计用于缓解网络攻击并管理内部网络访问权限的计算机。 在…

肖扬新书《微权力下的项目管理》读书笔记2

一个核心思想&#xff1a;“借力” 合格的项目经理是不热衷于培养人的。项目经理的工作场景和职能经理的工作场景往往有很 大不同。职能经理的工作方式通常适用于常态化工作&#xff0c;要有足够的时间去培养人&#xff0c;先把人培 养起来&#xff0c;然后再干事&#xff0c;可…