一、 圖像數據的介紹
1.1 灰度圖像
從這里開始我們進入到了圖像數據相關的部分,也是默認你有之前復試班計算機視覺相關的知識,但是一些基礎的概念我仍然會提。
昨天我們介紹了minist這個經典的手寫數據集,作為圖像數據,相較于結構化數據(表格數據)他的特點在于他每個樣本的的形狀并不是(特征數,),而是(寬,高,通道數)
# 先繼續之前的代碼
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
# 設置隨機種子,確保結果可復現
torch.manual_seed(42)# 1. 數據預處理,該寫法非常類似于管道pipeline
# transforms 模塊提供了一系列常用的圖像預處理操作# 先歸一化,再標準化
transform = transforms.Compose([transforms.ToTensor(), # 轉換為張量并歸一化到[0,1]transforms.Normalize((0.1307,), (0.3081,)) # MNIST數據集的均值和標準差,這個值很出名,所以直接使用
])
import matplotlib.pyplot as plt# 2. 加載MNIST數據集,如果沒有會自動下載
train_dataset = datasets.MNIST(root='./data',train=True,download=True,transform=transform
)test_dataset = datasets.MNIST(root='./data',train=False,transform=transform
)
# 隨機選擇一張圖片,可以重復運行,每次都會隨機選擇
sample_idx = torch.randint(0, len(train_dataset), size=(1,)).item() # 隨機選擇一張圖片的索引
# len(train_dataset) 表示訓練集的圖片數量;size=(1,)表示返回一個索引;torch.randint() 函數用于生成一個指定范圍內的隨機數,item() 方法將張量轉換為 Python 數字
image, label = train_dataset[sample_idx] # 獲取圖片和標簽
# 可視化原始圖像(需要反歸一化)
def imshow(img):img = img * 0.3081 + 0.1307 # 反標準化npimg = img.numpy()plt.imshow(npimg[0], cmap='gray') # 顯示灰度圖像plt.show()print(f"Label: {label}")
imshow(image)
# 打印一張彩色圖像,用cifar-10數據集
import torch
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import numpy as np# 設置隨機種子確保結果可復現
torch.manual_seed(42)
# 定義數據預處理步驟
transform = transforms.Compose([transforms.ToTensor(), # 轉換為張量并歸一化到[0,1]transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) # 標準化處理
])# 加載CIFAR-10訓練集
trainset = torchvision.datasets.CIFAR10(root='./data',train=True,download=True,transform=transform
)# 創建數據加載器
trainloader = torch.utils.data.DataLoader(trainset,batch_size=4,shuffle=True
)# CIFAR-10的10個類別
classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')# 隨機選擇一張圖片
sample_idx = torch.randint(0, len(trainset), size=(1,)).item()
image, label = trainset[sample_idx]# 打印圖片形狀
print(f"圖像形狀: {image.shape}") # 輸出: torch.Size([3, 32, 32])
print(f"圖像類別: {classes[label]}")# 定義圖像顯示函數(適用于CIFAR-10彩色圖像)
def imshow(img):img = img / 2 + 0.5 # 反標準化處理,將圖像范圍從[-1,1]轉回[0,1]npimg = img.numpy()plt.imshow(np.transpose(npimg, (1, 2, 0))) # 調整維度順序:(通道,高,寬) → (高,寬,通道)plt.axis('off') # 關閉坐標軸顯示plt.show()# 顯示圖像
imshow(image)
二、 圖像相關的神經網絡的定義
考慮課程內容的推進,今日的內容只提定義,不涉及訓練和測試過程
2.1 黑白圖像模型的定義
# 先歸一化,再標準化
transform = transforms.Compose([transforms.ToTensor(), # 轉換為張量并歸一化到[0,1]transforms.Normalize((0.1307,), (0.3081,)) # MNIST數據集的均值和標準差,這個值很出名,所以直接使用
])
import matplotlib.pyplot as plt# 2. 加載MNIST數據集,如果沒有會自動下載
train_dataset = datasets.MNIST(root='./data',train=True,download=True,transform=transform
)test_dataset = datasets.MNIST(root='./data',train=False,transform=transform
)
# 定義兩層MLP神經網絡
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()device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device) # 將模型移至GPU(如果可用)from torchsummary import summary # 導入torchsummary庫
print("\n模型結構信息:")
summary(model, input_size=(1, 28, 28)) # 輸入尺寸為MNIST圖像尺寸
2.2 彩色圖像模型的定義
class MLP(nn.Module):def __init__(self, input_size=3072, hidden_size=128, num_classes=10):super(MLP, self).__init__()# 展平層:將3×32×32的彩色圖像轉為一維向量# 輸入尺寸計算:3通道 × 32高 × 32寬 = 3072self.flatten = nn.Flatten()# 全連接層self.fc1 = nn.Linear(input_size, hidden_size) # 第一層self.relu = nn.ReLU()self.fc2 = nn.Linear(hidden_size, num_classes) # 輸出層def forward(self, x):x = self.flatten(x) # 展平:[batch, 3, 32, 32] → [batch, 3072]x = self.fc1(x) # 線性變換:[batch, 3072] → [batch, 128]x = self.relu(x) # 激活函數x = self.fc2(x) # 輸出層:[batch, 128] → [batch, 10]return x# 初始化模型
model = MLP()device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device) # 將模型移至GPU(如果可用)from torchsummary import summary # 導入torchsummary庫
print("\n模型結構信息:")
summary(model, input_size=(3, 32, 32)) # CIFAR-10 彩色圖像(3×32×32)
from torch.utils.data import DataLoader# 定義訓練集的數據加載器,并指定batch_size
train_loader = DataLoader(dataset=train_dataset, # 加載的數據集batch_size=64, # 每次加載64張圖像shuffle=True # 訓練時打亂數據順序
)# 定義測試集的數據加載器(通常batch_size更大,減少測試時間)
test_loader = DataLoader(dataset=test_dataset,batch_size=1000,shuffle=False
)
@浙大疏錦行