PyTorch之LeNet-5:利用PyTorch实现最经典的LeNet-5卷积神经网络对手写数字图片识别CNN
生活随笔
收集整理的這篇文章主要介紹了
PyTorch之LeNet-5:利用PyTorch实现最经典的LeNet-5卷积神经网络对手写数字图片识别CNN
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
PyTorch之LeNet-5:利用PyTorch實現最經典的LeNet-5卷積神經網絡對手寫數字圖片識別CNN
?
?
?
目錄
訓練過程
代碼設計
?
?
?
?
訓練過程
?
?
代碼設計
#PyTorch:利用PyTorch實現最經典的LeNet卷積神經網絡對手寫數字進行識別CNN——Jason niu import torch import torch.nn as nn import torch.optim as optimclass LeNet(nn.Module):def __init__(self):super(LeNet,self).__init__()#Conv1 和 Conv2:卷積層,每個層輸出在卷積核(小尺寸的權重張量)和同樣尺寸輸入區域之間的點積;self.conv1 = nn.Conv2d(1,10,kernel_size=5)self.conv2 = nn.Conv2d(10,20,kernel_size=5)self.conv2_drop = nn.Dropout2d()self.fc1 = nn.Linear(320,50)self.fc2 = nn.Linear(50,10)def forward(self,x):x = F.relu(F.max_pool2d(self.conv1(x),2)) #使用 max 運算執行特定區域的下采樣(通常 2x2 像素);x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)),2))x = x.view(-1, 320)x = F.relu(self.fc1(x)) #修正線性單元函數,使用逐元素的激活函數 max(0,x);x = F.dropout(x, training=self.training) #Dropout2D隨機將輸入張量的所有通道設為零。當特征圖具備強相關時,dropout2D 提升特征圖之間的獨立性;x = self.fc2(x)return F.log_softmax(x, dim=1) #將 Log(Softmax(x)) 函數應用到 n 維輸入張量,以使輸出在 0 到 1 之間。#創建 LeNet 類后,創建對象并移至 GPU model = LeNet()criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(),lr = 0.005, momentum = 0.9) #要訓練該模型,我們需要使用帶動量的 SGD,學習率為 0.01,momentum 為 0.5。import os from torch.autograd import Variable import torch.nn.functional as Fcuda_gpu = torch.cuda.is_available() def train(model, epoch, criterion, optimizer, data_loader):model.train()for batch_idx, (data, target) in enumerate(data_loader):if cuda_gpu:data, target = data.cuda(), target.cuda()model.cuda()data, target = Variable(data), Variable(target)output = model(data)optimizer.zero_grad()loss = criterion(output, target)loss.backward()optimizer.step()if (batch_idx+1) % 400 == 0:print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, (batch_idx+1) * len(data), len(data_loader.dataset),100. * (batch_idx+1) / len(data_loader), loss.data[0]))from torchvision import datasets, transformsbatch_num_size = 64 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_num_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_num_size, shuffle=True)def test(model, epoch, criterion, data_loader):model.eval()test_loss = 0correct = 0for data, target in data_loader:if cuda_gpu:data, target = data.cuda(), target.cuda()model.cuda()data, target = Variable(data), Variable(target)output = model(data)test_loss += criterion(output, target).data[0]pred = output.data.max(1)[1] # get the index of the max log-probabilitycorrect += pred.eq(target.data).cpu().sum()test_loss /= len(data_loader) # loss function already averages over batch sizeacc = correct / len(data_loader.dataset)print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(data_loader.dataset), 100. * acc))return (acc, test_loss)epochs = 5 #僅僅需要 5 個 epoch(一個 epoch 意味著你使用整個訓練數據集來更新訓練模型的權重),就可以訓練出一個相當準確的 LeNet 模型。 #這段代碼檢查可以確定文件中是否已有預訓練好的模型。有則加載;無則訓練一個并保存至磁盤。 if (os.path.isfile('pretrained/MNIST_net.t7')):print ('Loading model')model.load_state_dict(torch.load('pretrained/MNIST_net.t7', map_location=lambda storage, loc: storage))acc, loss = test(model, 1, criterion, test_loader) else:print ('Training model') #打印出該模型的信息。打印函數顯示所有層(如 Dropout 被實現為一個單獨的層)及其名稱和參數。for epoch in range(1, epochs + 1):train(model, epoch, criterion, optimizer, train_loader)acc, loss = test(model, 1, criterion, test_loader)torch.save(model.state_dict(), 'pretrained/MNIST_net.t7') print (type(t.cpu().data))#以使用 .cpu() 方法將張量移至 CPU(或確保它在那里)。 #或當 GPU 可用時(torch.cuda. 可用),使用 .cuda() 方法將張量移至 GPU。你可以看到張量是否在 GPU 上,其類型為 torch.cuda.FloatTensor。 #如果張量在 CPU 上,則其類型為 torch.FloatTensor。 if torch.cuda.is_available():print ("Cuda is available")print (type(t.cuda().data)) else:print ("Cuda is NOT available")if torch.cuda.is_available():try:print(t.data.numpy())except RuntimeError as e:"you can't transform a GPU tensor to a numpy nd array, you have to copy your weight tendor to cpu and then get the numpy array" print(type(t.cpu().data.numpy())) print(t.cpu().data.numpy().shape) print(t.cpu().data.numpy())data = model.conv1.weight.cpu().data.numpy() print (data.shape) print (data[:, 0].shape)kernel_num = data.shape[0]fig, axes = plt.subplots(ncols=kernel_num, figsize=(2*kernel_num, 2))for col in range(kernel_num):axes[col].imshow(data[col, 0, :, :], cmap=plt.cm.gray) plt.show()相關文章
LeNet-5 is our latest convolutional network designed for handwritten and machine-printed character recognition.
總結
以上是生活随笔為你收集整理的PyTorch之LeNet-5:利用PyTorch实现最经典的LeNet-5卷积神经网络对手写数字图片识别CNN的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DL之LeNet-5:LeNet-5算法
- 下一篇: py之textgenrnn:Python