中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python怎樣實現LeNet網絡模型的訓練及預測

發布時間:2021-11-23 21:07:38 來源:億速云 閱讀:152 作者:柒染 欄目:開發技術

本篇文章給大家分享的是有關Python怎樣實現LeNet網絡模型的訓練及預測,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

    1.LeNet模型訓練腳本

    整體的訓練代碼如下,下面我會為大家詳細講解這些代碼的意思

    import torch
    import torchvision
    from torchvision.transforms import transforms
    import torch.nn as nn
    from torch.utils.data import DataLoader
    from pytorch.lenet.model import LeNet
    import torch.optim as optim
    import numpy as np
    import matplotlib.pyplot as plt
    
    transform = transforms.Compose(
        # 將數據集轉換成tensor形式
        [transforms.ToTensor(),
         # 進行標準化,0.5是均值,也是方差,對應三個維度都是0.5
         transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]
    )
    
    # 下載完整的數據集時,download=True,第一個為保存的路徑,下載完后download要改為False
    # 為訓練集時,train=True,為測試集時,train=False
    train_set = torchvision.datasets.CIFAR10('./data', train=True,
                                             download=False, transform=transform)
    
    # 加載訓練集,設置批次大小,是否打亂,number_works是線程數,window不設置為0會報錯,linux可以設置非零
    train_loader = DataLoader(train_set, batch_size=36,
                              shuffle=True, num_workers=0)
    
    test_set = torchvision.datasets.CIFAR10('./data', train=False,
                                            download=False, transform=transform)
    # 設置的批次大小一次性將所有測試集圖片傳進去
    test_loader = DataLoader(test_set, batch_size=10000,
                             shuffle=False, num_workers=0)
    
    # 迭代測試集的圖片數據和標簽值
    test_img, test_label = next(iter(test_loader))
    
    # CIFAR10的十個類別名稱
    classes = ('plane', 'car', 'bird', 'cat', 'deer',
               'dog', 'frog', 'horse', 'ship', 'truck')
    
    # # ----------------------------顯示圖片-----------------------------------
    # def imshow(img, label):
    #     fig = plt.figure()
    #     for i in range(len(img)):
    #         ax = fig.add_subplot(1, len(img), i+1)
    #         nping = img[i].numpy().transpose([1, 2, 0])
    #         npimg = (nping * 2 + 0.5)
    #         plt.imshow(npimg)
    #         title = '{}'.format(classes[label[i]])
    #         ax.set_title(title)
    #         plt.axis('off')
    #     plt.show()
    # 
    # 
    # batch_image = test_img[: 5]
    # label_img = test_label[: 5]
    # imshow(batch_image, label_img)
    # # ----------------------------------------------------------------------
    
    net = LeNet()
    # 定義損失函數,nn.CrossEntropyLoss()自帶softmax函數,所以模型的最后一層不需要softmax進行激活
    loss_function = nn.CrossEntropyLoss()
    # 定義優化器,優化網絡模型所有參數
    optimizer = optim.Adam(net.parameters(), lr=0.001)
    
    # 迭代五次
    for epoch in range(5):
        # 初始損失設置為0
        running_loss = 0
        # 循環訓練集,從1開始
        for step, data in enumerate(train_loader, start=1):
            inputs, labels = data
            # 優化器的梯度清零,每次循環都需要清零,否則梯度會無限疊加,相當于增加批次大小
            optimizer.zero_grad()
            # 將圖片數據輸入模型中
            outputs = net(inputs)
            # 傳入預測值和真實值,計算當前損失值
            loss = loss_function(outputs, labels)
            # 損失反向傳播
            loss.backward()
            # 進行梯度更新
            optimizer.step()
            # 計算該輪的總損失,因為loss是tensor類型,所以需要用item()取具體值
            running_loss += loss.item()
            # 每500次進行日志的打印,對測試集進行預測
            if step % 500 == 0:
                # torch.no_grad()就是上下文管理,測試時不需要梯度更新,不跟蹤梯度
                with torch.no_grad():
                    # 傳入所有測試集圖片進行預測
                    outputs = net(test_img)
                    # torch.max()中dim=1是因為結果為(batch, 10)的形式,我們只需要取第二個維度的最大值
                    # max這個函數返回[最大值, 最大值索引],我們只需要取索引就行了,所以用[1]
                    predict_y = torch.max(outputs, dim=1)[1]
                    # (predict_y == test_label)相同返回True,不相等返回False,sum()對正確率進行疊加
                    # 因為計算的變量都是tensor,所以需要用item()拿到取值
                    accuracy = (predict_y == test_label).sum().item() / test_label.size(0)
                    # running_loss/500是計算每一個step的loss,即每一步的損失
                    print('[%d, %5d] train_loss: %.3f   test_accuracy: %.3f' %
                          (epoch+1, step, running_loss/500, accuracy))
                    running_loss = 0.0
    
    print('Finished Training!')
    
    save_path = 'lenet.pth'
    # 保存模型,字典形式
    torch.save(net.state_dict(), save_path)

    (1).下載CIFAR10數據集

    首先要訓練一個網絡模型,我們需要足夠多的圖片做數據集,這里我們用的是torchvision.dataset為我們提供的CIFAR10數據集(更多的數據集可以去pytorch官網查看pytorch官網提供的數據集)

    train_set = torchvision.datasets.CIFAR10('./data', train=True,
                                             download=False, transform=transform)
    test_set = torchvision.datasets.CIFAR10('./data', train=False,
                                            download=False, transform=transform)

    這部分代碼是下載CIFAR10,第一個參數是下載數據集后存放的路徑,train=True和False對應下載的訓練集和測試集,transform是對應的圖像增強方式

    (2).圖像增強

    transform = transforms.Compose(
        # 將數據集轉換成tensor形式
        [transforms.ToTensor(),
         # 進行標準化,0.5是均值,也是方差,對應三個維度都是0.5
         transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]
    )

    這就是簡單的圖像圖像增強,transforms.ToTensor()將數據集的所有圖像轉換成tensor, transforms.Normalize()是標準化處理,包含兩個元組對應均值和標準差,每個元組包含三個元素對應圖片的三個維度[channels, height, width],為什么是這樣排序,別問,問就是pytorch要求的,順序不能變,之后會看到transforms.Normalize([0.485, 0.406, 0.456], [0.229, 0.224, 0.225])這兩組數據,這是官方給出的均值和標準差,之后標準化的時候會經常用到

    (3).加載數據集

    # 加載訓練集,設置批次大小,是否打亂,number_works是線程數,window不設置為0會報錯,linux可以設置非零
    train_loader = DataLoader(dataset=train_set, batch_size=36,
                              shuffle=True, num_workers=0)
    test_loader = DataLoader(dataset=test_set, batch_size=36,
                             shuffle=False, num_workers=0)

    這里只簡單的設置的四個參數也是比較重要的,第一個就是需要加載的訓練集和測試集,shuffle=True表示將數據集打亂,batch_size表示一次性向設備放入36張圖片,打包成一個batch,這時圖片的shape就會從[3, 32, 32]----》[36, 3, 32, 32],傳入網絡模型的shape也必須是[None, channels, height, width],None代表一個batch多少張圖片,否則就會報錯,number_works是代表線程數,window系統必須設置為0,否則會報錯,linux系統可以設置非0數

    (4).顯示部分圖像

    def imshow(img, label):
        fig = plt.figure()
        for i in range(len(img)):
            ax = fig.add_subplot(1, len(img), i+1)
            nping = img[i].numpy().transpose([1, 2, 0])
            npimg = (nping * 2 + 0.5)
            plt.imshow(npimg)
            title = '{}'.format(classes[label[i]])
            ax.set_title(title)
            plt.axis('off')
        plt.show()
    
    
    batch_image = test_img[: 5]
    label_img = test_label[: 5]
    imshow(batch_image, label_img)

    這部分代碼是顯示測試集當中前五張圖片,運行后會顯示5張拼接的圖片

    Python怎樣實現LeNet網絡模型的訓練及預測

    由于這個數據集的圖片都比較小都是32x32的尺寸,有些可能也看的不太清楚,圖中顯示的是真實標簽,注:顯示圖片的代碼可能會這個報警(Clipping input data to the valid range for imshow with RGB data ([0…1] for floats or [0…255] for integers).),警告解決的方法:將圖片數組轉成uint8類型即可,即 plt.imshow(npimg.astype(‘uint8'),但是那樣顯示出來的圖片會變,所以暫時可以先不用管。

    (5).初始化模型

    數據圖片處理完了,下面就是我們的正式訓練過程

    net = LeNet()
    # 定義損失函數,nn.CrossEntropyLoss()自帶softmax函數,所以模型的最后一層不需要softmax進行激活
    loss_function = nn.CrossEntropyLoss()
    # 定義優化器,優化模型所有參數
    optimizer = optim.Adam(net.parameters(), lr=0.001)

    首先初始化LeNet網絡,定義交叉熵損失函數,以及Adam優化器,關于注釋寫的,我們可以ctrl+鼠標左鍵查看CrossEntropyLoss(),翻到CrossEntropyLoss類,可以看到注釋寫的這個標準包含LogSoftmax函數,所以搭建LetNet模型的最后一層沒有使用softmax激活函數

    Python怎樣實現LeNet網絡模型的訓練及預測

    (6).訓練模型及保存模型參數

    for epoch in range(5):
        # 初始損失設置為0
        running_loss = 0
        # 循環訓練集,從1開始
        for step, data in enumerate(train_loader, start=1):
            inputs, labels = data
            # 優化器的梯度清零,每次循環都需要清零,否則梯度會無限疊加,相當于增加批次大小
            optimizer.zero_grad()
            # 將圖片數據輸入模型中得到輸出
            outputs = net(inputs)
            # 傳入預測值和真實值,計算當前損失值
            loss = loss_function(outputs, labels)
            # 損失反向傳播
            loss.backward()
            # 進行梯度更新(更新W,b)
            optimizer.step()
            # 計算該輪的總損失,因為loss是tensor類型,所以需要用item()取到值
            running_loss += loss.item()
            # 每500次進行日志的打印,對測試集進行測試
            if step % 500 == 0:
                # torch.no_grad()就是上下文管理,測試時不需要梯度更新,不跟蹤梯度
                with torch.no_grad():
                    # 傳入所有測試集圖片進行預測
                    outputs = net(test_img)
                    # torch.max()中dim=1是因為結果為(batch, 10)的形式,我們只需要取第二個維度的最大值,第二個維度是包含十個類別每個類別的概率的向量
                    # max這個函數返回[最大值, 最大值索引],我們只需要取索引就行了,所以用[1]
                    predict_y = torch.max(outputs, dim=1)[1]
                    # (predict_y == test_label)相同返回True,不相等返回False,sum()對正確結果進行疊加,最后除測試集標簽的總個數
                    # 因為計算的變量都是tensor,所以需要用item()拿到取值
                    accuracy = (predict_y == test_label).sum().item() / test_label.size(0)
                    # running_loss/500是計算每一個step的loss,即每一步的損失
                    print('[%d, %5d] train_loss: %.3f   test_accuracy: %.3f' %
                          (epoch+1, step, running_loss/500, accuracy))
                    running_loss = 0.0
                    
    print('Finished Training!')
    
    save_path = 'lenet.pth'
    # 保存模型,字典形式
    torch.save(net.state_dict(), save_path)

    這段代碼注釋寫的很清楚,大家仔細看就能看懂,流程不復雜,多看幾遍就能理解,最后再對訓練好的模型進行保存就好了(* ̄︶ ̄)

    2.預測腳本

    上面已經訓練好了模型,得到了lenet.pth參數文件,預測就很簡單了,可以去網上隨便找一張數據集包含的類別圖片,將模型參數文件載入模型,通過對圖像進行一點處理,喂入模型即可,下面奉上代碼:

    import torch
    import numpy as np
    import torchvision.transforms as transforms
    from PIL import Image
    from pytorch.lenet.model import LeNet
    
    classes = ('plane', 'car', 'bird', 'cat', 'deer',
               'dog', 'frog', 'horse', 'ship', 'truck')
    
    transforms = transforms.Compose(
        # 對數據圖片調整大小
        [transforms.Resize([32, 32]),
         transforms.ToTensor(),
         transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]
    )
    
    net = LeNet()
    # 加載預訓練模型
    net.load_state_dict(torch.load('lenet.pth'))
    # 網上隨便找的貓的圖片
    img_path = '../../Photo/cat2.jpg'
    img = Image.open(img_path)
    # 圖片的處理
    img = transforms(img)
    # 增加一個維度,(channels, height, width)------->(batch, channels, height, width),pytorch要求必須輸入這樣的shape
    img = torch.unsqueeze(img, dim=0)
    
    with torch.no_grad():
        output = net(img)
        # dim=1,只取[batch, 10]中10個類別的那個維度,取預測結果的最大值索引,并轉換為numpy類型
        prediction1 = torch.max(output, dim=1)[1].data.numpy()
        # 用softmax()預測出一個概率矩陣
        prediction2 = torch.softmax(output, dim=1)
        # 得到概率最大的值得索引
        prediction2 = np.argmax(prediction2)
    # 兩種方式都可以得到最后的結果
    print(classes[int(prediction1)])
    print(classes[int(prediction2)])

    反正我最后預測出來結果把貓識別成了狗,還有90.01%的概率,就離譜哈哈哈,但也說明了LeNet這個網絡模型確實很淺,特征提取的不夠深,才會出現這種。

    以上就是Python怎樣實現LeNet網絡模型的訓練及預測,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    丹凤县| 亳州市| 修水县| 黎平县| 麻城市| 根河市| 商南县| 忻州市| 英山县| 萨迦县| 西城区| 太湖县| 固始县| 松潘县| 康马县| 凤山市| 陵川县| 含山县| 昌图县| 抚顺市| 临邑县| 辽阳市| 高州市| 胶州市| 桦甸市| 甘肃省| 天全县| 荣成市| 平阳县| 玉树县| 白玉县| 石城县| 宁乡县| 阿克苏市| 汽车| 浦北县| 宕昌县| 临湘市| 通海县| 阿拉善盟| 莱芜市|