普通视图

发现新文章,点击刷新页面。
昨天以前Power's Wiki

机器学习入门 - 模型评估指标

2024年4月7日 19:06

机器学习入门 - 模型评估指标

参考与致谢


不同的机器学习任务需要使用不同指标来评估,本篇文章基于 scikit-learn ,从实际代码上介绍机器学习中回归、分类、聚类这三种模型的评估指标。

回归模型的评估指标

对于回归模型而言,目标是使得预测值能够尽量拟合实际值。常用的性能评估指标有绝对误差和均方误差两种。

平均绝对误差(Mean Absolute Error, MAE)

用于衡量回归问题中预测值与真实值之间平均绝对差异。MAE 的值越小,表示预测值与真实值之间的平均差异越小,即预测的准确性越高。

\[ MAE = \frac{1}{n} \sum_{i=1}^{n} |y_{\text{true}, i} - y_{\text{pred}, i}| \]

公式中,\(n\) 是样本数量, \(y_\text{true}\) 是真实值,\(y_\text{pred}\) 是预测值。

>>> from sklearn.metrics import mean_absolute_error

>>> y_true = [3, -0.5, 2, 7]
>>> y_pred = [2.5, 0.0, 2, 8]
>>> mean_absolute_error(y_true, y_pred)
0.5

>>> y_true = [[0.5, 1], [-1, 1], [7, -6]]
>>> y_pred = [[0, 2], [-1, 2], [8, -5]]
>>> mean_absolute_error(y_true, y_pred)
0.75

均方误差(Mean Squared Error, MSE)

用于衡量预测值与真实值之间的平均差异。数值越小表示预测结果与真实值的拟合程度越好。

\[ MSE = \frac{1}{n} \sum_{i=1}^{n} (y_{\text{true}, i} - y_{\text{pred}, i})^2 \]

公式中,\(n\) 是样本数量, \(y_\text{true}\) 是真实值,\(y_\text{pred}\) 是预测值。

>>> from sklearn.metrics import mean_squared_error

>>> y_true = [3, -0.5, 2, 7]
>>> y_pred = [2.5, 0.0, 2, 8]
>>> mean_squared_error(y_true, y_pred)
0.375

>>> y_true = [[0.5, 1],[-1, 1],[7, -6]]
>>> y_pred = [[0, 2],[-1, 2],[8, -5]]
>>> mean_squared_error(y_true, y_pred)
0.708...

分类模型的评估指标

分类模型的评估指标比较多,不同的评估指标之间甚至可能有冲突

机器学习入门 - 基础流程

2024年4月18日 15:43

机器学习入门 - 基础流程

一般而言,传统的编程是告诉计算机一些数据以及计算规律,让计算机输出结果。当规则制定好之后,对于每一次输入,计算机输出的答案应该也是唯一确定的。

flowchart LR
  classDef default fill:#fff,stroke:#000,stroke-width:2px,font-size:16px,fill: white
      规则-->传统编程方法;
      数据-->传统编程方法;
      传统编程方法-->答案;

而机器学习的方法,是告诉计算机数据和一部分答案(标签),计算机输出答案与规律。这种方法是从已知答案的数据背后寻找某种规则。

flowchart LR
  classDef default fill:#fff,stroke:#000,stroke-width:2px,font-size:16px,fill: white
      数据-->机器学习方法;
      部分答案-->机器学习方法;
      机器学习方法-->规则;

机器学习的基本流程大致如下:

数据收集

机器学习就像「神农尝百草」,是一种归纳法(传统编程是演绎法)。而对于归纳法而言,数据是基础,越多越好。数据决定了机器学习的上限,而模型和算法再好,也只是逼近这个上限。

数据预处理

在最初的阶段,需要处理带标签的原始数据,形成用于训练和用于验证的数据集。这一步骤的主要的工作是特征提取和数据清洗。

特征提取是将特征提取出来,作为模型训练的输入。而数据清洗通常的流程有:

  • 去除唯一属性:唯一属性通常是一些 id 编码,这些属性不能刻画样本的分布规律。
  • 处理缺失值:可以选择直接补全缺失值,也可以直接删除含有这个属性的特征。
  • 特征编码:把文字或其他形式的特征转换为数字编码,方便模型处理。比如把 ON/OFF 编码为 1/0.
  • 特征缩放:通过归一化和标准化的手段,将样本属性缩放到某个指定的范围内,避免数量级差异大的属性占据主导地位。

模型的构建和训练

