使用PyTorch设计卷积神经网络(CNN)来处理遥感图像Indian Pines数据集

目录

使用PyTorch设计卷积神经网络(CNN)来处理遥感图像Indian Pines数据集,以下是设计和实现这些网络的步骤:

1.数据准备:

        1.1 首先,需要加载Indian Pines数据集。

        1.2 将数据集转换为PyTorch张量,以便能够使用PyTorch框架进行处理。

2.数据预处理:

        2.1 根据需要对数据进行归一化或标准化。

        2.2 将数据集分割为训练集和测试集。

3.定义网络结构:

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

        4.1 选择一个适合分类任务的损失函数,例如交叉熵损失。

         4.2 选择一个优化器,如Adam或SGD。

5.训练网络:

        使用训练数据来训练网络,并通过反向传播更新权重。

6.评估网络:

        在测试集上评估网络的性能。


使用PyTorch设计卷积神经网络(CNN)来处理遥感图像Indian Pines数据集,以下是设计和实现这些网络的步骤:

1.数据准备:

        1.1 首先,需要加载Indian Pines数据集。
data = scipy.io.loadmat("D:/Indian_pines_corrected.mat")['indian_pines_corrected']
gt = scipy.io.loadmat("D:/Indian_pines_gt.mat")['indian_pines_gt'].ravel()  # 确保标签是一个一维数组
        因为数据集是一个MAT文件,所以使用scipy.io模块来读取它。
        1.2 将数据集转换为PyTorch张量,以便能够使用PyTorch框架进行处理。
# 将NumPy数组转换为PyTorch张量
X_train_tensor = torch.tensor(X_train, dtype=torch.float32)
y_train_tensor = torch.tensor(y_train, dtype=torch.long)
X_test_tensor = torch.tensor(X_test, dtype=torch.float32)
y_test_tensor = torch.tensor(y_test, dtype=torch.long)
        这段代码是在使用PyTorch库将NumPy数组转换为PyTorch张量(tensor),这是进行深度学习训练之前常见的步骤。 

2.数据预处理:

        2.1 根据需要对数据进行归一化或标准化。
# 数据预处理
num_bands = data.shape[2]
X = data.reshape(-1, num_bands)

# 归一化数据
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
        在机器学习和数据科学中,数据预处理是一个非常重要的步骤,它可以帮助提高模型的性能和准确性。首先我们要使用Python语言中的NumPy库进行数据预处理的常见操作。
        在这段代码中,data 变量假定是一个多维数组,通常是一个三维数组,其中包含了图像数据或其他类型的多维数据。data.shape[2] 表示这个数组的第三个维度的大小,也就是波段数(例如在遥感图像中)。
   X = data.reshape(-1, num_bands) 这行代码的作用是将原始的多维数组 data 重塑为一个二维数组 X。其中 -1 表示让NumPy自动计算这个维度的大小,以确保数组的元素总数保持不变。num_bands 是数组的第三个维度的大小,表示每个样本的特征数或波段数。
        具体来说,如果 data 是一个形状为 (a, b, num_bands) 的数组,那么 reshape(-1, num_bands) 操作将把它转换为一个形状为 (a*b, num_bands) 的数组。这样,每一行代表一个样本,每一列代表一个特征。       
        归一化是数据预处理中的一个关键步骤,特别是当你的数据集包含不同量级的特征时。归一化可以帮助算法更有效地工作,因为它确保了所有特征对模型的影响是均衡的。
        在这里的代码片段中,使用了 StandardScaler 来进行数据的归一化处理,这是 scikit-learn 库中的一个常用工具。
   scaler = StandardScaler():创建一个 StandardScaler 对象。StandardScaler 是一个预处理器,用于将数据标准化(或归一化)到均值为0,标准差为1的标准正态分布。
   X_scaled = scaler.fit_transform(X):对数据集 X 执行 fit_transform 方法。这个方法首先计算数据集 X 的均值和标准差(fit 阶段),然后使用这些统计量来转换数据,使其符合标准化的要求(transform 阶段)。结果 X_scaled 就是归一化后的数据集。
        归一化后的数据具有以下特点:
                 每个特征的均值变为0。 
                 每个特征的标准差变为1。
        2.2 将数据集分割为训练集和测试集。
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, gt, test_size=0.2, random_state=42)
划分训练集和测试集是非常重要的,因为:
  • 训练集用于训练模型,学习数据的特征和模式。
  • 测试集用于评估模型的性能,确保模型没有过拟合,并且能够泛化到未见过的数据上。
         X_train, X_test:表示划分后的训练特征集和测试特征集。
         y_train, y_test:表示对应的训练目标集和测试目标集。这里的目标变量 gt 应该是一个数组,包含了你想要模型预测的值。
         test_size=0.2:指定测试集占整个数据集的比例,这里是20%。这意味着80%的数据将用于训练,20%的数据将用于测试。
         random_state=42:指定随机数生成器的种子,以确保每次运行代码时,数据的划分是一致的。这有助于实验的可重复性。

