day39_2025-08-13

知識點回顧:

彩色和灰度圖片測試和訓練的規范寫法:封裝在函數中
展平操作:除第一個維度batchsize外全部展平
dropout操作:訓練階段隨機丟棄神經元,測試階段eval模式關閉dropout
作業:仔細學習下測試和訓練代碼的邏輯,這是基礎,這個代碼框架后續會一直沿用,后續的重點慢慢就是轉向模型定義階段了。

昨天我們介紹了圖像數據的格式以及模型定義的過程,發現和之前結構化數據的略有不同,主要差異體現在2處

  1. 模型定義的時候需要展平圖像

  2. 由于數據過大,需要將數據集進行分批次處理,這往往涉及到了dataset和dataloader來規范代碼的組織

現在我們把注意力放在訓練和測試代碼的規范寫法上

單通道圖片的規范寫法

# 先繼續之前的代碼
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader , Dataset # DataLoader 是 PyTorch 中用于加載數據的工具
from torchvision import datasets, transforms # torchvision 是一個用于計算機視覺的庫,datasets 和 transforms 是其中的模塊
import matplotlib.pyplot as plt
import warnings
# 忽略警告信息
warnings.filterwarnings("ignore")
# 設置隨機種子,確保結果可復現
torch.manual_seed(42)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"使用設備: {device}")
# 1. 數據預處理
transform = transforms.Compose([transforms.ToTensor(),  # 轉換為張量并歸一化到[0,1]transforms.Normalize((0.1307,), (0.3081,))  # MNIST數據集的均值和標準差
])# 2. 加載MNIST數據集
train_dataset = datasets.MNIST(root='./data',train=True,download=True,transform=transform
)test_dataset = datasets.MNIST(root='./data',train=False,transform=transform
)# 3. 創建數據加載器
batch_size = 64  # 每批處理64個樣本
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)# 4. 定義模型、損失函數和優化器
class MLP(nn.Module):def __init__(self):super(MLP, self).__init__()self.flatten = nn.Flatten()  # 將28x28的圖像展平為784維向量self.layer1 = nn.Linear(784, 128)  # 第一層:784個輸入,128個神經元self.relu = nn.ReLU()  # 激活函數self.layer2 = nn.Linear(128, 10)  # 第二層:128個輸入,10個輸出(對應10個數字類別)def forward(self, x):x = self.flatten(x)  # 展平圖像x = self.layer1(x)   # 第一層線性變換x = self.relu(x)     # 應用ReLU激活函數x = self.layer2(x)   # 第二層線性變換,輸出logitsreturn x# 初始化模型
model = MLP()
model = model.to(device)  # 將模型移至GPU(如果可用)# from torchsummary import summary  # 導入torchsummary庫
# print("\n模型結構信息:")
# summary(model, input_size=(1, 28, 28))  # 輸入尺寸為MNIST圖像尺寸criterion = nn.CrossEntropyLoss()  # 交叉熵損失函數,適用于多分類問題
optimizer = optim.Adam(model.parameters(), lr=0.001)  # Adam優化器
# 5. 訓練模型(記錄每個 iteration 的損失)
def train(model, train_loader, test_loader, criterion, optimizer, device, epochs):model.train()  # 設置為訓練模式# 新增:記錄每個 iteration 的損失all_iter_losses = []  # 存儲所有 batch 的損失iter_indices = []     # 存儲 iteration 序號(從1開始)for epoch in range(epochs):running_loss = 0.0correct = 0total = 0for batch_idx, (data, target) in enumerate(train_loader):# enumerate() 是 Python 內置函數,用于遍歷可迭代對象(如列表、元組)并同時獲取索引和值。# batch_idx:當前批次的索引(從 0 開始)# (data, target):當前批次的樣本數據和對應的標簽,是一個元組,這是因為dataloader內置的getitem方法返回的是一個元組,包含數據和標簽。# 只需要記住這種固定寫法即可data, target = data.to(device), target.to(device)  # 移至GPU(如果可用)optimizer.zero_grad()  # 梯度清零output = model(data)  # 前向傳播loss = criterion(output, target)  # 計算損失loss.backward()  # 反向傳播optimizer.step()  # 更新參數# 記錄當前 iteration 的損失(注意:這里直接使用單 batch 損失,而非累加平均)iter_loss = loss.item()all_iter_losses.append(iter_loss)iter_indices.append(epoch * len(train_loader) + batch_idx + 1)  # iteration 序號從1開始# 統計準確率和損失running_loss += loss.item() #將loss轉化為標量值并且累加到running_loss中,計算總損失_, predicted = output.max(1) # output:是模型的輸出(logits),形狀為 [batch_size, 10](MNIST 有 10 個類別)# 獲取預測結果,max(1) 返回每行(即每個樣本)的最大值和對應的索引,這里我們只需要索引total += target.size(0) # target.size(0) 返回當前批次的樣本數量,即 batch_size,累加所有批次的樣本數,最終等于訓練集的總樣本數correct += predicted.eq(target).sum().item() # 返回一個布爾張量,表示預測是否正確,sum() 計算正確預測的數量,item() 將結果轉換為 Python 數字# 每100個批次打印一次訓練信息(可選:同時打印單 batch 損失)if (batch_idx + 1) % 100 == 0:print(f'Epoch: {epoch+1}/{epochs} | Batch: {batch_idx+1}/{len(train_loader)} 'f'| 單Batch損失: {iter_loss:.4f} | 累計平均損失: {running_loss/(batch_idx+1):.4f}')# 測試、打印 epoch 結果epoch_train_loss = running_loss / len(train_loader)epoch_train_acc = 100. * correct / totalepoch_test_loss, epoch_test_acc = test(model, test_loader, criterion, device)print(f'Epoch {epoch+1}/{epochs} 完成 | 訓練準確率: {epoch_train_acc:.2f}% | 測試準確率: {epoch_test_acc:.2f}%')# 繪制所有 iteration 的損失曲線plot_iter_losses(all_iter_losses, iter_indices)# 保留原 epoch 級曲線(可選)# plot_metrics(train_losses, test_losses, train_accuracies, test_accuracies, epochs)return epoch_test_acc  # 返回最終測試準確率

