App后端开发

什么是API? 前后端工作的一个完整的工作流,是前端发送HTTP请求,后端接受,完整请求任务(查找信息、调用ai等),并返回请求值。由于一个应用功能很多,故给后端上需要分而治之,即每个功能定义一个api,实现: 接收 调用对应脚本(通常是许多函数,链接到对应脚本) 返回 这个过程中,前端通过api定义的格式来发送请求到对应功能的api,并按照api定义的格式返回数据 如何搭建API? 自己从零开始写是不可能的,涉及许多HTTP等网络相关的繁琐工作,故需要API框架。这些API框架帮你完成了诸如通信、交互等繁琐的任务,你只需要专注于功能的实现即可。 常用的api框架有fastapi、flask、nodejs等,由于我对python比较熟悉,这里以fastapi为例。 1 2 3 4 5 6 7 8 9 10 11 12 from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"Hello": "World"} @app.get("/items/{item_id}") def read_item(item_id: int, q: str | None = None): # 不在路径大括号里的参数,会被 FastAPI 自动识别为 Query Parameter(查询参数) return {"item_id": item_id, "q": q} 以上是FASTAPI官方例程,这里做简单语法解释: @app.get("/") @是python的装饰器,我将其理解为api的标志 get:fastapi的方法,表示查看数据的动作(不更改数据),除此之外还有post(创建)、put(修改)、delect(删除) "/":路径。我觉得这是最抽象的一点。这个路径和你开发时app的目录结构没有任何关系,它代表的是你的功能模块之间的结构和路径,表示你要对哪个功能进行操作。举个例子,我想实现一个集查询信息和论坛功能一体的应用: 有关竞赛的功能:放在competitions目录下;有关论坛的,放在forum目录下,功能结构非常清晰 总得来说,get等动作命令和路径化的功能信息明确指出了“要对哪个功能进行什么操作”。 下面的就是通过不同函数的调用实现功能并返回值了。 如何阅读API文档?(以FASTAPI为例) 部署代码到服务器上 推送到github 生成requirements.txt 使用pipreqs包,检测项目中用到的所有库和版本,并写入requirements.txt pip install pipreqs pipreqs . –force .: 当前目录(终端打开的目录)下所有文件的依赖库 --force: 强制覆盖,即使已存在requirements文件 内网穿透 使用cpolar uvicorn app.main:app --host 0.0.0.0 --port 8080开启你的后端 下载、注册cpolar 在“验证”中找到你的Authtoken 在cmd上运行cpolar authtoken <你的TOKEN内容>,将你的token添加到你的环境变量中 cmd上cpolar http 8080 输出一个http开头的随机域名,对应localhost。 访问api:直接在该随机域名后添加api路径 FASTAPI文档:直接在该随机域名后添加/docs 免费模式,每次重启后端域名都会随机生成,下次开启后端后要重复步骤4,获取新域名。

March 4, 2026 · 1 min · pearl

Softmax回归

abstract: 李沐动手深度学习–softmax回归的数学原理与从零实现 story: 什么是适合新手的教程? Attention: 关于语法的讲解主要涉及torch库,其他库的用法可能略有出入 一. 回归 vs 分类 本质上:输出连续与否 譬如softmax回归,其输出是预测为某类别的概率,是连续值,属于[0, 1]之间,故即使最后用于分类问题,其本质也是一个回归模型 二. 神经元与激活函数 2.1 神经元 所谓神经元,指的是一个运算过程:f(W*X + b) ,W是该神经元前一层的权重,X是该神经元前一层的输出,这两者通常是两个矩阵。b是偏置,决定W*X有多难被激活(对于阶跃函数或ReLu这种激活函数,自变量小于零时函数值为0,故可以通过调节偏置b的值,进而调节W*X被激活的阈值)。而f()就是激活函数。 2.2 激活函数 神经网络中,激活函数必须是非线性的,否则网络的层数和深度都没有意义。而激活函数是非线性的,不代表网络一定是非线性的。非线性的网络需要满足两个条件: 非线性的激活函数 复合运算或者高次运算 在网络中,复合运算就是指多层网络,即至少存在一层隐藏层神经元,两组W权重矩阵的网络 三. softmax 3.1 两个作用 非负化 将数值映射到0-1区间(概率化) 3.2 公式 $$\frac{}$$四.代码一般结构 4.1 工具函数 4.1.1 定义net 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 def softmax(X): ''' softmax 的 Docstring :param X: 二维矩阵,每行代表一个样本,每列代表一个类别,即每行代表一个样本的各类别的得分 ''' X_exp = torch.exp(X) example_sum = X_exp.sum(dim=1, keepdim=True) return X_exp / example_sum def net(X): ''' net 的 Docstring batch_size*(H*W) @ (H*W)*num_classes -> batch_size*num_classes :param X: 输入数据,形状为 (batch_size, 1, 28, 28),需要先 reshape 成 (batch_size, 784) 才能与权重矩阵 W 相乘. ''' return softmax(torch.matmul(X.reshape(-1,W.shape[0]), W) + b) # 这里reshape不会改变原始数据形状, 也不创建新副本, 数据还是那个数据,这里创建了一个新视图,改变了查看数据的方式 -sum(dim = 0): dim等于几,shape中第几项就变为1。比如dim = 0,一个[2,3]的矩阵变为了[1,3],也就是对每一行求和,成了一个列向量;同样地,dim = 1时对每一列求和,成了一个行向量 ...

