当前位置: 首页 > news >正文

使用 PyTorch 实现 AlexNet 进行 MNIST 图像分类

AlexNet 是一种经典的深度学习模型,它在 2012 年的 ImageNet 图像分类比赛中大放异彩,彻底改变了计算机视觉领域的格局。AlexNet 的核心创新包括使用深度卷积神经网络(CNN)来处理图像,并采用了多个先进的技术如 ReLU 激活函数、Dropout 正则化等。

本文将介绍如何使用 PyTorch 框架实现 AlexNet,并在 MNIST 数据集上进行训练。MNIST 是一个简单但经典的数据集,常用于初学者测试机器学习算法。

文末附完整项目。

一、AlexNet 网络结构

AlexNet 的结构大致可以分为两部分:特征提取部分(卷积层)和分类部分(全连接层)。下面是 AlexNet 的简要结构:

  • 卷积层:五个卷积层用于提取特征。每个卷积层后面都有一个激活函数(ReLU)和一个池化层。
  • 全连接层:三个全连接层,第一个和第二个全连接层后有 Dropout 层,防止过拟合。
  • 输出层:使用 Softmax 激活函数输出 1000 个类别的概率。

二、使用 PyTorch 实现 AlexNet

训练部分

1. 导入必要的库

首先,我们需要导入一些必要的库,包括 PyTorch 和一些数据处理工具。

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
from torchvision import datasets
from torch.cuda.amp import GradScaler, autocast  # 导入混合精度训练
from tqdm import tqdm
import multiprocessing
import matplotlib.pyplot as plt

2. 定义 AlexNet 模型

接下来,我们定义一个类 AlexNet,继承自 nn.Module,并在其中实现 AlexNet 的结构。

class AlexNet(nn.Module):def __init__(self):super(AlexNet, self).__init__()# 定义卷积层和池化层self.features = nn.Sequential(nn.Conv2d(1, 64, kernel_size=11, stride=4, padding=2),  # 第一个卷积层nn.ReLU(inplace=True),  # 激活函数nn.MaxPool2d(kernel_size=3, stride=2),  # 池化层nn.Conv2d(64, 192, kernel_size=5, padding=2),  # 第二个卷积层nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=3, stride=2),nn.Conv2d(192, 384, kernel_size=3, padding=1),  # 第三个卷积层nn.ReLU(inplace=True),nn.Conv2d(384, 256, kernel_size=3, padding=1),  # 第四个卷积层nn.ReLU(inplace=True),nn.Conv2d(256, 256, kernel_size=3, padding=1),  # 第五个卷积层nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=3, stride=2)  # 池化层)# 定义全连接层self.classifier = nn.Sequential(nn.Dropout(),  # Dropout 层,防止过拟合nn.Linear(256 * 6 * 6, 4096),  # 第一个全连接层nn.ReLU(inplace=True),nn.Dropout(),nn.Linear(4096, 4096),  # 第二个全连接层nn.ReLU(inplace=True),nn.Linear(4096, 10)  # 输出层,10 个类别)def forward(self, x):# 前向传播x = self.features(x)  # 卷积层x = x.view(x.size(0), -1)  # 展平数据x = self.classifier(x)  # 全连接层return x

3. 数据预处理和加载

在进行训练之前,我们需要对 MNIST 数据集进行预处理。AlexNet 要求输入的图像大小为 227x227,因此我们需要调整图像的大小。

# 使用 torchvision.transforms 对图像进行一系列的预处理操作
transform = transforms.Compose([transforms.Resize((227, 227)),  # 调整输入图像的大小为 227x227 (符合 AlexNet 的要求)transforms.ToTensor(),  # 将图像转换为 Tensor 格式transforms.Normalize((0.5,), (0.5,))  # 标准化操作,均值0.5,标准差0.5
])# 下载并加载 MNIST 数据集,数据集已经被预处理
trainset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
testset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)# 使用 DataLoader 加载训练集和测试集,设置 batch size 和多线程加载
trainloader = DataLoader(trainset, batch_size=128, num_workers=2, pin_memory=True)
testloader = DataLoader(testset, batch_size=128, num_workers=2, pin_memory=True)