之前我們用mlp訓練鳶尾花數據集的時候并沒有用函數的形式來封裝訓練和測試過程,這樣寫會讓代碼更加具有邏輯-----隔離參數和內容。

  1. 后續直接修改參數就行,不需要去找到對應操作的代碼

  2. 方便復用,未來有多模型對比時,就可以復用這個函數

這里我們先不寫早停策略,因為規范的早停策略需要用到驗證集,一般還需要劃分測試集

  1. 劃分數據集:訓練集(用于訓練)、驗證集(用于早停和調參)、測試集(用于最終報告性能)。
  2. 在訓練過程中,使用驗證集觸發早停。
  3. 訓練結束后,僅用測試集運行一次測試函數,得到最終準確率。

測試函數和繪圖函數均被封裝在了train函數中,但是test和繪圖函數在定義train函數之后,這是因為在 Python 中,函數定義的順序不影響調用,只要在調用前已經完成定義即可。

# 6. 測試模型(不變)
def test(model, test_loader, criterion, device):model.eval()  # 設置為評估模式test_loss = 0correct = 0total = 0with torch.no_grad():  # 不計算梯度,節省內存和計算資源for data, target in test_loader:data, target = data.to(device), target.to(device)output = model(data)test_loss += criterion(output, target).item()_, predicted = output.max(1)total += target.size(0)correct += predicted.eq(target).sum().item()avg_loss = test_loss / len(test_loader)accuracy = 100. * correct / totalreturn avg_loss, accuracy  # 返回損失和準確率

如果打印每一個batchsize的損失和準確率,會看的更加清晰,更加直觀