February 14, 2026 · 4 min · pearl

远程服务器常用命令

abstract:记录在远程服务器跑代码遇到的问题和常用的命令行语句 story:公用服务器上改代码,显存爆炸后差点把同门进程给鲨了,故作此文以记录 查看GPU状态 nvidia-smi: 关注这几个点: 上半张表:GPU信息 Memory-Usage:显存 Volatile GPU-Util:GPU利用率 下半张表:进程信息 PID:进程号(你会发现1152339进程占了两张卡) xorg:Linux的图形化驱动,不用管 GPU0上1152339进程占了11个G,这就是我显存炸掉的罪魁祸首!我的进程需要的显存大于24-11=13G,自动卡退了 这个进程是谁的呢? 进程 kill -9 1152339 强行杀死进程 ps -u -p 1152339 看看这个进程是谁的 ps -ef | grep 1152339 搜索所有含有“1152339”名字的进程,并显示完整信息 还可以ps -ef | grep yourusername,查看和你有关的所有进程

February 6, 2026 · 1 min · pearl

远程服务器文件传输

abstract:如何把一份10G的代码从本地传输到远程服务器 story:原来git也会被push死 以传输HSI_ATTACK2代码为例 查看子文件夹大小 linux:在母目录下输入: du -h –max-depth=1 | sort -hr -h:hunman redable,人类可读 –max-depth=1:最大深度,为1则只统计下一级目录的大小,不会具体到文件 |:管道,把数据传输到sort管道里 -hr:按易读数字反向排序,h指明白1G比200M大,r指reverse,逆序 结果: 把占用大的数据通过rsync传输,git仅传输代码 1. Git git不能传输过大文件夹,例如这里的10G直接push会连接超时 1.1. .gitignore 把不想要的文件类型或文件目录写入.gitignore bash: nano .gitignore # 创建并打开.gitignore文件 # 写入 params/ logs/ RESREPORT/ dataset/ abundance_matrix/ # ^X退出编辑 查看文件 bash: cat .gitignore # 用于查看简短文件 直接将文件内容输出在终端 less .gitignore # 查看长文件 可翻页 按q退出 1.2. 在服务器上建仓库 之前仓库一直都建立在github上,而仓库也可以建立在服务器上,而且仓库可以不托管源代码,只托管代码的“基因”,也就是–bare,通过克隆仓库复原源代码 (本地的wsl上:) 从用du查看的目录大小可以发现,.git托管了所有代码的所有更改,特别臃肿,所以删掉 rm -rf .git 重新初始化(在本地的HSI_ATTACK2目录下) git init 确保已经编辑好.gitignore后,将更改加入暂存区 git add . ...

February 6, 2026 · 1 min · pearl

Stm32小车电路设计

元件引脚功能 tb6612 左列(连接单片机) PWMA:控制A电机转速 通过PWM的占空比控制电机转速 AIN1:和AIN2一起控制A电机转向,电平高低变为0-1信号,即通过两边施力与否控制转向,两两组合: GPIO-A4 0-1:正转 1-0:反转 0-0:空档(两侧均不施力) 1-1:刹车(两侧同时施力) AIN2 GPIO-A5 STBY:控制驱动模块是否工作的开关 BIN1:类似AIN1 BIN2 PWMB GND: 连接单片机接地 右列(连接电机) VM:M指的是machine,也就是驱动电机需要的电压(一般为高电压,4.5-15v不等) VCC:cc:逻辑电路,指的是让tb6612这块板子运行起来的电压,一般为3.3v或5v GND:电机接地 AO1:连A电机M+ AO2:M- BO1:连B电机M- BO2: M+ GND:电机接地 这三个GND要共地,否则会故障。出现问题时检查是否共地 霍尔编码器 VCC:3.3v GND A相:接单片机脉冲检测接口 B相 M+:电机接口,接tb6612的AO1 M-:AO2 oled屏幕 VCC GND SCL:接单片机 用于IIC通信 SDA:同上 MPU6050 VCC GND SCL SDA 剩余引脚用于连接电磁传感器形成九轴传感器

December 3, 2025 · 1 min · pearl

HSI攻击