4. 定义损失函数和优化器

使用交叉熵损失函数和 Adam 优化器来训练模型。

#创建模型实例并将其移动到 GPU 上
model = AlexNet().to(device)
#定义损失函数和优化器
criterion = nn.CrossEntropyLoss()  # 分类问题常用的损失函数
optimizer = optim.AdamW(model.parameters(), lr=0.001)  # 使用 AdamW 优化器# 用于保存训练过程中的损失和准确率
train_losses = []
train_accuracies = []

5. 训练模型

现在我们可以开始训练模型了。我们会对训练集进行多轮训练,并每轮输出损失和准确率。

def train_model():epochs = 5  # 训练周期数accumulation_steps = 4  # 梯度累积的步骤数(当前未使用)scaler = GradScaler()  # 初始化混合精度训练的 GradScalerfor epoch in range(epochs):model.train()  # 设置模型为训练模式running_loss = 0.0  # 初始化当前 epoch 的损失correct = 0  # 记录正确的预测个数total = 0  # 记录总的样本数print(f"Epoch [{epoch + 1}/{epochs}] started.")# 使用 tqdm 包装 trainloader 以显示进度条for i, (inputs, labels) in enumerate(tqdm(trainloader, desc=f"Epoch {epoch + 1}/{epochs}", ncols=100), 1):inputs, labels = inputs.to(device), labels.to(device)  # 将数据和标签移动到 GPU 上optimizer.zero_grad()  # 清空优化器中的梯度信息with autocast():  # 启用混合精度训练outputs = model(inputs)  # 获取模型输出loss = criterion(outputs, labels)  # 计算损失scaler.scale(loss).backward()  # 反向传播计算梯度if (i + 1) % accumulation_steps == 0:  # 每 accumulation_steps 次更新一次梯度(目前无效)scaler.step(optimizer)scaler.update()optimizer.zero_grad()running_loss += loss.item()  # 累加当前 batch 的损失_, predicted = torch.max(outputs, 1)  # 获取模型的预测结果total += labels.size(0)  # 更新总样本数correct += (predicted == labels).sum().item()  # 更新正确的预测个数# 计算本轮训练的平均损失和准确率epoch_loss = running_loss / len(trainloader)epoch_accuracy = correct / total * 100train_losses.append(epoch_loss)  # 保存当前 epoch 的损失train_accuracies.append(epoch_accuracy)  # 保存当前 epoch 的准确率print(f"Epoch [{epoch + 1}/{epochs}] finished. Loss: {epoch_loss:.4f}, Accuracy: {epoch_accuracy:.2f}%\n")# 6. 保存模型torch.save(model.state_dict(), 'alexnet_mnist.pth')  # 保存模型权重print("Model saved successfully!")

测试部分

6. 数据预处理和加载

首先,我们需要对 MNIST 数据集进行预处理,确保图像的尺寸符合 AlexNet 的输入要求。AlexNet 的标准输入尺寸为 227x227,因此我们需要调整 MNIST 图像的尺寸,并将其转换为张量格式进行处理。

# 定义对图像的转换操作:调整大小、转换为Tensor、标准化
transform = transforms.Compose([transforms.Resize((227, 227)),  # 调整输入图像的大小为 227x227 (符合 AlexNet 的要求)transforms.ToTensor(),  # 将图像转换为 Tensor 格式transforms.Normalize((0.5,), (0.5,))  # 标准化操作,均值0.5,标准差0.5
])# 加载 MNIST 数据集(训练集),并应用定义的图像转换
trainset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = DataLoader(trainset, batch_size=64, shuffle=False)  # 使用 DataLoader 批量加载数据

        数据预处理:我们使用 transforms.Compose 来组合多个数据转换操作。首先将图像调整为 227x227 像素,以符合 AlexNet 的输入要求,然后将图像转换为 Tensor 格式,并进行标准化处理。

        加载数据:通过 DataLoader 加载训练数据,设定批处理大小为 64,并禁用数据打乱(因为我们并不进行训练,仅展示前几个图像)。

