树莓派摔地上,断电,sd卡坏了。又要再配一次所有环境,干脆记下来。(torch装麻了)

装系统

装64位桌面系统。更新系统。用官方烧录工具,设置好wifi信息。

sudo apt update
sudo apt upgrade
python -m pip install --upgrade pip

换清华源

主要是apt和pip要换源。

用 sudo pcmanfm 打开文件管理修改相关文件。

pip更新所有包:

numpy必须更新,不然后面torch安装会报错。

开VNC

raspi-config ->  interface Options ->  VNC

设置root账号

sudo passwd root

允许root用ssh连接

sudo pcmanfm
打开/etc/ssh/sshd_config
找到以下这一行:
# PermitRootLogin prohibit-pass
变为:
PermitRootLogin yes

解决鼠标延迟

SD卡插电脑,找到cmdline.txt,尾加:(注意开头有个空格)

usbhid.mousepoll=0

解决显示器在彩虹屏后无信号

在/boot/config.txt中把

dtoverlay=vc4-kms-v3d

取消注释!(插一句。搜到贴吧有人说二极管烧了,急死我了。这是去谷歌搜到的答案,搜索结果质量比百度高。必应也比百度好。)

摄像头配置

断电装好摄像头。sudo raspi-config中打开摄像头 sudo pcmanfm,找到/boot/config.txt,尾加:

dtoverlay=ov5647

(不知道为什么解决了显示屏的问题摄像头就打不开了。但是没显示屏是肯定可以的)
“ov5647”是V1摄像头,需要根据买的摄像头查。
重启,用libcamera-hello测试摄像头。

附参考资料,包含了libcamera和opencv的基础使用:

浏览器调默认搜索引擎

谷歌浏览器右上角三个点->settings->search engine->bing设为默认

pytorch安装( important ! )

最重要的一步,必须选对版本:

在pytorch所有whl文件,下载“cpu/torch-1.8.1-cp39-cp39-manylinux2014_aarch64.whl”和“cpu/torchvision-0.9.1-cp39-cp39-manylinux2014_aarch64.whl”,用“pip install 文件名”安装。

OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.

所以尝试了一下其他版本:

Illegal instructionUserWarning: Named tensors and all their associated APIs are an experimental feature and subject to change. Please do not use them for anything important until they are released as stable.
Failed to load image Python extension: warn(f"Failed to load image Python extension: {e}")Illegal instruction

综上,要想报错少就1.8.1。
不装conda,因为符合树莓派的conda的版本太老了。

yolo&face_recognition安装

参考对应github项目readme。参考之前的文章:

OpenBLAS Warning解决

使用torch的时候可能会出现这种警告:

两个解决方法,法1解决命令行调用yolo时的报错,法二针对自己写的程序,方便点: 1. 每个终端里先输入

export OMP_NUM_THREADS=1

写bashrc里面没用,必须每次先输入这个。效果如下图:

2. 程序里明确使用单线程:

torch.set_num_threads(1)

编写GPIO模版文件

import RPi.GPIO as gpio
import time

gpio.setmode(gpio.BOARD)    # 物理引脚
# gpio.setmode(gpio.BCM)      # BCM引脚

def basic():
    gpio.setup(12,gpio.OUT,initial=gpio.LOW)
    gpio.output(12,1)
    time.sleep(1)
    gpio.output(12,0)
    gpio.cleanup()

def pwm():
    gpio.setup(12,gpio.OUT,initial=gpio.LOW)
    p = gpio.PWM(12,440)
    p.start(50)
    time.sleep(1)
    p.ChangeFrequency(880)
    time.sleep(1)
    p.ChangeDutyCycle(30)
    time.sleep(1)
    p.stop()
    gpio.cleanup()

编写torch神经网络模版文件

import torch
from torch import nn
import torchvision
from torch.utils.data import DataLoader
from PIL import Image
import os

torch.set_num_threads(1)    # 消警告"OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option"
Device = torch.device('cpu')

dir = os.path.dirname(__file__)
train_data = torchvision.datasets.CIFAR10(root=os.path.join(
    dir, 'data'), train=True, transform=torchvision.transforms.ToTensor(), download=True)