拥有可用的数据集之后,就可以根据需求选择合适的算法模型了。机器学习主要有三种方式:监督学习(Supervised Learning),无监督学习(Unsuoervised learing)和强化学习(RL, Reinforcement Learning)。

  • 监督学习(Supervised Learning):监督意味着已经有标注好的数据集。通过已标注好的数据进行模型训练,从而利用训练好的模型来对新的数据进行预测。监督学习的应用一般分为 回归分类
    • 回归(Regression):预测一个数字,有无限种可能的结果
    • 分类(Classification):预测分类,只有两种或以上的少数选择,是拟合不同类别之间的分界线。
  • 无监督学习(Unsuoervised learing):无需标注数据(有时候人也不知道问题的准确答案),应用一般有 聚类降维异常检测(Anomaly Detection) 这几种:
    • 聚类(Clustering):例如给出一堆图片,把相似的图片划分到一起。
    • 降维(Dimensionality Reduction):数据特征过多、维度过高时,要将数据降到合适的低维空间处理,保留最重要的特征数据。主要算法有主成分分析(PCA, Principal Component Analysis)。
  • 强化学习(Reinforcement Learning, RL):把学习的过程作为一个试探评价的环节,会根据具体的环境得到反馈的强化信号(奖赏/惩罚)。让机器不断尝试,从而得到一种趋利避害的策略,形成一套解决问题的最优解。

我们可以对处理好的数据先做一个顶层的分析,是用监督学习还是无监督模型,问题的类型是属于分类还是回归。在实际选择时,也通常会选用不同的模型进行训练,然后比较输出结果并选择最佳的那个。

模型训练的根本,是找到最合适的权重,以最大限度地进行分类(分类问题中)、或使误差尽量小(回归问题中)。

我们以一个包含权重的公式为例:

\[ y=ax_1+bx_2+cx_3 \]

其中,\(y\) 就是标签,在训练数据集中已经有正确的标注;而 \(x_1, x_2, x_3\) 即特征值。举个实际的例子:

\[ 花的种类=a*花蕊颜色+b*叶子颜色+c*花瓣颜色 \]

在这个阶段的工作,就是通过训练反推出权重 a、b、c,使得这条公式的结果尽量逼近原始输入数据。并且要设定损失函数(Loss Function),设法减小整体误差,实际中常使用均方误差(MSE, Mean Squared Error)来计算损失函数的误差。

模型评估

在上一个阶段把误差降到足够小后即可停止训练,用预处理后的测试数据集来验证模型效果。

预测

在上个阶段模型达到了预期的准确率和覆盖率(召回率)之后,就可以把模型拿来实际使用了。


入门机器学习要两手抓,一方面是算法基础,另一方面是代码练习。这样才能在学习中巩固,把理论基础转化为实际用途。

下一篇文章我们先介绍机器学习环境的配置。


