基于Pytorch深度學(xué)習(xí)的衛(wèi)星圖像分類(Kaggle比賽項(xiàng)目實(shí)戰(zhàn))
一、主題介紹:
在Pytorch框架下,實(shí)戰(zhàn)Kaggle比賽:衛(wèi)星圖像分類(Satellite Remote Sensing Image -RSI-CB256),利用Pycharm調(diào)試運(yùn)行代碼。
二、環(huán)境配置要求:
python版本:3.7
pycharm版本:2020.3.5
pytorch版本:1.12.1
numpy版本:1.21.6
matplotlib版本:3.2.2
tqdm版本:4.65.0

把需要的包下載好,在你的有cuda或者cpu的pytorch環(huán)境中下載
三、主要步驟與涉及知識(shí):
3.1 主要步驟:
- 啟用pycharm,新建實(shí)驗(yàn)項(xiàng)目,選擇編譯環(huán)境
- 下載數(shù)據(jù)集
- 預(yù)處理數(shù)據(jù)集
- 定義網(wǎng)絡(luò)
- 模型訓(xùn)練及預(yù)測(cè)
3.2涉及知識(shí):常見(jiàn)Anaconda終端命令的使用
1.Python編程語(yǔ)言
2.數(shù)據(jù)處理分析庫(kù)pandas、科學(xué)計(jì)算庫(kù)numpy,進(jìn)度條庫(kù)tqdm,畫圖庫(kù)matplotlib,python機(jī)器學(xué)習(xí)庫(kù)等使用,torch中nn、loss、optimizer模塊使用
四、實(shí)驗(yàn)步驟:
4.1 數(shù)據(jù)下載
在pycharm中新建實(shí)驗(yàn)三項(xiàng)目,名為“deep_learning_experiments_3”,在該項(xiàng)目文件夾路徑下下載項(xiàng)目數(shù)據(jù)。
方法 網(wǎng)址下載 Satellite Image Classification | Kaggle


衛(wèi)星圖像分類數(shù)據(jù)集包含來(lái)自傳感器和谷歌地圖快照的大約5600張圖像。它有屬于4個(gè)不同類別的衛(wèi)星圖像。
cloudy:從衛(wèi)星拍攝的1500張?jiān)茍D像。desert:從衛(wèi)星拍攝的1131張沙漠圖像。
green_area:主要是森林覆蓋的衛(wèi)星圖像1500張圖片。water:1500張湖泊和其他水體的衛(wèi)星圖像。