3.定义网络结构:

        根据选择,设计一个一维卷积网络或全连接网络。对于一维卷积,可使用torch.nn.Conv1d,而对于全连接网络,可使用torch.nn.Linear。
# 为Conv1d增加通道维度
X_train_tensor = X_train_tensor.unsqueeze(1)
X_test_tensor = X_test_tensor.unsqueeze(1)

# 定义网络
class SpectralCNN(nn.Module):
    def __init__(self, num_bands, num_classes):
        super(SpectralCNN, self).__init__()
        self.conv1 = nn.Conv1d(in_channels=1, out_channels=64, kernel_size=3, padding=1)
        self.pool = nn.MaxPool1d(kernel_size=2)
        self.conv2 = nn.Conv1d(in_channels=64, out_channels=128, kernel_size=3, padding=1)

        # 计算经过两次卷积和池化后的输出大小
        # 卷积后,宽度保持不变;池化后,宽度减半
        conv_output_size = num_bands
        pool_output_size = int(np.ceil(conv_output_size / 2))  # 第一次池化后的大小
        pool_output_size = int(np.ceil(pool_output_size / 2))  # 第二次池化后的大小

        # 更新全连接层的输入大小
        self.fc1 = nn.Linear(128 * pool_output_size, num_classes)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = self.pool(x)
        x = F.relu(self.conv2(x))
        x = self.pool(x)
        x = x.view(x.size(0), -1)  # 扁平化特征向量
        x = self.fc1(x)
        return x
这段代码定义了一个使用PyTorch框架的卷积神经网络(CNN)类 SpectralCNN,它继承自 nn.Module。这个网络专门设计用于处理光谱数据,其中 num_bands 表示输入数据的波段数,num_classes 表示输出的类别数。下面是对这段代码的详细解释:
  1. 初始化方法 (__init__):
    • 首先,它调用父类 nn.Module 的初始化方法。
  2. 卷积层 (self.conv1self.conv2):
    • self.conv1 是第一个一维卷积层,具有1个输入通道(对应于波段数),64个输出通道,卷积核大小为3,填充为1。填充为1意味着在输入的两侧各添加一个零填充,以保持输出的宽度不变。
    • self.conv2 是第二个一维卷积层,具有64个输入通道(第一个卷积层的输出通道数),128个输出通道,卷积核和填充与第一个卷积层相同。
  3. 池化层 (self.pool):
    • 使用最大池化 (MaxPool1d),池化窗口大小为2。这将减少特征图的宽度,但保持高度不变。
  4. 计算输出大小:
    • 通过两次卷积和池化操作后,需要计算全连接层的输入大小。这里使用了 np.ceil 函数来向上取整,以确保即使在池化后,输出大小也能正确计算。
  5. 全连接层 (self.fc1):
    • 根据经过两次卷积和池化后的特征图大小,创建一个全连接层,将特征图展平后连接到 num_classes 个输出节点。

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

        4.1 选择一个适合分类任务的损失函数,例如交叉熵损失。
         4.2 选择一个优化器,如Adam或SGD。
# 初始化模型
num_classes = len(np.unique(gt))
model = SpectralCNN(num_bands=X_train.shape[1], num_classes=num_classes)

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
损失函数 (criterion): 
        这里使用的是 nn.CrossEntropyLoss(),这是一个常用于多分类问题的损失函数。它结合了 LogSoftmax 层和 NLLLoss(负对数似然损失),使得模型在训练时可以优化分类任务的性能。CrossEntropyLoss 会计算模型输出的对数概率和目标类别的负对数似然损失。
优化器 (optimizer):
        这里使用的是 torch.optim.Adam 优化器,它是 Adam(自适应矩估计)算法的实现。Adam 优化器是一种流行的算法,因为它结合了动量(Momentum)和 RMSprop 的优点。在你的代码中,model.parameters() 指定了优化器需要更新的模型参数,lr=0.001 设置了学习率为0.001,这是每次参数更新时使用的步长。

5.训练网络:

        使用训练数据来训练网络,并通过反向传播更新权重。
# 训练模型
num_epochs = 10000  # 设置训练轮数

