丁香五月天婷婷久久婷婷色综合91|国产传媒自偷自拍|久久影院亚洲精品|国产欧美VA天堂国产美女自慰视屏|免费黄色av网站|婷婷丁香五月激情四射|日韩AV一区二区中文字幕在线观看|亚洲欧美日本性爱|日日噜噜噜夜夜噜噜噜|中文Av日韩一区二区

您正在使用IE低版瀏覽器,為了您的雷峰網(wǎng)賬號安全和更好的產(chǎn)品體驗,強烈建議使用更快更安全的瀏覽器
此為臨時鏈接,僅用于文章預(yù)覽,將在時失效
人工智能 正文
發(fā)私信給AI研習(xí)社-譯站
發(fā)送

0

如何用PyTorch訓(xùn)練圖像分類器

本文作者: AI研習(xí)社-譯站 2018-11-26 17:31
導(dǎo)語:如果你剛剛開始使用PyTorch并想學(xué)習(xí)如何進行基本的圖像分類,那么你可以參考本教程。

如何用PyTorch訓(xùn)練圖像分類器

本文為 AI 研習(xí)社編譯的技術(shù)博客,原標(biāo)題 :

How to Train an Image Classifier in PyTorch and use it to Perform Basic Inference on Single Images

作者 | Chris Fotache

翻譯 | shunshun

校對 | 醬番梨        整理 | 菠蘿妹

原文鏈接:

https://medium.com/@chrisfotache/how-to-train-an-image-classifier-in-pytorch-and-use-it-to-perform-basic-inference-on-single-images-99465a1e9bf5

如果你剛剛開始使用PyTorch并想學(xué)習(xí)如何進行基本的圖像分類,那么你可以參考本教程。它將介紹如何組織訓(xùn)練數(shù)據(jù),使用預(yù)訓(xùn)練神經(jīng)網(wǎng)絡(luò)訓(xùn)練模型,然后預(yù)測其他圖像。

為此,我將使用由Google地圖中的地圖圖塊組成的數(shù)據(jù)集,并根據(jù)它們包含的地形特征對它們進行分類。我會在另一篇文章中介紹如何使用它(簡而言之:為了識別無人機起飛或降落的安全區(qū)域)。但是現(xiàn)在,我只想使用一些訓(xùn)練數(shù)據(jù)來對這些地圖圖塊進行分類。

下面的代碼片段來自Jupyter Notebook。你可以將它們拼接在一起以構(gòu)建自己的Python腳本,或從GitHub下載。這些Notebook是基于Udacity的PyTorch課程的。如果你使用云端虛擬機進行深度學(xué)習(xí)開發(fā)并且不知道如何遠(yuǎn)程打開notebook,請查看我的教程。


  組織訓(xùn)練數(shù)據(jù)集

PyTorch希望數(shù)據(jù)按文件夾組織,每個類對應(yīng)一個文件夾。大多數(shù)其他的PyTorch教程和示例都希望你先按照訓(xùn)練集和驗證集來組織文件夾,然后在訓(xùn)練集和驗證集中再按照類別進行組織。但我認(rèn)為這非常麻煩,必須從每個類別中選擇一定數(shù)量的圖像并將它們從訓(xùn)練集文件夾移動到驗證集文件夾。由于大多數(shù)人會通過選擇一組連續(xù)的文件作為驗證集,因此選擇可能存在很多偏差。

因此,這兒有一個將數(shù)據(jù)集快速分為訓(xùn)練集和測試集的更好的方法,就像Python開發(fā)人員習(xí)慣使用sklearn一樣。首先,讓我們導(dǎo)入模塊:

%matplotlib inline
%config InlineBackend.figure_format = 'retina'
import matplotlib.pyplot as plt
import numpy as np
import torch
from torch import nn
from torch import optim
import torch.nn.functional as F
from torchvision import datasets, transforms, models

接下來,我們將定義train/validation數(shù)據(jù)集加載器,使用SubsetRandomSampler進行拆分:

data_dir = '/data/train'
def load_split_train_test(datadir, valid_size = .2):
   train_transforms = transforms.Compose([transforms.Resize(224),
                                      transforms.ToTensor(),
                                      ])
   test_transforms = transforms.Compose([transforms.Resize(224),
                                     transforms.ToTensor(),
                                     ])
   train_data = datasets.ImageFolder(datadir,      
                   transform=train_transforms)
   test_data = datasets.ImageFolder(datadir,
                   transform=test_transforms)
   num_train = len(train_data)
   indices = list(range(num_train))
   split = int(np.floor(valid_size * num_train))
   np.random.shuffle(indices)
   from torch.utils.data.sampler import SubsetRandomSampler
   train_idx, test_idx = indices[split:], indices[:split]
   train_sampler = SubsetRandomSampler(train_idx)
   test_sampler = SubsetRandomSampler(test_idx)
   trainloader = torch.utils.data.DataLoader(train_data,
                  sampler=train_sampler, batch_size=64)
   testloader = torch.utils.data.DataLoader(test_data,
                  sampler=test_sampler, batch_size=64)
   return trainloader, testloader
trainloader, testloader = load_split_train_test(data_dir, .2)
print(trainloader.dataset.classes)

接下來我們將確定是否有GPU。我假設(shè)你有一臺GPU機器,否則代碼將至少慢10倍。但是,檢查GPU可用性是個好主意。

我們還將加載預(yù)訓(xùn)練模型。對于這種情況,我選擇ResNet 50:

device = torch.device("cuda" if torch.cuda.is_available()
                                 else "cpu")
model = models.resnet50(pretrained=True)
print(model)

打印模型將顯示ResNet模型的圖層體系結(jié)構(gòu)。這可能超出了我的意識或你的理解,但看到那些深層隱藏層內(nèi)的東西仍然很有趣。

這取決于你選擇什么樣的模型,根據(jù)你的特定數(shù)據(jù)集模型可能會不同。這里列出了所有的PyTorch模型。

現(xiàn)在我們進入深度神經(jīng)網(wǎng)絡(luò)的有趣部分。首先,我們必須凍結(jié)預(yù)訓(xùn)練過的層,因此在訓(xùn)練期間它們不會進行反向傳播。然后,我們重新定義最后的全連接層,即使用我們的圖像來訓(xùn)練的圖層。我們還創(chuàng)建了標(biāo)準(zhǔn)(損失函數(shù))并選擇了一個優(yōu)化器(在這種情況下為Adam)和學(xué)習(xí)率。

for param in model.parameters():
   param.requires_grad = False
   
model.fc = nn.Sequential(nn.Linear(2048, 512),
                                nn.ReLU(),
                                nn.Dropout(0.2),
                                nn.Linear(512, 10),
                                nn.LogSoftmax(dim=1))
criterion = nn.NLLLoss()
optimizer = optim.Adam(model.fc.parameters(), lr=0.003)
model.to(device)

現(xiàn)在完成了,讓我們訓(xùn)練模型吧!在這個例子中只有一個epoch,但在大多數(shù)情況下你需要更多。從代碼中可以看出基本過程非常直觀:加載批量圖像并執(zhí)行前向傳播循環(huán)。然后計算損失函數(shù),并使用優(yōu)化器在反向傳播中應(yīng)用梯度下降。

PyTorch就這么簡單。下面的大多數(shù)代碼是每10個批次顯示損失并計算的準(zhǔn)確度,所以你在訓(xùn)練運行時得到更新。在驗證期間,不要忘記將模型設(shè)置為eval()模式,然后在完成后返回train()。

epochs = 1
steps = 0
running_loss = 0
print_every = 10
train_losses, test_losses = [], []
for epoch in range(epochs):
   for inputs, labels in trainloader:
       steps += 1
       inputs, labels = inputs.to(device), labels.to(device)
       optimizer.zero_grad()
       logps = model.forward(inputs)
       loss = criterion(logps, labels)
       loss.backward()
       optimizer.step()
       running_loss += loss.item()
       
       if steps % print_every == 0:
           test_loss = 0
           accuracy = 0
           model.eval()
           with torch.no_grad():
               for inputs, labels in testloader:
                   inputs, labels = inputs.to(device),
                                     labels.to(device)
                   logps = model.forward(inputs)
                   batch_loss = criterion(logps, labels)
                   test_loss += batch_loss.item()
                   
                   ps = torch.exp(logps)
                   top_p, top_class = ps.topk(1, dim=1)
                   equals =
                       top_class == labels.view(*top_class.shape)
                   accuracy +=
                  torch.mean(equals.type(torch.FloatTensor)).item()
           train_losses.append(running_loss/len(trainloader))
           test_losses.append(test_loss/len(testloader))                    
           print(f"Epoch {epoch+1}/{epochs}.. "
                 f"Train loss: {running_loss/print_every:.3f}.. "
                 f"Test loss: {test_loss/len(testloader):.3f}.. "
                 f"Test accuracy: {accuracy/len(testloader):.3f}")
           running_loss = 0
           model.train()
torch.save(model, 'aerialmodel.pth')

等待幾分鐘后(或更長時間后,取決于數(shù)據(jù)集的大小和時期數(shù)量),完成訓(xùn)練并保存模型以供以后預(yù)測!

現(xiàn)在還有一件事可以做,即繪制訓(xùn)練和驗證損失圖:

plt.plot(train_losses, label='Training loss')
plt.plot(test_losses, label='Validation loss')
plt.legend(frameon=False)
plt.show()

如何用PyTorch訓(xùn)練圖像分類器

如你所見,在我的一個epoch的特定例子中,驗證損失(這是我們感興趣的)在第一個epoch結(jié)束時的平坦線條甚至開始有上升趨勢,所以可能1個epoch就足夠了。正如預(yù)期的那樣,訓(xùn)練損失非常低。

現(xiàn)在進入第二部分。你訓(xùn)練模型,保存模型,并需要在應(yīng)用程序中使用它。為此,你需要能夠?qū)D像執(zhí)行簡單推理。你也可以在我們的存儲庫中找到此演示notebook。我們導(dǎo)入與訓(xùn)練筆記本中相同的模塊,然后再次定義變換(transforms)。我只是再次聲明圖像文件夾,所以我可以使用那里的一些例子:

data_dir = '/datadrive/FastAI/data/aerial_photos/train'
test_transforms = transforms.Compose([transforms.Resize(224),
                                     transforms.ToTensor(),
                                    ])

然后我們再次檢查GPU可用性,加載模型并將其置于評估模式(因此參數(shù)不會改變):

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model=torch.load('aerialmodel.pth')
model.eval()

預(yù)測特定圖像的類的功能非常簡單。請注意,它需要Pillow圖像,而不是文件路徑。

def predict_image(image):
   image_tensor = test_transforms(image).float()
   image_tensor = image_tensor.unsqueeze_(0)
   input = Variable(image_tensor)
   input = input.to(device)
   output = model(input)
   index = output.data.cpu().numpy().argmax()
   return index

現(xiàn)在為了便于測試,我還創(chuàng)建了一個從數(shù)據(jù)集文件夾中選擇大量隨機圖像的函數(shù):

def get_random_images(num):
   data = datasets.ImageFolder(data_dir, transform=test_transforms)
   classes = data.classes
   indices = list(range(len(data)))
   np.random.shuffle(indices)
   idx = indices[:num]
   from torch.utils.data.sampler import SubsetRandomSampler
   sampler = SubsetRandomSampler(idx)
   loader = torch.utils.data.DataLoader(data,
                  sampler=sampler, batch_size=num)
   dataiter = iter(loader)
   images, labels = dataiter.next()
   return images, labels

最后,為了演示預(yù)測函數(shù),我得到隨機圖像樣本,預(yù)測它們并顯示結(jié)果:

to_pil = transforms.ToPILImage()
images, labels = get_random_images(5)
fig=plt.figure(figsize=(10,10))
for ii in range(len(images)):
   image = to_pil(images[ii])
   index = predict_image(image)
   sub = fig.add_subplot(1, len(images), ii+1)
   res = int(labels[ii]) == index
   sub.set_title(str(classes[index]) + ":" + str(res))
   plt.axis('off')
   plt.imshow(image)
plt.show()

以下是Google地圖圖塊上此類預(yù)測的一個示例。標(biāo)簽是預(yù)測的類,我也在顯示它是否是正確的預(yù)測。

如何用PyTorch訓(xùn)練圖像分類器

這就是它。繼續(xù)嘗試數(shù)據(jù)集。只要你正確組織圖像,此代碼應(yīng)該按原樣運行。很快我就會有更多關(guān)于神經(jīng)網(wǎng)絡(luò)和PyTorch可以做的很酷的文章。

Chris Fotache是位于 New Jersey的 CYNET.ai的人工智能研究員。他涵蓋了與生活中的人工智能,Python編程,機器學(xué)習(xí),計算機視覺,自然語言處理等相關(guān)的主題。雷鋒網(wǎng)雷鋒網(wǎng)雷鋒網(wǎng)



想要繼續(xù)查看該篇文章相關(guān)鏈接和參考文獻?

長按鏈接點擊打開或點擊【如何使用PyTorch訓(xùn)練圖像分類器】:

http://ai.yanxishe.com/page/TextTranslation/1272


AI研習(xí)社每日更新精彩內(nèi)容,觀看更多精彩內(nèi)容:

使用Python來圖像增強

新手必看:手把手教你入門 Python

多目標(biāo)追蹤器:用OpenCV實現(xiàn)多目標(biāo)追蹤(C++/Python)

數(shù)據(jù)科學(xué)家應(yīng)當(dāng)了解的五個統(tǒng)計基本概念:統(tǒng)計特征、概率分布、降維、過采樣/欠采樣、貝葉斯統(tǒng)計


等你來譯:

基于圖像的路徑規(guī)劃:Dijkstra算法

掌握機器學(xué)習(xí)必須要了解的4個概念

正向和反向運動學(xué):雅可比和微分運動

取得自然語言處理SOA結(jié)果的分層多任務(wù)學(xué)習(xí)模型(HMTL) 


雷峰網(wǎng)原創(chuàng)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。

如何用PyTorch訓(xùn)練圖像分類器

分享:
相關(guān)文章

知情人士

AI研習(xí)社(yanxishe.com)譯站頻道,傳播前沿人工智能知識,讓語言不再成為學(xué)習(xí)知識的門檻。(原雷鋒字幕組)
當(dāng)月熱門文章
最新文章
請?zhí)顚懮暾埲速Y料
姓名
電話
郵箱
微信號
作品鏈接
個人簡介
為了您的賬戶安全,請驗證郵箱
您的郵箱還未驗證,完成可獲20積分喲!
請驗證您的郵箱
立即驗證
完善賬號信息
您的賬號已經(jīng)綁定,現(xiàn)在您可以設(shè)置密碼以方便用郵箱登錄
立即設(shè)置 以后再說