Machine Learning
Full Course

講師 - 呂家睿
- 建中資訊38屆學術長+副社
- 玩雀魂
- 頭像是應急食品
- 被電爛
- 有問題歡迎來問我啊

- Fastapi
- Qt(C++)
- 數學好難
- 一點點sandbox
- Machine Learning
- discord bot
- 打開電腦
學術力

講師 - 林瑋浩
成功電研38屆教學
- 擅長寫O(2ⁿ)演算法
- 不會數學
- 回訊息很快
- C++
- Python
littleWeb前端- Discord bot
Bongosort- Machine Learning
- Godot
學術力


CNN
CNN



Convolutional Neural Network
- 卷基層
- 池化層
- 全連接層
一種專門處理圖像的神經網路,中文叫做「卷積」神經網路
CNN - 卷積層
在上次的課程中我們做mnist資料集(手寫數字)時我們是把每個像素都傳進去分析

28 * 28 = 724 px

6904 * 4609 = 31866626

CNN - 卷積層
卷積是一種數學運算,一種有點恐怖的數學運算
在這一層我們會把我們的圖像跟特徵檢測器做卷積運算,然後得到一個特徵圖

這裡我們指的卷積嚴格來說不是數學的這個卷積
CNN - 卷積層
其實我們人在看照片的時候並不是一個像素一個像素看,而是以小圖形判斷大圖形,以大圖形判斷圖像內容

BAD
GOOD

CNN - 卷積層
所以我們會用不只一種特徵偵測器來幫我們找不同的小形狀

然後我們用一次ReLU去掉負值

ReLU
- 最常用的激活函數
- 非常快
- 導數為1是個好東西
CNN - 池化層
雖然我們現在已經改成用小圖形來判斷,但資料量還是太大了需要減少
Max Pooling:
非常簡單,在2x2的格子裡面取值最大的

Average Pooling:
在2x2的格子裡面平均值
CNN
我們會把前面兩部重複好幾次再把它攤平,建構普通的神經網路

Code
conv
恩正常來講不會這樣寫,但我還是展示一下最原始的寫法幫助你們了解
import numpy as np
image = np.random.rand(5, 5)
kernel = np.array([[1, 0, -1],
[1, 0, -1],
[1, 0, -1]])
output = np.zeros((3, 3))
for i in range(3):
for j in range(3):
chunk = image[i:i+3, j:j+3]
output[i, j] = np.sum(chunk * kernel)image
| 1 | 0 | -1 |
|---|---|---|
| 1 | 0 | -1 |
| 1 | 0 | -1 |
pool
恩正常來講不會這樣寫,但我還是展示一下最原始的寫法幫助你們了解
import numpy as np
feature_map = np.random.rand(4, 4)
output = np.zeros((2, 2))
for i in range(0, 4, 2):
for j in range(0, 4, 2):
block = feature_map[i:i+2, j:j+2]
output[i//2, j//2] = np.max(block)
真正在寫的時候feature_map會是上一頁得到的output
實作
實作
我們今天要來用CIFAR-10資料集,這是一個很經典的圖像資料集,包含10個類別的圖像

Code
pip install torchvision首先我們要取得資料集
這裡面有一些常用資料集
import torch
import torch.nn as nn
import torchvision
from torchvision.transforms import transforms
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
num_epochs = 5
batch_size = 4
learning_rate = 0.001
transform = transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
train_dataset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
test_dataset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
epoch 世代
batch size 資料分群
learning rate 學習率
建立一個把圖片變成張量的工具,0.5是標準差
取得訓練和測試的資料集
Code
簡單處理一下資料內容還有讓資料可以呈現
classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
def imshow(img):
img = img / 2 + 0.5
npimg = img.numpy()
plt.imshow(np.transpose(npimg, (1, 2, 0)))
plt.show()
dataiter = iter(train_loader)
images, labels = next(dataiter)
imshow(torchvision.utils.make_grid(images))資料的十種類別
把資料轉換成numpy形式(才能用pyplot呈現)
從訓練資料中抓出幾張圖片
Code
class ConvNet(nn.Module):
def __init__(self):
self.conv1 = nn.Conv2d(3, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16*5*5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x))) # -> n, 6, 14, 14
x = self.pool(F.relu(self.conv2(x))) # -> n, 16, 5, 5
x = x.view(-1, 16 * 5 * 5) # -> n, 400
x = F.relu(self.fc1(x)) # -> n, 120
x = F.relu(self.fc2(x)) # -> n, 84
x = self.fc3(x) # -> n, 10
return x接下來我們要搞定核心的部分,也就是我們的模型
結構
前向傳播
卷積
池化
卷積
全連接層x3
Code
model = ConvNet().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
n_total_steps = len(train_loader)
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
images = images.to(device)
labels = labels.to(device)
outputs = model(images)
loss = criterion(outputs, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (i+1) % 2000 == 0:
print (f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{n_total_steps}], Loss: {loss.item():.4f}')
print('Finished Training')
PATH = './cnn.pth'
torch.save(model.state_dict(), PATH)有了模型之後我們可以開始訓練
接模型
optim跟損失函數
前向傳播
後向傳播
可以把我們的模型存起來
拿資料
Code
with torch.no_grad():
n_correct = 0
n_samples = 0
n_class_correct = [0 for i in range(10)]
n_class_samples = [0 for i in range(10)]
for images, labels in test_loader:
images = images.to(device)
labels = labels.to(device)
outputs = model(images)
# max returns (value ,index)
_, predicted = torch.max(outputs, 1)
n_samples += labels.size(0)
n_correct += (predicted == labels).sum().item()
for i in range(batch_size):
label = labels[i]
pred = predicted[i]
if (label == pred):
n_class_correct[label] += 1
n_class_samples[label] += 1
acc = 100.0 * n_correct / n_samples
print(f'Accuracy of the network: {acc} %')
for i in range(10):
acc = 100.0 * n_class_correct[i] / n_class_samples[i]
print(f'Accuracy of {classes[i]}: {acc} %')最後可以來測試
Code
如果電腦沒有gpu的話建議使用google colab,不然大概率會等到天荒地老
現在模型的預測率偏低,可以調調看參數或模型來看成效
看看能不能把accuracy調到80%以上
Code
import torchvision.models as models
import torch.nn as nn
model = models.resnet18(weights=models.ResNet18_Weights.DEFAULT)
for param in model.parameters():
param.requires_grad = False
model.fc = nn.Linear(in_features=model.fc.in_features, out_features=10)偷模型的部分
下課!!!!!

Machine Learning-6
By ck11300111呂家睿
Machine Learning-6
- 45