# 开始训练模型
for epoch in range(num_epochs):
    model.train()
    optimizer.zero_grad()
    outputs = model(X_train_tensor)
    loss = criterion(outputs, y_train_tensor)
    loss.backward()
    optimizer.step()
    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item()}')
这段代码展示了一个基本的深度学习模型训练循环,这是一个迭代过程,模型在每个周期(epoch)上学习数据的特征。下面是对代码的解释:
  1. 训练循环:
    for epoch in range(num_epochs): 这个循环会执行指定次数的训练周期。num_epochs 应该在代码的其他地方定义。
  2. 训练模式:
    model.train() 将模型设置为训练模式,这会启用如 Dropout 等特定于训练阶段的层。
  3. 梯度清零:
    optimizer.zero_grad() 清除之前的梯度,以防止它们在反向传播时累积。
  4. 前向传播:
    outputs = model(X_train_tensor) 执行模型的前向传播,计算给定输入的输出。
  5. 计算损失:
    loss = criterion(outputs, y_train_tensor) 计算模型输出和目标标签之间的损失。
  6. 反向传播:
    loss.backward() 计算损失相对于模型参数的梯度。
  7. 参数更新:
    optimizer.step() 更新模型的参数以减少损失。
  8. 打印损失:
    print 语句在每个周期结束时打印当前周期的损失值,这有助于监控训练过程。

6.评估网络:

        在测试集上评估网络的性能。
# 测试模型
def evaluate_model(model, X_test_tensor, y_test_tensor):
    model.eval()  # 设置模型为评估模式
    with torch.no_grad():  # 禁用梯度计算
        outputs = model(X_test_tensor)
        _, predicted = torch.max(outputs.data, 1)
        total = y_test_tensor.size(0)
        correct = (predicted == y_test_tensor).sum().item()

        print('Accuracy of the network on the test images: %d %%' % (100 * correct / total))

# 在训练结束后评估模型
evaluate_model(model, X_test_tensor, y_test_tensor)
这里定义的 evaluate_model 函数是一个用于评估模型性能的实用工具,特别是在分类任务中。下面是这段代码的详细解释:
  1. 设置评估模式:
    • model.eval() 将模型设置为评估模式,这会禁用如 Dropout 等在训练时使用的特定层。
  2. 禁用梯度计算:
    • with torch.no_grad(): 上下文管理器禁用了梯度计算,这在评估阶段是有用的,因为它减少了内存消耗并加速了计算。
  3. 执行前向传播:
    • outputs = model(X_test_tensor) 执行模型的前向传播,得到模型对测试数据的预测输出。
  4. 获取预测结果:
    • _, predicted = torch.max(outputs.data, 1) 计算模型输出中概率最高的类别索引,即预测的类别。这里 outputs.data 是一个二维张量,第一维是批次中的样本,第二维是类别的概率。
  5. 计算正确预测数量:
    • correct = (predicted == y_test_tensor).sum().item() 计算预测正确的样本数量。这里使用 .sum() 来累加所有正确的预测,并通过 .item() 将其转换为一个标量。
  6. 计算准确率:
    • total = y_test_tensor.size(0) 获取测试集的样本总数。
    • print 语句打印出模型在测试集上的准确率,即正确预测的样本数占总样本数的比例

代码汇总:

import scipy.io
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 加载数据和标签
data = scipy.io.loadmat("D:/Indian_pines_corrected.mat")['indian_pines_corrected']
gt = scipy.io.loadmat("D:/Indian_pines_gt.mat")['indian_pines_gt'].ravel()  # 确保标签是一个一维数组

# 数据预处理
num_bands = data.shape[2]
X = data.reshape(-1, num_bands)

# 归一化数据
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, gt, test_size=0.2, random_state=42)

# 将NumPy数组转换为PyTorch张量
X_train_tensor = torch.tensor(X_train, dtype=torch.float32)
y_train_tensor = torch.tensor(y_train, dtype=torch.long)
X_test_tensor = torch.tensor(X_test, dtype=torch.float32)
y_test_tensor = torch.tensor(y_test, dtype=torch.long)

# 为Conv1d增加通道维度
X_train_tensor = X_train_tensor.unsqueeze(1)
X_test_tensor = X_test_tensor.unsqueeze(1)

