1 图片channels_【深度学习】卷积神经网络图片分类案例(pytorch实现)
前言
前文已經介紹過卷積神經網絡的基本概念【深度學習】卷積神經網絡-CNN簡單理論介紹[1]。下面開始動手實踐吧。本文任務描述如下:從公開數據集CIFAR10中創建訓練集、測試集數據,使用Pytorch構建CNN模型對訓練集數據進行訓練,然后在測試集中測試,查看簡單的CNN模型訓練效果如何。CIFAR10公開數據地址:http://www.cs.toronto.edu/~kriz/cifar.html[2]。CIFAR-10數據集包含 60000 張 32x32 的彩色 10 中類型的數據, 其中50000張訓練圖片和10000測試圖片。下面是每個類別隨機10張圖片的結果。
在這里插入圖片描述下面就根據CNN的原理:【深度學習】卷積神經網絡-CNN簡單理論介紹[3]設計相關的網絡和程序,建議使用jupyter。
1 數據集
這里結合torchvision包下載相關數據集并進行數據的預處理。代碼如下:
import?torchimport?torchvision
import?torchvision.transforms?as?transforms
#?數據預處理轉換器
transform?=?transforms.Compose([
????transforms.ToTensor(),
????transforms.Normalize((0.5,?0.5,?0.5),?(0.5,?0.5,?0.5))
])
#?構建訓練集數據,使用transform處理數據集供模型直接使用
train_set?=?torchvision.datasets.CIFAR10('./data',?train=True,?download=True,?transform=transform)
#?將數據集轉成可迭代的批次處理數據
train_loader?=?torch.utils.data.DataLoader(train_set,?batch_size=4,?shuffle=True,?num_workers=1)
#?同理構建測試集數據
test_set?=?torchvision.datasets.CIFAR10('./data',?train=False,?download=True,?transform=transform)
test_loader?=?torch.utils.data.DataLoader(test_set,?batch_size=4,?shuffle=True,?num_workers=1)
#?數據對應標簽
classes?=?('plane',?'car',?'bird',?'cat',?'deer',?'dog',?'frog',?'horse',?'ship',?'truck')
注: 如果數據下載較慢,可以在官網下載(cifar-10-python.tar.gz),然后放在data目錄下,再將download改為False即可。
另外:transforms.Compose組合兩種處理圖片的方法,一種是將圖片轉成模型輸入的張量格式數據,另一個則為數據標準化函數。
到此數據應該處理好了。下面我們可以查看一下數據,代碼如下:
import?matplotlib.pyplot?as?pltimport?numpy?as?np
%matplotlib?inline
def?imshow(img):
????"""
????展示圖片
????img:圖片數據
????"""
????img?=?img?/?2?+?0.5??#?反標準化
????npimg?=?img.numpy()??#?將數據轉換成numpy格式
????plt.imshow(np.transpose(npimg,?(1,?2,?0)))?
#?隨機獲取部分訓練數據
dataiter?=?iter(train_loader)
images,?labels?=?dataiter.next()
#?顯示圖像
imshow(torchvision.utils.make_grid(images))
#?打印標簽
print("?".join('%5s'?%?classes[labels[j]]?for?j?in?range(4)))?
#?結果:car ship truck horse
我這邊隨機顯示的圖片如下:
到這里數據已基本上沒什么問題了。
注: 這里暫不考究圖像預處理的內容,感興趣的可以深入了解。
2 構建網絡
下面就是構建CNN網絡了,根據之前的介紹以及pytorch,代碼如下:
import?torch.nn?as?nnimport?torch.nn.functional?as?F
#?如果有gpu的可使用GPU加速
device?=?torch.device("cuda:0"?if?torch.cuda.is_available()?else?"cpu")
class?CNNNet(nn.Module):
????def?__init__(self):
????????super(CNNNet,?self).__init__()
????????#?定義第一個卷積層
????????self.conv1?=?nn.Conv2d(in_channels=3,?out_channels=16,?kernel_size=5,?stride=1)
????????#?定義第一個池化層
????????self.pool1?=?nn.MaxPool2d(kernel_size=2,?stride=2)
????????#?定義第二個卷積層
????????self.conv2?=?nn.Conv2d(in_channels=16,?out_channels=36,?kernel_size=3,?stride=1)
????????#?定義第二個池化層
????????self.pool2?=?nn.MaxPool2d(kernel_size=2,?stride=2)
????????#?定義第一個全連接層
????????self.fc1?=?nn.Linear(1296,?128)
????????#?定義第二個全連接層
????????self.fc2?=?nn.Linear(128,?10)
????
????def?forward(self,?x):
????????#?連接各個cnn各個模塊
????????x?=?self.pool1(F.relu(self.conv1(x)))
????????x?=?self.pool2(F.relu(self.conv2(x)))
????????#?print(x.shape)
????????x=x.view(-1,?36*6*6)
????????x=F.relu(self.fc2(F.relu(self.fc1(x))))
????????#?返回運算后的結果
????????return?x
#?實例化模型
net?=?CNNNet()
net.to(device)??#?模型設備轉移
#?查看模型
print(net)
打印的模型輸出結果如下:
CNNNet((conv1): Conv2d(3, 16, kernel_size=(5, 5), stride=(1, 1))
(pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(conv2): Conv2d(16, 36, kernel_size=(3, 3), stride=(1, 1))
(pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(fc1): Linear(in_features=1296, out_features=128, bias=True)
(fc2): Linear(in_features=128, out_features=10, bias=True)
)
針對模型中一些層的參數介紹如下:
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1,bias=True, padding_model='zeros') 其中主要參數釋義:
- in_channels(int):輸入圖片的通道數目,彩色圖片的通道數為3(RGB)
- out_channels(int): 卷積產生的通道數
- kernel_size(int or tuple):卷積核的尺寸,單個值則認為卷積核長寬相同
- stride(int or tuple):卷積步長
- padding(int or tuple, optional):輸入的每一條邊填充0的圈數,參數可選,默認為0
- bias(bool, optional):如果bias=True,添加偏置。
這里需要補充一下多維數據中卷積是如何計算的
對于一張三通道的圖片,每個通道對應一個卷積核,最后計算得到三個結果矩陣,三個結果矩陣對應值相加到最后的結果,即為一個輸出通道。輸出形狀的計算可參考前文。
torch.nn.MaxPool2d(kernel_size,stride=None,padding=0,diltion=1,return_indices=False,ceil_mode=False) 其中主要參數如下:
- kernel_size:池化窗口的大小[height, weight],如果一個數,則兩者相等
- stride:窗口在每個維度上滑動的步長,一般為[stride_h, stride_w],如果兩者相等,則可為一個數字
輸出形狀的計算可參考前文。
3 選擇優化器和損失函數
由于是分類問題,以及做個簡單的模型實現,選擇交叉熵損失函數以及帶動量的隨機梯度下降算法,如下:
##?選擇優化器import?torch.optim?as?optim
criterion?=?nn.CrossEntropyLoss()
optimizer?=?optim.SGD(net.parameters(),?lr=0.001,?momentum=0.9)
4 模型訓練
模型訓練10輪,使用train_loader構建的mini-batch迭代器進行mini-batch的數據訓練,每2000個mini-batch打印一次。代碼如下:
##?訓練模型for?epoch?in?range(10):
????running_loss?=?0.0
????#?迭代,批次訓練
????for?i,?data?in?enumerate(train_loader,?0):
????????#?獲取訓練數據
????????inputs,?labels?=?data
????????inputs,?labels?=?inputs.to(device),?labels.to(device)
????????#?權重參數梯度清零
????????optimizer.zero_grad()
????????
????????#?正向傳播
????????outputs?=?net(inputs)
????????#?計算損失值
????????loss?=?criterion(outputs,?labels)
????????#?反向傳播
????????loss.backward()
????????#?參數更新
????????optimizer.step()
????????#?損失值累加
????????running_loss?+=?loss.item()
????????#?每2000個mini-batch顯示一次損失值
????????if?i?%?2000?==?1999:
????????????print('[%d,?%d]?loss:%.3f'?%?(epoch?+?1,?i?+?1,?running_loss?/?2000))
????????????running_loss?=?0.0
print('Finished?Training')
對應的訓練過程如下圖:
訓練過程5 模型測試
模型訓練結束之后,就可以進行模型的測試了。模型使用時,不需要進去相關梯度計算,則需要使用torch.no_grad()方法。
correct?=?0????#?預測正確數目total?=?0?????#?測試樣本總數
with?torch.no_grad():
????for?data?in?test_loader:
????????images,?labels?=?data
????????images,?labels?=?images.to(device),?labels.to(device)
????????outputs?=?net(images)
????????_,?predicted?=?torch.max(outputs.data,?1)??#?獲取批次預測結果
????????total?+=?labels.size(0)????????????????????#?批次數目累加
????????correct?+=?(predicted?==?labels).sum().item()??#?預測正確數累加
print('Accuracy?of?the?network?on?the?10000?test?images:?%d?%%'?%(100*correct/total))
#?Accuracy?of?the?network?on?the?10000?test?images:?68?%
最后得到的結果是:這個簡單的CNN模型對10分類的數據正確率達到68%,總體還是可以的。我們可以看看各個類別預測的正確率,使用代碼如下:
##?各類別的準確率class_correct?=?list(0.?for?i?in?range(10))
class_total?=?list(0.?for?i?in?range(10))
with?torch.no_grad():
????for?data?in?test_loader:
????????images,?labels?=?data
????????images,?labels?=?images.to(device),?labels.to(device)
????????outputs?=?net(images)
????????_,?predicted?=?torch.max(outputs,?1)
????????c?=?(predicted?==?labels).squeeze()
????????for?i?in?range(4):
????????????label?=?labels[i]
????????????class_correct[label]?+=?c[i].item()
????????????class_total[label]?+=?1
????????????
for?i?in?range(10):
????print('Accuracy?of?%5s:?%2d?%%'?%(classes[i],?100?*?class_correct[i]?/class_total[i]))
結果如下:
Accuracy of plane: 74 %Accuracy of car: 83 %
Accuracy of bird: 56 %
Accuracy of cat: 41 %
Accuracy of deer: 65 %
Accuracy of dog: 61 %
Accuracy of frog: 75 %
Accuracy of horse: 73 %
Accuracy of ship: 78 %
Accuracy of truck: 71 %
6 總結
總體來說,CNN是一個簡單而高效的神經網絡算法,當前也有很多基于經典CNN改進的卷積神經網絡,感興趣的可以深入學習,后面我們可以看看CNN是如何進行文本分類的,也就是textcnn模型。
參考資料
[1]【深度學習】卷積神經網絡-CNN簡單理論介紹: https://piqiandong.blog.csdn.net/article/details/109905697
[2]http://www.cs.toronto.edu/~kriz/cifar.html: http://www.cs.toronto.edu/~kriz/cifar.html
[3]【深度學習】卷積神經網絡-CNN簡單理論介紹: https://piqiandong.blog.csdn.net/article/details/109905697
劍指Offer刷題集|?Python基礎
更多精彩文章
卷積神經網絡-CNN簡單理論介紹
RST文件打開——以torchtext官方github文檔為例
機器學習分類器性能標準(Accuracy、Precision、Recall、P-R曲線、F1等)你是否真的懂了?
不僅僅要會導別人的包也要會導自定義的包——Python導包總結!
如何用Python書寫計算任一多變量函數任一點的偏導導數值?
一個繪制決策樹的工具——graphviz,但你忽視了它的其他功能,如結構句法分析結果!
VSCode再添新功能——繪制流程圖,來看看如何操作吧!
如何解決下載Github源碼慢的問題
Python中的迭代器和生成器
最優化問題:拉格朗日乘子法、KKT條件以及對偶問題
總結
以上是生活随笔為你收集整理的1 图片channels_【深度学习】卷积神经网络图片分类案例(pytorch实现)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 移动平均滤波_Kalman滤波理论与MA
- 下一篇: python 倒叙 数组_打基础一定要吃