iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0
AI & Data

「AI之旅:Python、Keras、PyTorch」 - 深度學習與數據入門挑戰系列 第 12

【Day12】PyTorch - 今晚我想來點不一樣的

  • 分享至 

  • xImage
  •  

今天我們將開始Pytorch部分,前面使用keras主要是因為他好上手好入門,但是他在優化部分作太好,時常都是資料丟一丟,模型隨意編能跑就跑,糊裡糊塗就跑完了,因此這裡我們選用pytorch作為進階,下面就讓我們來說明

  • PyTorch簡介
  • 模型說明
  • 實際操作

PyTorch簡介

為什麼用PyTorch? 主要有幾點

  • 動態計算圖:PyTorch使用動態計算圖,使模型構建和調試更加直觀和靈活。
  • Python風格:PyTorch基於Python,具有直觀的API,容易上手和學習。
  • Autograd:PyTorch的Autograd模組可以自動計算梯度,簡化了反向傳播的實現。
  • 活躍的社群:PyTorch**擁有龐大活躍的社群,提供豐富的教程、示例和擴展庫。
  • 適用於研究和生產:PyTorch同樣適用於研究實驗和實際部署中的生產環境。

前面有大概介紹過這裡就不多介紹

下面讓我們來安裝

  • PyTorch安裝
    使用pip:在命令字元(win11終端機)中運行
pip install torch torchvision

以安裝PyTorch及其相關庫。

以前面提到過win+R 叫出CMD方式

Tensor基礎

PyTorch張量
前面有講過關於張量這裡就不做解釋,忘記的可以往前複習~
PyTorch的張量類似於NumPy陣列,但具有GPU支持,我們可以建立、操作和索引張量,例如:

import torch

# 創建張量
x = torch.tensor([1.0, 2.0, 3.0])

# 張量操作
y = x + 1
z = torch.sin(x)

# 張量索引
element = x[0]
  • Autograd
    自動求導(Autograd)

PyTorchAutograd模組允許我們自動計算梯度,無需手動編寫反向傳播,如下:

import torch

# 創建張量並跟踪梯度
x = torch.tensor(2.0, requires_grad=True)
y = x**2

# 計算梯度
y.backward()

# 輸出梯度
print(x.grad)  # 輸出為4.0

模型說明

下面來介紹模型

簡單的神經網絡

  • 構建一個簡單的神經網絡

我們可以使用PyTorchnn.Module類來構建神經網絡,定義網絡結構、前向傳播和損失函數,如下:

import torch
import torch.nn as nn

# 定義一個簡單的神經網絡
class SimpleNet(nn.Module):
    def __init__(self):
        super(SimpleNet, self).__init__()
        self.fc = nn.Linear(2, 1)

    def forward(self, x):
        return self.fc(x)

# 創建網絡實例
net = SimpleNet()

神經網路訓練部分

跟前面keras一樣我們可以定義優化器(如SGD或Adam),並構建訓練循環來訓練神經網絡,如下:

import torch
import torch.nn as nn
import torch.optim as optim

# 定義損失函數和優化器
criterion = nn.MSELoss()
optimizer = optim.SGD(net.parameters(), lr=0.01)

# 訓練循環
for epoch in range(100):
    optimizer.zero_grad()  # 梯度清零
    output = net(input_data)  # 前向傳播
    loss = criterion(output, target)  # 計算損失
    loss.backward()  # 反向傳播
    optimizer.step()  # 更新參數



實際操作

這裡我們用CNN作為一開始示範,我們以前面用過手寫數字當作訓練集。

以下是對這段程式碼的解釋:

  • 引入必要的函式庫
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
from tqdm import tqdm  # 導入tqdm函數庫
import matplotlib.pyplot as plt
  • 定義數據預處理操作
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])

這裡定義了數據預處理操作,包括將圖像轉換為Tensor格式並進行歸一化處理。

  • 下載訓練集和測試集
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)

testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False)

這裡下載了MNIST數據集的訓練集和測試集,並使用上述定義的預處理操作。

  • 定義卷積神經網絡模型
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 3)
        self.conv2 = nn.Conv2d(32, 64, 3)
        self.fc1 = nn.Linear(64 * 5 * 5, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.max_pool2d(x, 2)
        x = F.relu(self.conv2(x))
        x = F.max_pool2d(x, 2)
        x = x.view(-1, 64 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

net = Net()

這裡定義了一個簡單的CNN模型,包括兩個卷積層和兩個全連接層。

  • 定義損失函數和優化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

在這裡選擇了損失函數(CrossEntropyLoss)和優化器(SGD)。

  • 訓練模型
train_losses = []  # 儲存每個epoch的訓練損失
for epoch in range(10):  # 訓練10個epoch
    running_loss = 0.0
    for i, data in enumerate(tqdm(trainloader), 0):  # 使用tqdm來顯示進度條
        inputs, labels = data
        optimizer.zero_grad()
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    train_loss = running_loss / len(trainloader)
    train_losses.append(train_loss)
    print(f'Epoch {epoch + 1}, Training Loss: {train_loss}')

print('Finished Training')

這段程式碼用於訓練CNN模型,模型將訓練10個epoch,每個epoch使用訓練集進行訓練,並計算每個epoch的訓練損失。

  • 測試模型性能
correct = 0
total = 0
test_losses = []  # 儲存每個epoch的測試損失
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()
        test_loss = criterion(outputs, labels)
        test_losses.append(test_loss.item())

print(f'Accuracy on test images: {100 * correct / total}%')

這段程式碼用於測試已訓練的CNN模型的性能,計算模型在測試集上的準確率。

  • 繪製Loss圖
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend()
plt.show()

這段程式碼用於繪製訓練過程中的訓練損失和測試損失的圖表,以便可視化模型的性能。

今天真的是手很殘....連續2次還沒存草稿就把頁面按掉QQ,以上就是今天的部分,會發現pytorch裡相較於keras定義模型多很多,一開始看到頭有點痛,不過以pytorch可以看到更多細節!希望今天內容有幫助到你~明天見!


上一篇
【Day11】變種RNN?:用LSTM進行情感分類的模型實作
下一篇
【Day13】自製訓練集:爬蟲? 為什麼要爬蟲?
系列文
「AI之旅:Python、Keras、PyTorch」 - 深度學習與數據入門挑戰22
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言