7. 定义 AlexNet 模型结构

接下来,我们实现 AlexNet 的卷积层和全连接层。这里我们将使用灰度图像作为输入,因此输入通道数为 1(而非 3)。

# 这个模型是基于经典的 AlexNet 结构,只不过输入是灰度图像(1通道),而非 RGB 图像(3通道)
class AlexNet(nn.Module):def __init__(self):super(AlexNet, self).__init__()# 特征提取部分(卷积层 + 激活函数 + 池化层)self.features = nn.Sequential(nn.Conv2d(1, 64, kernel_size=11, stride=4, padding=2),  # 输入1通道(灰度图),输出64通道nn.ReLU(inplace=True),  # 激活函数 ReLUnn.MaxPool2d(kernel_size=3, stride=2),  # 池化层nn.Conv2d(64, 192, kernel_size=5, padding=2),  # 第二个卷积层nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=3, stride=2),  # 池化层nn.Conv2d(192, 384, kernel_size=3, padding=1),  # 第三个卷积层nn.ReLU(inplace=True),nn.Conv2d(384, 256, kernel_size=3, padding=1),  # 第四个卷积层nn.ReLU(inplace=True),nn.Conv2d(256, 256, kernel_size=3, padding=1),  # 第五个卷积层nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=3, stride=2)  # 池化层)# 分类器部分(全连接层)self.classifier = nn.Sequential(nn.Dropout(),  # Dropout 层,防止过拟合nn.Linear(256 * 6 * 6, 4096),  # 全连接层1,输入大小 256*6*6,输出 4096nn.ReLU(inplace=True),nn.Dropout(),nn.Linear(4096, 4096),  # 全连接层2,输出 4096nn.ReLU(inplace=True),nn.Linear(4096, 10)  # 输出层,10个类别(MNIST 0-9))def forward(self, x):# 前向传播过程x = self.features(x)  # 通过卷积层提取特征x = x.view(x.size(0), -1)  # 展平数据(展平成一维)x = self.classifier(x)  # 通过全连接层进行分类return x

3. 加载预训练模型

在实际使用中,我们通常会保存训练好的模型权重并进行加载。这里,我们假设已经训练好模型并将其保存为 alexnet_mnist.pth

# 此函数用于加载保存的模型权重
def load_model(model_path='alexnet_mnist.pth'):model = AlexNet().to(device)  # 创建模型实例并移动到设备(GPU/CPU)model.load_state_dict(torch.load(model_path))  # 加载模型权重model.eval()  # 设置模型为评估模式print("Model loaded successfully!")return model

4. 批量进行图片预测

接下来,我们将编写一个函数,用于批量预测图像,并返回其对应的预测结果。

# 该函数从 dataloader 中获取指定数量的图像,并进行预测
def batch_predict_images(model, dataloader, num_images=6):predictions = []  # 用于保存预测结果images = []  # 用于保存输入图像labels = []  # 用于保存实际标签# 不计算梯度以提高效率with torch.no_grad():for i, (input_images, input_labels) in enumerate(dataloader):if i * 64 >= num_images:  # 控制处理的图像数量breakinput_images = input_images.to(device)  # 将图像数据转移到 GPU 上input_labels = input_labels.to(device)  # 将标签数据转移到 GPU 上# 通过模型进行预测outputs = model(input_images)_, predicted = torch.max(outputs, 1)  # 获取预测的类别predictions.extend(predicted.cpu().numpy())  # 保存预测结果到 CPU 上images.extend(input_images.cpu().numpy())  # 保存输入图像到 CPU 上labels.extend(input_labels.cpu().numpy())  # 保存真实标签到 CPU 上return images[:num_images], labels[:num_images], predictions[:num_images]

