深度学习练手项目(一)-----利用PyTorch实现MNIST手写数字识别
生活随笔
收集整理的這篇文章主要介紹了
深度学习练手项目(一)-----利用PyTorch实现MNIST手写数字识别
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、前言
MNIST手寫數(shù)字識(shí)別程序就不過多贅述了,這個(gè)程序在深度學(xué)習(xí)中的地位跟C語言中的Hello World地位并駕齊驅(qū),雖然很基礎(chǔ),但很重要,是深度學(xué)習(xí)入門必備的程序之一。
二、MNIST數(shù)據(jù)集介紹
MNIST包括6萬張28*28的訓(xùn)練樣本,1萬張測試樣本。
三、PyTorch實(shí)現(xiàn)
3.1 定義超參數(shù)
# 定義超參數(shù) BATCH_SIZE=512 #大概需要2G的顯存 EPOCHS=20 # 總共訓(xùn)練批次 DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 讓torch判斷是否使用GPU,建議使用GPU環(huán)境,因?yàn)闀?huì)快很多3.2 導(dǎo)入訓(xùn)練、測試數(shù)據(jù)
# 分別導(dǎo)入訓(xùn)練、測試數(shù)據(jù),PyTorch中已經(jīng)集成了MNIST數(shù)據(jù)集,我們只需要DataLoader導(dǎo)入即可 train_loader = torch.utils.data.DataLoader(datasets.MNIST('data', train=True, download=True, transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,))])),batch_size=BATCH_SIZE, shuffle=True)test_loader = torch.utils.data.DataLoader(datasets.MNIST('data', train=False, transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,))])),batch_size=BATCH_SIZE, shuffle=True)3.3 搭建深度學(xué)習(xí)網(wǎng)絡(luò)模型
class ConvNet(nn.Module):def __init__(self):super().__init__()# batch*1*28*28(每次會(huì)送入batch個(gè)樣本,輸入通道數(shù)1(黑白圖像),圖像分辨率是28x28)# 下面的卷積層Conv2d的第一個(gè)參數(shù)指輸入通道數(shù),第二個(gè)參數(shù)指輸出通道數(shù),第三個(gè)參數(shù)指卷積核的大小self.conv1 = nn.Conv2d(1, 10, 5) # 輸入通道數(shù)1,輸出通道數(shù)10,核的大小5self.conv2 = nn.Conv2d(10, 20, 3) # 輸入通道數(shù)10,輸出通道數(shù)20,核的大小3# 下面的全連接層Linear的第一個(gè)參數(shù)指輸入通道數(shù),第二個(gè)參數(shù)指輸出通道數(shù)self.fc1 = nn.Linear(20*10*10, 500) # 輸入通道數(shù)是2000,輸出通道數(shù)是500self.fc2 = nn.Linear(500, 10) # 輸入通道數(shù)是500,輸出通道數(shù)是10,即10分類def forward(self,x):in_size = x.size(0) # 在本例中in_size=512,也就是BATCH_SIZE的值。輸入的x可以看成是512*1*28*28的張量。out = self.conv1(x) # batch*1*28*28 -> batch*10*24*24(28x28的圖像經(jīng)過一次核為5x5的卷積,輸出變?yōu)?4x24)out = F.relu(out) # batch*10*24*24(激活函數(shù)ReLU不改變形狀))out = F.max_pool2d(out, 2, 2) # batch*10*24*24 -> batch*10*12*12(2*2的池化層會(huì)減半)out = self.conv2(out) # batch*10*12*12 -> batch*20*10*10(再卷積一次,核的大小是3)out = F.relu(out) # batch*20*10*10out = out.view(in_size, -1) # batch*20*10*10 -> batch*2000(out的第二維是-1,說明是自動(dòng)推算,本例中第二維是20*10*10)out = self.fc1(out) # batch*2000 -> batch*500out = F.relu(out) # batch*500out = self.fc2(out) # batch*500 -> batch*10out = F.log_softmax(out, dim=1) # 計(jì)算log(softmax(x))return out3.4 確定要使用的優(yōu)化算法
這里使用簡單粗暴的Adam
model = ConvNet().to(DEVICE) optimizer = optim.Adam(model.parameters())3.5 定義訓(xùn)練函數(shù)
def train(model, device, train_loader, optimizer, epoch):model.train()for batch_idx, (data, target) in enumerate(train_loader):data, target = data.to(device), target.to(device)optimizer.zero_grad()output = model(data)loss = F.nll_loss(output, target)loss.backward()optimizer.step()if(batch_idx+1)%30 == 0: print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset),100. * batch_idx / len(train_loader), loss.item()))3.6 定義測試函數(shù)
def test(model, device, test_loader):model.eval()test_loss = 0correct = 0with torch.no_grad():for data, target in test_loader:data, target = data.to(device), target.to(device)output = model(data)test_loss += F.nll_loss(output, target, reduction='sum').item() # 將一批的損失相加pred = output.max(1, keepdim=True)[1] # 找到概率最大的下標(biāo)correct += pred.eq(target.view_as(pred)).sum().item()test_loss /= len(test_loader.dataset)print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset),100. * correct / len(test_loader.dataset)))3.7 訓(xùn)練并測試
for epoch in range(1, EPOCHS + 1):train(model, DEVICE, train_loader, optimizer, epoch)test(model, DEVICE, test_loader) 與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的深度学习练手项目(一)-----利用PyTorch实现MNIST手写数字识别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 两个企业级产品设计思路:流程效率指标功能
- 下一篇: 2021年中国电影营销数字化发展分析