# 7. 繪制每個 iteration 的損失曲線
def plot_iter_losses(losses, indices):plt.figure(figsize=(10, 4))plt.plot(indices, losses, 'b-', alpha=0.7, label='Iteration Loss')plt.xlabel('Iteration(Batch序號)')plt.ylabel('損失值')plt.title('每個 Iteration 的訓練損失')plt.legend()plt.grid(True)plt.tight_layout()plt.show()
# 8. 執行訓練和測試(設置 epochs=2 驗證效果)
epochs = 2  
print("開始訓練模型...")
final_accuracy = train(model, train_loader, test_loader, criterion, optimizer, device, epochs)
print(f"訓練完成!最終測試準確率: {final_accuracy:.2f}%")
開始訓練模型...
Epoch: 1/2 | Batch: 100/938 | 單Batch損失: 0.3583 | 累計平均損失: 0.6321
Epoch: 1/2 | Batch: 200/938 | 單Batch損失: 0.2035 | 累計平均損失: 0.4776
Epoch: 1/2 | Batch: 300/938 | 單Batch損失: 0.3044 | 累計平均損失: 0.4053
Epoch: 1/2 | Batch: 400/938 | 單Batch損失: 0.1427 | 累計平均損失: 0.3669
Epoch: 1/2 | Batch: 500/938 | 單Batch損失: 0.1742 | 累計平均損失: 0.3321
Epoch: 1/2 | Batch: 600/938 | 單Batch損失: 0.3089 | 累計平均損失: 0.3104
Epoch: 1/2 | Batch: 700/938 | 單Batch損失: 0.0455 | 累計平均損失: 0.2921
Epoch: 1/2 | Batch: 800/938 | 單Batch損失: 0.1018 | 累計平均損失: 0.2762
Epoch: 1/2 | Batch: 900/938 | 單Batch損失: 0.2935 | 累計平均損失: 0.2628
Epoch 1/2 完成 | 訓練準確率: 92.42% | 測試準確率: 95.84%
Epoch: 2/2 | Batch: 100/938 | 單Batch損失: 0.1767 | 累計平均損失: 0.1356
Epoch: 2/2 | Batch: 200/938 | 單Batch損失: 0.1742 | 累計平均損失: 0.1289
Epoch: 2/2 | Batch: 300/938 | 單Batch損失: 0.1273 | 累計平均損失: 0.1282
Epoch: 2/2 | Batch: 400/938 | 單Batch損失: 0.2078 | 累計平均損失: 0.1234
Epoch: 2/2 | Batch: 500/938 | 單Batch損失: 0.0236 | 累計平均損失: 0.1209
Epoch: 2/2 | Batch: 600/938 | 單Batch損失: 0.0573 | 累計平均損失: 0.1193
Epoch: 2/2 | Batch: 700/938 | 單Batch損失: 0.0990 | 累計平均損失: 0.1170
Epoch: 2/2 | Batch: 800/938 | 單Batch損失: 0.1580 | 累計平均損失: 0.1152
Epoch: 2/2 | Batch: 900/938 | 單Batch損失: 0.0749 | 累計平均損失: 0.1139
Epoch 2/2 完成 | 訓練準確率: 96.63% | 測試準確率: 96.93%


在PyTorch中處理張量(Tensor)時,以下是關于展平(Flatten)、維度調整(如view/reshape)等操作的關鍵點,這些操作通常不會影響第一個維度(即批量維度batch_size):

圖像任務中的張量形狀
輸入張量的形狀通常為:
(batch_size, channels, height, width)
例如:(batch_size, 3, 28, 28)
其中,batch_size 代表一次輸入的樣本數量。

NLP任務中的張量形狀
輸入張量的形狀可能為:
(batch_size, sequence_length)
此時,batch_size 同樣是第一個維度。

  1. Flatten操作

功能:將張量展平為一維數組,但保留批量維度。
示例:
輸入形狀:(batch_size, 3, 28, 28)(圖像數據)
Flatten后形狀:(batch_size, 3×28×28) = (batch_size, 2352)
說明:第一個維度batch_size不變,后面的所有維度被展平為一個維度。

  1. view/reshape操作

功能:調整張量維度,但必須顯式保留或指定批量維度。
示例:
輸入形狀:(batch_size, 3, 28, 28)
調整為:(batch_size, -1)
結果:展平為兩個維度,保留batch_size,第二個維度自動計算為3×28×28=2352。

總結