abstract:高光谱图像攻击中需要了解的知识 story:这篇没有story:D A. 高光谱图像数据集 高光谱:像素的记录格式不再是rgb,而是按照光谱波段记录 Indian pine 只有一张图片,分辨率为145*145 该图片的每个像素作为一个样本,每个像素都由一个200个数字描述,表示各个波段的反射强度,理论上属于0-1 这张图拍的主要为农作物,共有16个类别,即10249个样本对应16个类别,包括草地、玉米地、林地等 Indian Pines 数据集的规模: 145*145*200 (width height 波段数) 下载得到的数据集形式 Indian_pines.mat :原始的Indian Pines 数据集: 145*145*220 Indian_pines_corrected.mat 矫正后的Indian Pines 数据集: 145*145*200 Indian_pines_gt.mat 标签矩阵 145*145 部分内容引自知乎 AVIRIS 成像光谱仪成像波长范围为 0.4-2.5μm,是在连续的 220 个波段对地物连续成像的,但是由于第 104-108,第 150-163 和第 220 个波段不能被水反射,因此,我们一般使用的是剔除了这 20 个波段后剩下的 200 个波段作为研究的对象。 145*145 = 21025=10776(背景,黑)+ 10249(多种地物,彩) > 10249 = 各类地物占得像素个数。 解混 我们对丰度矩阵A添加扰动,丰度矩阵表示每个像素中不同端元的占比,端元库表示不同端元(纯净)在光谱中200个波段下的值 B. Universal Perturbation 算法:在每一轮迭代中都找到$\Delta v$ C. 经典神经网络的训练逻辑 DataLoader 一个迭代器 pbar = tqdm(enumerate(attack_loader), total=len(attack_loader)) for index, (_, abun, abun_sum, noise, labels, _) in pbar: # 每次迭代使用一个batch的数据来更新扰动(正常32个,但如果最后一组样本量不足32,那就不足32,不舍弃) 用for迭代,每次迭代使用一个batch的数据来更新扰动(正常32个,但如果最后一组样本量不足32,那就不足32,不舍弃) ...

November 24, 2025 · 1 min · pearl

视觉_K230开发实践

记录学习k230的过程 25.11.11 准备工作、学习摄像模块 准备工作 固件烧录 例程复现 找到了ocr(文字识别)现成例程 小声:结合多平台教程文档,如01studio或嘉楠等等,这个没有的例程,另一个说不定有呢 摄像模块 k230摄像头架构 板子最多搭载三个摄像头 每个摄像头可以接入三个不同的处理模块(对输入图像进行加工处理) 每个模块(camera_device)有三个输出通道,可以多输出并行 摄像头模块编程 sensor基础语法 创建处理模块 1 2 from media.sensor import * sensor = Sensor(id ,width ,height ,fps) # 实例化,对应架构中的处理模块 id:摄像头id,默认为2 width ,height ,fps:最大输出图像参数 设置图像输出大小和位置 1 2 3 4 sensor.reset() # 初始化sensor对象及传感器 sensor.set_framesize(chn=CAM_CHN_ID_0, width=640, height=480) sensor.set_framesize(chn=CAM_CHN_ID_3, framesize = Sensor.VGA) framesize参数对应width、height,表示输出图像分辨率,二者作用相同。 framesize = Sensor.VGA即表示640*480分辨率,除此之外,还有Sensor.HD等表示分辨率的代号,这些代号统称为图像帧尺寸 chn:channel_number,表示输出通道,即架构中每个模块的三个输出通道 设置图像怎么输出、输出位置 sensor.set_pixformat(pix_format, chn=CAM_CHN_ID_0) pix_format:输出图像的像素格式,即每个像素在计算机中如何存储,也就是RGB三个通道数据用多少位存储。 常用有: RGB565:R for 5 bits ; G for 6 bits ; B for 5 bits RGB888: R G B for 8 bits respectively 水平与竖直反转 sensor.set_hmirror(True) # 水平 sensor.set_vflip(False) # 竖直 启动、关闭摄像头 sensor.run() sensor.stop() 多个摄像头只用启动一次,但要分别关闭 ...

November 11, 2025 · 11 min · pearl

个人博客学习笔记

个人博客搭建 ========================================================== Part 1. hugo搭建并在本地预览 25.11.10. 创建博客总站 新建文件夹,存放你的博客。在该文件夹下运行 hugo new site . -初始化站点 创建一篇文章 hugo new posts/这篇博客的名字.md 然后,你可以看到在content/posts目录下多了一个md文档 编辑完成后将draft改为false,否则不在网页上显示 主题 git clone你喜欢的主题,并将文件复制到themes文件夹下 在hugo.toml(参数文档)中增加: theme = “hugo-PaperMod” 别忘记双引号! 其他设置 在hugo.toml(参数文档)中 [params] description = “my first blog” author = “pearl” 本地预览 终端输入 hugo server 打开终端显示的域名即可 25.11.11 1. 补充:wsl中配置代理 之前登录时wsl会提示: wsl: 检测到 localhost 代理配置,但未镜像到 WSL。NAT 模式下的 WSL 不支持 localhost 代理。 这句话有两点值得注意 NAT模式:相当于wsl2运行在一个小虚拟机中,该虚拟机有自己的ip:通常为172. 镜像模式:作为localhost(windows本机)的镜像映射,windows有啥,wsl就有啥 配置WSL镜像 windows的用户目录(30743)下新建建立新文件.wslconfig并写入: [wsl2] networkingMode=mirrored< autoProxy=true 重启wsl 提示消失,wsl可以访问github Part 2. 部署到git page 25.11.14 根据网上“hugo + git page”教程配置即可 注意 ...

November 10, 2025 · 1 min · pearl

My First Post

abstrct:梦开始的地方 Hello World! I have borned!

November 9, 2025 · 1 min · pearl