# 定义网络
class SpectralCNN(nn.Module):
    def __init__(self, num_bands, num_classes):
        super(SpectralCNN, self).__init__()
        self.conv1 = nn.Conv1d(in_channels=1, out_channels=64, kernel_size=3, padding=1)
        self.pool = nn.MaxPool1d(kernel_size=2)
        self.conv2 = nn.Conv1d(in_channels=64, out_channels=128, kernel_size=3, padding=1)

        # 计算经过两次卷积和池化后的输出大小
        # 卷积后,宽度保持不变;池化后,宽度减半
        conv_output_size = num_bands
        pool_output_size = int(np.ceil(conv_output_size / 2))  # 第一次池化后的大小
        pool_output_size = int(np.ceil(pool_output_size / 2))  # 第二次池化后的大小

        # 更新全连接层的输入大小
        self.fc1 = nn.Linear(128 * pool_output_size, num_classes)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = self.pool(x)
        x = F.relu(self.conv2(x))
        x = self.pool(x)
        x = x.view(x.size(0), -1)  # 扁平化特征向量
        x = self.fc1(x)
        return x

# 初始化模型
num_classes = len(np.unique(gt))
model = SpectralCNN(num_bands=X_train.shape[1], num_classes=num_classes)

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 训练模型
num_epochs = 10000  # 设置训练轮数

# 开始训练模型
for epoch in range(num_epochs):
    model.train()
    optimizer.zero_grad()
    outputs = model(X_train_tensor)
    loss = criterion(outputs, y_train_tensor)
    loss.backward()
    optimizer.step()
    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item()}')


# 测试模型
def evaluate_model(model, X_test_tensor, y_test_tensor):
    model.eval()  # 设置模型为评估模式
    with torch.no_grad():  # 禁用梯度计算
        outputs = model(X_test_tensor)
        _, predicted = torch.max(outputs.data, 1)
        total = y_test_tensor.size(0)
        correct = (predicted == y_test_tensor).sum().item()

        print('Accuracy of the network on the test images: %d %%' % (100 * correct / total))

# 在训练结束后评估模型
evaluate_model(model, X_test_tensor, y_test_tensor)

训练结果展示:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/785809.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

股指期货有哪些对冲类型?

股指期货对冲交易主要分为两类:沽出(卖出)对冲和揸入(购入)对冲。 沽出对冲旨在保护未来股票组合价格下跌的风险。在此策略下,对冲者通过出售期货合约来锁定未来的现金售价,并将价格风险从股票…

软件架构之计算机网络

软件架构之计算机网络 第 4 章 计算机网络4.1 网络架构与协议4.1.1 网络互联模型4.1.2 常见的网络协议4.1.3 IPv6 4.2 局域网与广域网4.2.2 无线局域网4.2.3 广域网技术4.2.4 网络接入技术 4.3 网络互连与常用设备4.4 网络工程4.4.1 网络规划4.4.2 网络设计4.4.3 网络实施 4.5 …

web端已有项目集成含UI腾讯IM

通过 npm 方式下载 TUIKit 组件,将 TUIKit 组件复制到自己工程的 src 目录下: npm i tencentcloud/chat-uikit-vue mkdir -p ./src/TUIKit && rsync -av --exclude{node_modules,package.json,excluded-list.txt} ./node_modules/tencentcloud/…

ubuntu下aarch64-linux-gnu(交叉编译) gdb/gdbserver

ubuntu下aarch64-linux-gnu(交叉编译) gdb/gdbserver gdb是一款开源的、强大的、跨平台的程序调试工具。主要用于在程序运行时对程序进行控制和检查,如设置断点、单步执行、查看变量值、修改内存数据等,从而帮助开发者定位和修复代码中的错误。 gdbserve…

昇思MindSpore学习笔记6-02计算机视觉--ResNet50迁移学习

摘要: 记录MindSpore AI框架使用ResNet50迁移学习方法对ImageNet狼狗图片分类的过程、步骤。包括环境准备、下载数据集、数据集加载、构建模型、固定特征训练、训练评估和模型预测等。 一、概念 迁移学习的方法 在大数据集上训练得到预训练模型 初始化网络权重参数…

突发!马斯克3140亿参数Grok开源!Grok原理大公开!

BIG NEWS: 全球最大开源大模型!马斯克Grok-1参数量3410亿,正式开源!!! 说到做到,马斯克xAI的Grok,果然如期开源了! 就在刚刚,马斯克的AI创企xAI正式发布了此前备受期待大模型Grok-1,其参数量达…

【Linux】文件和目录管理命令——ls,cp,rm,mv

1.文件与目录的查看:Is ls [-aAdfFhilnrRst] 文件名或目录名称ls [ --color{never,auto,always} ]文件名或目录名称ls [ --full-time ]文件名或目录名称 选项与参数: -a:全部的文件,连同隐藏文件&am…

高质量PPT模板素材,免费下载