批量維度不變性:無論進行flatten、view還是reshape操作,第一個維度batch_size通常保持不變。
動態維度指定:使用-1讓PyTorch自動計算該維度的大小,但需確保其他維度的指定合理,避免形狀不匹配錯誤。
二、彩色圖片的規范寫法
彩色的通道也是在第一步被直接展平,其他代碼一致

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
import numpy as np# 設置中文字體支持
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams['axes.unicode_minus'] = False  # 解決負號顯示問題# 1. 數據預處理
transform = transforms.Compose([transforms.ToTensor(),                # 轉換為張量transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))  # 標準化處理
])# 2. 加載CIFAR-10數據集
train_dataset = datasets.CIFAR10(root='./data',train=True,download=True,transform=transform
)test_dataset = datasets.CIFAR10(root='./data',train=False,transform=transform
)# 3. 創建數據加載器
batch_size = 64
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)# 4. 定義MLP模型(適應CIFAR-10的輸入尺寸)
class MLP(nn.Module):def __init__(self):super(MLP, self).__init__()self.flatten = nn.Flatten()  # 將3x32x32的圖像展平為3072維向量self.layer1 = nn.Linear(3072, 512)  # 第一層:3072個輸入,512個神經元self.relu1 = nn.ReLU()self.dropout1 = nn.Dropout(0.2)  # 添加Dropout防止過擬合self.layer2 = nn.Linear(512, 256)  # 第二層:512個輸入,256個神經元self.relu2 = nn.ReLU()self.dropout2 = nn.Dropout(0.2)self.layer3 = nn.Linear(256, 10)  # 輸出層:10個類別def forward(self, x):# 第一步:將輸入圖像展平為一維向量x = self.flatten(x)  # 輸入尺寸: [batch_size, 3, 32, 32] → [batch_size, 3072]# 第一層全連接 + 激活 + Dropoutx = self.layer1(x)   # 線性變換: [batch_size, 3072] → [batch_size, 512]x = self.relu1(x)    # 應用ReLU激活函數x = self.dropout1(x) # 訓練時隨機丟棄部分神經元輸出# 第二層全連接 + 激活 + Dropoutx = self.layer2(x)   # 線性變換: [batch_size, 512] → [batch_size, 256]x = self.relu2(x)    # 應用ReLU激活函數x = self.dropout2(x) # 訓練時隨機丟棄部分神經元輸出# 第三層(輸出層)全連接x = self.layer3(x)   # 線性變換: [batch_size, 256] → [batch_size, 10]return x  # 返回未經過Softmax的logits# 檢查GPU是否可用
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 初始化模型
model = MLP()
model = model.to(device)  # 將模型移至GPU(如果可用)criterion = nn.CrossEntropyLoss()  # 交叉熵損失函數
optimizer = optim.Adam(model.parameters(), lr=0.001)  # Adam優化器# 5. 訓練模型(記錄每個 iteration 的損失)
def train(model, train_loader, test_loader, criterion, optimizer, device, epochs):model.train()  # 設置為訓練模式# 記錄每個 iteration 的損失all_iter_losses = []  # 存儲所有 batch 的損失iter_indices = []     # 存儲 iteration 序號for epoch in range(epochs):running_loss = 0.0correct = 0total = 0for batch_idx, (data, target) in enumerate(train_loader):data, target = data.to(device), target.to(device)  # 移至GPUoptimizer.zero_grad()  # 梯度清零output = model(data)  # 前向傳播loss = criterion(output, target)  # 計算損失loss.backward()  # 反向傳播optimizer.step()  # 更新參數# 記錄當前 iteration 的損失iter_loss = loss.item()all_iter_losses.append(iter_loss)iter_indices.append(epoch * len(train_loader) + batch_idx + 1)# 統計準確率和損失running_loss += iter_loss_, predicted = output.max(1)total += target.size(0)correct += predicted.eq(target).sum().item()# 每100個批次打印一次訓練信息if (batch_idx + 1) % 100 == 0:print(f'Epoch: {epoch+1}/{epochs} | Batch: {batch_idx+1}/{len(train_loader)} 'f'| 單Batch損失: {iter_loss:.4f} | 累計平均損失: {running_loss/(batch_idx+1):.4f}')# 計算當前epoch的平均訓練損失和準確率epoch_train_loss = running_loss / len(train_loader)epoch_train_acc = 100. * correct / total# 測試階段model.eval()  # 設置為評估模式test_loss = 0correct_test = 0total_test = 0with torch.no_grad():for data, target in test_loader:data, target = data.to(device), target.to(device)output = model(data)test_loss += criterion(output, target).item()_, predicted = output.max(1)total_test += target.size(0)correct_test += predicted.eq(target).sum().item()epoch_test_loss = test_loss / len(test_loader)epoch_test_acc = 100. * correct_test / total_testprint(f'Epoch {epoch+1}/{epochs} 完成 | 訓練準確率: {epoch_train_acc:.2f}% | 測試準確率: {epoch_test_acc:.2f}%')# 繪制所有 iteration 的損失曲線plot_iter_losses(all_iter_losses, iter_indices)return epoch_test_acc  # 返回最終測試準確率# 6. 繪制每個 iteration 的損失曲線
def plot_iter_losses(losses, indices):plt.figure(figsize=(10, 4))plt.plot(indices, losses, 'b-', alpha=0.7, label='Iteration Loss')plt.xlabel('Iteration(Batch序號)')plt.ylabel('損失值')plt.title('每個 Iteration 的訓練損失')plt.legend()plt.grid(True)plt.tight_layout()plt.show()# 7. 執行訓練和測試
epochs = 20  # 增加訓練輪次以獲得更好效果
print("開始訓練模型...")
final_accuracy = train(model, train_loader, test_loader, criterion, optimizer, device, epochs)
print(f"訓練完成!最終測試準確率: {final_accuracy:.2f}%")# # 保存模型
# torch.save(model.state_dict(), 'cifar10_mlp_model.pth')
# # print("模型已保存為: cifar10_mlp_model.pth")
開始訓練模型...
Epoch: 1/20 | Batch: 100/782 | 單Batch損失: 1.8807 | 累計平均損失: 1.9089
Epoch: 1/20 | Batch: 200/782 | 單Batch損失: 1.5888 | 累計平均損失: 1.8412
Epoch: 1/20 | Batch: 300/782 | 單Batch損失: 1.7336 | 累計平均損失: 1.7983
Epoch: 1/20 | Batch: 400/782 | 單Batch損失: 1.5493 | 累計平均損失: 1.7679
Epoch: 1/20 | Batch: 500/782 | 單Batch損失: 1.5747 | 累計平均損失: 1.7443
Epoch: 1/20 | Batch: 600/782 | 單Batch損失: 1.5258 | 累計平均損失: 1.7273
Epoch: 1/20 | Batch: 700/782 | 單Batch損失: 1.8130 | 累計平均損失: 1.7144
Epoch 1/20 完成 | 訓練準確率: 39.63% | 測試準確率: 45.20%
Epoch: 2/20 | Batch: 100/782 | 單Batch損失: 1.3518 | 累計平均損失: 1.4666
Epoch: 2/20 | Batch: 200/782 | 單Batch損失: 1.4150 | 累計平均損失: 1.4644
Epoch: 2/20 | Batch: 300/782 | 單Batch損失: 1.6774 | 累計平均損失: 1.4667
Epoch: 2/20 | Batch: 400/782 | 單Batch損失: 1.5217 | 累計平均損失: 1.4600
Epoch: 2/20 | Batch: 500/782 | 單Batch損失: 1.3729 | 累計平均損失: 1.4601
Epoch: 2/20 | Batch: 600/782 | 單Batch損失: 1.5887 | 累計平均損失: 1.4555
Epoch: 2/20 | Batch: 700/782 | 單Batch損失: 1.5309 | 累計平均損失: 1.4560
Epoch 2/20 完成 | 訓練準確率: 48.49% | 測試準確率: 49.26%
Epoch: 3/20 | Batch: 100/782 | 單Batch損失: 1.4234 | 累計平均損失: 1.3375
Epoch: 3/20 | Batch: 200/782 | 單Batch損失: 1.3234 | 累計平均損失: 1.3256
Epoch: 3/20 | Batch: 300/782 | 單Batch損失: 1.2906 | 累計平均損失: 1.3335
Epoch: 3/20 | Batch: 400/782 | 單Batch損失: 1.1346 | 累計平均損失: 1.3364
Epoch: 3/20 | Batch: 500/782 | 單Batch損失: 1.5469 | 累計平均損失: 1.3391
Epoch: 3/20 | Batch: 600/782 | 單Batch損失: 1.3636 | 累計平均損失: 1.3389
Epoch: 3/20 | Batch: 700/782 | 單Batch損失: 1.3753 | 累計平均損失: 1.3411
Epoch 3/20 完成 | 訓練準確率: 52.59% | 測試準確率: 51.27%
...
Epoch: 20/20 | Batch: 500/782 | 單Batch損失: 0.3417 | 累計平均損失: 0.3713
Epoch: 20/20 | Batch: 600/782 | 單Batch損失: 0.4816 | 累計平均損失: 0.3757
Epoch: 20/20 | Batch: 700/782 | 單Batch損失: 0.6223 | 累計平均損失: 0.3821
Epoch 20/20 完成 | 訓練準確率: 86.27% | 測試準確率: 52.40%

# 7. 執行訓練和測試
epochs = 20  # 增加訓練輪次以獲得更好效果
print("開始訓練模型...")
final_accuracy = train(model, train_loader, test_loader, criterion, optimizer, device, epochs)
print(f"訓練完成!最終測試準確率: {final_accuracy:.2f}%")
開始訓練模型...
Epoch: 1/20 | Batch: 100/782 | 單Batch損失: 1.4619 | 累計平均損失: 1.3271
Epoch: 1/20 | Batch: 200/782 | 單Batch損失: 1.2312 | 累計平均損失: 1.2557
Epoch: 1/20 | Batch: 300/782 | 單Batch損失: 1.1511 | 累計平均損失: 1.2159
Epoch: 1/20 | Batch: 400/782 | 單Batch損失: 0.9654 | 累計平均損失: 1.1774
Epoch: 1/20 | Batch: 500/782 | 單Batch損失: 1.2084 | 累計平均損失: 1.1537
Epoch: 1/20 | Batch: 600/782 | 單Batch損失: 1.2039 | 累計平均損失: 1.1260
Epoch: 1/20 | Batch: 700/782 | 單Batch損失: 1.0381 | 累計平均損失: 1.1123
Epoch 1/20 完成 | 訓練準確率: 63.63% | 測試準確率: 52.61%
Epoch: 2/20 | Batch: 100/782 | 單Batch損失: 0.3717 | 累計平均損失: 0.4796
Epoch: 2/20 | Batch: 200/782 | 單Batch損失: 0.3691 | 累計平均損失: 0.4380
Epoch: 2/20 | Batch: 300/782 | 單Batch損失: 0.3134 | 累計平均損失: 0.4115
Epoch: 2/20 | Batch: 400/782 | 單Batch損失: 0.3479 | 累計平均損失: 0.3937
Epoch: 2/20 | Batch: 500/782 | 單Batch損失: 0.3160 | 累計平均損失: 0.3820
Epoch: 2/20 | Batch: 600/782 | 單Batch損失: 0.4037 | 累計平均損失: 0.3761
Epoch: 2/20 | Batch: 700/782 | 單Batch損失: 0.4130 | 累計平均損失: 0.3708
Epoch 2/20 完成 | 訓練準確率: 87.23% | 測試準確率: 53.91%
Epoch: 3/20 | Batch: 100/782 | 單Batch損失: 0.3526 | 累計平均損失: 0.2483
Epoch: 3/20 | Batch: 200/782 | 單Batch損失: 0.4958 | 累計平均損失: 0.2644
Epoch: 3/20 | Batch: 300/782 | 單Batch損失: 0.2418 | 累計平均損失: 0.2742
Epoch: 3/20 | Batch: 400/782 | 單Batch損失: 0.2887 | 累計平均損失: 0.2823
Epoch: 3/20 | Batch: 500/782 | 單Batch損失: 0.2651 | 累計平均損失: 0.2902
Epoch: 3/20 | Batch: 600/782 | 單Batch損失: 0.4208 | 累計平均損失: 0.2969
Epoch: 3/20 | Batch: 700/782 | 單Batch損失: 0.5297 | 累計平均損失: 0.3066
Epoch 3/20 完成 | 訓練準確率: 88.99% | 測試準確率: 52.74%
...
Epoch: 20/20 | Batch: 500/782 | 單Batch損失: 0.3291 | 累計平均損失: 0.2262
Epoch: 20/20 | Batch: 600/782 | 單Batch損失: 0.3049 | 累計平均損失: 0.2267
Epoch: 20/20 | Batch: 700/782 | 單Batch損失: 0.2965 | 累計平均損失: 0.2274
Epoch 20/20 完成 | 訓練準確率: 92.31% | 測試準確率: 52.40%


