1. 數據準備
首先,我們需要準備手寫數字的數據集。在這裡,我們將使用MNIST數據集,它包含了60000個訓練樣本和10000個測試樣本,每個樣本都是一個28x28像素的灰度圖像,表示一個手寫數字。我們可以使用pytorch內置的torchvision庫來下載和加載MNIST數據集。
``` python
import torchimport torchvisionimport torchvision.transforms as transforms# 定义数据转换transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,), (0.5,))])# 加载训练集trainset = torchvision.datasets.MNIST( root ='./data', train=True,download=True, transform=transform)trainloader = torch.utils.data.DataLoader(trainset, batch _size=64,shuffle=True, num_workers=2)# 加载测试集testset = torchvision.datasets.MNIST(root='./data', train=False,download=True, transform=transform)testloader = torch.utils.data.DataLoader(testset, batch_size=64,shuffle=False, num_workers=2)```
在這段代碼中,我們定義了一個數據轉換transform,它將圖像轉換為張量,並對每個像素進行歸一化。然後,我們使用torchvision.datasets.MNIST函數加載MNIST數據集,設置訓練集和測試集的參數,使用DataLoader函數將數據集轉換為可迭代的數據加載器。
2. 構建模型
接下來,我們需要構建一個循環神經網絡LSTM模型。在這裡,我們將使用pytorch內置的nn.LSTM模塊來實現。
import torch.nn as nnclass LSTM(nn.Module): def __init__(self, input_dim, hidden_dim, layer_dim, output_dim):super(LSTM, self).__init__()# 输入维度self.input_dim = input_dim# 隐藏层维度self.hidden_dim = hidden_dim# LSTM层数self.layer_dim = layer_dim# LSTMself.lstm = nn.LSTM(input_dim, hidden_dim, layer_dim, batch_first=True)# 输出层self.fc = nn.Linear(hidden_dim, output_dim)def forward(self, x):# 初始化隐藏状态和单元状态h0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_()c0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_()# 前向传播out, (hn, cn) = self.lstm(x, (h0.detach(), c0.detach()))# 取最后一个时间步的输出out = self.fc(out[:, -1, :])return out在這段代碼中,我們定義了一個LSTM類,它繼承自nn.Module類,重寫了__init__和forward方法。在__init__方法中,我們定義了LSTM的輸入維度、隱藏層維度、LSTM層數和輸出維度,並使用nn.LSTM模塊構建了LSTM層和輸出層。在forward方法中,我們首先初始化了隱藏狀態和單元狀態,然後將輸入x傳入LSTM層,得到輸出out和最後一個時間步的隱藏狀態和單元狀態hn和cn,最後將out傳入輸出層得到預測結果。
3. 訓練模型
接下來,我們需要訓練我們的模型。在這裡,我們將使用交叉熵損失函數和隨機梯度下降優化器。
```python
# 定义模型、损失函数和优化器input_dim = 28hidden_dim = 100layer_dim = 1output_dim = 10model = LSTM(input_dim, hidden_dim, layer_dim, output_dim)criterion = nn.CrossEntropyLoss()learning_rate = 0.1optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)# 训练模型num_epochs = 5for epoch in range(num_epochs):for i, (images, labels) in enumerate(trainloader):# 将数据加载到GPU上images = images.view(-1, 28, 28).requires_grad_(). cuda ()labels = labels.cuda()# 前向传播outputs = model(images)# 计算损失loss = criterion(outputs, labels)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()# 每100个batch输出一次损失if (i+1) % 100 == 0:print('Epoch [{}/{}], Batch [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, i+1, len(trainloader), loss.item()))```
在這段代碼中,我們首先定義了模型、損失函數和優化器。然後,我們使用for循環和enumerate函數遍歷訓練集中的每個batch,將數據加載到GPU上,進行前向傳播,計算損失,進行反向傳播和優化。最後,我們每100個batch輸出一次損失。
4. 測試模型
最後,我們需要測試我們的模型。在這裡,我們將使用測試集來評估模型的性能。
```python
# 测试模型correct = 0total = 0with torch.no_grad():for images, labels in testloader:# 将数据加载到GPU上images = images.view(-1, 28, 28).cuda()labels = labels.cuda()# 前向传播outputs = model(images)# 取预测结果中最大值的索引作为预测标签_, predicted = torch.max(outputs.data, 1)# 统计正确预测的数量和总数量total += labels.size(0)correct += (predicted == labels).sum().item()print('Test Accuracy of the model on the 10000 test images: {} %'.format(100 * correct / total))```
在這段代碼中,我們首先定義了correct和total變量,用於統計正確預測的數量和總數量。然後,我們使用with torch.no_grad()語句禁用梯度計算,遍歷測試集中的每個樣本,進行前向傳播,取預測結果中最大值的索引作為預測標籤,統計正確預測的數量和總數量。最後,我們輸出模型在測試集上的準確率。
没有评论:
发表评论