在制作演示文稿时,选择合适的PPT模板至关重要。为了帮助您轻松找到免费的PPT模板资源,这里分享了6个优秀的网站。这些资源库提供了各种风格和主题的PPT模板,让您的演示内容更生动、更吸引人。 1、baotuppt ppt模板下载-ppt背景 一个专业分享…

如何使用HTML和JavaScript读取文件夹中的所有图片并显示RGB范围

如何使用HTML和JavaScript读取文件夹中的所有图片并显示RGB范围 在这篇博客中&#xff0c;我将介绍如何使用HTML和JavaScript读取文件夹中的所有图片&#xff0c;并显示这些图片以及它们的RGB范围。这个项目使用现代浏览器提供的<input type"file" webkitdirecto…

探展2024世界人工智能大会之合合信息扫描黑科技~

文章目录 ⭐️ 前言⭐️ AIGC古籍修复文化遗产焕新⭐️ 高效的文档图像处理解决方案⭐️ AIGC扫描黑科技一键全搞定⭐️ 行业级的大模型加速器⭐️ 结语 ⭐️ 前言 大家好&#xff0c;我是 哈哥&#xff08;哈哥撩编程&#xff09; &#xff0c;这次非常荣幸受邀作为专业观众参…

深入解析工信认证分类:价值及重要性

随着科技的发展和全球化的推进&#xff0c;企业对于产品和服务的质量、安全、环保等方面的要求日益提高。在这样的背景下&#xff0c;工信认证作为一种权威的第三方认证服务&#xff0c;受到了众多企业的青睐。 一、工信认证的类型 工信认证涵盖了多个领域&#xff0c;包括但不…

温州海经区管委会主任、乐清市委书记徐建兵带队莅临麒麟信安调研

7月8日上午&#xff0c;温州海经区管委会主任、乐清市委书记徐建兵&#xff0c;乐清市委常委、副市长叶序锋&#xff0c;乐清市委办主任郑志坚一行莅临麒麟信安调研&#xff0c;乐清市投资促进服务中心及湖南省浙江总商会相关人员陪同参加。麒麟信安董事长杨涛、总裁刘文清热情…

百度Feed业务数仓建模实践

作者 | XY 导读 Feed&#xff0c;即个性化推荐信息流&#xff0c;是百度 App 上承载各种类型内容&#xff08;如文章、视频、图集等&#xff09;的重要 topic。本文概要讲述了随着业务发展&#xff0c;移动生态数据研发部在 Feed 数据宽表建模上的演进过程以及一些实践&#xf…

自动驾驶SLAM又一开源巅峰之作!深挖时间一致性,精准构建超清地图

论文标题&#xff1a; DTCLMapper: Dual Temporal Consistent Learning for Vectorized HD Map Construction 论文作者&#xff1a; Siyu Li, Jiacheng Lin, Hao Shi, Jiaming Zhang, Song Wang, You Yao, Zhiyong Li, Kailun Yang 导读&#xff1a; 本文介绍了一种用于自动…

【触想智能】工业一体机在工程机械车辆上的应用分析

随着工程机械行业的不断发展和自动化程度的提高&#xff0c;工业一体机在工程机械车辆上的应用越来越广泛。工业一体机是集电脑、显示器、触摸屏、通讯、测量、控制等多种功能于一体的高度集成化的工业控制系统&#xff0c;在工程机械车辆上的应用可以为用户提供更为便捷、高效…

Android EditText+ListPopupWindow实现可编辑的下拉列表

Android EditTextListPopupWindow实现可编辑的下拉列表 &#x1f4d6;1. 可编辑的下拉列表✅步骤一&#xff1a;准备视图✅步骤二&#xff1a;封装显示方法✅步骤三&#xff1a;获取视图并监听 &#x1f4d6;2. 扩展上下箭头✅步骤一&#xff1a;准备上下箭头icon图标✅步骤二&…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第一篇 嵌入式Linux入门篇-第十三章 Linux连接档

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

js碰撞检测

碰撞检测 碰撞检测&#xff08;边界检测&#xff09;在前端游戏&#xff0c;以及涉及拖拽交互的场景应用十分广泛。 碰撞&#xff0c;顾名思义&#xff0c;就是两个物体碰撞在了一起&#xff0c;眼睛是可以直观的观察到碰撞的发生。但对于前端实现&#xff0c;如何让 JavaScrip…

使用Simulink基于模型设计(二):系统定义和布局

Simulink模型的顶层系统布局是许多工程团队可以使用的公共环境&#xff0c;是基于模型的设计范式&#xff1a;分析、设计、检验和实现。您可以通过确定模型的结构和各个组件来定义顶层系统。然后&#xff0c;您可以将模型按照层次结构进行组织&#xff0c;分别与系统的各个组件…