test_data = torchvision.datasets.CIFAR10(root=os.path.join(
    dir, 'data'), train=False, transform=torchvision.transforms.ToTensor(), download=True)

train_loader = DataLoader(train_data, batch_size=64)
test_loader = DataLoader(test_data, batch_size=64)
test_len = len(test_data)


class Beshar(nn.Module):
    def __init__(self) -> None:
        super().__init__()
        self.learn_rate = 0.002
        self.loss_fn = nn.CrossEntropyLoss().to(Device)
        self.model = nn.Sequential(
            nn.Conv2d(3, 32, 5, 1, 2),
            nn.AvgPool2d(2),
            nn.Conv2d(32, 32, 5, 1, 2),
            nn.AvgPool2d(2),
            nn.Conv2d(32, 64, 5, 1, 2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.LeakyReLU(),
            nn.Linear(64*4*4, 64),
            nn.LeakyReLU(),
            nn.Linear(64, 10)
        )
        self.optimizer = torch.optim.SGD(self.parameters(), lr=self.learn_rate)

    def forward(self, x):
        return self.model(x)

# 创建网络
b = Beshar().to(Device)
if os.path.isfile(os.path.join(dir,'Beshar_model.pth')):
    b.load_state_dict(torch.load(os.path.join(dir,'Beshar_model.pth')))
    print("load model from existed file!")

def Train():
    b.train()
    train_step = 0
    for i in range(30):
        print(f"-------round {i}-------")
        # 训练
        for data in train_loader:
            imgs, targets = data
            imgs = imgs.to(Device)
            targets = targets.to(Device)
            loss = b.loss_fn(b(imgs), targets)
            b.optimizer.zero_grad()     # 清空优化器
            loss.backward()             # 反向传播获取梯度
            b.optimizer.step()          # 修改权值
            train_step = train_step+1
            if train_step%200==0:
                print(f"have trained {train_step}, loss {loss.item()}")
        # 保存模型
        torch.save(b.state_dict(),os.path.join(dir,'Beshar_model.pth'))
        # 测试
        b.eval()
        right_num = 0
        with torch.no_grad():
            for data in test_loader:
                imgs, targets = data
                imgs = imgs.to(Device)
                targets = targets.to(Device)
                output = b(imgs)
                loss = b.loss_fn(output, targets)
                right_num = right_num + (output.argmax(1) == targets).sum()
        print(f"test right rate: {right_num/test_len}")

def Detect(path:str):
    img = Image.open(path)
    transform = torchvision.transforms.Compose([torchvision.transforms.Resize((32,32)),torchvision.transforms.ToTensor()])
    img = transform(img)
    img = torch.reshape(img,(1,3,32,32))
    b.eval()
    with torch.no_grad():
        result = b(img)
    print(train_data.class_to_idx[result.argmax(1).item()])


Train()
Detect(os.path.join(dir,'example.jpg'))

NoneBot安装

个人安装流程:

pip install nb-cli

下载适配器:

nb adapter
Install a Published Adapter
OneBot V11
(之所以不用nb adapter install是因为V11之前有个空格会被当做参数)

​我是有一个已经配置好的QQbot项目,需要下载树莓派对应的go-cqhttp:

  1. 去Releases · Mrs4s/go-cqhttp · GitHub下载go-cqhttp_1.0.0-rc3_linux_arm64.deb
  2. cd到压缩包所在文件夹然后解压:dpkg ./go-cqhttp_1.0.0-rc3_linux_arm64.deb ./
  3. 替换掉:/usr/bin/go-cqhttp
  4. 开权限:chmod 777 ./go-cqhttp
  5. ./go-cqhttp运行,扫码登录以更新配置文件

一键运行脚本:

cd /home/pi/Programs/QQbot/usr/bin    # 项目所在
lxterminal -e ./go-cqhttp
cd /home/pi/Programs/QQbot/beshar
lxterminal -e python bot.py

Github备份

怕后面又出什么幺蛾子导致前功尽弃,所以创建私有仓库进行程序的备份。

.gitignore:

yolov5/   # clone的,没必要
core.181  # 太大了
torch/data/  # 训练没必要
QQbot/usr/   # 每天都在变

git配置用户,不要在树莓派上做,因为即使输入token也不行;在vscode远程连接里完成,因为会打开浏览器,直接授权即可。