三、可视化

为了更好地了解模型的训练情况,我们可以通过绘制图表来展示训练过程中的损失和准确率。

def plot_training_progress():plt.figure(figsize=(12, 6))  # 创建一个宽12英寸、高6英寸的图形窗口# 绘制训练损失的子图plt.subplot(1, 2, 1)  # 1行2列的第一个子图plt.plot(range(1, 6), train_losses, marker='o', label='Train Loss')plt.title('Train Loss per Epoch')plt.xlabel('Epoch')plt.ylabel('Loss')plt.grid(True)# 绘制训练准确率的子图plt.subplot(1, 2, 2)  # 1行2列的第二个子图plt.plot(range(1, 6), train_accuracies, marker='o', label='Train Accuracy')plt.title('Train Accuracy per Epoch')plt.xlabel('Epoch')plt.ylabel('Accuracy (%)')plt.grid(True)# 调整布局,避免子图重叠plt.tight_layout()# 显示图形窗口plt.show()

我们编写一个函数来可视化批量图像及其对应的预测结果。我们将使用 matplotlib 来绘制图像。

# 该函数显示图像和预测结果
def visualize_images(images, labels, predictions):fig, axes = plt.subplots(2, 3, figsize=(10, 7))  # 创建 2x3 的图像子图axes = axes.ravel()  # 将子图展平成一维数组for i in range(6):image = images[i].squeeze()  # 去掉多余的维度(例如[1, 227, 227] -> [227, 227])ax = axes[i]ax.imshow(image, cmap='gray')  # 显示图像,使用灰度图ax.set_title(f"Pred: {predictions[i]} | Actual: {labels[i]}")  # 显示预测标签和实际标签ax.axis('off')  # 关闭坐标轴显示plt.tight_layout()  # 调整子图之间的间距plt.show()  # 显示图像

四、启动

#训练
if __name__ == '__main__':# 设置 multiprocessing 的启动方法为 'spawn'(Windows 需要)multiprocessing.set_start_method('spawn')# 开始训练模型train_model()# 绘制训练过程图plot_training_progress()#测试
if __name__ == '__main__':# 设置 multiprocessing 的启动方法为 'spawn',用于兼容不同操作系统(Windows需要)multiprocessing.set_start_method('spawn')# 加载训练好的模型model = load_model()# 获取前6张图像及其预测结果images, labels, predictions = batch_predict_images(model, trainloader, num_images=6)# 可视化这些图像及其预测结果visualize_images(images, labels, predictions)

五、总结

在本文中,我们介绍了如何使用 PyTorch 实现 AlexNet 并在 MNIST 数据集上进行训练。通过这个过程,你可以了解如何构建卷积神经网络、加载数据集、训练模型并进行评估。AlexNet 的结构在计算机视觉任务中仍然具有重要意义,尤其是在图像分类任务中。

PyTorch 使得实现和训练深度学习模型变得更加简便和灵活,你可以通过对本文代码的修改来尝试不同的模型或数据集,从而加深对深度学习的理解。

五、参考资料

  • PyTorch 官方文档
  • AlexNet 论文
  • AlexNet: 使用 PyTorch 实现 AlexNet 进行 MNIST 图像分类icon-default.png?t=O83Ahttps://gitee.com/qxdlll/alex-net
  • GitHub - qxd-ljy/AlexNet: 使用 PyTorch 实现 AlexNet 进行 MNIST 图像分类使用 PyTorch 实现 AlexNet 进行 MNIST 图像分类. Contribute to qxd-ljy/AlexNet development by creating an account on GitHub.icon-default.png?t=O83Ahttps://github.com/qxd-ljy/AlexNet

相关文章:

使用 PyTorch 实现 AlexNet 进行 MNIST 图像分类

AlexNet 是一种经典的深度学习模型,它在 2012 年的 ImageNet 图像分类比赛中大放异彩,彻底改变了计算机视觉领域的格局。AlexNet 的核心创新包括使用深度卷积神经网络(CNN)来处理图像,并采用了多个先进的技术如 ReLU 激…...

Python爬虫项目 | 一、网易云音乐热歌榜歌曲

文章目录 1.文章概要1.1 实现方法1.2 实现代码1.3 最终效果 2.具体讲解2.1 使用的Python库2.2 代码说明2.2.1 创建目录保存文件2.2.2 爬取网易云音乐热歌榜单歌曲 2.3 过程展示 3 总结 1.文章概要 学习Python爬虫知识,实现简单的一个小案例,网易云音乐热…...

【Linux】HTTP协议和HTTPS加密

文章目录 HTTP1、概念2、认识URL3、协议格式、请求方法和状态码4、HTTP请求和响应报头5、Cookie和Session HTTPS1、对称和非对称加密2、对称非对称加密安全分析3、证书 HTTP 1、概念 我们在应用层定制协议时,不建议直接发送结构体对象,因为在不同的环境…...

Linux编辑/etc/fstab文件不当,不使用快照;进入救援模式

目录 红帽镜像9救援模式 现象 解决 第一步:修改启动参数以进入救援模式 第二步:进入救援模式、获取root权限、编辑/etc/fstab文件 第三步:编辑好后在重启 下面是ai给的模板 红帽镜像9救援模式 编辑/etc/fstab不当时 17 /dev/nvme0n3p1…...

ubuntu升级postgres

已经有了postgres12,记录一下升级从postgres12升级到15的过程及遇到的一些问题,我没有备份,单纯升级 1、升级过程 深色版本 sudo systemctl stop postgresql 升级PostgreSQL 停止PostgreSQL服务: 停止当前版本的PostgreSQL服务…...

vue2在el-dialog打开的时候使该el-dialog中的某个输入框获得焦点方法总结

在 Vue 2 中,如果你想通过 ref 调用一个方法(如 inputFocus)来聚焦一个输入框,确保以下几点: 确保 ref 的设置正确:你需要确保在模板中正确设置了 ref,并且它指向了你想要操作的组件或 DOM 元素…...

SpringBoot(十七)创建多模块Springboot项目

在gitee上查找资料的时候,发现有不少Springboot项目里边都是嵌套了多个Springboot项目的。这个玩意好,在协作开发的时候,将项目分成多个模块,有多个团队协作开发,模块间定义标准化通信接口进行数据交互即可。 这个好这个。我之前创建的博客项目是单模块的SpringBoot项目,…...

Vue.js 高质量翻页功能的完整开发指南

文章目录 Vue.js 翻页组件的完整开发与优化指南前言分析分页需求与设计要点基础分页功能的实现分页逻辑 优化分页:封装为组件化设计组件化代码 提升用户体验与性能动态调整每页显示的条目数优化移动端与桌面端的展示高性能翻页策略:按需加载与懒加载提示…...

android dvr黑屏

问题现象:dvr拍摄的图片是黑的,没有buffer数据的。 查看相关的log文件发现: video surface 未释放导致 祥见一下报错信息: 38298 2024-10-16 01:02:51.855 4056 32068 W MediaCodecRenderer: java.lang.IllegalStateExcepti…...

css文字间距撑满横向距离

效果: 代码: 、 text-align:justify;text-align-last: justify;...

【Unity基础】对比OnCollisionEnter与OnTriggerEnter

在Unity中,OnCollisionEnter 和 OnTriggerEnter 是两种用于处理碰撞的回调函数,但它们的工作方式和使用场景有所不同: 1. OnCollisionEnter 触发条件:当一个带有 Collider 组件并且**未勾选“Is Trigger”**的物体,与…...

