Task:
1.彩色和灰度圖片測試和訓練的規范寫法:封裝在函數中
2.展平操作:除第一個維度batchsize外全部展平
3.dropout操作:訓練階段隨機丟棄神經元,測試階段eval模式關閉dropout
作業:仔細學習下測試和訓練代碼的邏輯,這是基礎,這個代碼框架后續會一直沿用,后續的重點慢慢就是轉向模型定義階段了。
1. 彩色和灰度圖片測試和訓練的規范寫法(封裝在函數中):
-
目的: 將數據預處理和加載過程封裝成函數,提高代碼的可讀性、可維護性和復用性。
-
關鍵步驟:
- 數據加載: 使用
torchvision.datasets
或自定義數據集類加載圖像數據。 - 數據預處理: 使用
torchvision.transforms
定義一系列圖像變換,例如:Resize()
:調整圖像大小。ToTensor()
:將圖像轉換為 Tensor,并將像素值歸一化到 [0, 1] 范圍。Normalize()
:對圖像進行標準化,使其具有零均值和單位方差。Grayscale()
:將彩色圖像轉換為灰度圖像。
- 數據增強(僅訓練集): 在訓練集上應用隨機變換,例如:
RandomHorizontalFlip()
:隨機水平翻轉圖像。RandomRotation()
:隨機旋轉圖像。RandomCrop()
:隨機裁剪圖像。
- 數據加載器: 使用
torch.utils.data.DataLoader
創建數據加載器,用于批量加載數據,并進行 shuffle 和多線程處理。
- 數據加載: 使用
-
函數示例:
import torch import torchvision from torchvision import transforms from torch.utils.data import DataLoaderdef load_data(data_dir, batch_size, is_train=True, grayscale=False):"""加載圖像數據,并進行預處理。Args:data_dir (str): 數據集目錄。batch_size (int): 批量大小。is_train (bool): 是否為訓練集。grayscale (bool): 是否轉換為灰度圖像。Returns:torch.utils.data.DataLoader: 數據加載器。"""transform_list = []if is_train:transform_list.append(transforms.RandomHorizontalFlip())transform_list.append(transforms.RandomRotation(10)) # 隨機旋轉transform_list.append(transforms.Resize((224, 224))) # 調整大小if grayscale:transform_list.append(transforms.Grayscale())transform_list.append(transforms.ToTensor())transform_list.append(transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])) # 標準化transform = transforms.Compose(transform_list)dataset = torchvision.datasets.ImageFolder(data_dir, transform=transform)data_loader = DataLoader(dataset, batch_size=batch_size, shuffle=is_train, num_workers=4)return data_loader
2. 展平操作:除第一個維度 batchsize 外全部展平
-
目的: 將卷積層或池化層的輸出轉換為一維向量,以便輸入到全連接層。
-
方法: 使用
torch.flatten(x, start_dim=1)
函數,從第二個維度開始展平。 -
示例:
import torchx = torch.randn(32, 64, 7, 7) # batch_size=32, 64個特征圖, 7x7大小 x_flattened = torch.flatten(x, start_dim=1) # 展平除 batch_size 以外的所有維度 print(x_flattened.shape) # 輸出: torch.Size([32, 3136]) (64 * 7 * 7 = 3136)
3. Dropout 操作:訓練階段隨機丟棄神經元,測試階段 eval 模式關閉 dropout
-
目的: 防止過擬合,提高模型的泛化能力。
-
原理: 在訓練過程中,隨機將一部分神經元的輸出設置為 0,迫使網絡學習更魯棒的特征。
-
實現: 使用
torch.nn.Dropout(p=0.5)
層,其中p
是丟棄概率。 -
關鍵點:
- 訓練階段:
model.train()
模式下,Dropout 層會隨機丟棄神經元。 - 測試階段:
model.eval()
模式下,Dropout 層會被禁用,所有神經元都會參與計算。 這確保了模型在測試時使用完整的網絡結構進行預測。
- 訓練階段:
-
示例:
import torch import torch.nn as nnclass MyModel(nn.Module):def __init__(self):super(MyModel, self).__init__()self.fc1 = nn.Linear(100, 50)self.dropout = nn.Dropout(p=0.5)self.fc2 = nn.Linear(50, 10)def forward(self, x):x = torch.relu(self.fc1(x))x = self.dropout(x)x = self.fc2(x)return xmodel = MyModel()# 訓練階段 model.train() x = torch.randn(32, 100) output = model(x)# 測試階段 model.eval() with torch.no_grad(): # 禁用梯度計算x = torch.randn(32, 100)output = model(x)
總結:
我理解了數據加載和預處理的重要性,以及如何使用 torchvision.transforms
和 torch.utils.data.DataLoader
來實現。 我也理解了展平操作的必要性,以及 Dropout 層在訓練和測試階段的不同行為。 這些都是構建深度學習模型的基礎,我會繼續深入學習和實踐。