4.2數(shù)據(jù)預(yù)處理
4.2.1導(dǎo)入所需的PyTorch模塊定義一些常量
import torch from torch.utils.data import DataLoader, Subset from torchvision import datasets, transforms # 驗(yàn)證集比例 valid_split = 0.2 # 批量大小 batch_size = 64 # 數(shù)據(jù)根目錄路徑 root_dir = 'D:/pycharm projects/deep_learning_experiments/experiment_4/data'
使用20%的數(shù)據(jù)進(jìn)行驗(yàn)證,批大小為64,如果本地機(jī)器上訓(xùn)練面臨OOM(內(nèi)存不足)問(wèn)題,那么降低批大小32或16。
batch_size(批次大小)是機(jī)器學(xué)習(xí)和深度學(xué)習(xí)訓(xùn)練中的一個(gè)核心超參數(shù),用于控制每次迭代時(shí)模型處理的樣本數(shù)量。簡(jiǎn)單來(lái)說(shuō),當(dāng)你有一個(gè)包含 1000 張圖片的訓(xùn)練集,若設(shè)置
batch_size=100,則模型會(huì):
- 每次從訓(xùn)練集中取 100 張圖片
- 計(jì)算這 100 張圖片的總損失(通過(guò)前向傳播)
- 根據(jù)根據(jù)總損失反向傳播更新一次模型參數(shù)
- 重復(fù)這一過(guò)程,直到所有 1000 張圖片都被處理完(即完成 1 個(gè) epoch 的訓(xùn)練)
作用與影響:
內(nèi)存占用:
batch_size越大,一次需要加載到內(nèi)存(或 GPU 顯存)的數(shù)據(jù)越多,可能導(dǎo)致內(nèi)存不足(OOM 錯(cuò)誤)。訓(xùn)練效率:較大的
batch_size可以利用 GPU 并行的并行計(jì)算能力加速訓(xùn)練(單次處理處理大批次數(shù)據(jù)的效率更高),但單次迭代的計(jì)算時(shí)間會(huì)更長(zhǎng)。模型收斂:
- 過(guò)小的
batch_size(如batch_size=1,即隨機(jī)梯度下降 SGD):訓(xùn)練波動(dòng)大,收斂路徑曲折,但可能更容易跳出局部最優(yōu)。- 適中的
batch_size(如 32、64、128):在收斂穩(wěn)定性和效率間取得平衡,是最常用的選擇。- 過(guò)大的
batch_size:訓(xùn)練更穩(wěn)定,但可能收斂到較差的局部最優(yōu),且需要更大的學(xué)習(xí)率配合。
4.2.2訓(xùn)練集和測(cè)試集轉(zhuǎn)換
#訓(xùn)練集數(shù)據(jù)增強(qiáng),以及將圖像數(shù)據(jù)類型轉(zhuǎn)化為張量做歸一化
train_transform = transforms.Compose([
transforms.Resize(224),
transforms.RandomHorizontalFlip(p=0.5),
transforms.RandomVerticalFlip(p=0.5),
transforms.GaussianBlur(kernel_size=(5, 9), sigma=(0.1, 5)), #kernel_size:高斯卷積核大小, sigma:標(biāo)準(zhǔn)差(min,max)
transforms.RandomRotation(degrees=(30, 70)),
transforms.ToTensor(),
transforms.Normalize(
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]
)
])
valid_transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]
)
])
#空間變換增強(qiáng)
#翻轉(zhuǎn) → 位置不變性
#旋轉(zhuǎn) → 方向不變性
#組合使用 → 強(qiáng)大的幾何不變性
#外觀變換增強(qiáng)
#高斯模糊 → 對(duì)圖像質(zhì)量的魯棒性
#標(biāo)準(zhǔn)化??增強(qiáng)效果可視化
假設(shè)原始圖像經(jīng)過(guò)這個(gè)流水線可能產(chǎn)生:
原圖 → 清晰、正立的圖像
增強(qiáng)1 → 水平翻轉(zhuǎn) + 輕微模糊
增強(qiáng)2 → 旋轉(zhuǎn)45° + 垂直翻轉(zhuǎn)
增強(qiáng)3 → 強(qiáng)烈模糊 + 旋轉(zhuǎn)60°
4.2.3定義數(shù)據(jù)加載器
# 加載數(shù)據(jù)集
dataset = datasets.ImageFolder(root_dir, transform=train_transform)
dataset_test = datasets.ImageFolder(root_dir, transform=valid_transform)
# 數(shù)據(jù)集信息
print(f"Classes: {dataset.classes}") # 輸出類別名稱
dataset_size = len(dataset)
valid_size = int(valid_split * dataset_size)
# 隨機(jī)劃分訓(xùn)練集和驗(yàn)證集
indices = torch.randperm(len(dataset)).tolist() # 隨機(jī)打亂索引
dataset_train = Subset(dataset, indices[:-valid_size]) # 訓(xùn)練集:前80%
dataset_valid = Subset(dataset_test, indices[-valid_size:]) # 驗(yàn)證集:后20%
print(f"Total training images: {len(dataset_train)}")
print(f"Total valid_images: {len(dataset_valid)}")
train_loader = DataLoader(
dataset_train, batch_size=batch_size, shuffle=True # 訓(xùn)練時(shí)打亂
)
valid_loader = DataLoader(
dataset_valid, batch_size=batch_size, shuffle=False # 驗(yàn)證時(shí)不打亂
)4. 3構(gòu)建模型(ResNet34)
4.3.1訓(xùn)練腳本train.py
導(dǎo)入所有庫(kù)模塊以及上面編寫的模塊,還有參數(shù)解析器,控制--epochs
import torch
import argparse
import torch.nn as nn
import torch.optim as optim
from model import build_model
from utils import save_model, save_plots
from datasets import train_loader, valid_loader, dataset
from tqdm.auto import tqdm
# 通過(guò)命令行控制訓(xùn)練輪數(shù)
parser = argparse.ArgumentParser()
parser.add_argument('-e', '--epochs', type=int, default=20,
help='number of epochs to train our network for')
args = vars(parser.parse_args())4.3.2定義學(xué)習(xí)率、計(jì)算設(shè)備,構(gòu)建ResNet34模型并定義優(yōu)化器和損失函數(shù)
# 學(xué)習(xí)參數(shù)設(shè)置
#學(xué)習(xí)率: 0.001 (Adam優(yōu)化器的常用值)
#設(shè)備: 自動(dòng)檢測(cè)GPU/CPU
lr = 0.001
epochs = args['epochs']
device = ('cuda' if torch.cuda.is_available() else 'cpu')
print(f"Computation device: {device}\n")
# 構(gòu)建模型
model = build_model(
pretrained=True, fine_tune=False, num_classes=len(dataset.classes)
).to(device)
#總參數(shù)量: 所有參數(shù)的數(shù)量
#可訓(xùn)練參數(shù): 僅計(jì)算需要梯度的參數(shù)
total_params = sum(p.numel() for p in model.parameters())
print(f"{total_params:,} total parameters.")
total_trainable_params = sum(
p.numel() for p in model.parameters() if p.requires_grad)
print(f"{total_trainable_params:,} training parameters.\n")
# 優(yōu)化器: Adam,適合大多數(shù)場(chǎng)景
optimizer = optim.Adam(model.parameters(), lr=lr)
# 損失函數(shù): 交叉熵?fù)p失,用于多分類
criterion = nn.CrossEntropyLoss()4.3.3訓(xùn)練與驗(yàn)證函數(shù)
4.3.3.1訓(xùn)練函數(shù)
# 訓(xùn)練過(guò)程
def train(model, trainloader, optimizer, criterion):
model.train()
print('Training')
train_running_loss = 0.0
train_running_correct = 0
counter = 0
for i, data in tqdm(enumerate(trainloader), total=len(trainloader)):
counter += 1
image, labels = data
image = image.to(device)
labels = labels.to(device)
# 梯度清零
optimizer.zero_grad()
# 前向傳播
outputs = model(image)
# 計(jì)算損失
loss = criterion(outputs, labels)
train_running_loss += loss.item()
# 計(jì)算準(zhǔn)確率
_, preds = torch.max(outputs.data, 1)
train_running_correct += (preds == labels).sum().item()
# 反向傳播
loss.backward()
# 更新參數(shù)
optimizer.step()
# 統(tǒng)計(jì)一批次的損失率和準(zhǔn)確率
epoch_loss = train_running_loss / counter
epoch_acc = 100. * (train_running_correct / len(trainloader.dataset))
return epoch_loss, epoch_acc在每個(gè)epoch之后,該函數(shù)返回該epoch的損失和準(zhǔn)確度。
epoch(輪次)是深度學(xué)習(xí)訓(xùn)練中的核心概念,指模型完整遍歷一次所有訓(xùn)練數(shù)據(jù)的過(guò)程,可以理解為 “訓(xùn)練一輪”。簡(jiǎn)單來(lái)說(shuō),假設(shè)你有 1000 張訓(xùn)練圖片,無(wú)論
batch_size(批次大小)是多少,只要模型把這 1000 張圖片全部處理完一次,就算完成了 1 個(gè)epoch。比如之前的代碼設(shè)置了20個(gè)epoch,就意味著模型要把 4502 張訓(xùn)練圖完整訓(xùn)練 20 遍。
4.3.3.2驗(yàn)證函數(shù)
def validate(model, testloader, criterion, class_names):
# 設(shè)置為評(píng)估模式(禁用dropout和batchnorm的隨機(jī)性)
model.eval()
print('驗(yàn)證中...')
# 累計(jì)損失值
valid_running_loss = 0.0
# 累計(jì)正確預(yù)測(cè)數(shù)量
valid_running_correct = 0
# 批次計(jì)數(shù)器
counter = 0
# 初始化列表來(lái)跟蹤每個(gè)類別的準(zhǔn)確率
# class_correct: 每個(gè)類別的正確預(yù)測(cè)數(shù)
# class_total: 每個(gè)類別的總樣本數(shù)
class_correct = list(0. for i in range(len(class_names)))
class_total = list(0. for i in range(len(class_names)))
# 禁用梯度計(jì)算以節(jié)省內(nèi)存和加速計(jì)算
with torch.no_grad():
# 遍歷驗(yàn)證集中的所有批次
for i, data in tqdm(enumerate(testloader), total=len(testloader)):
counter += 1
# 獲取圖像數(shù)據(jù)和標(biāo)簽
image, labels = data
# 將數(shù)據(jù)轉(zhuǎn)移到指定設(shè)備(GPU或CPU)
image = image.to(device)
labels = labels.to(device)
# 前向傳播:通過(guò)模型獲取預(yù)測(cè)輸出
outputs = model(image)
# 計(jì)算損失值
loss = criterion(outputs, labels)
# 累加損失值
valid_running_loss += loss.item()
# 計(jì)算準(zhǔn)確率:獲取預(yù)測(cè)類別(最大概率的索引)
_, preds = torch.max(outputs.data, 1)
# 累加正確預(yù)測(cè)的數(shù)量
valid_running_correct += (preds == labels).sum().item()
# 計(jì)算每個(gè)類別的準(zhǔn)確率
# 獲取每個(gè)樣本的預(yù)測(cè)是否正確(布爾張量)
correct = (preds == labels).squeeze()
# 遍歷當(dāng)前批次中的每個(gè)樣本
for i in range(len(preds)):
# 獲取當(dāng)前樣本的真實(shí)標(biāo)簽
label = labels[i]
# 如果預(yù)測(cè)正確,則對(duì)應(yīng)類別的正確數(shù)加1
class_correct[label] += correct[i].item()
# 對(duì)應(yīng)類別的總樣本數(shù)加1
class_total[label] += 1
# 計(jì)算整個(gè)epoch的平均損失(總損失除以批次數(shù)量)
epoch_loss = valid_running_loss / counter
# 計(jì)算整體準(zhǔn)確率(正確預(yù)測(cè)數(shù)除以總樣本數(shù),轉(zhuǎn)換為百分比)
epoch_acc = 100. * (valid_running_correct / len(testloader.dataset))
# 打印每個(gè)類別的準(zhǔn)確率
print('\n')
for i in range(len(class_names)):
# 計(jì)算并打印每個(gè)類別的準(zhǔn)確率
print(f"類別 {class_names[i]} 的準(zhǔn)確率: {100 * class_correct[i] / class_total[i]:.3f}%")
print('\n')
# 返回平均損失和整體準(zhǔn)確率
return epoch_loss, epoch_acc4.3.4訓(xùn)練循環(huán)
# 初始化列表來(lái)跟蹤損失和準(zhǔn)確率
# train_loss: 訓(xùn)練損失列表
# valid_loss: 驗(yàn)證損失列表
# train_acc: 訓(xùn)練準(zhǔn)確率列表
# valid_acc: 驗(yàn)證準(zhǔn)確率列表
train_loss, valid_loss = [], []
train_acc, valid_acc = [], []
# 開(kāi)始訓(xùn)練循環(huán)
for epoch in range(epochs):
# 打印當(dāng)前訓(xùn)練輪次信息
print(f"[INFO]: 第 {epoch+1} 輪 / 共 {epochs} 輪")
# 訓(xùn)練一個(gè)epoch并獲取訓(xùn)練損失和準(zhǔn)確率
train_epoch_loss, train_epoch_acc = train(model, train_loader,
optimizer, criterion)
# 驗(yàn)證一個(gè)epoch并獲取驗(yàn)證損失和準(zhǔn)確率
valid_epoch_loss, valid_epoch_acc = validate(model, valid_loader,
criterion, dataset.classes)
# 將當(dāng)前epoch的結(jié)果添加到列表中
train_loss.append(train_epoch_loss)
valid_loss.append(valid_epoch_loss)
train_acc.append(train_epoch_acc)
valid_acc.append(valid_epoch_acc)
# 打印當(dāng)前epoch的訓(xùn)練和驗(yàn)證結(jié)果
print(f"訓(xùn)練損失: {train_epoch_loss:.3f}, 訓(xùn)練準(zhǔn)確率: {train_epoch_acc:.3f}%")
print(f"驗(yàn)證損失: {valid_epoch_loss:.3f}, 驗(yàn)證準(zhǔn)確率: {valid_epoch_acc:.3f}%")
print('-'*50) # 打印分隔線
# 保存訓(xùn)練好的模型權(quán)重(每個(gè)epoch都保存)
save_model(epochs, model, optimizer, criterion)
# 訓(xùn)練完成后保存損失和準(zhǔn)確率圖表
save_plots(train_acc, valid_acc, train_loss, valid_loss)
print('訓(xùn)練完成')4.3.5模型測(cè)試
4.3.5.1測(cè)試參數(shù)設(shè)置
# 導(dǎo)入必要的庫(kù)
import torch # PyTorch深度學(xué)習(xí)框架
import cv2 # OpenCV計(jì)算機(jī)視覺(jué)庫(kù),用于圖像處理
import torchvision.transforms as transforms # PyTorch圖像變換模塊
import argparse # 命令行參數(shù)解析庫(kù)
# 構(gòu)建參數(shù)解析器
# 創(chuàng)建ArgumentParser對(duì)象,用于處理命令行參數(shù)
parser = argparse.ArgumentParser()
# 添加輸入?yún)?shù)
# -i 或 --input: 指定輸入圖像路徑,默認(rèn)值為'input/test_data/cloudy.jpeg'
parser.add_argument('-i', '--input',
default='input/test_data/cloudy.jpeg',
help='輸入圖像的路徑')
# 解析輸入?yún)?shù)并將其轉(zhuǎn)換為字典格式
args = vars(parser.parse_args())
# 計(jì)算設(shè)備設(shè)置
# 指定使用CPU進(jìn)行計(jì)算(如果需要GPU可改為'cuda')
device = 'cpu'4.3.5.2加載模型處理轉(zhuǎn)換
對(duì)于預(yù)處理只需要將圖像轉(zhuǎn)換為 PIL 圖像格式,調(diào)整其大小,將其轉(zhuǎn)換為張量,然后應(yīng)用歸一化。
# 定義所有類別標(biāo)簽的列表
# 對(duì)應(yīng)模型的4個(gè)輸出類別:多云、沙漠、綠地、水域
labels = ['cloudy', 'desert', 'green_area', 'water']
# 初始化模型并加載訓(xùn)練好的權(quán)重
# pretrained=False: 不加載預(yù)訓(xùn)練權(quán)重
# fine_tune=False: 不進(jìn)行微調(diào)
# num_classes=4: 設(shè)置輸出類別數(shù)為4
model = build_model(
pretrained=False, fine_tune=False, num_classes=4
).to(device) # 將模型移動(dòng)到指定設(shè)備(CPU)
print('[INFO]: 正在加載自定義訓(xùn)練權(quán)重...')
# 加載訓(xùn)練好的模型檢查點(diǎn)文件
# map_location=device: 確保權(quán)重加載到正確的設(shè)備上
checkpoint = torch.load('outputs/model.pth', map_location=device)
# 將訓(xùn)練好的權(quán)重加載到模型中
model.load_state_dict(checkpoint['model_state_dict'])
# 將模型設(shè)置為評(píng)估模式(禁用dropout和batchnorm的隨機(jī)性)
model.eval()
# 定義圖像預(yù)處理變換流程
transform = transforms.Compose([
transforms.ToPILImage(), # 將numpy數(shù)組或tensor轉(zhuǎn)換為PIL圖像
transforms.Resize(224), # 調(diào)整圖像大小為224x224像素
transforms.ToTensor(), # 將PIL圖像轉(zhuǎn)換為tensor,并歸一化到[0,1]
transforms.Normalize( # 標(biāo)準(zhǔn)化處理,使用ImageNet數(shù)據(jù)集的均值和標(biāo)準(zhǔn)差
mean=[0.485, 0.456, 0.406], # RGB通道的均值
std=[0.229, 0.224, 0.225] # RGB通道的標(biāo)準(zhǔn)差
)
])4.3.5.3讀取圖像與前饋
# 讀取并預(yù)處理輸入圖像
# 使用OpenCV讀取圖像文件
image = cv2.imread(args['input'])
# 從文件路徑中提取真實(shí)類別(ground truth)
# 例如:'input/test_data/cloudy.jpeg' -> 'cloudy'
gt_class = args['input'].split('/')[-1].split('.')[0]
# 保存原始圖像的副本用于后續(xù)顯示
orig_image = image.copy()
# 將圖像從BGR格式轉(zhuǎn)換為RGB格式(OpenCV默認(rèn)使用BGR,但模型需要RGB)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 對(duì)圖像應(yīng)用預(yù)處理變換(調(diào)整大小、標(biāo)準(zhǔn)化等)
image = transform(image)
# 添加批次維度(將3D張量[H,W,C]轉(zhuǎn)換為4D張量[1,H,W,C])
# 因?yàn)槟P推谕斎刖哂信尉S度
image = torch.unsqueeze(image, 0)
# 在不計(jì)算梯度的情況下進(jìn)行推理(節(jié)省內(nèi)存和計(jì)算資源)
with torch.no_grad():
# 將圖像數(shù)據(jù)移動(dòng)到設(shè)備并通過(guò)模型進(jìn)行前向傳播
outputs = model(image.to(device))
# 獲取模型輸出的最高概率類別
# torch.topk返回前k個(gè)最大值和對(duì)應(yīng)的索引,這里k=1表示取最高概率
output_label = torch.topk(outputs, 1)
# 將預(yù)測(cè)的索引轉(zhuǎn)換為對(duì)應(yīng)的類別名稱
pred_class = labels[int(output_label.indices)]
# 在原始圖像上添加真實(shí)類別文本(綠色)
cv2.putText(orig_image,
f"GT: {gt_class}", # 顯示真實(shí)類別
(10, 25), # 文本位置坐標(biāo)(x,y)
cv2.FONT_HERSHEY_SIMPLEX, # 字體類型
1, # 字體大小
(0, 255, 0), # 字體顏色(綠色)
2, # 字體粗細(xì)
cv2.LINE_AA # 抗鋸齒線型
)
# 在原始圖像上添加預(yù)測(cè)類別文本(紅色)
cv2.putText(orig_image,
f"Pred: {pred_class}", # 顯示預(yù)測(cè)類別
(10, 55), # 文本位置坐標(biāo)(x,y),在真實(shí)類別下方
cv2.FONT_HERSHEY_SIMPLEX, # 字體類型
1, # 字體大小
(0, 0, 255), # 字體顏色(紅色)
2, # 字體粗細(xì)
cv2.LINE_AA # 抗鋸齒線型
)
# 在控制臺(tái)打印真實(shí)類別和預(yù)測(cè)類別
print(f"真實(shí)類別: {gt_class}, 預(yù)測(cè)類別: {pred_class}")
# 顯示帶有標(biāo)注的結(jié)果圖像
cv2.imshow('Result', orig_image)
# 等待按鍵操作(0表示無(wú)限等待)
cv2.waitKey(0)
# 將結(jié)果圖像保存到outputs目錄
# 文件名格式:outputs/真實(shí)類別.png
cv2.imwrite(f"outputs/{gt_class}.png", orig_image)4.4訓(xùn)練測(cè)試終端命令
4.4.1訓(xùn)練命令
python train.py --epochs 100
4.4.2測(cè)試命令
python inference.py --input test_data/cloudy.jpg
或者直接點(diǎn)運(yùn)行也可以
運(yùn)行中……