参考与致谢

  • Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow, 3rd Edition (https://github.com/ageron/handson-ml3)
  • 《程序员的 AI 书:从代码开始》
  • 《AI 制胜:机器学习极简入门》

机器学习入门 - 基础流程

2024年4月18日 15:43

机器学习入门 - 基础流程

一般而言,传统的编程是告诉计算机一些数据以及计算规律,让计算机输出结果。当规则制定好之后,对于每一次输入,计算机输出的答案应该也是唯一确定的。

flowchart LR
  classDef default fill:#fff,stroke:#000,stroke-width:2px,font-size:16px,fill: white
      规则-->传统编程方法;
      数据-->传统编程方法;
      传统编程方法-->答案;

而机器学习的方法,是告诉计算机数据和一部分答案(标签),计算机输出答案与规律。这种方法是从已知答案的数据背后寻找某种规则。

flowchart LR
  classDef default fill:#fff,stroke:#000,stroke-width:2px,font-size:16px,fill: white
      数据-->机器学习方法;
      部分答案-->机器学习方法;
      机器学习方法-->规则;

机器学习的基本流程大致如下:

数据收集

机器学习就像「神农尝百草」,是一种归纳法(传统编程是演绎法)。而对于归纳法而言,数据是基础,越多越好。数据决定了机器学习的上限,而模型和算法再好,也只是逼近这个上限。

数据预处理

在最初的阶段,需要处理带标签的原始数据,形成用于训练和用于验证的数据集。这一步骤的主要的工作是特征提取和数据清洗。

特征提取是将特征提取出来,作为模型训练的输入。而数据清洗通常的流程有:

  • 去除唯一属性:唯一属性通常是一些 id 编码,这些属性不能刻画样本的分布规律。
  • 处理缺失值:可以选择直接补全缺失值,也可以直接删除含有这个属性的特征。
  • 特征编码:把文字或其他形式的特征转换为数字编码,方便模型处理。比如把 ON/OFF 编码为 1/0.
  • 特征缩放:通过归一化和标准化的手段,将样本属性缩放到某个指定的范围内,避免数量级差异大的属性占据主导地位。

模型的构建和训练

拥有可用的数据集之后,就可以根据需求选择合适的算法模型了。机器学习主要有三种方式:监督学习(Supervised Learning),无监督学习(Unsuoervised learing)和强化学习(RL, Reinforcement Learning)。

  • 监督学习(Supervised Learning):监督意味着已经有标注好的数据集。通过已标注好的数据进行模型训练,从而利用训练好的模型来对新的数据进行预测。监督学习的应用一般分为 回归分类
    • 回归(Regression):预测一个数字,有无限种可能的结果
    • 分类(Classification):预测分类,只有两种或以上的少数选择,是拟合不同类别之间的分界线。
  • 无监督学习(Unsuoervised learing):无需标注数据(有时候人也不知道问题的准确答案),应用一般有 聚类降维异常检测(Anomaly Detection) 这几种:
    • 聚类(Clustering):例如给出一堆图片,把相似的图片划分到一起。
    • 降维(Dimensionality Reduction):数据特征过多、维度过高时,要将数据降到合适的低维空间处理,保留最重要的特征数据。主要算法有主成分分析(PCA, Principal Component Analysis)。
  • 强化学习(Reinforcement Learning, RL):把学习的过程作为一个试探评价的环节,会根据具体的环境得到反馈的强化信号(奖赏/惩罚)。让机器不断尝试,从而得到一种趋利避害的策略,形成一套解决问题的最优解。

我们可以对处理好的数据先做一个顶层的分析,是用监督学习还是无监督模型,问题的类型是属于分类还是回归。在实际选择时,也通常会选用不同的模型进行训练,然后比较输出结果并选择最佳的那个。

模型训练的根本,是找到最合适的权重,以最大限度地进行分类(分类问题中)、或使误差尽量小(回归问题中)。

我们以一个包含权重的公式为例:

\[ y=ax_1+bx_2+cx_3 \]

其中,\(y\) 就是标签,在训练数据集中已经有正确的标注;而 \(x_1, x_2, x_3\) 即特征值。举个实际的例子:

\[ 花的种类=a*花蕊颜色+b*叶子颜色+c*花瓣颜色 \]

在这个阶段的工作,就是通过训练反推出权重 a、b、c,使得这条公式的结果尽量逼近原始输入数据。并且要设定损失函数(Loss Function),设法减小整体误差,实际中常使用均方误差(MSE, Mean Squared Error)来计算损失函数的误差。

模型评估

在上一个阶段把误差降到足够小后即可停止训练,用预处理后的测试数据集来验证模型效果。

预测

在上个阶段模型达到了预期的准确率和覆盖率(召回率)之后,就可以把模型拿来实际使用了。


入门机器学习要两手抓,一方面是算法基础,另一方面是代码练习。这样才能在学习中巩固,把理论基础转化为实际用途。

下一篇文章我们先介绍机器学习环境的配置。


参考与致谢

  • Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow, 3rd Edition (https://github.com/ageron/handson-ml3)
  • 《程序员的 AI 书:从代码开始》
  • 《AI 制胜:机器学习极简入门》

Homelab - 开源的远程桌面方案 RustDesk

2024年4月18日 15:43

Homelab - 开源的远程桌面方案 RustDesk

RustDesk 是一套开源的远程桌面方案,在内网可直接使用各平台的客户端进行远程,本文章主要讲解公网下如何搭建自己的服务器。

部署(Docker Compose)

首先创建 compose.yaml 文件,并粘贴以下内容:

compose.yaml
version: "3"

networks:
  rustdesk-net:
    external: false

services:
  hbbs:
    container_name: ${STACK_NAME}_hbbs
    ports:
      - 21115:21115
      - 21116:21116
      - 21116:21116/udp
      - 21118:21118
    image: rustdesk/rustdesk-server:${APP_VERSION}
    command: hbbs -r ${STACK_DOMAIN}:21117 -k _
    volumes:
      - ${STACK_DIR}/data:/root
    networks:
      - rustdesk-net
    depends_on:
      - hbbr
    restart: unless-stopped

  hbbr:
    container_name: ${STACK_NAME}_hbbr
    ports:
      - 21117:21117
      - 21119:21119
    image: rustdesk/rustdesk-server:${APP_VERSION}
    command: hbbr -k _
    volumes:
      - ${STACK_DIR}/data:/root
    networks:
      - rustdesk-net
    restart: unless-stopped

在这个 docker compose 中,编排了两个服务:

  • hbbs: RustDesk ID 注册服务器
  • hbbr: RustDesk 中继服务器

(可选)推荐在 compose.yaml 同级目录下创建 .env 文件,并自定义你的环境变量。如果不想使用环境变量的方式,也可以直接在 compose.yaml 内自定义你的参数(比如把 ${STACK_NAME} 替换为 rustdesk-server)。

.env
STACK_NAME=rustdesk-server
STACK_DIR=xxx # 自定义项目储存路径,例如 ./rustdesk-server
STACK_DOMAIN=xxx # 部署 RustDesk 服务器的域名或 IP

# rustdesk-server
APP_VERSION=latest

最后,在 compose.yaml 同级目录下执行 docker compose up -d 命令即可启动编排的容器。

配置说明

如果遇到错误 Registered email required (-m option). Please pay and register on https://rustdesk.com/server...,说明可能下载的不是最新版本的包,解决方法如下:

  1. https://hub.docker.com/r/rustdesk/rustdesk-server/tags 上找到最新版本的 DIGEST 编号(比如 83e259792b50)。
  2. 在本地使用命令 docker image pull rustdesk/rustdesk-server:latest@sha256:83e259792b50 下载最新的包,注意把最后的字符替换为你自己的。

参考与致谢

原文地址:https://wiki-power.com/
本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

Hello blog

2023年10月16日 10:30

终于,我还是给知识库加上了博客的功能。

在听了 捕蛇者说 的播客节目「个人知识管理体系系列」后,我思考了一番,发现之前倾向的单一知识库的做法,存在一些弊端:

  • 日常一些零碎的观点或想法,不适合提出来长篇大论、单独成文。
  • 知识库的文风比较正式,需要引经据典、咬文嚼字,这样一来写作的周期也会被拉长,这也削弱了零碎写作的积极性。

我希望把博客当 gist 用,简单记录一些零碎观点或想法。

不要自己感动自己

2023年10月16日 10:30

这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。 —— 于宙《我们这一代人的困惑》

该工作工作,该学习学习,该睡觉睡觉,该玩就放开玩。

有限与无限世界

2024年4月6日 20:54

Take a piano. The keys begin, the keys end. You know there are 88 of them, nobody can tell you any different. They are not infinite. You are infinite. And on these keys the music that you can make is infinite. I like that. That I can live by. -- The legend Of 1900

我在构想一个有限的世界,它是被约束在一个小区域内,你只能在其中进行探索,而不能越出其边界。

这样的描述也许过于抽象,但是可以有具体的实例来比喻:它是 iPod 里有限层级且功能很少的菜单、它是封闭式的学校、疫情下不进不出的社区、抑或是《海上钢琴师》中 1900 一生所在的船上。

它们都有一些共同的特征:因为是有限的范围内,所以探索程度会随时间推进而逐渐饱和,且呈现出边际效益递减的趋势。

生活在有限世界中,我们每天都经历着重复的景色。但是,如果你愿意花心思去探索,也许能发现彩蛋,有时转瞬即逝,有时微乎其微,但我们仍能惊叹于它的出现,感受着它带来不一样的体验。

在大学封校的那段日子里,我爬上了学校几乎所有楼的楼顶,仔细欣赏形色各异的落日与景色。在一栋文科楼的楼顶,我发现了围墙上的涂鸦。这种感觉,正如在孤独的银河系中找到了人类以外的其它智慧生命体一般。

这就是有限的世界,每天重复的景色也许会使你感到无聊,但也在无形中让你思考,在已知中发掘未知。

继而说到无限世界。在这里,每一步都可以是全新的探索,沿途的景色可以永不重复,探索永远不会趋向饱和。

现代人生活在无限世界中。我们每天都在摄入新的信息,但我们鲜有想过,如何将它们消化。

以前的世界并没有现在这么过量的信息流,普通人想要获得一些信息需要拼尽全力,因此他们有大把的时间去反复咀嚼自己已经获得的信息。

一本书翻来覆去看几十上百遍,每一句话都会在他们脑中无意识的回想,在日常生活里,在他们那些闲着没事的时间里,突然蹦出来,突然有了新的感悟。

但到了我们这里,我们每天花很少的时间思考,我们追求干货、追求结论,直接将别人整理好的观点拿来用,并对其坚信不疑。

结果每个人的脑中都充满了思想,但这些思想绝大部分都不是自己的,只是一个片面的结论,大家很擅长用这些已经得出来的结论去互相攻击,但却少有人知道这些结论得出来的过程。

人类所有的问题,都源于人无法独自安静地坐在房间里。身处于无限世界中的我们,有时候也需要为自己构建一个有限世界,任思想纷飞、碰撞、绽放出火花。

参考与致谢:

BeagleBone 系列 - 无线连接

2024年4月18日 15:43

BeagleBone 系列 - 无线连接

各版本 BeagleBone 的区别

BeagleBone® Black Seeed Studio BeagleBone® Green Seeed Studio BeagleBone® Green Wireless Seeed Studio BeagleBone® Green Gateway
$ 60.00 USD $ 44.00 USD $ 52.90 USD $ 78.90 USD
1 x USB Host 1 x USB Host 4 x USB2.0 Host 2 x USB2.0 Host
Ethernet Ethernet 10/100M Wi-Fi 802.11b/g/n 2.4GHz and Bluetooth 4.1 LE Ethernet 10/100M Bit and Wi-Fi 802.11b/g/n 2.4GHz and Bluetooth 4.1 LE
HDMI Port 2 x Grove Connectors 2 x Grove Connectors 2 x Grove Connectors

BeagleBone Green Gateway

连接 Wi-Fi

debian@beaglebone:~$ connmanctl
connmanctl> scan wifi
Scan completed for wifi
connmanctl> services
    se.101               wifi_1862e41aec0d_73652e313031_managed_psk
    STU-EE               wifi_1862e41aec0d_5354552d4545_managed_psk
connmanctl> agent on
Agent registered
connmanctl> connect wifi_1862e41aec0d_5354552d4545_managed_psk
Agent RequestInput wifi_1862e41aec0d_5354552d4545_managed_psk
  Passphrase = [ Type=psk, Requirement=mandatory, Alternates=[ WPS ] ]
  WPS = [ Type=wpspin, Requirement=alternate ]
Passphrase? 输入密码
Connected wifi_1862e41aec0d_5354552d4545_managed_psk
connmanctl> quit

连接蓝牙

sudo apt install bluez

如果有错误,就先更新一下:

sudo apt update

连接附近的蓝牙:

bb-wl18xx-bluetooth
bluetoothctl
scan on

配对连接设备(后面一串是要配对设备的 MAC 地址):

pair A4:xx:xx:xx:xx:30
trust A4:xx:xx:xx:xx:30
connect A4:xx:xx:xx:xx:30

可使用 quit 推出蓝牙命令行。

参考与致谢

原文地址:https://wiki-power.com/
本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

CentOS 配置 Oh My Zsh

2024年4月18日 15:43

CentOS 配置 Oh My Zsh

查看当前 Shell

echo $SHELL

一般情况下会返回 bin/bash

安装 zsh

yum install -y zsh

切换默认 Shell 为 zsh

需要在 root 用户下运行此命令:

chsh -s /bin/zsh

安装 git

yum install -y git

安装 Oh My Zsh

自动

sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"

手动

如果无法通过上面的方式安装(可能因为墙),则可通过以下方式手动安装:

下载源码:

git clone https://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh

复制配置:

cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc

修改 Oh My Zsh 主题

列出所有主题:

ls ~/.oh-my-zsh/themes

修改主题:

vim ~/.zshrc

将默认主题是 ZSH_THEME="robbyrussell" 修改为自己喜欢的即可。

重启生效

reboot

参考与致谢

原文地址:https://wiki-power.com/
本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

C 与 STM32 常用宏定义

2024年4月18日 15:43

C 与 STM32 常用宏定义

在嵌入式开发中,有些通用的宏定义,可以让项目兼容性和可移植性更佳。

防止头文件被重复定义

#ifndef COMDEF_H
#define COMDEF_H

//头文件内容

#endif

自定义数据类型

自定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异。这样也方便移植。

typedef unsigned char boolean; /* Boolean value type. */
typedef unsigned long int uint32; /* Unsigned 32 bit value */
typedef unsigned short uint16; /* Unsigned 16 bit value */
typedef unsigned char uint8; /* Unsigned 8 bit value */
typedef signed long int int32; /* Signed 32 bit value */
typedef signed short int16; /* Signed 16 bit value */
typedef signed char int8; /* Signed 8 bit value */

获取指定地址上的一个字或字节

#define MEM_B( x ) ( *( (byte *) (x) ) )
#define MEM_W( x ) ( *( (word *) (x) ) )

获取最大 / 最小值

#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )

返回数组元素的个数

#define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )

将首字母转换为大写

#define UPCASE( c ) ( ((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c) )

判断字符是否为十进制

#define DECCHK( c ) ((c) >= '0' && (c) <= '9')

判断字符是否为十六进制

#define HEXCHK( c ) ( ((c) >= '0' && (c) <= '9') ||\
((c) >= 'A' && (c) <= 'F') ||\
((c) >= 'a' && (c) <= 'f') )

参考与致谢

原文地址:https://wiki-power.com/
本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

ESXi 初始化指南

2024年4月18日 15:43

ESXi 初始化指南

VMware ESXi 是一个可裸机安装的虚拟机管理器。本篇教程基于 ESXi 8,仍在草稿阶段。

可以先跟着这篇教程上手:『软路由踩坑指南』 篇二:ESXi 8.0 虚拟机必备知识与保姆级安装过程

进行至 5.修改ESXI的默认空间 这个地方时,改用以下方法,修改 ESXI 的默认空间大小。

减小 VMFSL 的占用

在点安装系统后 5 秒内,按 Shift + O,输入 cdromBoot runweasel systemMediaSize=min, 将虚拟内存配置到最小值。具体可参考官方文档 ESXi System Storage Overview

Windows 11 虚拟机的安装

Win11 对系统配置比较严苛,安装的时候可能会出现 这台电脑无法运行Windows 11。一般问题来自于 TPM 检查,可以通过以下的方法避开:

  1. 在虚拟机的初始化页面,启用 Windows 基于虚拟化的安全性
  2. 在进入 Windows 虚拟机后的 现在安装 页面,按快捷键 Shift + F10 启动 cmd 窗口(如果调出 cmd 界面,有可能是笔记本的键盘键位问题,可以尝试外接一个键盘)。
  3. 输入 regedit,打开注册表。在 HKEY_LOCAL_MACHINE\SYSTEM\Setup 路径下,创建两个 32 位的 DWORD 值:
    • BypassTPMCheck,数值为 16 进制 1
    • BypassSecureBootCheck,数值为 16 进制 1

如果仍然无法安装,可以尝试检查其他的条件。可能是有一些条件达不到要求,比如 1GHz 以上的主频、64GB 以上的磁盘空间、4G 以上的内存。具体可参考 System requirements

HAL 库开发笔记 - CAN 通信 🚧

2024年4月18日 15:43

HAL 库开发笔记 - CAN 通信 🚧

本篇基于自研 RobotCtrl 开发套件,单片机内核为 STM32F407ZET6,CAN 通信使用 TJA1050 芯片,原理图及详细介绍请见 RobotCtrl - STM32 通用开发套件

回环测试简单步骤

CubeMX 内配置

  1. 根据所用的 CAN 硬件,在左侧栏点开 CAN1CAN2 页面,勾选 Activated,在参数页面,配置这些参数:
    1. Prescaler (for Time Quantum) 设置为 6Time Quanta in Bit Segment 1Time Quanta in Bit Segment 2 都设置为 3 Times,这个组合将比特率设置为 1Mbps(最高)。
    2. ReSynchronization Jump Width 配置为 1 Time ,这是重新同步时可调整的最大步长。
    3. Operating Mode 配置为 Loopback,用于回环测试。
  2. NVIC Settings 标签页,开启 CANx RX0 interrupts

代码内配置

在项目下创建 can.c,设置筛选器,这里配置的是列表模式,筛选了拓展 ID 0x2233 和标准 ID 0

```c title="can.c"/* * 函数名:CAN_Filter_Config * 描述 :CAN的过滤器 配置 * 输入 :无 * 输出 : 无 * 调用 :内部调用 */ static void CAN_Filter_Config(void) { CAN_FilterTypeDef CAN_FilterTypeDef;

/*CAN筛选器初始化*/
CAN_FilterTypeDef.FilterBank = 0;                       //筛选器组0
CAN_FilterTypeDef.FilterMode = CAN_FILTERMODE_IDLIST;   //工作在列表模式
CAN_FilterTypeDef.FilterScale = CAN_FILTERSCALE_32BIT;  //筛选器位宽为单个32位。
/* 使能筛选器,按照标志的内容进行比对筛选,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。 */

CAN_FilterTypeDef.FilterIdHigh = ((((uint32_t) 0x2233 << 3) | CAN_ID_EXT
        | CAN_RTR_DATA) & 0xFFFF0000) >> 16;        //要筛选的ID高位
CAN_FilterTypeDef.FilterIdLow = (((uint32_t) 0x2233 << 3) | CAN_ID_EXT
        | CAN_RTR_DATA) & 0xFFFF; //要筛选的ID低位
CAN_FilterTypeDef.FilterMaskIdHigh = 0;     //第二个ID的高位
CAN_FilterTypeDef.FilterMaskIdLow = 0;          //第二个ID的低位
CAN_FilterTypeDef.FilterFIFOAssignment = CAN_FILTER_FIFO0;  //筛选器被关联到FIFO0
CAN_FilterTypeDef.FilterActivation = ENABLE;            //使能筛选器
HAL_CAN_ConfigFilter(&hcan1, &CAN_FilterTypeDef);

} ```

测试

打开设备管理器查看设备是否已经显示,如果没有发现设备,或有黄色的感叹号,请到 ST 官网下载驱动 STM32 Virtual COM Port Driver

如果安装了驱动还是未能正常识别,可尝试在 CubeMX - Project Manager - Project - Linker Settings,将 Minimum Heap Size 调整为 0x600 或更高。

打开串口工具(波特率任意),可发现发送任意字符,将返回相同字符。

参考与致谢

原文地址:https://wiki-power.com/
本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

Hugo 极简搭建指南

2024年4月18日 15:43

Hugo 极简搭建指南

Hugo 是一个搭建网页的框架,有极高的构建和部署速度。至于在 Windows 下的安装配置,官方文档并未详细说明,第三方教程也参差不齐,所以我写了这一篇教程。

下载安装

  1. 打开 Hugo 官方 GitHub 的 ** Releases** 页面
  2. 选择最新的版本下载(选择 hugo_xxx_Windows-64/32bit.zip
  3. 将压缩包内的 hugo.exe 文件解压至 D:\hugo 文件夹目录下
  4. 文件资源管理器(即 我的电脑)中空白处点击鼠标右键,打开属性
  5. 依次点击 高级系统设置 - 环境变量 ,双击打开系统变量中的 Path
  6. 在环境变量界面中双击空白行,添加 D:\hugo,点击确定

打开命令提示符,输入语句:

hugo version

以确认 Hugo 是否安装成功(如果安装成功就能看到版本号)

创建站点

切换至相应目录下,使用如下语句:

hugo new site quickstart

这将在一个叫 quickstart 的文件夹内创建一个新的 Hugo 站点。

添加主题

主题的挑选可以到官方的 主题页面

直接跳转至 GitHub 下载主题文件夹,解压至站点的 theme 目录下即可。

执行如下命令,将主题添加至站点的配置文件中:

echo 'theme = "主题文件夹的名字"' >> config.toml

创建文章

使用如下命令,创建一篇文章:

hugo new posts/my-first-post.md

然后打开文章,将 front matter 中的 draft: true 改为 draft: false,以移出草稿区,正常呈现出来。

启动 Hugo 服务

使用以下命名启动 Hugo 本地预览服务:

hugo server -D

打开 http://localhost:1313/ ,即可看到实时预览的站点(在本地的任何修改,将即时更新)。

本地部署

使用如下命令:

Build static pages

将站点部署进行本地部署(输出于 public 文件夹目录下)。

参考与致谢

原文地址:https://wiki-power.com/
本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

JavaScript 学习笔记

2024年4月18日 15:43

JavaScript 学习笔记

调用外部 JS

<!DOCTYPE html>
<html>
    <head>
        <script src="xx1.js"></script>
    </head>
    <body>
        <script src="xx2.js"></script>
    </body>
</html>

输出

弹出警告框

window.alert("Hello");

操作 HTML 元素

<!DOCTYPE html>
<html>
    <body>
        <h1> 我的第一个 Web 页面 </h1>
        <p id="demo"> 我的第一个段落 </p>
        <script>
            document.getElementById ("demo").innerHTML = "段落已修改。";
        </script>
    </body>
</html>

数据类型

创建变量:

var carname = "Volvo";

值类型 \(基本类型、):字符串(String)、数字 \(Number\)、布尔 \(Boolean\)、对空(Null)、未定义(Undefined)、Symbol。

引用数据类型:对象 \(Object\)、数组 \(Array\)、函数 \(Function\)

原文地址:https://wiki-power.com/
本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

Linux 学习笔记 - 用户操作

2024年4月18日 15:43

Linux 学习笔记 - 用户操作

基本操作

添加用户

useradd -m 用户名

设置密码

passwd 用户名

删除用户

userdel  -r  用户名

删除用户目录

rm -rf 用户名

切换当前用户

su 用户名

参考与致谢

原文地址:https://wiki-power.com/
本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

MkDocs 测试实验室

2024年4月18日 15:43

MkDocs 测试实验室

MkDocs-Lab

Mermaid

graph TD
    a1("Collect Voltage vs. QUOT data across skew and temperature")
    a2("Select RO and define Target QUOT (fix value)" )
    a1-->a2
graph LR
    A[Square Rect] -- Link text --> B((Circle))
    A --> C(Round Rect)
    B --> D{Rhombus}
    C --> D
graph LR
  A[Start] --> B{Error?};
  B -->|Yes| C[Hmm...];
  C --> D[Debug];
  D --> B;
  B ---->|No| E[Yay!];
sequenceDiagram
  Alice->>John: Hello John, how are you?
  loop Healthcheck
      John->>John: Fight against hypochondria
  end
  Note right of John: Rational thoughts!
  John-->>Alice: Great!
  John->>Bob: How about you?
  Bob-->>John: Jolly good!
stateDiagram-v2
  state fork_state <<fork>>
    [*] --> fork_state
    fork_state --> State2
    fork_state --> State3

    state join_state <<join>>
    State2 --> join_state
    State3 --> join_state
    join_state --> State4
    State4 --> [*]

References & Acknowledgements

Original: https://wiki-power.com/
This post is protected by CC BY-NC-SA 4.0 agreement, should be reproduced with attribution.

PlatformIO 搭配 CubeMX 食用

2024年4月18日 15:43

PlatformIO 搭配 CubeMX 食用

背景

上一篇文章 中,我们可以看到,PlatformIO 用起来比 Keil 优雅多了。
众所周知,STM32 打开方式中,HAL 库比标准库更方便易用(配合神器 CubeMX),但 PlatformIO 官方对 CubeMX 的兼容不是特别完美(需通过 Python 中间件来进行代码转换)

在这篇文章中,我将介绍一种独特的方法,让 PlatformIO 配合 CubeMX 食用起来更加美味。

初始化项目

太长不看:我把以下步骤创建的项目文件夹放在 这个仓库,直接克隆即可。

CubeMX 的初始化操作

  1. 新建项目
  2. 选择 MCU 型号
  3. 配置 Pinout & Configuration
    1. 配置 RCC(选外部 / 内部时钟,视情况可略)
    2. 配置 SYS(将 DEBUG 选项由 No Debug 修改为 Serial Wire
  4. 配置 Clock Configuration
  5. 配置 Project Manager
    1. Project 页面 1. 填写项目名称 (Project Name) e.g. Template_of_PlatformIO_with_CubeMX 2. 修改项目路径 (Project Location) e.g. D:/Desktop 3. 将工具链(Toolchain / IDE)修改为 Other Toolchains
    2. Code Generator 页面 1. 将软件包选项(STM32Cube Firmware Library Package)选择为 Copy only the necessary library files 2. 在文件生成选项(Generated files)勾选 Generate peripheral initialization as a pair of '.c/.h' files per peripheral

终于配置完成了,我们点击右上角 Generate Code 生成代码吧。

PlatformIO 的初始化操作

  1. 打开 PlatformIO 的主页
  2. 点击 New Project 新建工程
    1. 填写工程的名字。注意:一定要与 CubeMX 中配置的相同!(e.g. Template_of_PlatformIO_with_CubeMX
    2. 选择板子 / MCU 型号。这儿可以直接选择 MCU 的型号(e.g. STM32F103C8),也可以直接选择版型(e.g. BluePill F103C8)。注意:一定要与 CubeMX 中配置的相同!
    3. 代码框架 Framework 选择 STM32Cube
    4. 将路径 LocationUse default location 取消掉,我们自定义路径。注意:一定要与 CubeMX 中配置的相同!(e.g. D:/Desktop
  3. 打开项目中 platformio.ini 文件,添加如下几行:

    [platformio]
    include_dir=Inc
    src_dir=Src
    

    这里是因为 PlatformIO 与 CubeMX 默认生成的框架文件夹不一样,为了兼容性,我们顺从 CubeMX.

  4. 可以将项目中的 include 文件夹删了。而因为 Windows 文件命名不区分大小写,所以 src 文件夹顺理成章变为 Src.

尽情享用吧!

项目中, .c 存放于 Src 文件夹中,.hInc 中。
只要在 /* USER CODE BEGIN *//* USER CODE END */ 之间的代码,后续从 CubeMX 生成的过程中,都将得以保留,不会被覆盖掉。

PlatformIO 可以用快捷键 Ctrl + Alt + B 编译,用 Ctrl + Alt + U 编译并上传,按 F5 开启调试。

接下来的探索,就是 HAL 库的学习了。未完待续 ~

参考与致谢

原文地址:https://wiki-power.com/
本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

STM32CubeIDE 串口重定向(printf)及输出浮点型

2024年4月18日 15:43

STM32CubeIDE 串口重定向(printf)及输出浮点型

重定向 printf 至串口

usart.c
/* USER CODE BEGIN 0 */

#include "stdio.h"

/* USER CODE END 0 */

/* USER CODE BEGIN 1 */

//_write 函数在 syscalls.c 中, 使用 __weak 定义, 所以可以直接在其他文件中定义 _write 函数
__attribute__((weak)) int _write(int file, char *ptr, int len)
{
    int DataIdx;
    for (DataIdx = 0; DataIdx < len; DataIdx++)
    {
          while ((USART1->SR & 0X40) == 0); //等待发送完毕
          USART1->DR = (uint8_t) *ptr++;
    }
    return len;
}

/* USER CODE END 1 */

STM32CubeIDE 串口输出浮点型

  1. 在 STM32CubeIDE 侧栏选中工程,右键选择 Properties - C/C++ Build - Settings - MCU GCC Linker - Miscellaneous
  2. Other flags 栏添加一个项目,填 -u_printf_float
  3. 重新编译即可。

HAL_UART_Receive_IT 乱码问题

HAL_UART_Transmit(&huart1, (uint8_t *)aRxBuffer, 10,0xFFFF); 的字长(10)改为 1 即可。

参考与致谢

原文地址:https://wiki-power.com/
本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

❌
❌