在樹莓派上使用numpy實現簡單的MLP神經網絡推理,pytorch在服務器或PC上訓練好模型保存成numpy格式的數據,推理在樹莓派上加載模型

這幾天又在玩樹莓派,先是搞了個物聯網,又在嘗試在樹莓派上搞一些簡單的神經網絡,這次搞得是mlp識別mnist手寫數字識別

訓練代碼在電腦上,cpu就能訓練,很快的:

 1 import torch
 2 import torch.nn as nn
 3 import torch.optim as optim
 4 from torchvision import datasets, transforms
 5 
 6 # 設置隨機種子
 7 torch.manual_seed(42)
 8 
 9 # 定義MLP模型
10 class MLP(nn.Module):
11     def __init__(self):
12         super(MLP, self).__init__()
13         self.fc1 = nn.Linear(784, 256)
14         self.fc2 = nn.Linear(256, 128)
15         self.fc3 = nn.Linear(128, 10)
16 
17     def forward(self, x):
18         x = x.view(-1, 784)
19         x = torch.relu(self.fc1(x))
20         x = torch.relu(self.fc2(x))
21         x = self.fc3(x)
22         return x
23 
24 # 加載MNIST數據集
25 transform = transforms.Compose([
26     transforms.ToTensor(),
27     # transforms.Normalize((0.1307,), (0.3081,))
28 ])
29 
30 train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
31 test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)
32 
33 train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
34 test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False)
35 
36 # 創建模型實例
37 model = MLP()
38 
39 # 定義損失函數和優化器
40 criterion = nn.CrossEntropyLoss()
41 optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)
42 
43 # 訓練模型
44 def train(model, train_loader, optimizer, criterion, epochs):
45     model.train()
46     for epoch in range(1, epochs + 1):
47         for batch_idx, (data, target) in enumerate(train_loader):
48             optimizer.zero_grad()
49             output = model(data)
50             loss = criterion(output, target)
51             loss.backward()
52             optimizer.step()
53             
54             if batch_idx % 100 == 0:
55                 print('Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
56                     epoch, batch_idx * len(data), len(train_loader.dataset),
57                     100. * batch_idx / len(train_loader), loss.item()))
58 
59 # 訓練模型
60 train(model, train_loader, optimizer, criterion, epochs=5)
61 
62 # 保存模型爲NumPy格式
63 numpy_model = {}
64 numpy_model['fc1.weight'] = model.fc1.weight.detach().numpy()
65 numpy_model['fc1.bias'] = model.fc1.bias.detach().numpy()
66 numpy_model['fc2.weight'] = model.fc2.weight.detach().numpy()
67 numpy_model['fc2.bias'] = model.fc2.bias.detach().numpy()
68 numpy_model['fc3.weight'] = model.fc3.weight.detach().numpy()
69 numpy_model['fc3.bias'] = model.fc3.bias.detach().numpy()
70 
71 # 保存爲NumPy格式的數據
72 import numpy as np
73 np.savez('mnist_model.npz', **numpy_model)

然後需要自己倒出一些圖片在dataset裏:我保存在了mnist_pi文件夾下,“_”後面的是標籤,主要是在pc端導出保存到樹莓派下

 

樹莓派推理端的代碼,需要numpy手動重新搭建網絡,然後加載那些保存的矩陣參數,做矩陣乘法和加法

 1 import numpy as np
 2 import os
 3 from PIL import Image
 4 
 5 # 加載模型
 6 model_data = np.load('mnist_model.npz')
 7 weights1 = model_data['fc1.weight']
 8 biases1 = model_data['fc1.bias']
 9 weights2 = model_data['fc2.weight']
10 biases2 = model_data['fc2.bias']
11 weights3 = model_data['fc3.weight']
12 biases3 = model_data['fc3.bias']
13 
14 # 進行推理
15 def predict(image, weights1, biases1,weights2, biases2,weights3, biases3):
16     image = image.flatten()/255  # 將輸入圖像展平並進行歸一化
17     output = np.dot(weights1, image) + biases1
18     output = np.dot(weights2, output) + biases2
19     output = np.dot(weights3, output) + biases3
20     predicted_class = np.argmax(output)
21     return predicted_class
22 
23 
24 
25 
26 folder_path = './mnist_pi'  # 替換爲圖片所在的文件夾路徑
27 def infer_images_in_folder(folder_path):
28     for file_name in os.listdir(folder_path):
29         file_path = os.path.join(folder_path, file_name)
30         if os.path.isfile(file_path) and file_name.endswith(('.jpg', '.jpeg', '.png')):
31             image = Image.open(file_path)
32             label = file_name.split(".")[0].split("_")[1]
33             image = np.array(image)
34             print("file_path:",file_path,"img size:",image.shape,"label:",label)
35             predicted_class = predict(image, weights1, biases1,weights2, biases2,weights3, biases3)
36             print('Predicted class:', predicted_class)
37         
38 infer_images_in_folder(folder_path)

 

結果:

效果還不錯:

 

這次內容就到這裏了,下次爭取做一個卷積的神經網絡在樹莓派上推理,然後爭取做一個目標檢測的模型在樹莓派上 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章