@浙大疏錦行

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

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

相關文章

使用GTX ip core + SDI IP core實現SDI設計

使用GTX ip core SDI IP core實現SDI設計 1.SDI接口可以調用GTX IP,具體代碼可以參考xapp592,將代碼移植進入工程里,增加SDI IP核,增加引腳約束即可運行起來 2.使用transceiver的gt的ip core,然后協議選擇SDI協議 3.使…

【無標題】centos 配置阿里云的yum源

1、查看系統正在使用的yum源列表yum repolist結果分析:目前這里看出有base ,extras ,updates三個yum源,這三個也是系統默認的yum源,一般還需要一個epel企業級額外的yum源,本文主要就是更改yum源的配置文件&…

GPT-5全面開放!OpenAI回應用戶反饋:GPT-4o已重新上線!

OpenAI 近日宣布,其最新模型 GPT-5 現已全面向所有 Plus、Pro、Team 和免費用戶開放。 為進一步優化用戶體驗并應對初期反饋: 用戶額度提升: 在剛剛過去的周末,OpenAI已將 Plus 和 Team 用戶的 GPT-5 使用額度提升至原來的 2 倍…

線程安全的單例模式,STL和智能指針

目錄 什么是單例模式 什么是設計模式 單例模式的特點 餓漢實現方式和懶漢實現方式 餓漢方式實現單例模式 懶漢方式實現單例模式 懶漢方式實現單例模式(線程安全版本) STL,智能指針和線程安全 STL中的容器是否是線程安全的? 智能指針是否是線程安全的? 其他常見的各種鎖 什么是…