算法训练(leetcode)二刷第二十五天 | *134. 加油站、*135. 分发糖果、860. 柠檬水找零、*406. 根据身高重建队列

刷题记录 *134. 加油站*135. 分发糖果860. 柠檬水找零*406. 根据身高重建队列 *134. 加油站 leetcode题目地址 当前站点可以剩余油量gas[i] - cost[i]; 将每站的剩余油量求和计算累计剩余油量,总剩余油量小于0,则无法行驶一周。 若在到达某一站时累计剩…...

Springboot 整合 itext 实现PDF文件合并,识别图片则转成PDF拼接

目录 前言一、引用依赖二、使用步骤1.Controller2.Service接口3.实现类三、请求接口及结果前言 本文实现 Springboot 整合 itext 实现PDF文件合并,图片转PDF拼接。 一、引用依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itext7-co…...

TypeScript 中的 ! 和 ? 操作符

在 TypeScript 中&#xff0c;! 和 ? 是两个非常重要且常用的操作符&#xff0c;分别用于非空断言和可选链操作。下面简单介绍一下二者。 1. 非空断言操作符 ! 1.1 含义 非空断言操作符 !&#xff08;Non-null assertion operator&#xff09;用来告诉 TypeScript 编译器&a…...

开源三代示波器的高速波形刷新方案开源,支持VNC远程桌面,手机,Pad,电脑均可访问(2024-11-11)

说明&#xff1a; 1、本来这段时间是一年一度Hackaday硬件设计开源盛宴&#xff0c;但hackaday电子大赛在去年终结了。所以我开源个我的吧。 2、三代示波器的高速波形刷新方案&#xff0c;前两年就做好了&#xff0c;这两年忙H7-TOOL的更新比较多&#xff0c;三代示波器的更新…...

谷歌推出设备内置人工智能,实时向手机用户发出诈骗电话警报

Google 宣布推出适用于 Android 的新安全功能&#xff0c;可实时防御诈骗和有害应用。 这些功能由先进的设备内置 AI 提供支持&#xff0c;可在不损害隐私的情况下增强用户安全性。 这些新的安全功能首先在 Pixel 上推出&#xff0c;并将很快在更多 Android 设备上推出。 诈…...

AI换人脸facefusion项目口型同步‌API化改造及部署

一. 简介 ‌FaceFusion‌是一款强大的AI换脸软件&#xff0c;它支持图片、视频以及直播换脸&#xff0c;官方将其称为“下一代脸部交换器和增强器”。FaceFusion的最新版本为2.6.1&#xff0c;这个版本在原有基础上增加了更多的模型和高清算法&#xff0c;显著提升了图片和视频…...

移动端问题

这里只是做一个记录&#xff0c;不一定大家都会有问题&#xff0c;参考就行 一、页面回弹 苹果有&#xff0c;安卓没有 解决&#xff1a;pages.json下 app-plus { bounce: none} 关闭回弹效果 二、onreachBottom触底生命周期&#xff0c;ios无法触发 修改触底数值&#xff1a…...

Linux网络——网络初识

目录 1. 认识协议 2. 协议的分层 3. OSI 七层模型 && TCP/IP 五层(四层)模型 4. 网络传输的基本流程 5. 以太网的通信原理 6. 数据的跨网络传播 7. 认识 IP 地址 ① IP 是什么 ② IP 与 MAC 的关系 ③ 为什么需要 IP 在谈及网络之前&#xff0c;我们要先对学…...

从华为到创业公司

我有一个朋友&#xff0c;在华为工作了很长一段时间&#xff0c;一年多前&#xff0c;他从华为出来到了一家创业公司。 周末趁着有时间&#xff0c;我跟他聊了下关于从华为到创业公司的一些问题&#xff0c;总结给大伙看看。 ▎1 在华为工作和在创业公司工作最大的差别是什么呢…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...