深度学习基础实战使用MNIST数据集对图片分类
生活随笔
收集整理的這篇文章主要介紹了
深度学习基础实战使用MNIST数据集对图片分类
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本文代碼完全借鑒pytorch中文手冊
'''我們找到數據集,對數據做預處理,定義我們的模型,調整超參數,測試訓練,再通過訓練結果對超參數進行調整或者對模型進行調整。''' import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim #實現各種優化算法的庫 from torchvision import datasets,transformsBATCH_SIZE=512 #大概需要2G的顯存 EPOCHS=20 #總共訓練20次 DEVICE=torch.device("cuda" if torch.cuda.is_available() else "cpu") #讓torch判斷是否使用GPU#對數據進行預處理 transforms=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,),(0.3081,))]) #準備數據集,路徑是關于py文件的相對路徑 trainset=datasets.MNIST(root='./MNIST_data',train=True,download=False,transform=transforms)#加載數據集 train_loader=torch.utils.data.DataLoader(trainset,batch_size=BATCH_SIZE,shuffle=True)#準備測試集 testset=datasets.MNIST(root='./MNIST_data',train=True,download=False,transform=transforms)#加載測試集 test_loader=torch.utils.data.DataLoader(testset,batch_size=BATCH_SIZE,shuffle=True)#定義卷積神經網絡 class ConvNet(nn.Module):def __init__(self):super().__init__()#batch*1*28*28(每次會送入batch個樣本,輸入通道數1(黑白圖像)),圖像分辨率是28*28)#下面的卷積層Conv2d的第一個參數指輸入通道數,第二個參數指輸出通道數,第三個參數指卷積核的大小self.conv1=nn.Conv2d(1,10,5)self.conv2=nn.Conv2d(10,20,3)#下面的全連接層Linear的第一個參數指輸入通道數,第二個參數指輸出通道數self.fc1=nn.Linear(20*10*10,500) #輸入通道數是2000,輸出通道數是500self.fc2=nn.Linear(500,10) #輸入通道數是500,輸出通道數是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(28×28的圖像經過一次核為5×5的卷積,輸出變為24×24)out=F.relu(out) #batch*10*24*24(激活函數ReLU不改變形狀)out=F.max_pool2d(out,2,2)#batch*10*24*24 -> batch*10*12*12(2×2的池化層會減半)out=self.conv2(out) #batch*10*12*12 -> batch*20*10*10(再卷積一次,核的大小是3)out=F.relu(out)out=out.view(in_size,-1) #batch*20*10*10 -> batch*2000(out的第二維是-1,說明是自動推算,本例中第二維是20*10*10)out=self.fc1(out) #batch*2000 -> batch*500out=F.relu(out) out=self.fc2(out) #batch*500 -> batch*10out=F.log_softmax(out,dim=1) #計算log(softmax(x)),用log是為了防止數過大。return out#我們實例化一個網絡,實例化后使用.to方法將網絡移動到GPU model=ConvNet().to(DEVICE)#優化器我們也直接選擇簡單暴力的Adam optimizer=optim.Adam(model.parameters())#定義一個訓練函數 def train(model,device,train_loader,optimizer,epoch):model.train() #啟用BatchNormalization和Dropout,將BatchNormalization和Dropout置為Truefor batch_idex,(data,target) in enumerate(train_loader): ##將迭代器的數據組成一個索引系列,并輸出索引和值,batch_diex是序號,后者是數據data,target=data.to(device),target.to(device) #在gpu上跑optimizer.zero_grad() #梯度清零output=model(data) #將數據放入模型loss=F.nll_loss(output,target) #計算損失函數loss.backward() #計算梯度optimizer.step()if (batch_idex+1)%30 == 0: #每訓練30個打印一次print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch,batch_idex*len(data),len(train_loader.dataset),100. * batch_idex/len(train_loader.dataset),loss.item()))#定義一個測試函數 def test(model,device,test_loader):model.eval() #不啟用BatchNormalization和Dropout,將BatchNormalization和Dropout置為Falsetest_loss=0correct=0with torch.no_grad():for data,target in test_loader:data,target=data.to(device),target.to(device) #在gpu上跑output=model(data)test_loss+=F.nll_loss(output,target,reduction='sum').item() #將一批的損失相加pred=output.max(1,keepdim=True)[1] #找到概率最大的下標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)))#下面開始訓練,這里就體現出封裝起來的好處了,只要寫兩行就可以了 for epoch in range(1,EPOCHS+1):train(model,DEVICE,train_loader,optimizer,epoch)test(model,DEVICE,test_loader)總結
以上是生活随笔為你收集整理的深度学习基础实战使用MNIST数据集对图片分类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓星星符号(安卓星星)
- 下一篇: 深度学习基本概念笔记