以Mnist為例從頭開始自己建立數據集,搭建resnet34,識別Mnist


寫在前面:

       本人小白研一,剛開始學習深度學習,將自己的第一個實驗過程總結下來,看了很多的大牛的博客,在下面的程序中也參考了很多大牛的博客。在剛開始入門的學習的時候,直接編寫程序下載數據集,但是后來覺得可能會用到自己手動構建數據集。所以自己參考了一些博客,嘗試了從自己手動構造數據集——搭建Resnet34網絡——訓練——驗證的一整個過程。下面將自己的實驗過程記錄如下。本文重點介紹自己構建數據集與神經網絡搭建部分

本人才疏學淺,剛入門,有錯誤紕漏的地方懇請各位批評指正。

第一章: 

       首先需要自己構建Mnist數據集,當然也可以自己從網絡上下載。在這里,由於本人有點作,想嘗試自己構造數據集,話不多說,直接貼代碼

 1 #!/usr/bin/env python 3.6
 2 #_*_coding:utf-8 _*_
 3 #@Time    :2019/11/7 9:10
 4 #@Author  :控制工程小白
 5 #@FileName: 自己制作Mnist數據集.py
 6 
 7 #@Software: PyCharm
 8 import torch
 9 import torchvision
10 from skimage import io
11 #import os
12 mnist_train=torchvision.datasets.MNIST('./make_mnistdata',train=True,download=True)#首先下載數據集,並數據分割成訓練集與數據集
13 mnist_test=torchvision.datasets.MNIST('./make_mnistdata',train=False,download=True)
14 print('testset:',len(mnist_test))
15 #txt_path = "G:/Mnist_Recognition/mnist_label.txt"
16 # if not os.path.exists(txt_path):
17 #     os.makedirs(txt_path)
18 f=open("./mnist_test.txt",'w')#在指定路徑之下生成.txt文件
19 for i,(img,label) in enumerate(mnist_test):
20     img_path = "./mnist_test/" + str(i) + ".jpg"
21     io.imsave(img_path, img)#將圖片數據以圖片.jpg格式存在指定路徑下
22     img_paths=img_path+str(i)+".jpg"
23     f.write(img_path+' '+str(label)+'\n')#將路徑與標簽組合成的字符串存在.txt文件下
24 f.close()#關閉文件

注意,在運行這段代碼之前應該在根目錄下新建一個mnist_train文件夾用於存放訓練集的圖片,新建mnist_test文件夾用於存放測試集的圖片,運行這段代碼之后會生成一個mnist_test.txt與mnist_train.txt 文件,用來儲存各個字符串,這個字符串由每個圖片的路徑與對應的標簽組成,至於這樣做有什么用,請看下文。貼一下上述代碼運行結果

 

 

 

 

 

 第二章:

           下面將會用到上一章生成的.txt 文件,先上代碼

 1 #!/usr/bin/env python 3.6
 2 #_*_coding:utf-8 _*_
 3 #@Time    :2019/11/7 11:38
 4 #@Author  :控制工程小白
 5 #@FileName: My_dataset.py
 6 
 7 #@Software: PyCharm
 8 from PIL import Image
 9 import torch
10 from torch.utils import data
11 import torchvision.transforms as transforms
12 from torch.utils.data import DataLoader
13 import matplotlib.pyplot as plt
14 class MyDataset(data.Dataset):
15     def __init__(self,datatxt,transform=None,target_transform=None):
16         super(MyDataset,self).__init__()
17         fh=open(datatxt,'r')#讀取標簽文件.txt
18         imgs=[]#暫時定義一個空的列表
19         for line in fh:
20             line.strip('\n')#出去字符串末尾的空格、制表符
21             words=line.split()#將路徑名與標簽分離出來
22             imgs.append((words[0],int(words[1])))#word[0]表示圖片的路徑名,word[1]表示該數字圖片對應的標簽
23         self.imgs=imgs
24         self.transform=transform
25         self.target_transform=target_transform
26         #self.loader=loader
27     def __getitem__(self, index):
28         fn,label=self.imgs[index]#fn表示圖片的路徑
29         img = Image.open(fn)#.convert('RGB'),這里時候需要轉換成RGB圖像視神經網絡結構而定,讀取文件的路徑名,也即打開圖片
30         if self.transform is not None:
31             img=self.transform(img)
32         return img,label#返回圖片與標簽
33     def __len__(self):
34         return len(self.imgs)

