1.灰度圖像
作為圖像數據,相較于結構化數據(表格數據)他的特點在于他每個樣本的的形狀并不是(特征數,),而是(寬,高,通道數)
# 先繼續之前的代碼
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)
Label: 7上述是昨天的代碼,我們介紹了圖像數據的預處理,這是我們首次接觸圖像數據,他和之前的結構化數據有什么差異點呢?結構化數據(如表格)的形狀通常是 (樣本數, 特征數),例如 (1000, 5) 表示 1000 個樣本,每個樣本有 5 個特征。圖像數據的形狀更復雜,需要保留空間信息(高度、寬度、通道),因此不能直接用一維向量表示。其中顏色信息往往是最開始輸入數據的通道的含義,因為每個顏色可以用紅綠藍三原色表示,因此一般輸入數據的通道數是 3。維度索引 含義 數值說明
0 通道數(Channels) 1 表示這是一張灰度圖(僅有一個顏色通道,如黑白照片)。
如果是彩色圖(如RGB),通道數為 3。
1 高度(Height) 28 表示圖像的垂直像素數為28像素。
2 寬度(Width) 28 表示圖像的水平像素數為28像素。
MNIST 數據集是手寫數字的 灰度圖像,每個像素點的取值范圍為 0-255(黑白程度),因此 通道數為 1。圖像尺寸統一為 28×28 像素。# 打印下圖片的形狀
image.shape
torch.Size([1, 28, 28])
1.2 彩色圖像
在 PyTorch 中,圖像數據的形狀通常遵循 (通道數, 高度, 寬度) 的格式(即 Channel First 格式),這與常見的 (高度, 寬度, 通道數)(Channel Last,如 NumPy 數組)不同。---注意順序關系,注意點:如果用matplotlib庫來畫圖,需要轉換下順序,我們后續介紹
模型輸入通常需要 批次維度(Batch Size),形狀變為 (批次大小, 通道數, 高度, 寬度)。例如,批量輸入 10 張 MNIST 圖像時,形狀為 (10, 1, 28, 28)。
# 打印一張彩色圖像,用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.黑白圖像模型的定義
# 先歸一化,再標準化
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圖像尺寸模型結構信息:
----------------------------------------------------------------Layer (type) Output Shape Param #
================================================================Flatten-1 [-1, 784] 0Linear-2 [-1, 128] 100,480ReLU-3 [-1, 128] 0Linear-4 [-1, 10] 1,290
================================================================
Total params: 101,770
Trainable params: 101,770
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 0.01
Params size (MB): 0.39
Estimated Total Size (MB): 0.40
@浙大疏錦行