使用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_bandspool_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_bandspool_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)

訓練結果展示:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/43249.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/43249.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/43249.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LLM推理引擎怎么選?TensorRT vs vLLM vs LMDeploy vs MLC-LLM

LLM擅長文本生成應用程序,如聊天和代碼完成模型,能夠高度理解和流暢。但是它們的大尺寸也給推理帶來了挑戰。有很多個框架和包可以優化LLM推理和服務,所以在本文中我將整理一些常用的推理引擎并進行比較。 TensorRT-LLM TensorRT-LLM是NV發布…

imazing電腦怎么下載 imazing怎么下載軟件 使用iMazing下載和卸載Apple設備上的應用程序

iMazing官方版是一款管理蘋果設備的軟件,是一款幫助用戶管理 iOS手機的PC端應用程序,能力遠超 iTunes 提供的終極 iOS 設備管理器。在iMazing官方版上與蘋果設備連接后,可以輕松傳輸文件,瀏覽保存信息等,功能比iTunes更…

泛微開發修煉之旅--35關于基于頁面擴展和自定義按鈕實現與后端交互調用的方法

文章鏈接:35關于基于頁面擴展和自定義按鈕實現與后端交互調用的方法

vue3中使用 tilwindcss報錯 Unknown at rule @tailwindcss

解決方法: vscode中安裝插件 Tailwind CSS IntelliSense 在項目中的 .vscode中 settings.json添加 "files.associations": {"*.css": "tailwindcss"}

基于YOLOv9的腦腫瘤區域檢測

數據集 腦腫瘤區域檢測,我們直接采用kaggle公開數據集,Br35H 數據中已對醫學圖像中腦腫瘤位置進行標注 數據集我已經按照YOLO格式配置好,數據內容如下 數據集中共包含700張圖像,其中訓練集500張,驗證集200張 模型訓…

Perl語言入門到高級學習

Perl語言介紹 Perl,全稱為Practical Extraction and Report Language,即“實用報表提取語言”,是一種高級、通用、直譯式、動態的編程語言。Perl最初由Larry Wall設計,并于1987年12月18日首次發布。經過多年的不斷發展和更新,Perl已經成為一種功能豐富且應用廣泛的計算機程…

AI繪畫:藝術與科技的交融,創新浪潮與無限可能

在科技日新月異的當下,AI 繪畫作為人工智能領域的一顆璀璨新星,正以驚人的速度在國內嶄露頭角,引發了藝術與技術交融的全新變革。隨著人工智能技術的飛速發展,AI繪畫已成為藝術與科技交融的新寵。2024年,AI繪畫行業在國…

昇思MindSpore學習筆記2-03 LLM原理和實踐--基于MindSpore通過GPT實現情感分類

摘要: 昇思MindSpore AI框架中使用openai-gpt的方法、步驟。 沒調通,存疑。 一、環境配置 %%capture captured_output # 實驗環境已經預裝了mindspore2.2.14,如需更換mindspore版本,可更改下面mindspore的版本號 !pip uninsta…

Autogen智能體實戰-Autogen框架介紹

文章目錄 一,Autogen簡介二,Autogen原理1,Autogen原理圖解2,拆解Autogen是如何完成繪制特斯拉股票趨勢圖的 這篇文章介紹一個開源的Agent框架-微軟的Autogen。 一,Autogen簡介 官網:https://microsoft.github.io/aut…

前端頁面操作防抖函數封裝及應用

1、使用背景 函數防抖其實是作為一名前端同學必備的技能了,之前一直偷懶都借用頁面loading或者按鈕loading來實現。最近在開發微信小程序,過多的loading會帶來不好的體驗,同時在跳轉頁面的時候,不好用loading來防抖。所以就會出現…

【Unity】RPG2D龍城紛爭(九)戰斗系統之角色移動

更新日期:2024年7月8日。 項目源碼:第五章發布(正式開始游戲邏輯的章節) 索引 簡介一、角色戰斗狀態二、角色移動1.角色起飛(移動前)2.角色降落(移動后)3.生成移動路徑4.角色移動三、整合簡介 之前的章節做了這么多準備工作,現在終于要進入我們最為核心的戰斗系統的編…

在idea中查看某個接口的所有實現類圖

一、選中某個接口右鍵 ---> Diagrams ---> show Diagrams,然后就會進入一個新的 tab 頁; 二、然后在出來的圖上選中某個接口右鍵 ---> show Implementations,就會顯示選中接口的所有實現類列表; 三、最后 ctrl A 全部選…

Defender Cloud Apps部署方案

目錄 Defender Cloud Apps是什么? Defender Cloud Apps:保護您的云應用程序免受威脅 1. 全面的云應用發現與評估 2. 實時的用戶活動監控 3. 深度的數據保護 4. 合規性管理與報告 5. 統一的安全管理 Defender Cloud Apps主要功能 1. 可見性和洞察 2. 數據保…

uniapp父頁面調用子頁面 組件方法記錄

文章目錄 導文如何點擊父頁面,觸發子頁面函數先寫一個子頁面的基礎內容父元素 如何點擊父頁面,修改子頁面的值先寫一個子頁面的基礎內容父元素 導文 如何點擊父頁面,觸發子頁面函數? 如何點擊父頁面,修改子頁面的值&am…

英區PayPal賬號3分鐘綁定WISE英鎊的銀行收款賬戶

正文開始,我們先登錄英區PayPal賬號后 有很多銀行給我們選擇,但是沒有WISE的選項,所以我們手動輸入“WISE”,然后如下圖所示點擊“Enter Your Bank Detailds”輸入銀行詳細信息按鈕。 然后輸入我們的WISE英鎊賬戶的收款銀行信息&a…

Advanced Electronic Materials:磁性智能皮膚作為人機界面

近年來,電子可穿戴設備的普及率迅速上升,柔性可穿戴設備因其高生物相容性、功能性、適應性和低成本而在人機界面上引起了極大的關注。柔性磁性智能皮膚是這一快速發展的柔性可穿戴電子領域的一部分,為人類感知發展開辟了一條新的道路。磁感是…

SpringCloud第一篇Docker基礎

文章目錄 一、常見命令二、數據卷三、數據掛載四、自定義鏡像五、網絡 一、常見命令 Docker最常見的命令就是操作鏡像、容器的命令,詳見官方文檔: https://docs.docker.com/ 需求: 在DockerHub中搜索Nginx鏡像,查看鏡像的名稱 …

k8s集群如kubeadm init和kube-flannel.yam問題

查看k8s中角色內容kubectl get all (顯示pod和server以及delment) 刪除應用資源選擇刪除先刪除部署查看部署和pod沒了服務還在,但資源和功能以及刪除,刪除服務kubectl delete 服務名(部署名),get pods 獲取默認空間的容…

A133 Android10 root修改

1.前言 客戶應用需求root相關的權限,我們需要修改系統的權限才可以滿足客戶需求 2.修改方法 frameworks層:注釋掉 diff --git a/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp b/frameworks/base/core/jni/com_android_internal_os_…

從資金到未來:技術融資如何重塑IT顧問在AI與網絡安全的角色?

一方面是人工智能 (AI) 和機器學習 (ML) 的雙引擎,另一方面是網絡安全和數據泄露威脅中不斷變化的威脅形勢,IT 格局正在經歷翻天覆地的變化。這場數字革命對 IT 顧問來說既是挑戰也是機遇,但要成…