【卷积神经网络】LeNet实践
模型建立
- 数据初始化
- 根据模型搭建前向传播
- 打印模型结构
前向传播数据初始化
def __init__(self):super(LeNet, self).__init__()# 第一层卷积层:# 输入:灰度图像 (1通道,大小 28x28)# 输出:6个特征图 (大小 28x28, 通过padding=2保持尺寸不变)# 卷积核大小为 5x5,步幅为 1self.c1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5, padding=2)# 激活函数:# 使用 Sigmoid 作为激活函数,将卷积输出的值压缩到 (0,1) 区间self.sig = nn.Sigmoid()# 第一层池化层:# 输入:6个特征图 (28x28)# 输出:6个特征图 (14x14, 通过池化降采样)# 池化窗口大小为 2x2,步幅为 2self.s2 = nn.AvgPool2d(kernel_size=2, stride=2)# 第二层卷积层:# 输入:6个特征图 (14x14)# 输出:16个特征图 (10x10, 无padding)# 卷积核大小为 5x5,步幅为 1self.c3 = nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5)# 第二层池化层:# 输入:16个特征图 (10x10)# 输出:16个特征图 (5x5, 通过池化降采样)# 池化窗口大小为 2x2,步幅为 2self.s4 = nn.AvgPool2d(kernel_size=2, stride=2)# 展平层:# 输入:16个特征图 (5x5)# 输出:展平为长度为 400 的向量self.flatten = nn.Flatten()# 全连接层 1:# 输入:长度为 400 的向量# 输出:长度为 120 的向量self.f5 = nn.Linear(400, 120)# 全连接层 2:# 输入:长度为 120 的向量# 输出:长度为 84 的向量self.f6 = nn.Linear(120, 84)# 全连接层 3:# 输入:长度为 84 的向量# 输出:长度为 10 的向量(对应10个分类标签,如MNIST数字分类)self.f7 = nn.Linear(84, 10)
构建前向传播
def forward(self, x):# 前向传播过程# 1. 卷积层 + 激活函数x = self.sig(self.c1(x)) # 第一层卷积 + 激活函数# 2. 池化层x = self.s2(x) # 第一层池化# 3. 卷积层 + 激活函数x = self.sig(self.c3(x)) # 第二层卷积 + 激活函数# 4. 池化层x = self.s4(x) # 第二层池化# 5. 展平x = self.flatten(x) # 将特征图展平为向量# 6. 全连接层 1x = self.sig(self.f5(x)) # 第一全连接层 + 激活函数# 7. 全连接层 2x = self.sig(self.f6(x)) # 第二全连接层 + 激活函数# 8. 全连接层 3x = self.f7(x) # 第三全连接层(输出分类结果)return x
打印模型参数
if __name__ == "__main__":# 判断当前是否有可用的GPU,如果有则使用CUDA(GPU),否则使用CPUdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 初始化模型(LeNet类假设在之前已定义)# 并将模型加载到指定的设备(CPU或GPU)上model = LeNet().to(device)# 打印模型的摘要,包括模型结构、每层的参数数量以及输出形状# 输入形状指定为 (1, 28, 28),即单通道灰度图像print(summary(model, (1, 28, 28)))
运行结果
数据预处理
- 加载训练数据集
- 创建数据加载器
from torchvision.datasets import FashionMNIST # 导入 FashionMNIST 数据集
from torchvision import transforms # 图像处理工具
import torch.utils.data as Data # 数据加载工具
import numpy as np # 数值计算工具
import matplotlib.pyplot as plt # 数据可视化工具# 加载训练数据集
train_data = FashionMNIST(root='./data', # 数据存储的根目录train=True, # 加载训练数据transform=transforms.Compose([transforms.Resize(size=224), # 将图像调整到 224x224 的大小transforms.ToTensor() # 将图像转换为 PyTorch 张量]),download=True # 如果数据集不存在,则自动下载
)# 创建数据加载器
train_loader = Data.DataLoader(dataset=train_data, # 数据集batch_size=64, # 每批次加载 64 张图片shuffle=True, # 随机打乱数据num_workers=0 # 数据加载时使用的子线程数(Windows 环境下设置为 0)
)# 提取一个批次的数据
for step, (b_x, b_y) in enumerate(train_loader): # 遍历训练数据加载器if step > 0: # 只提取第一个批次break# 将图像数据转换为 NumPy 格式,并移除单一的维度
batch_x = b_x.squeeze().numpy() # b_x: 形状为 [64, 1, 224, 224],squeeze 移除第 2 维
batch_y = b_y.numpy() # 将标签转换为 NumPy 数组
class_label = train_data.classes # 获取数据集中的类别标签
# print(class_label) # 如果需要调试,可以打印类别标签列表# 打印当前批次的维度
print("The size of batch in train data:", batch_x.shape) # 输出批次大小,例如 [64, 224, 224]# 可视化一个批次的图像
plt.figure(figsize=(12, 5)) # 创建一个 12x5 的画布
for ii in np.arange(len(batch_y)): # 遍历当前批次的每个样本plt.subplot(4, 16, ii + 1) # 在 4x16 网格中创建子图plt.imshow(batch_x[ii, :, :], cmap=plt.cm.gray) # 绘制图像,灰度显示plt.title(class_label[batch_y[ii]], size=10) # 设置标题为对应的类别标签plt.axis("off") # 隐藏坐标轴plt.subplots_adjust(wspace=0.05) # 调整子图之间的间距
plt.show() # 显示图像
模型训练
数据预处理
import torch
from torchvision.datasets import FashionMNIST
from torchvision import transforms
import torch.utils.data as Data
import numpy as np
import matplotlib.pyplot as plt
from model import LeNet
import torch.nn as nn
import pandas as pddef train_val_data_process():train_data = FashionMNIST(root='./data',train=True,transform=transforms.Compose([transforms.Resize(size=28), transforms.ToTensor()]),download=True)#划分训练集与验证集 80%用于训练train_data, val_data = Data.random_split(train_data, [round(0.8 * len(train_data)), round(0.2 * len(train_data))])#训练数据加载器train_dataloader = Data.DataLoader(dataset=train_data,batch_size=32,shuffle=True,num_workers=2)#验证数据加载器val_dataloader = Data.DataLoader(dataset=val_data,batch_size=32,shuffle=True,num_workers=2)return train_dataloader, val_dataloader# train_val_data_process()
训练逻辑
代码训练逻辑如果是学习新知识考试
初始化(学习计划制定)
- 学生决定使用纸质书还是电子书来学习,类似于代码中选择 GPU 或 CPU
- 优化器类似于学习方法(比如背诵、做笔记),损失函数类似于判断学习效果的标准(是否答对问题)
训练阶段(学习阶段)
- 学生每天从学习材料中抽取一部分内容(批次)
- 学习时通过练习题测试自己的理解,找出错误并改正(前向传播和反向传播)
- 每天记录自己学了多少内容以及正确率(累加损失和正确样本数)
验证阶段(考试)
- 学生在考试中用未见过的题目检验学习效果
- 只计算考试的分数(验证损失和准确率),不再对学习内容进行改动
记录结果(反思总结)
- 每天记录学习和考试的情况(损失和准确率)
- 如果某天考试成绩比历史最好成绩高,就记录这一天的学习成果(保存最优模型参数)
最终总结(保存模型)
- 保存最优模型(保存学习笔记以备后续复习)
训练函数实现
实现逻辑简单理解(训练过程类似应对考试的全流程)
###########################################
####深度学习训练与验证
##########################################
def train_model_process(model, train_dataloader, val_dataloader, num_epochs):##############################################设备设置和优化器初始化########################################### 设定训练所用到的设备,有GPU用GPU没有GPU用CPUdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 使用Adam优化器,学习率为0.001optimizer = torch.optim.Adam(model.parameters(), lr=0.001)# 损失函数为交叉熵函数criterion = nn.CrossEntropyLoss()# 将模型放入到训练设备中model = model.to(device)# 复制当前模型的参数best_model_wts = copy.deepcopy(model.state_dict())##############################################初始化变量########################################### 最高准确度best_acc = 0.0# 训练集损失列表train_loss_all = []# 验证集损失列表val_loss_all = []# 训练集准确度列表train_acc_all = []# 验证集准确度列表val_acc_all = []# 当前时间since = time.time()##############################################训练和验证循环##########################################for epoch in range(num_epochs):print("Epoch {}/{}".format(epoch, num_epochs-1))print("-"*10)# 初始化参数# 训练集损失函数train_loss = 0.0# 训练集准确度train_corrects = 0# 验证集损失函数val_loss = 0.0# 验证集准确度val_corrects = 0# 训练集样本数量train_num = 0# 验证集样本数量val_num = 0# 对每一个mini-batch训练和计算for step, (b_x, b_y) in enumerate(train_dataloader):# 将特征放入到训练设备中b_x = b_x.to(device)# 将标签放入到训练设备中b_y = b_y.to(device)# 设置模型为训练模式model.train()# 前向传播过程,输入为一个batch,输出为一个batch中对应的预测output = model(b_x)# 查找每一行中最大值对应的行标pre_lab = torch.argmax(output, dim=1)# 计算每一个batch的损失函数loss = criterion(output, b_y)# 将梯度初始化为0optimizer.zero_grad()# 反向传播计算loss.backward()# 根据网络反向传播的梯度信息来更新网络的参数,以起到降低loss函数计算值的作用optimizer.step()# 对损失函数进行累加(学到了多少内容)train_loss += loss.item() * b_x.size(0)# 如果预测正确,则准确度train_corrects加1(正确率)train_corrects += torch.sum(pre_lab == b_y.data)# 当前用于训练的样本数量train_num += b_x.size(0)##############################################验证阶段##########################################for step, (b_x, b_y) in enumerate(val_dataloader):# 将特征放入到验证设备中b_x = b_x.to(device)# 将标签放入到验证设备中b_y = b_y.to(device)# 设置模型为评估模式model.eval()# 前向传播过程,输入为一个batch,输出为一个batch中对应的预测output = model(b_x)# 查找每一行中最大值对应的行标pre_lab = torch.argmax(output, dim=1)# 计算每一个batch的损失函数loss = criterion(output, b_y)# 对损失函数进行累加val_loss += loss.item() * b_x.size(0)# 如果预测正确,则准确度train_corrects加1val_corrects += torch.sum(pre_lab == b_y.data)# 当前用于验证的样本数量val_num += b_x.size(0)##############################################记录和打印结果########################################### 计算并保存每一次迭代的loss值和准确率# 计算并保存训练集的loss值train_loss_all.append(train_loss / train_num)# 计算并保存训练集的准确率train_acc_all.append(train_corrects.double().item() / train_num)# 计算并保存验证集的loss值val_loss_all.append(val_loss / val_num)# 计算并保存验证集的准确率val_acc_all.append(val_corrects.double().item() / val_num)print("{} train loss:{:.4f} train acc: {:.4f}".format(epoch, train_loss_all[-1], train_acc_all[-1]))print("{} val loss:{:.4f} val acc: {:.4f}".format(epoch, val_loss_all[-1], val_acc_all[-1]))##############################################保存最优模型##########################################if val_acc_all[-1] > best_acc:# 保存当前最高准确度best_acc = val_acc_all[-1]# 保存当前最高准确度的模型参数best_model_wts = copy.deepcopy(model.state_dict())# 计算训练和验证的耗时time_use = time.time() - sinceprint("训练和验证耗费的时间{:.0f}m{:.0f}s".format(time_use//60, time_use%60))# 选择最优参数,保存最优参数的模型torch.save(best_model_wts, "E:\秋招就业\CNN卷积神经网络\测试用例\LeNet\\best_model.pth")train_process = pd.DataFrame(data={"epoch":range(num_epochs),"train_loss_all":train_loss_all,"val_loss_all":val_loss_all,"train_acc_all":train_acc_all,"val_acc_all":val_acc_all,})return train_process
可视化打印
ef matplot_acc_loss(train_process):# 显示每次迭代后的训练集和验证集的损失与准确率plt.figure(figsize=(12, 4)) # 创建一个宽 12、高 4 的画布# 第一个子图:训练与验证的损失函数变化plt.subplot(1, 2, 1) # 第 1 行、第 1 列、第 1 个子图plt.plot(train_process['epoch'], train_process.train_loss_all, "ro-", label="Train loss") # 绘制训练损失曲线plt.plot(train_process['epoch'], train_process.val_loss_all, "bs-", label="Val loss") # 绘制验证损失曲线plt.legend() # 显示图例plt.xlabel("epoch") # x 轴标签plt.ylabel("Loss") # y 轴标签# 第二个子图:训练与验证的准确率变化plt.subplot(1, 2, 2) # 第 1 行、第 2 列、第 2 个子图plt.plot(train_process['epoch'], train_process.train_acc_all, "ro-", label="Train acc") # 绘制训练准确率曲线plt.plot(train_process['epoch'], train_process.val_acc_all, "bs-", label="Val acc") # 绘制验证准确率曲线plt.xlabel("epoch") # x 轴标签plt.ylabel("Accuracy") # y 轴标签plt.legend() # 显示图例plt.show() # 显示绘制的图像if __name__ == '__main__':# 加载需要的模型LeNet = LeNet()# 加载数据集train_data, val_data = train_val_data_process()# 利用现有的模型进行模型的训练train_process = train_model_process(LeNet, train_data, val_data, num_epochs=20)matplot_acc_loss(train_process)
训练结果
左边错误率,右边正确率
Epoch 0/19
----------
0 train loss:0.9156 train acc: 0.6530
0 val loss:0.6296 val acc: 0.7583
训练和验证耗费的时间0m24s
Epoch 1/19
----------
1 train loss:0.5498 train acc: 0.7897
1 val loss:0.5201 val acc: 0.8092
训练和验证耗费的时间0m46s
Epoch 2/19
----------
2 train loss:0.4720 train acc: 0.8251
2 val loss:0.4770 val acc: 0.8291
训练和验证耗费的时间1m8s
Epoch 3/19
----------
3 train loss:0.4265 train acc: 0.8422
3 val loss:0.4196 val acc: 0.8462
训练和验证耗费的时间1m31s
Epoch 4/19
----------
4 train loss:0.3963 train acc: 0.8534
4 val loss:0.3953 val acc: 0.8558
训练和验证耗费的时间1m53s
Epoch 5/19
----------
5 train loss:0.3690 train acc: 0.8626
5 val loss:0.3777 val acc: 0.8602
训练和验证耗费的时间2m16s
Epoch 6/19
----------
6 train loss:0.3500 train acc: 0.8687
6 val loss:0.3656 val acc: 0.8663
训练和验证耗费的时间2m38s
Epoch 7/19
----------
7 train loss:0.3332 train acc: 0.8743
7 val loss:0.3465 val acc: 0.8734
训练和验证耗费的时间2m60s
Epoch 8/19
----------
8 train loss:0.3180 train acc: 0.8819
8 val loss:0.3365 val acc: 0.8747
训练和验证耗费的时间3m22s
Epoch 9/19
----------
9 train loss:0.3078 train acc: 0.8842
9 val loss:0.3389 val acc: 0.8735
训练和验证耗费的时间3m44s
Epoch 10/19
----------
10 train loss:0.2982 train acc: 0.8871
10 val loss:0.3327 val acc: 0.8801
训练和验证耗费的时间4m8s
Epoch 11/19
----------
11 train loss:0.2879 train acc: 0.8919
11 val loss:0.3068 val acc: 0.8852
训练和验证耗费的时间4m31s
Epoch 12/19
----------
12 train loss:0.2786 train acc: 0.8954
12 val loss:0.3040 val acc: 0.8870
训练和验证耗费的时间4m54s
Epoch 13/19
----------
13 train loss:0.2704 train acc: 0.8978
13 val loss:0.3089 val acc: 0.8881
训练和验证耗费的时间5m18s
Epoch 14/19
----------
14 train loss:0.2629 train acc: 0.9015
14 val loss:0.2877 val acc: 0.8935
训练和验证耗费的时间5m41s
Epoch 15/19
----------
15 train loss:0.2547 train acc: 0.9033
15 val loss:0.2968 val acc: 0.8901
训练和验证耗费的时间6m5s
Epoch 16/19
----------
16 train loss:0.2508 train acc: 0.9057
16 val loss:0.2915 val acc: 0.8921
训练和验证耗费的时间6m28s
Epoch 17/19
----------
17 train loss:0.2440 train acc: 0.9080
17 val loss:0.3284 val acc: 0.8809
训练和验证耗费的时间6m51s
Epoch 18/19
----------
18 train loss:0.2381 train acc: 0.9102
18 val loss:0.2834 val acc: 0.8954
训练和验证耗费的时间7m13s
Epoch 19/19
----------
19 train loss:0.2318 train acc: 0.9125
19 val loss:0.2842 val acc: 0.8950
训练和验证耗费的时间7m37s
模型测试
测试模型搭建逻辑
- 老师加载学生的答案
- 设备选择(GPU或CPU):老师选择在哪个地方(教室或办公室)批改试卷。如果有更多的资源(GPU),可以更快地批改;否则,就用现有的资源(CPU)
- 模型移动到设备上:类似于老师将试卷放到指定的位置开始批改
- 初始化计数器:老师开始计数正确和总的试题数
- 批改数据(循环遍历测试数据)
- 禁用梯度计算:就像老师在批改试卷时只关注答案,不需要反复修改试卷内容
- 循环遍历试卷:
- 数据迁移:老师将试卷放到批改台上
- 评估模式:老师保持客观,不带情绪地批改试卷
- 前向传播:老师查看学生的答案
- 预测标签:老师判断学生的答案是否正确
- 计算正确数量:如果答案正确,计数器加1
- 更新总数:统计总共批改了多少份试卷
- 最后计算准确率
具体实现
def test_data_process():test_data = FashionMNIST(root='./data',train=False,transform=transforms.Compose([transforms.Resize(size=28), transforms.ToTensor()]),download=True)test_dataloader = Data.DataLoader(dataset=test_data,batch_size=1,shuffle=True,num_workers=0)return test_dataloaderdef test_model_process(model, test_dataloader):# 设定测试所用到的设备,有GPU用GPU没有GPU用CPUdevice = "cuda" if torch.cuda.is_available() else 'cpu'# 将模型放入到测试设备中model = model.to(device)# 初始化参数test_corrects = 0.0test_num = 0# 只进行前向传播计算,不计算梯度,从而节省内存,加快运行速度with torch.no_grad():for test_data_x, test_data_y in test_dataloader:# 将特征放入到测试设备中test_data_x = test_data_x.to(device)# 将标签放入到测试设备中test_data_y = test_data_y.to(device)# 设置模型为评估模式model.eval()# 前向传播过程,输入为测试数据集,输出为对每个样本的预测值output = model(test_data_x)# 查找每一行中最大值对应的行标pre_lab = torch.argmax(output, dim=1)# 如果预测正确,则准确度test_corrects加1test_corrects += torch.sum(pre_lab == test_data_y.data)# 将所有的测试样本进行累加test_num += test_data_x.size(0)# 计算测试准确率test_acc = test_corrects.double().item() / test_numprint("测试的准确率为:", test_acc)if __name__=="__main__":# 加载模型model = LeNet()model.load_state_dict(torch.load('best_model.pth'))# 加载测试数据test_dataloader = test_data_process()# 加载模型测试的函数test_model_process(model, test_dataloader)
测试结果
如果想要提供精度,提升训练轮数即可
相关文章:
【卷积神经网络】LeNet实践
模型建立 数据初始化根据模型搭建前向传播打印模型结构 前向传播数据初始化 def __init__(self):super(LeNet, self).__init__()# 第一层卷积层:# 输入:灰度图像 (1通道,大小 28x28)# 输出:6个特征图 (大小 28x28, 通过padding2保…...
FPGA实现GTP光口数据回环传输,基于Aurora 8b/10b编解码架构,提供2套工程源码和技术支持
目录 1、前言工程概述免责声明 2、相关方案推荐我已有的所有工程源码总目录----方便你快速找到自己喜欢的项目我这里已有的 GT 高速接口解决方案 3、工程详细设计方案工程设计原理框图用户数据发送模块基于GTP高速接口的数据回环传输架构GTP IP 简介GTP 基本结构GTP 发送和接收…...
Tongweb8命令行使用收集(by lqw)
文章目录 声明对应版本修改thanos用户密码部署应用到默认实例节点相关操作新增节点(一般一个服务器ip只能装一个节点)启动节点(需确认节点没有运行)停止节点删除节点节点新增应用节点查看应用节点启动应用节点停止应用节点卸载应用(谨慎操作,卸载后应用就没有了,建议备份后…...
基于STM32的火灾烟雾报警器设计开题报告
开题报告 题目:基于STM32的火灾烟雾报警器Proteus仿真设计 一、研究背景与意义 随着现代城市化进程的加快,火灾安全问题日益凸显,火灾的早期预警对于减少人员伤亡和财产损失至关重要。传统的火灾报警系统往往依赖于烟雾或温度的单一检测&a…...
go 语言zero项目设置后台运行的几种方式
在 Go 项目中将程序设置为后台运行通常有几种方法。你可以使用 systemd、nohup 或者将 Go 程序作为服务启动。以下是几种常见的方法,分别适用于不同的场景。 ### 1. 使用 nohup 命令将 Go 程序后台运行 nohup 是一个常用的 Linux 工具,它可以将命令行程…...
数据库中的代数运算
这些代数基本运算通常被封装在数据库查询语言中,如SQL中的SELECT、FROM、WHERE等子句,使得用户可以更方便地对数据库进行查询和处理。 下面的介绍基于以下两个关系来说明: 传统的集合运算 并(∪) 合并两个关系中的元组…...
【机器学习】机器学习的基本分类-无监督学习-核密度估计(Kernel Density Estimation, KDE)
核密度估计(Kernel Density Estimation, KDE) 核密度估计(KDE)是一种非参数化方法,用于估计数据的概率密度函数(PDF)。与直方图相比,KDE 能够生成平滑的概率密度曲线,是…...
语义分割——DeeplabV3plus
DeeplabV3plus 是一种先进的用于语义分割任务的深度学习模型。DeepLabV3plus模型采用了编码器-解码器(Encoder-Decoder)结构,通过编码器提取图像特征,再通过解码器将这些特征映射回原始图像尺寸,实现像素级的分类。具体…...
【Leetcode 每日一题 - 扩展】50. Pow(x, n)
问题背景 实现 p o w ( x , n ) pow(x, n) pow(x,n),即计算 x x x 的整数 n n n 次幂函数(即, x n x_n xn)。 数据约束 − 100.0 < x < 100.0 -100.0 \lt x \lt 100.0 −100.0<x<100.0 − 2 31 ≤ n ≤ 2 31 −…...
富士相机基本参数学习
一色彩 富士相机视频调色入门课[上]|胶片模拟,白平衡与色彩|全是样片哦_哔哩哔哩_bilibili 步骤: 1设置曝光模式: 自动模式下拍摄降低难度 2设置白平衡:自动 不满意可以设置 3色彩&…...
MySQL:表的约束
目录 一. 表的约束和约束的目标 二. 空属性 三. 默认值default 四. 列描述 五. zerofill 六. 主键 6.1 建表时定义主键 6.2 去掉主键 6.3 建表后添加主键 6.4 复合主键 七. 自增长 八. 唯一键 九. 外键 一. 表的约束和约束的目标 表…...
Python鼠标轨迹算法(游戏防检测)
一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言,原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势: 模拟…...
Elasticsearch 架构及 Lucene 索引结构原理入门
文章目录 Elasticsearch 整体架构Lucene 索引结构Lucene 倒排索引核心原理倒排索引倒排表(Posting List) Elasticsearch 整体架构 一个 ES Index 在集群模式下,有多个Node(节点)组成,每个节点就是ES的 inst…...
vue3项目通过修改虚拟dom实现向页面上追加内容
前言: demo效果: 1、刚进页面,渲染welcome.vue组件内容。2、向输入框中输入数据按回车,页面上追加text.vue组件内容,输入框中的数据也被传递给text.vue组件,并在页面上进行了展示。3、点击text.vue组件中的…...
Java:集合(List、Map、Set)
文章目录 1. Collection集合1-1. 迭代器遍历方式1-2. 通过for循环进行遍历1-3. forEach遍历 2. List集合2-1. ArrayList底层实现原理2-2. LinkedList底层实现原理 3. Set集合3-1. HashSet 底层实现3-2. LinkedHashSet 底层实现3-3. TreeSet 4. Collection集合->总结5. Map集…...
208-Base Camera Link 图像信号模拟器
1、板卡概述 该板卡是基于Altra FPGA处理芯片EP3C40F484C8(兼容EP3C16F484C8),模拟产生自定义分辨率的Camera Link 图像信号,并以base Camera Link输出。主要用于作为Camera Link 图像信号模拟器,模拟各类C…...
【创建模式-蓝本模式(Prototype Pattern)】
目录 Overview应用场景代码演示JDK Prototype pattern 更优实践泛型克隆接口 https://doc.hutool.cn/pages/Cloneable/#%E6%B3%9B%E5%9E%8B%E5%85%8B%E9%9A%86%E7%B1%BB The prototype pattern is a creational design pattern in software development. It is used when the t…...
(一)强化学习基础概念及学习路径
目录 前言 一、强化学习是什么? 二、强化学习中的基本概念 1.状态 2.动作 3.奖励 4.策略 5.智能体 6.环境 7.智能体与环境交互 三、强化学习路径 总结 前言 强化学习(Reinforcement Learning, RL)是机器学习的范式和方法论之一&a…...
Android 好的开源库
1. 权限请求框架 GitHub - getActivity/XXPermissions: Android 权限请求框架,已适配 Android 14 2. 下载框架 GitHub - lingochamp/okdownload: A Reliable, Flexible, Fast and Powerful download engine....
Spring中xxAware接口和InitializingBean接口的作用
question:Aware接口和InitializingBean接口的作用都可以用例如Autowired PostConstruct注解来实现,那么其相比较于注解的实现,优势是什么呢? 早期的Spring中并不存在注解开发,注解开发是在后期的Spring中引入…...
Nginx WebDAV扩展模块安装与配置完全指南
Nginx WebDAV扩展模块安装与配置完全指南 nginx-dav-ext-module nginx WebDAV PROPFIND,OPTIONS,LOCK,UNLOCK support [这里是图片001] 项目地址: https://gitcode.com/gh_mirrors/ng/nginx-dav-ext-module 项目基础介绍 Nginx WebDAV扩展模块(nginx-dav-ext-module)是由a…...
算法刷题Day16: BM41 输出二叉树的右视图
题目链接 描述 思路: 递归构造二叉树在Day15有讲到。复习一下,就是使用递归构建左右子树。将中序和前序一分为二。 接下来是找出每一层的最右边的节点,可以利用队列层次遍历。 利用队列长度记录当前层有多少个节点,每次从队列里…...
1.2 计算机网络的分类和应用(重要知识点)
1.2.1 计算机网络的分类 计算机网络的定义: 由通信线路互相连接的、能自主工作的计算机构成,强调各计算机(工作站)拥有独立的计算资源和任务能力。与多终端分时系统不同,后者终端仅作为主机接口,不具备计…...
Xcode
info.plist Appearance Light 关闭黑暗模式 Bundle display name 设置app名称,默认为工程名 Location When In Use Usage Description 定位权限一共有3个key 1.Privacy - Location When In Use Usage Description 2.Privacy - Location Always and When In U…...
HarmonyOS 5.0应用开发——属性动画
【高心星出品】 文章目录 属性动画animateTo属性动画animation属性动画 属性动画 属性接口(以下简称属性)包含尺寸属性、布局属性、位置属性等多种类型,用于控制组件的行为。针对当前界面上的组件,其部分属性(如位置属…...
Freertos任务切换
一、操作系统进行任务切换的时机: 采用信号量实现任务的互斥: 二、FreeRTOS 任务切换场合 PendSV 中断的时候提到了上下文(任务)切换被触发的场合: ● 可以执行一个系统调用 ● 系统滴答定时器(SysTick)中断。 1、执行系统调用 执行系统…...
【汇编】思考汇编中的两个基本问题
1. 若干年前的疑问 几年前还在大学学习汇编时,不管是考试还是课程设计,其实都很顺利。但是心里一直对什么时候使用哪个寄存器存在疑惑,编写汇编时,没有十足的把握,都是抱着试一试的心态去完成了课程任务。 工作八年有…...
开发环境服务器 vs 生产环境服务器:开发与生产须分明
【背景】作为开发者,我们在不同的阶段都与两种服务器环境打交道——开发环境服务器和生产环境服务器。虽然听起来名字相似,但它们的职责和工作方式简直是天差地别! 不知道朋友们有没有跟我一开始刚了解的时候的一些疑惑,因为刚开始…...
Tomcat的安装即使用
Tomcat的概念 Tomcat服务器是Java语言开发的,免费的开放源代码的Web应用服务器。 Tomcat处理静态HTML的能力远不及Apache或者Nginx,通常是作为一个Servlet和JSP容器,单独运行在后端。 Tomcat是由三个功能组合而成: java servlet&…...
外包干了9天,技术退步明显。。。。。
时光荏苒,转眼我已是一个拥有近四年功能测试经验的大专生。19年,我满怀激情地通过校招进入湖南某知名软件公司,期待在这里开启我的职业生涯。然而,长时间的舒适环境让我渐渐失去了前进的动力,技术停滞不前,…...
梳理你的思路(从OOP到架构设计)_基本OOP知识04
目录 1、 主动型 vs.基於被动型 API 1)卡榫函数实现API 2)API的分类 3)回顾历史 4)API >控制力 2、 结语&复习: 接口与类 1)接口的表示 2)Java的接口表示 1、 主动型 vs.基於被动…...
每天40分玩转Django:简介和环境搭建
Django简介和环境搭建 一、课程概述 学习项目具体内容预计用时Django概念Django框架介绍、MVC/MTV模式、Django特点60分钟环境搭建Python安装、pip配置、Django安装、IDE选择45分钟创建项目项目结构、基本配置、运行测试75分钟实战练习创建个人博客项目框架60分钟 二、Djang…...
OpenCV相关函数
一、Sobel算子函数 (cv2.Sobel) 功能 Sobel算子是一个梯度算子,用于边缘检测。通过计算图像中像素的梯度,Sobel算子可以检测出水平和垂直方向上的边缘。 参数 src:输入图像。 ddepth:输出图像的深度(如cv2.CV_8U, cv…...
【理想汽车中科院】基于模仿学习的端到端自动驾驶数据缩放规律
论文: https://arxiv.org/pdf/2412.02689 项目: https://github.com/ucaszyp/Driving-Scaling-Law 0. 摘要 端到端自动驾驶范式因其可扩展性而最近吸引了大量关注。然而,现有方法受到现实世界数据规模有限的制约,这阻碍了对端到端自动驾驶相关扩展规律…...
重卡补能新未来:光储充换一体开启高效之路
《重卡补能新未来:光储充换一体开启高效之路》 一、光储充换一体重卡补能模式的兴起 重卡运输行业在电动化进程加速下迎来变革,光储超充快换一体化补能站成为新趋势。 随着国家 “双碳” 战略的持续推进,新能源汽车市场蓬勃发展,…...
Mybatis Plus 3.0 快速入门
1、简介 MyBatis-Plus (简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 2、创建并初始化数据库 2.1、创建数据库 mybatis_plus 2.2、创建 User 表 其表结构如下: idnameageemail1Jone18test1@baomidou.com2Jack…...
ABAP:MB51字段增强
MB51所对应的程序:RM07DOCS 1.定义增强字段:RM07DOCS_GENERATED中定义 2.取值:RM07DOCS中detail_list中加取值逻辑 也有对ITAB取值做调整的,但是要写很多处,直接这里取值就很简单。 3.展示字段:RM07DOCS中…...
nVisual 定制化APP打包流程
一、下载打包软件 HBuilder X 下载地址:https://dcloud.io/hbuilderx.html 安装:此软件为绿色软件,解压即可使用。进入目录,双击exe启动。 此软件需要注册,打开时会提供跳转链接,通过邮箱注册账号。 注册成功后&#…...
k8s的节点亲和性NodeAffinity
关键词: ① requiredDuringSchedulingIgnoredDuringExecution:表示强匹配,必须要满足 ② preferredDuringSchedulingIgnoredDuringExecution:表示弱匹配,尽可能满足,但不保证 示例: apiVersion: v1 kind:…...
比特币国家与企业机构“战略储备”潮起
100 万枚 BTC 的战略储备资产,是一个什么概念? 据世界黄金协会统计数据显示,截至 2024 年第三季度,美联储黄金储备总量达 8133.46 吨(约合 5300 亿美元),稳居全球首位。而 100 万枚 BTC 当前市…...
Vue生命周期钩子函数:深入解析与实践
作为高级Vue前端开发人员,对Vue组件的生命周期钩子函数有着深刻的理解是至关重要的。生命周期钩子函数是指在Vue组件的创建、更新、销毁等过程中,Vue自动调用的一系列方法。通过这些钩子函数,我们可以在组件的不同生命周期阶段执行特定的操作…...
mysql、postgresql、oceanbase调优
一、mysql 1、my.cnf [mysqld_safe] log-error=/data/mysql/log/mysql.log pid-file=/data/mysql/run/mysqld.pid[client] socket=/data/mysql/run/mysql.sock default-character-set=utf8[mysqld] basedir=/usr/local/mysql tmpdir=/data/mysql/tmp datadir=/data/mysql/dat…...
【Flux.jl】 卷积神经网络
Flux.jl 是包含卷积神经网络的, 但是官方API文件中没有给出一个完整的程序框架, 只是对所需神经元给了局部解释, 此外对 model-zoo 模型动物园中的案例没有及时跟着 Flux.jl 的版本更新, 也无法运行出来结果。 因此本文搭建了一个完整可训练的卷积神经网络。 Conv 卷积算子…...
数字证书管理工具 openssl keytool
OPENSSL 命令 openssl command [ command_opts ] [ command_args ] 常用command: version 用于查看版本信息 enc 用于加解密 ciphers 列出加密套件 genrsa 用于生成私钥 -des|-des3|-idea:用来加密私钥文件的三种对称加密算法。 rsa …...
notify和notifyAll
notify和notifyAll 简单来说: notify():只唤醒一个等待的线程,如果有多个线程在等待,那么被唤醒的线程是随机选择的。 notifyAll():唤醒在该对象监视器上等待的所有线程,但是这些被唤醒的线程仍然需要竞争…...
删除MySQL的多余实例步骤
删除 MySQL 的多余实例通常意味着我们希望卸载或停止某个 MySQL 服务器实例,并从系统中完全移除它。这通常涉及到几个步骤,包括但不限于停止服务、删除数据目录、卸载软件(如果适用)等。 1.基于 Linux 的系统上删除 MySQL 的多余…...
LDR6500应用:C转DP线材双向投屏开启全新体验
在当今这个科技日新月异、蓬勃发展的时代,高清视频传输以及显示技术已经深深融入到我们日常生活与工作的方方面面,其重要性不言而喻。不管是在商务场合的会议演示,还是教育领域的娱乐享受,以及充满激情的游戏竞技领域,…...
商业化大前端在性能优化领域的探索与实践
导读:在业务飞速发展的过程中,用户体验是必不可少的一个环节,而页面性能是直接影响用户体验的重要因素。当页面加载时间过长、交互操作不流畅时,意味着业务可能会出现转化率降低、用户流失等业务问题。在过去一年,为了…...
FinClip | 2024年11月产品大事记
FinClip 的使命是使您(业务专家和开发人员)能够通过小程序解决关键业务流程挑战,并完成数字化转型的相关操作。不妨让我们看看在11月的产品与市场发布亮点,看看是否有助于您实现目标。 产品方面的相关动向👇…...
EasyPlayer.js在同一个http的mp4视频流地址,浏览器可以播放,播放器中却播放不了
流媒体技术正站在数字化时代的前沿,随着互联网技术的不断进步和市场需求的日益增长,其发展前景显得尤为广阔。随着全球数字化转型的不断深入,流媒体行业将迎来更加繁荣的未来,成为信息传播和娱乐消费的主要渠道。 用户遇到在同一个…...