[每周一更]-(第155期):深入Go反射機制:架構師視角下的動態力量與工程智慧

在構建高復雜度、高靈活性的Go語言系統時,反射(reflect)就像一把雙刃劍——用得好能斬斷開發枷鎖,用不好則可能自傷程序。本文將深入探討反射的內部機理、典型應用場景、安全邊界及性能優化策略。一、反射核心:類型與值…

15_基于深度學習的蘋果病害檢測識別系統(yolo11、yolov8、yolov5+UI界面+Python項目源碼+模型+標注好的數據集)

目錄 項目介紹🎯 功能展示🌟 一、環境安裝🎆 環境配置說明📘 安裝指南說明🎥 環境安裝教學視頻 🌟 二、數據集介紹🌟 三、系統環境(框架/依賴庫)說明🧱 系統環…

Kotlin 數據容器 - MutableList(MutableList 概述、MutableList 增刪改查、MutableList 遍歷元素)

一、MutableList 概述MutableList 是 Kotlin 中可變的列表接口,它繼承自 List 接口并添加了修改列表內容的方法MutableList 允許添加、刪除、更新元素二、創建 MutableList 1、基礎創建 使用 mutableListOf 函數 // 創建一個 MutableList,包含 4 個元素 …

數據庫規范化:消除冗余與異常的核心法則

規范化(Normalization) 是數據庫設計中的核心流程,旨在通過結構化表與字段,消除數據冗余和避免數據異常(插入/更新/刪除異常),同時確保數據依賴合理。其核心方法是將大表拆分為多個小表&#xf…

AI繪畫與攝影新紀元:ChatGPT+Midjourney+文心一格 共繪夢幻世界

文章目錄一、AI藝術的新時代二、ChatGPT:創意的引擎與靈感的火花三、Midjourney:圖像生成的魔法與技術的奇跡四、文心一格:藝術的升華與情感的共鳴五、融合創新:AI繪畫與攝影實戰的無限可能六、應用場景與實踐案例AI藝術的美好未來…

如何衡量需求的緊急程度

衡量需求的緊急程度,其核心在于建立一套客觀、量化、且基于商業影響的評估框架,從而將干系人主觀的“緊迫感”,轉化為團隊可進行理性決策的“優先級數據”。一套行之有效的緊急程度衡量體系,其構建必須綜合考量五大關鍵維度&#…