這段代碼構造了一個類,用於獲取剛剛建立的數據集,思想就是讀取剛剛建立的.txt文件,將其中的圖片的路徑名與該圖片對應的標簽分離,然后根據根據圖片的路徑名獲取數據集。

第三章:

          搭建神經網絡,隨着深度學習的發展,已經出現了很多種神經網絡,一般而言,神經網絡越深越好,但是神經網絡的維度太深的話,會導致神經網絡過擬合,於是開發者開發了一種殘差神經網絡Resnet,它是由很多個殘差快組成,每個殘差塊都包含跳連接,防止過擬合,這樣可以達到網絡更深同時性能不會受到過擬合的影響。

 

 

 

 

 

 下面直接貼Resnet34代碼

#!/usr/bin/env python 3.6
#_*_coding:utf-8 _*_
#@Time    :2019/11/7 15:44
#@Author  :hujinzhou 
#@FileName: neural_network4.py

#@Software: PyCharm

import torch.nn as nn
class Reslock(nn.Module):
     def __init__(self, in_channels, out_channels, stride=1):
         super(Reslock, self).__init__()

        
         self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1)
         self.bn1 = nn.BatchNorm2d(out_channels)
         self.relu = nn.ReLU(inplace=True)

         
         self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1)
         self.bn2 = nn.BatchNorm2d(out_channels)

         if in_channels != out_channels:
            self.downsample = nn.Sequential(
                 nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=2),
                 nn.BatchNorm2d(out_channels)
             )
         else:
            
             self.downsample = None

     def forward(self, x):
         identity = x

         out = self.conv1(x)
         out = self.bn1(out)
         out = self.relu(out)

         out = self.conv2(out)
         out = self.bn2(out)

         if self.downsample is not None:
             identity = self.downsample(x)

         out += identity
         out = self.relu(out)

         return out





class ResNet34(nn.Module):
     def __init__(self, num_classes=10):
         super(ResNet34, self).__init__()

         
         self.first = nn.Sequential(
             
             nn.Conv2d(1, 64, 7, 2, 3),
             nn.BatchNorm2d(64),
             nn.ReLU(inplace=True),

            
             nn.MaxPool2d(3, 1, 1)
         )

        
         self.layer1 = self.make_layer(64, 64, 3, 1)

       
         self.layer2 = self.make_layer(64, 128, 4, 2)  
         self.layer3 = self.make_layer(128, 256, 6, 2)  
         self.layer4 = self.make_layer(256, 512, 3, 2)

         self.avg_pool = nn.AvgPool2d(2)  
         self.fc = nn.Linear(512, num_classes)

     def make_layer(self, in_channels, out_channels, block_num, stride):
         layers = []

         
         layers.append(Reslock(in_channels, out_channels, stride))

        
         for i in range(block_num - 1):
             layers.append(Reslock(out_channels, out_channels, 1))

         return nn.Sequential(*layers)

     def forward(self, x):
         x = self.first(x)
         x = self.layer1(x)
         x = self.layer2(x)
         x = self.layer3(x)
         x = self.layer4(x)
         x = self.avg_pool(x)

         # x.size()[0]: batch size
         x = x.view(x.size()[0], -1)
         x = self.fc(x)
         return x

第四章:

          上述過程弄好了,下面的過程就非常簡單了,下面直接訓練並識別驗證就可以了,訓練代碼與驗證代碼就很簡單了,在本文中直接貼訓練結果圖與識別精度圖

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM