日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【pytorch速成】Pytorch图像分类从模型自定义到测试

發布時間:2025/3/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【pytorch速成】Pytorch图像分类从模型自定义到测试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章首發于微信公眾號《與有三學AI》

【pytorch速成】Pytorch圖像分類從模型自定義到測試

前面已跟大家介紹了Caffe和TensorFlow,鏈接如下。

【caffe速成】caffe圖像分類從模型自定義到測試

【tensorflow速成】Tensorflow圖像分類從模型自定義到測試

今天說說Pytorch。

作者&編輯?|?言有三??

?

01 什么是 Pytorch

一句話總結 Pytorch = Python + Torch。

Torch 是紐約大學的一個機器學習開源框架,幾年前在學術界非常流行,包括 Lecun等大佬都在使用。但是由于使用的是一種絕大部分人絕對沒有聽過的 Lua 語言,導致很多人都被嚇退。后來隨著 Python 的生態越來越完善,Facebook 人工智能研究院推出了Pytorch并開源。Pytorch不是簡單的封裝 Torch并提供Python接口,而是對Tensor以上的所有代碼進行了重構,同TensorFlow一樣,增加了自動求導。

后來Caffe2全部并入Pytorch,如今已經成為了非常流行的框架。很多最新的研究如風格化、GAN 等大多數采用Pytorch源碼,這也是我們必須要講解它的原因。

1.1 特點

(1)動態圖計算。TensorFlow從靜態圖發展到了動態圖機制Eager Execution,pytorch則一開始就是動態圖機制。動態圖機制的好處就是隨時隨地修改,隨處debug,沒有類似編譯的過程。

(2)簡單。相比TensorFlow中Tensor、Variable、Session等概念充斥,數據讀取接口頻繁更新,tf.nn、tf.layers、tf.contrib各自重復,Pytorch則是從Tensor到Variable再到nn.Module,最新的Pytorch已經將Tensor和Variable合并,這分別就是從數據張量到網絡的抽象層次的遞進。有人調侃TensorFlow的設計是“make it complicated”,那么 Pytorch的設計就是“keep it simple”。

1.2 重要概念

(1)Tensor/Variable

每一個框架都有基本的數據結構,Caffe是blob,TensorFlow和Pytorch都是Tensor,都是高維數組。Pytorch中的Tensor使用與Numpy的數組非常相似,兩者可以互轉且共享內存。

tensor包括cpu和gpu兩種類型,如torch.FloatTensortorch.cuda.FloatTensorvirable,就分別表示cpu和gpu下的32位浮點數。

tensor包含一些屬性。data,即Tensor內容;Grad,是與data對應的梯度;requires_grad,是否容許進行反向傳播的學習,更多的可以去查看API。

(2)nn.module

抽象好的網絡數據結構,可以表示為網絡的一層,也可以表示為一個網絡結構,這是一個基類。在實際使用過程中,經常會定義自己的網絡,并繼承nn.Module。具體的使用,我們看下面的網絡定義吧。

(3)torchvision包,包含了目前流行的數據集,模型結構和常用的圖片轉換工具

?

02 Pytorch 訓練

安裝咱們就不說了,接下來的任務就是開始訓練模型。訓練模型包括數據準備、模型定義、結果保存與分析。

2.1 數據讀取

前面已經介紹了Caffe和TensorFlow的數據讀取,兩者的輸入都是圖片list,但是讀取操作過程差異非常大,Pytorch與這兩個又有很大的差異。這一次,直接利用文件夾作為輸入,這是 Pytorch更加方便的做法。數據讀取的完整代碼如下:

data_dir = '../../../../datas/head/' ? ?
? ?data_transforms = {
? ? ? ?'train': transforms.Compose([
? ? ? ? ? ?transforms.RandomSizedCrop(48),
? ? ? ? ? ?transforms.RandomHorizontalFlip(),
? ? ? ? ? ?transforms.ToTensor(),
? ? ? ? ? ?transforms.Normalize([0.5,0.5,0.5], [0.5,0.5,0.5])
? ? ? ?]),
? ? ? ?'val': transforms.Compose([
? ? ? ? ? ?transforms.Scale(64),
? ? ? ? ? ?transforms.CenterCrop(48),
? ? ? ? ? ?transforms.ToTensor(),
? ? ? ? ? ?transforms.Normalize([0.5,0.5,0.5], [0.5,0.5,0.5])
? ? ? ?]),
? ?}
? ?image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?data_transforms[x]) for x in ['train', 'val']}
? ?dataloders = {x: torch.utils.data.DataLoader(image_datasets[x],
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? batch_size=16,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? shuffle=True,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? num_workers=4) for x in ['train', 'val']}

下面一個一個解釋,完整代碼請移步 Git 工程。

?

(1)datasets.ImageFolder

Pytorch的torchvision模塊中提供了一個dataset 包,它包含了一些基本的數據集如mnist、coco、imagenet和一個通用的數據加載器ImageFolder。

它會以這樣的形式組織數據,具體的請到Git工程中查看。

root/left/1.png
root/left/2.png
root/left/3.png

root/right/1.png
root/right/2.png
root/right/3.png

imagefolder有3個成員變量。

self.classes:用一個list保存類名,就是文件夾的名字。

self.class_to_idx:類名對應的索引,可以理解為 0、1、2、3 等。

self.imgs:保存(imgpath,class),是圖片和類別的數組。

不同文件夾下的圖,會被當作不同的類,天生就用于圖像分類任務。

(2)Transforms

這一點跟Caffe非常類似,就是定義了一系列數據集的預處理和增強操作。到此,數據接口就定義完畢了,接下來在訓練代碼中看如何使用迭代器進行數據讀取就可以了,包括 scale、減均值等。

(3)torch.utils.data.DataLoader

這就是創建了一個 batch,生成真正網絡的輸入。關于更多 Pytorch 的數據讀取方法,請自行學習。

2.2 模型定義

import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
class simpleconv3(nn.Module):`
def __init__(self):
? ? ? ?super(simpleconv3,self).__init__()
? ? ? ?self.conv1 = nn.Conv2d(3, 12, 3, 2)
? ? ? ?self.bn1 = nn.BatchNorm2d(12)
? ? ? ?self.conv2 = nn.Conv2d(12, 24, 3, 2)
? ? ? ?self.bn2 = nn.BatchNorm2d(24)
? ? ? ?self.conv3 = nn.Conv2d(24, 48, 3, 2)
? ? ? ?self.bn3 = nn.BatchNorm2d(48)
? ? ? ?self.fc1 = nn.Linear(48 * 5 * 5 , 1200)
? ? ? ?self.fc2 = nn.Linear(1200 , 128)
? ? ? ?self.fc3 = nn.Linear(128 , 2)
def forward(self , x):
? ? ? ?x = F.relu(self.bn1(self.conv1(x)))
? ? ? ?x = F.relu(self.bn3(self.conv3(x)))
? ? ? ?x = x.view(-1 , 48 * 5 * 5)?
? ? ? ?x = F.relu(self.fc1(x))
? ? ? ?x = F.relu(self.fc2(x))
? ? ? ?x = self.fc3(x)
? ? ? ?return x

我們的例子都是采用一個簡單的3層卷積 + 2層全連接層的網絡結構。根據上面的網絡結構的定義,需要做以下事情。

(1)simpleconv3(nn.Module)

繼承nn.Module,前面已經說過,Pytorch的網絡層是包含在nn.Module 里,所以所有的網絡定義,都需要繼承該網絡層,并實現super方法,如下:

super(simpleconv3,self).__init__()

這個就當作一個標準執行就可以了。

(2)網絡結構的定義都在nn包里,舉例說明:

torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)

完整的接口如上,定義的第一個卷積層如下:

nn.Conv2d(3, 12, 3, 2)

即輸入通道為3,輸出通道為12,卷積核大小為3,stride=2,其他的層就不一一介紹了,大家可以自己去看nn的API。

(3)forward

backward方法不需要自己實現,但是forward函數是必須要自己實現的,從上面可以看出,forward 函數也是非常簡單,串接各個網絡層就可以了。

對比Caffe和TensorFlow可以看出,Pytorch的網絡定義更加簡單,初始化方法都沒有顯示出現,因為 Pytorch已經提供了默認初始化。

如果我們想實現自己的初始化,可以這么做:

init.xavier_uniform(self.conv1.weight)init.constant(self.conv1.bias, 0.1)

它會對conv1的權重和偏置進行初始化。如果要對所有conv層使用 xavier 初始化呢?可以定義一個函數:

def weights_init(m): ? ?
? ?if isinstance(m, nn.Conv2d):
? ? ? ?xavier(m.weight.data)
? ? ? ?xavier(m.bias.data) ?
? ?net = Net() ??
? ?net.apply(weights_init)

?

03 模型訓練

網絡定義和數據加載都定義好之后,就可以進行訓練了,老規矩先上代碼:

def train_model(model, criterion, optimizer, scheduler, num_epochs=25):
? ? ? ?for epoch in range(num_epochs):
? ? ? ? ? ?print('Epoch {}/{}'.format(epoch, num_epochs - 1))
? ? ? ? ? ?for phase in ['train', 'val']:
? ? ? ? ? ? ? ?if phase == 'train':
? ? ? ? ? ? ? ? ? ?scheduler.step()
? ? ? ? ? ? ? ? ? ?model.train(True) ?
? ? ? ? ? ? ? ?else:
? ? ? ? ? ? ? ? ? ?model.train(False) ?
? ? ? ? ? ? ? ? ? ?running_loss = 0.0 ? ? ? ? ? ? ? ?running_corrects = 0.0
? ? ? ? ? ? ? ?for data in dataloders[phase]:
? ? ? ? ? ? ? ? ? ?inputs, labels = data
? ? ? ? ? ? ? ? ? ?if use_gpu:
? ? ? ? ? ? ? ? ? ? ? ?inputs = Variable(inputs.cuda())
? ? ? ? ? ? ? ? ? ? ? ?labels = Variable(labels.cuda())
? ? ? ? ? ? ? ? ? ?else:
? ? ? ? ? ? ? ? ? ? ? ?inputs, labels = Variable(inputs), Variable(labels)

? ? ? ? ? ? ? ? ? ?optimizer.zero_grad()
? ? ? ? ? ? ? ? ? ?outputs = model(inputs)
? ? ? ? ? ? ? ? ? ?_, preds = torch.max(outputs.data, 1)
? ? ? ? ? ? ? ? ? ?loss = criterion(outputs, labels)
? ? ? ? ? ? ? ? ? ?if phase == 'train':
? ? ? ? ? ? ? ? ? ? ? ?loss.backward()
? ? ? ? ? ? ? ? ? ? ? ?optimizer.step()

? ? ? ? ? ? ? ? ? ?running_loss += loss.data.item()
? ? ? ? ? ? ? ? ? ?running_corrects += torch.sum(preds == labels).item()

? ? ? ? ? ? ? ?epoch_loss = running_loss / dataset_sizes[phase]
? ? ? ? ? ? ? ?epoch_acc = running_corrects / dataset_sizes[phase]

? ? ? ? ? ? ? ?if phase == 'train':
? ? ? ? ? ? ? ? ? ?writer.add_scalar('data/trainloss', epoch_loss, epoch)
? ? ? ? ? ? ? ? ? ?writer.add_scalar('data/trainacc', epoch_acc, epoch)
? ? ? ? ? ? ? ?else:
? ? ? ? ? ? ? ? ? ?writer.add_scalar('data/valloss', epoch_loss, epoch)
? ? ? ? ? ? ? ? ? ?writer.add_scalar('data/valacc', epoch_acc, epoch)

? ? ? ? ? ? ? ?print('{} Loss: {:.4f} Acc: {:.4f}'.format(
? ? ? ? ? ? ? ?phase, epoch_loss, epoch_acc))
? ? ? ?writer.export_scalars_to_json("./all_scalars.json")
? ? ? ?writer.close()
? ? ? ?return model

分析一下上面的代碼,外層循環是epoches,然后利用 for data in dataloders[phase] 循環取一個epoch 的數據,并塞入variable,送入model。需要注意的是,每一次forward要將梯度清零,即optimizer.zero_grad(),因為梯度會記錄前一次的狀態,然后計算loss進行反向傳播。

loss.backward()
optimizer.step()

下面可以分別得到預測結果和loss,每一次epoch 完成計算。

epoch_loss = running_loss / dataset_sizes[phase]
epoch_acc = running_corrects / dataset_sizes[phase]
_, preds = torch.max(outputs.data, 1)
loss = criterion(outputs, labels)

可視化是非常重要的,鑒于TensorFlow的可視化非常方便,我們選擇了一個開源工具包,tensorboardx,安裝方法為pip install tensorboardx,使用非常簡單。

第一步,引入包定義創建:

from tensorboardX import SummaryWriter
writer = SummaryWriter()

第二步,記錄變量,如train階段的 loss,writer.add_scalar('data/trainloss', epoch_loss, epoch)。

按照以上操作就完成了,完整代碼可以看配套的Git 項目,我們看看訓練中的記錄。Loss和acc的曲線圖如下:

?

網絡的收斂沒有Caffe和TensorFlow好,大家可以自己去調試調試參數了,隨便折騰吧。

?

04 Pytorch 測試

上面已經訓練好了模型,接下來的目標就是要用它來做inference了,同樣給出代碼。

import torch
import torch.nn as nn
import torch.optim as optim
from torch.optim import lr_scheduler
from torch.autograd import Variable
import torchvision
from torchvision import datasets, models, transforms
import time
import os
from PIL import Image
import sys
import torch.nn.functional as F

from net import simpleconv3
data_transforms = ?transforms.Compose([
? ? ? ? ? ? ? ?transforms.Resize(48),
? ? ? ? ? ? ? ?transforms.ToTensor(),
? ? ? ? ? ? ? ?transforms.Normalize([0.5,0.5,0.5], [0.5,0.5,0.5])])

net = simpleconv3()
modelpath = sys.argv[1]
net.load_state_dict(torch.load(modelpath,map_location=lambda storage,loc: storage))

imagepath = sys.argv[2]
image = Image.open(imagepath)
imgblob = data_transforms(image).unsqueeze(0)
imgblob = Variable(imgblob)
torch.no_grad()
predict = F.softmax(net(imgblob))
print(predict)

從上面的代碼可知,做了幾件事:

定義網絡并使用torch.load和load_state_dict載入模型。

用PIL的Image包讀取圖片,這里沒有用OpenCV,因為Pytorch默認的圖片讀取工具就是PIL的Image,它會將圖片按照RGB的格式,歸一化到 0~1 之間。讀取圖片之后,必須轉化為Tensor變量。

evaluation的時候,必須設置torch.no_grad(),然后就可以調用 softmax 函數得到結果了。

?

05 總結

本節講了如何用 Pytorch 完成一個分類任務,并學習了可視化以及使用訓練好的模型做測試。

?

同時,在我的知乎專欄也會開始同步更新這個模塊,歡迎來交流

https://zhuanlan.zhihu.com/c_151876233

注:部分圖片來自網絡

—END—

本系列完整文章:

第一篇:【caffe速成】caffe圖像分類從模型自定義到測試

第二篇:【tensorflow速成】Tensorflow圖像分類從模型自定義到測試

第三篇:【pytorch速成】Pytorch圖像分類從模型自定義到測試

第四篇:【paddlepaddle速成】paddlepaddle圖像分類從模型自定義到測試

第五篇:【Keras速成】Keras圖像分類從模型自定義到測試

第六篇:【mxnet速成】mxnet圖像分類從模型自定義到測試

第七篇:【cntk速成】cntk圖像分類從模型自定義到測試

第八篇:【chainer速成】chainer圖像分類從模型自定義到測試

第九篇:【DL4J速成】Deeplearning4j圖像分類從模型自定義到測試

第十篇:【MatConvnet速成】MatConvnet圖像分類從模型自定義到測試

第十一篇:【Lasagne速成】Lasagne/Theano圖像分類從模型自定義到測試

第十二篇:【darknet速成】Darknet圖像分類從模型自定義到測試

感謝各位看官的耐心閱讀,不足之處希望多多指教。后續內容將會不定期奉上,歡迎大家關注有三公眾號 有三AI

?

?

總結

以上是生活随笔為你收集整理的【pytorch速成】Pytorch图像分类从模型自定义到测试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成人av激情 | 久久精品视频偷拍 | 色欲色香天天天综合网www | 日韩午夜视频在线 | 国内视频一区二区三区 | 国产午夜免费福利 | 噜噜色av | 日韩三级小视频 | 少妇高潮淫片免费观看 | 亚洲综合av一区二区三区 | 激情欧美一区二区免费视频 | 色久阁| 波多野结衣在线免费观看视频 | 香港三级网站 | 性生活在线视频 | 欧美日韩一区二区三区在线播放 | 色婷婷色综合 | 国产精品va在线观看无码 | 天天做夜夜做 | 亚洲精品在线观看视频 | 国产91在线观看丝袜 | 一级全黄裸体免费视频 | 精品在线观看一区 | 精精国产xxxx视频在线播放 | 欧美性大战久久久久久久蜜桃 | 黄色工厂在线观看 | 亚洲欧美午夜 | 男插女视频在线观看 | 999伊人 | 亚洲视频在线观看网址 | 美足av| 超碰夜夜 | 九一精品国产 | 五月婷婷爱爱 | 色男人的天堂 | 人妻射精一区二区 | 亚洲人成在线播放 | 日韩久久久久久久久久久 | 欧美黑人孕妇孕交 | 黄色一级片欧美 | a天堂在线 | 在线观看中文字幕亚洲 | 樱花影院最新免费观看攻略 | 男人把女人捅爽 | 全程粗话对白视频videos | 1024毛片| 漂亮人妻洗澡被公强 日日躁 | 爱爱网视频 | 国产成人精品一区二区三区在线 | 久久高清一区 | 先锋资源av| 1024金沙人妻一区二区三区 | 黑花全肉高h湿play短篇 | 怡红院av亚洲一区二区三区h | 免费av一区 | 亚洲天堂h| 欧美性教育视频 | 午夜小视频网站 | 私密spa按摩按到高潮 | 国产精品自拍在线 | 中文字幕免费高清 | 欧美美女一区 | 成人一区二区三区四区 | 国内av网站 | 欧美在线一区二区 | 蜜芽一区二区 | 华人永久免费视频 | 日韩av无码中文字幕 | 天天干天天操天天 | 成人免费区一区二区三区 | 黄色大片在线免费观看 | 日韩成人免费视频 | 免费国产黄色 | 中文字幕日韩一区二区三区 | 啪视频在线观看 | 国产伦精品一区二区三区免费 | 亚洲精品传媒 | 在线播放无码后入内射少妇 | 日韩国产成人无码av毛片 | 伊人涩涩 | 中文字幕在线观看日本 | 岛国一区二区三区 | 精品国产一区二区三区在线 | 亚洲精品电影 | 国产高清精品软件丝瓜软件 | 麻豆成人91精品二区三区 | ww成人| 思思精品视频 | 尤物综合网| 国产美女永久免费无遮挡 | 很色的网站 | 99青草| 五月激情综合网 | 91爱爱视频 | 久久99精品久久久 | 五月天av影院| 夜色在线视频 | 欧美日韩xxx | 久久久久久91亚洲精品中文字幕 |