setInterval的任務正在執行時,setTimeout的任務會等待前者完成后再執行,這樣會造成2個計時器的時間精度出錯?

setInterval,setTimeout 2種計時器在同一個頁面處理任務,想看下精度用時情況。setInterval的任務正在執行時,setTimeout的任務會等待前者完成后再執行,這樣會造成2個計時器的時間精度出錯?本來settimeout啟動0.5秒&…

DeepSeek-R1-0528 推理模型完整指南:領先開源推理模型的運行平臺與選擇建議

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎?訂閱我們的簡報,深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同,從行業內部的深度分析和實用指南中受益。不要錯過這個機會,成為AI領…

【AI實戰】從零開始微調Qwen2-VL模型:打造制造業智能安全巡檢系統

【AI實戰】從零開始微調Qwen2-VL模型:打造制造業智能安全巡檢系統🎯 項目背景與目標🛠 環境準備硬件要求軟件環境搭建📊 數據準備:構建高質量訓練集第一步:提取規章制度知識第二步:創建標注數據…

5 重復匹配

在前幾章里,我們學習了如何使用各種元字符和特殊的字符集合去匹配單個字符。本章將學習如何匹配多個連續重復出現的字符或字符集合。5.1 有多少個匹配你現在已經學會了正則表達式的模式匹配中的基礎知識,但目前所有的例子都有一個非常嚴重的局限。請大家…

【瀏覽器兼容性處理】

瀏覽器兼容性處理是前端開發中重要的一環,指解決不同瀏覽器(或同一瀏覽器不同版本)對HTML、CSS、JavaScript解析執行存在差異,導致頁面顯示異常或功能失效的問題。以下是常見問題及系統的處理方案: 一、常見兼容性問題…

Android組件化實現方案深度分析

組件化是解決大型應用代碼臃腫、耦合嚴重、編譯緩慢、團隊協作困難等問題的關鍵架構手段,其核心在于 模塊化拆分、解耦、獨立開發和按需集成。 一、 組件化的核心目標與價值 解耦與高內聚: 將龐大單體應用拆分為功能獨立、職責單一的模塊(組件…

外賣:重構餐飲的線上服務密碼

外賣不是 “把堂食菜裝進盒子送出去”,而是 “用線上化服務重構餐飲與用戶連接” 的經營模式 —— 它的核心,是 “讓用戶在家也能吃到‘像在店里一樣好’的體驗”。一、外賣的底層邏輯用戶點外賣,本質是 “想在家獲得‘餐廳級體驗’”&#x…

C++——高性能組件

文章目錄一、什么是高性能組件1.1 C 中高性能組件的核心設計原則1.2 常見的 C 高性能組件 / 庫舉例1.3 實現高性能組件的關鍵工具二、定時器2.1 什么是用戶態定時器2.2 為什么要使用用戶態定時器2.3 高性能用戶態定時器的實現原理2.3.1 訓練營2.3.1.1 問題解析2.3.1.2 模擬問答…

【軟考中級網絡工程師】知識點之 UDP 協議:網絡通信中的高效輕騎兵

目錄一、UDP 協議簡介二、UDP 協議特點2.1 無連接性2.2 不可靠性2.3 面向數據報2.4 低開銷2.5 廣播支持三、UDP 協議工作原理3.1 UDP 報文格式3.2 UDP 數據傳輸過程四、UDP 協議應用場景4.1 實時音視頻傳輸4.2 在線游戲4.3 DNS 查詢4.4 其他應用場景五、UDP 與 TCP 對比5.1 可靠…

【Node.js從 0 到 1:入門實戰與項目驅動】2.1 安裝 Node.js 與 npm(Windows/macOS/Linux 系統的安裝步驟)

文章目錄 第 2 章:環境搭建 —— 準備你的開發工具 2.1 安裝 Node.js 與 npm(Windows/macOS/Linux 系統的安裝步驟) 一、通用安裝前檢查 二、Windows 系統安裝步驟 方法 1:通過官方安裝包(推薦) 方法 2:通過 nvm-windows 管理多版本(進階) 三、macOS 系統安裝步驟 方法…