最終結(jié)果展示:

再運(yùn)行下inference.py文件驗(yàn)證下:
隨便放個(gè)圖片:


驗(yàn)證結(jié)果完全正確?。?!是綠洲圖像


又測(cè)試了下cloudy的,也完全正確:

下面的是準(zhǔn)確率和損失率變化圖像,很直觀的展示:
準(zhǔn)確率:隨著訓(xùn)練輪數(shù)的增加準(zhǔn)確率顯著上升?。?!且訓(xùn)練集和驗(yàn)證集的準(zhǔn)確率最終逐漸趨于一致

損失率:訓(xùn)練集和驗(yàn)證集的損失率顯著下降,最終訓(xùn)練集的損失率降低到了0.05左右

五、訓(xùn)練總結(jié)
5.1 最終性能指標(biāo)
驗(yàn)證準(zhǔn)確率: 96.53%
訓(xùn)練準(zhǔn)確率: 98.22%
驗(yàn)證損失: 0.163
訓(xùn)練損失: 0.061
5.2 各類別準(zhǔn)確率進(jìn)展
| 類別 | 第1輪 | 第20輪 | 提升幅度 |
|---|---|---|---|
| cloudy | 87.42% | 98.43% | +11.01% |
| desert | 49.30% | 95.78% | +46.48% |
| green_area | 79.28% | 97.04% | +17.76% |
| water | 98.28% | 94.48% | -3.80% |
5.3關(guān)鍵觀察
5.3.1 優(yōu)秀表現(xiàn)
desert類巨大進(jìn)步 :從49%提升到96%,說(shuō)明模型成功學(xué)會(huì)了識(shí)別沙漠特征
整體性能卓越 :96.53%的驗(yàn)證準(zhǔn)確率非常優(yōu)秀
訓(xùn)練穩(wěn)定 :損失持續(xù)下降,沒(méi)有明顯過(guò)擬合
收斂良好 :最后幾輪性能穩(wěn)定在高水平
5.3.2 需要注意
water類輕微下降 :從98%降到94%,但仍保持高水平
訓(xùn)練時(shí)間波動(dòng) : 某些epoch訓(xùn)練時(shí)間較長(zhǎng)(可能受系統(tǒng)資源影響)
5.4 訓(xùn)練動(dòng)態(tài)分析
5.4.1關(guān)鍵轉(zhuǎn)折點(diǎn)
第5輪: desert類突破78%,整體準(zhǔn)確率超過(guò)92%
第9輪: 首次達(dá)到95%+驗(yàn)證準(zhǔn)確率
第18輪: 達(dá)到峰值96.53%,desert類突破96%
5.4.2 收斂情況
最后5輪性能穩(wěn)定在95-96.5%之間,說(shuō)明模型已經(jīng)充分訓(xùn)練。
這還只是考慮性能和速度將epoch設(shè)置在了20的情況下,如果訓(xùn)練次數(shù)設(shè)置在32/64,效果應(yīng)該會(huì)更好(根據(jù)你的電腦性能決定)~~~
到此這篇關(guān)于基于深度學(xué)習(xí)的衛(wèi)星圖像分類(Kaggle比賽實(shí)戰(zhàn))的文章就介紹到這了,更多相關(guān)基于深度學(xué)習(xí)的衛(wèi)星圖像Kaggle比賽內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python服務(wù)器中發(fā)送外部請(qǐng)求的基本步驟
在Python中,服務(wù)器發(fā)送外部請(qǐng)求是一個(gè)常見(jiàn)的操作,尤其是在需要集成不同服務(wù)或API時(shí),有多種庫(kù)可以幫助你完成這項(xiàng)任務(wù),但最流行和廣泛使用的庫(kù)之一是requests,下面給大家分享python服務(wù)器中發(fā)送外部請(qǐng)求的基本步驟,感興趣的朋友一起看看吧2024-08-08
Django中ajax發(fā)送post請(qǐng)求 報(bào)403錯(cuò)誤CSRF驗(yàn)證失敗解決方案
這篇文章主要介紹了Django中ajax發(fā)送post請(qǐng)求 報(bào)403錯(cuò)誤CSRF驗(yàn)證失敗解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08
一文秒懂python讀寫csv xml json文件各種騷操作
多年來(lái),數(shù)據(jù)存儲(chǔ)的可能格式顯著增加,但是,在日常使用中,還是以 CSV 、 JSON 和 XML 占主導(dǎo)地位。 在本文中,我將與你分享在Python中使用這三種流行數(shù)據(jù)格式及其之間相互轉(zhuǎn)換的最簡(jiǎn)單方法,需要的朋友可以參考下2019-07-07
最新解決'nvidia-smi' 不是內(nèi)部或外部命令也不是可運(yùn)行的程序
使用cmd查看電腦顯卡的信息,調(diào)用nvidia-smi查看顯卡使用情況報(bào)錯(cuò),提示'nvidia-smi' 不是內(nèi)部或外部命令,也不是可運(yùn)行的程序,本文給大家分享完美解決方案,感興趣的朋友跟隨小編一起看看吧2023-01-01
Python從Excel讀取數(shù)據(jù)并使用Matplotlib繪制成二維圖像
本課程實(shí)現(xiàn)使用 Python 從 Excel 讀取數(shù)據(jù),并使用 Matplotlib 繪制成二維圖像。這一過(guò)程中,將通過(guò)一系列操作來(lái)美化圖像,最終得到一個(gè)可以出版級(jí)別的圖像。本課程對(duì)于需要書寫實(shí)驗(yàn)報(bào)告,學(xué)位論文,發(fā)表文章,做報(bào)告的學(xué)員具有較大價(jià)值2023-02-02
Pycharm配置lua編譯環(huán)境過(guò)程圖解
這篇文章主要介紹了Pycharm配置lua編譯環(huán)境過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11

