一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

教你用PyTorch快速準(zhǔn)確地建立神經(jīng)網(wǎng)絡(luò)

電子工程師 ? 來(lái)源:lq ? 2019-02-11 14:33 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

你可能已經(jīng)在社交媒體上看到過(guò)N次關(guān)于PyTorch和TensorFlow的兩極分化的爭(zhēng)論。這些框架的普及推動(dòng)了近年來(lái)深度學(xué)習(xí)的興起。二者都不乏堅(jiān)定的支持者,但在過(guò)去的一年里,一個(gè)明顯的贏家已經(jīng)開(kāi)始出現(xiàn)。

PyTorch是2018年最流行的框架之一。它已迅速成為學(xué)術(shù)界和工業(yè)界研究人員的首選深度學(xué)習(xí)框架。在過(guò)去幾周使用了PyTorch之后,我體會(huì)到它是一個(gè)非常靈活且易于使用的深度學(xué)習(xí)庫(kù)。

在本文中,我們將探討PyTorch的全部?jī)?nèi)容。我們將不止學(xué)習(xí)理論-還包括編寫4個(gè)不同的用例,看看PyTorch的表現(xiàn)如何。建立深度學(xué)習(xí)模型從來(lái)沒(méi)有這么有趣過(guò)!

注:本文假設(shè)你對(duì)深度學(xué)習(xí)概念已經(jīng)有了基本的理解。如果沒(méi)有,我建議閱讀下文。

內(nèi)容

什么是PyTorch?

利用PyTorch構(gòu)建神經(jīng)網(wǎng)絡(luò)

用例1:手寫數(shù)字分類(數(shù)字?jǐn)?shù)據(jù),MLP)

用例2:物體圖像分類(圖像數(shù)據(jù),CNN)

用例3:情感文本分類(文本數(shù)據(jù),RNN)

用例4:圖像樣式的遷移(遷移學(xué)習(xí))

什么是PyTorch?

在深入研究PyTorch的實(shí)現(xiàn)之前,讓我們先了解一下PyTorch是什么,以及為什么它最近會(huì)變得如此流行。

PyTorch是一個(gè)基于Python的科學(xué)計(jì)算包,類似于NumPy,它具備GPU附加功能。與此同時(shí),它也是一個(gè)深度學(xué)習(xí)框架,為實(shí)現(xiàn)和構(gòu)建深層神經(jīng)網(wǎng)絡(luò)體系結(jié)構(gòu)提供了最大程度的靈活性和速度。

最近發(fā)布的PyTorch 1.0幫助研究人員應(yīng)對(duì)以下四大挑戰(zhàn):

大面積的返工

耗時(shí)的訓(xùn)練

Python語(yǔ)言缺乏靈活性

慢速擴(kuò)展

從本質(zhì)上講,PyTorch與其他深度學(xué)習(xí)框架有兩個(gè)不同點(diǎn):

命令式編程

動(dòng)態(tài)計(jì)算圖

命令式編程:PyTorch在遍歷每一行代碼的同時(shí)執(zhí)行計(jì)算,這與Python程序的執(zhí)行方式非常類似,這一概念稱為命令式編程,它的最大優(yōu)點(diǎn)是可以動(dòng)態(tài)地調(diào)試代碼和編程邏輯。

動(dòng)態(tài)計(jì)算圖:PyTorch被稱為“由運(yùn)行定義的”框架,這意味著計(jì)算圖結(jié)構(gòu)(神經(jīng)網(wǎng)絡(luò)體系結(jié)構(gòu))是在運(yùn)行時(shí)生成的。該屬性的主要優(yōu)點(diǎn)是:它提供了一個(gè)靈活的編程運(yùn)行時(shí)接口,通過(guò)連接操作來(lái)方便系統(tǒng)的構(gòu)建和修改。在PyTorch中,每個(gè)前向通路處定義一個(gè)新的計(jì)算圖,這與使用靜態(tài)圖的TensorFlow形成了鮮明的對(duì)比。

PyTorch1.0附帶了一個(gè)名為torch.jit的重要特性,它是一個(gè)高級(jí)編譯器,允許用戶分離模型和代碼。此外,它還支持在定制硬件(如GPU或TPU)上進(jìn)行有效的模型優(yōu)化。

用PyTorch構(gòu)建神經(jīng)網(wǎng)絡(luò)

讓我們通過(guò)一個(gè)實(shí)際案例來(lái)理解PyTorch。學(xué)習(xí)理論固然好,但是如果你不把它付諸實(shí)踐的話,它就沒(méi)有多大用處了!

神經(jīng)網(wǎng)絡(luò)的PyTorch實(shí)現(xiàn)看起來(lái)與NumPy實(shí)現(xiàn)完全一樣。本節(jié)的目標(biāo)是展示PyTorch和NumPy的等效性質(zhì)。為此,讓我們創(chuàng)建一個(gè)簡(jiǎn)單的三層網(wǎng)絡(luò),在輸入層中有5個(gè)節(jié)點(diǎn),在隱藏層中有3個(gè)節(jié)點(diǎn),在輸出層中有1個(gè)節(jié)點(diǎn)。我們只使用一個(gè)帶有五個(gè)特征和一個(gè)目標(biāo)的單行訓(xùn)練示例。

import torchn_input, n_hidden, n_output = 5, 3, 1

第一步是進(jìn)行參數(shù)初始化。這里,每個(gè)層的權(quán)重和偏置參數(shù)被初始化為張量變量。張量是PyTorch的基本數(shù)據(jù)結(jié)構(gòu),用于建立不同類型的神經(jīng)網(wǎng)絡(luò)。可以將它們當(dāng)作是數(shù)組和矩陣的推廣,換句話說(shuō),張量是N維矩陣。

## initialize tensor for inputs, and outputsx = torch.randn((1, n_input))y = torch.randn((1, n_output))## initialize tensor variables for weightsw1 = torch.randn(n_input, n_hidden) # weight for hidden layerw2 = torch.randn(n_hidden, n_output) # weight for output layer## initialize tensor variables for bias termsb1 = torch.randn((1, n_hidden)) # bias for hidden layerb2 = torch.randn((1, n_output)) # bias for output layer

在參數(shù)初始化完成之后,可以通過(guò)以下四個(gè)關(guān)鍵步驟來(lái)定義和訓(xùn)練神經(jīng)網(wǎng)絡(luò):

前向傳播

損失計(jì)算

反向傳播

更新參數(shù)

讓我們更詳細(xì)地了解每一個(gè)步驟。

前向傳播:在這個(gè)步驟中,每個(gè)層都使用以下兩個(gè)公式計(jì)算激活流。這些激活流從輸入層流向輸出層,以生成最終輸出。

1. z = weight * input + bias2. a = activation_function (z)

下面的代碼塊顯示了如何用PyTorch編寫這些步驟。請(qǐng)注意,大多數(shù)函數(shù),如指數(shù)和矩陣乘法,均與NumPy中的函數(shù)相類似。

## sigmoid activation function using pytorchdef sigmoid_activation(z): return 1 / (1 + torch.exp(-z))## activation of hidden layerz1 = torch.mm(x, w1) + b1a1 = sigmoid_activation(z1)## activation (output) of final layerz2 = torch.mm(a1, w2) + b2output = sigmoid_activation(z2)

損失計(jì)算:這一步在輸出層中計(jì)算誤差(也稱為損失)。一個(gè)簡(jiǎn)單的損失函數(shù)可以用來(lái)衡量實(shí)際值和預(yù)測(cè)值之間的差異。稍后,我們將查看PyTorch中可用的不同類型的損失函數(shù)。

loss = y - output

反向傳播:這一步的目的是通過(guò)對(duì)偏差和權(quán)重進(jìn)行邊際變化,從而將輸出層的誤差降到最低,邊際變化是利用誤差項(xiàng)的導(dǎo)數(shù)計(jì)算出來(lái)的。

根據(jù)鏈規(guī)則的微積分原理,將增量變化返回到隱藏層,并對(duì)其權(quán)重和偏差進(jìn)行相應(yīng)的修正。通過(guò)對(duì)權(quán)重和偏差的調(diào)整,使得誤差最小化。

## function to calculate the derivative of activationdef sigmoid_delta(x): return x * (1 - x)## compute derivative of error termsdelta_output = sigmoid_delta(output)delta_hidden = sigmoid_delta(a1)## backpass the changes to previous layersd_outp = loss * delta_outputloss_h = torch.mm(d_outp, w2.t())d_hidn = loss_h * delta_hidden

更新參數(shù):最后一步,利用從上述反向傳播中接收到的增量變化來(lái)對(duì)權(quán)重和偏差進(jìn)行更新。

learning_rate = 0.1w2 += torch.mm(a1.t(), d_outp) * learning_ratew1 += torch.mm(x.t(), d_hidn) * learning_rateb2 += d_outp.sum() * learning_rateb1 += d_hidn.sum() * learning_rate

當(dāng)使用大量訓(xùn)練示例對(duì)多個(gè)歷元執(zhí)行這些步驟時(shí),損失將降至最小值。得到最終的權(quán)重和偏差值之后,用它對(duì)未知數(shù)據(jù)進(jìn)行預(yù)測(cè)。

用例1:手寫數(shù)字分類

在上一節(jié)中,我們看到了用PyTorch編寫神經(jīng)網(wǎng)絡(luò)的簡(jiǎn)單用例。在本節(jié)中,我們將利用PyTorch提供的不同的實(shí)用程序包(nn、autograd、Optimm、torchvision、torchtext等)來(lái)建立和訓(xùn)練神經(jīng)網(wǎng)絡(luò)。

利用這些包可以方便地定義和管理神經(jīng)網(wǎng)絡(luò)。在這個(gè)用例中,我們將創(chuàng)建一個(gè)多層感知器(MLP)網(wǎng)絡(luò),用于構(gòu)建手寫數(shù)字分類器。我們將使用torchvision包中的MNIST數(shù)據(jù)集。

與你將要從事的任何項(xiàng)目一樣,第一步是數(shù)據(jù)預(yù)處理:首先需要將原始數(shù)據(jù)集轉(zhuǎn)換為張量,并在固定范圍內(nèi)將其歸一化。torchvision包提供了一個(gè)名為transforms的實(shí)用程序,利用它可以將不同的轉(zhuǎn)換組合在一起。

from torchvision import transforms_tasks = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) ])

第一個(gè)轉(zhuǎn)換是將原始數(shù)據(jù)轉(zhuǎn)換為張量,第二個(gè)轉(zhuǎn)換是通過(guò)以下操作執(zhí)行歸一化:

x_normalized = x-mean / std

數(shù)值為0.5,0.5表示紅色、綠色和藍(lán)色三個(gè)通道的均值和標(biāo)準(zhǔn)差。

from torchvision.datasets import MNIST## Load MNIST Dataset and apply transformationsmnist = MNIST("data", download=True, train=True, transform=_tasks)

PyTorch的另一個(gè)出色的實(shí)用工具是DataLoader迭代器,它為多個(gè)處理器之間并行地批處理、搬移和加載數(shù)據(jù)提供了實(shí)現(xiàn)的可能。為了評(píng)估這個(gè)模型,我們將數(shù)據(jù)集劃分為訓(xùn)練集和驗(yàn)證集。

from torch.utils.data import DataLoaderfrom torch.utils.data.sampler import SubsetRandomSampler## create training and validation splitsplit = int(0.8 * len(mnist))index_list = list(range(len(mnist)))train_idx, valid_idx = index_list[:split], index_list[split:]## create sampler objects using SubsetRandomSamplertr_sampler = SubsetRandomSampler(train_idx)val_sampler = SubsetRandomSampler(valid_idx)## create iterator objects for train and valid datasetstrainloader = DataLoader(mnist, batch_size=256, sampler=tr_sampler)validloader = DataLoader(mnist, batch_size=256, sampler=val_sampler)

PyTorch中的神經(jīng)網(wǎng)絡(luò)架構(gòu)可以定義為一個(gè)類,這個(gè)類繼承了稱為Module的nn包的基礎(chǔ)類的所有屬性。來(lái)自nn.Module類的繼承使得我們可以輕松地實(shí)現(xiàn)、訪問(wèn)和調(diào)用多個(gè)方法,還可以定義類的構(gòu)造函數(shù)中的各個(gè)層,以及前向傳播步驟中的前向函數(shù)。

我們將定義一個(gè)具有以下層配置的網(wǎng)絡(luò):[784,128,10]。此配置表示輸入層中有784個(gè)節(jié)點(diǎn)(28*28像素)、隱藏層中有128個(gè)節(jié)點(diǎn),輸出層中有10個(gè)節(jié)點(diǎn)。在前向函數(shù)中,我們將在隱藏層(可以通過(guò)nn模塊訪問(wèn))中使用Sigmoid激活函數(shù)。

import torch.nn.functional as Fclass Model(nn.Module): def __init__(self): super().__init__() self.hidden = nn.Linear(784, 128) self.output = nn.Linear(128, 10) def forward(self, x): x = self.hidden(x) x = F.sigmoid(x) x = self.output(x) return xmodel = Model()

利用nn和Optim包定義損失函數(shù)和優(yōu)化器:

from torch import optimloss_function = nn.CrossEntropyLoss()optimizer = optim.SGD(model.parameters(), lr=0.01, weight_decay= 1e-6, momentum = 0.9, nesterov = True)

現(xiàn)在已經(jīng)準(zhǔn)備好,可以開(kāi)始訓(xùn)練模型了,其核心步驟與前一節(jié)相同:前向傳播、損失計(jì)算、反向傳播和更新參數(shù)。

for epoch in range(1, 11): ## run the model for 10 epochs train_loss, valid_loss = [], [] ## training part model.train() for data, target in trainloader: optimizer.zero_grad() ## 1. forward propagation output = model(data) ## 2. loss calculation loss = loss_function(output, target) ## 3. backward propagation loss.backward() ## 4. weight optimization optimizer.step() train_loss.append(loss.item()) ## evaluation part model.eval() for data, target in validloader: output = model(data) loss = loss_function(output, target) valid_loss.append(loss.item()) print ("Epoch:", epoch, "Training Loss: ", np.mean(train_loss), "Valid Loss: ", np.mean(valid_loss))>> Epoch: 1 Training Loss: 0.645777 Valid Loss: 0.344971>> Epoch: 2 Training Loss: 0.320241 Valid Loss: 0.299313>> Epoch: 3 Training Loss: 0.278429 Valid Loss: 0.269018>> Epoch: 4 Training Loss: 0.246289 Valid Loss: 0.237785>> Epoch: 5 Training Loss: 0.217010 Valid Loss: 0.217133>> Epoch: 6 Training Loss: 0.193017 Valid Loss: 0.206074>> Epoch: 7 Training Loss: 0.174385 Valid Loss: 0.180163>> Epoch: 8 Training Loss: 0.157574 Valid Loss: 0.170064>> Epoch: 9 Training Loss: 0.144316 Valid Loss: 0.162660>> Epoch: 10 Training Loss: 0.133053 Valid Loss: 0.152957

完成了模型的訓(xùn)練之后,即可在驗(yàn)證數(shù)據(jù)基礎(chǔ)上進(jìn)行預(yù)測(cè)。

## dataloader for validation datasetdataiter = iter(validloader)data, labels = dataiter.next()output = model(data)_, preds_tensor = torch.max(output, 1)preds = np.squeeze(preds_tensor.numpy())print ("Actual:", labels[:10])print ("Predicted:", preds[:10])>>> Actual: [0 1 1 1 2 2 8 8 2 8]>>> Predicted: [0 1 1 1 2 2 8 8 2 8]

用例2:物體圖像分類

現(xiàn)在讓我們更進(jìn)一步。

在這個(gè)用例中,我們將在PyTorch中創(chuàng)建卷積神經(jīng)網(wǎng)絡(luò)(CNN)架構(gòu),利用流行的CIFAR-10數(shù)據(jù)集進(jìn)行物體圖像分類,此數(shù)據(jù)集也包含在torchvision包中。定義和訓(xùn)練模型的整個(gè)過(guò)程將與以前的用例相同,唯一的區(qū)別只是在網(wǎng)絡(luò)中引入了額外的層。

加載并轉(zhuǎn)換數(shù)據(jù)集:

## load the datasetfrom torchvision.datasets import CIFAR10cifar = CIFAR10('data', train=True, download=True, transform=_tasks)## create training and validation splitsplit = int(0.8 * len(cifar))index_list = list(range(len(cifar)))train_idx, valid_idx = index_list[:split], index_list[split:]## create training and validation sampler objectstr_sampler = SubsetRandomSampler(train_idx)val_sampler = SubsetRandomSampler(valid_idx)## create iterator objects for train and valid datasetstrainloader = DataLoader(cifar, batch_size=256, sampler=tr_sampler)validloader = DataLoader(cifar, batch_size=256, sampler=val_sampler)

我們將創(chuàng)建三個(gè)用于低層特征提取的卷積層、三個(gè)用于最大信息量提取的池化層和兩個(gè)用于線性分類的線性層。

class Model(nn.Module): def __init__(self): super(Model, self).__init__() ## define the layers self.conv1 = nn.Conv2d(3, 16, 3, padding=1) self.conv2 = nn.Conv2d(16, 32, 3, padding=1) self.conv3 = nn.Conv2d(32, 64, 3, padding=1) self.pool = nn.MaxPool2d(2, 2) self.linear1 = nn.Linear(1024, 512) self.linear2 = nn.Linear(512, 10) def forward(self, x): x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = self.pool(F.relu(self.conv3(x))) x = x.view(-1, 1024) ## reshaping x = F.relu(self.linear1(x)) x = self.linear2(x) return xmodel = Model()

定義損失函數(shù)和優(yōu)化器:

import torch.optim as optimloss_function = nn.CrossEntropyLoss()optimizer = optim.SGD(model.parameters(), lr=0.01, weight_decay= 1e-6, momentum = 0.9, nesterov = True)## run for 30 Epochsfor epoch in range(1, 31): train_loss, valid_loss = [], [] ## training part model.train() for data, target in trainloader: optimizer.zero_grad() output = model(data) loss = loss_function(output, target) loss.backward() optimizer.step() train_loss.append(loss.item()) ## evaluation part model.eval() for data, target in validloader: output = model(data) loss = loss_function(output, target) valid_loss.append(loss.item())

完成了模型的訓(xùn)練之后,即可在驗(yàn)證數(shù)據(jù)基礎(chǔ)上進(jìn)行預(yù)測(cè)。

## dataloader for validation datasetdataiter = iter(validloader)data, labels = dataiter.next()output = model(data)_, preds_tensor = torch.max(output, 1)preds = np.squeeze(preds_tensor.numpy())print ("Actual:", labels[:10])print ("Predicted:", preds[:10])Actual: ['truck', 'truck', 'truck', 'horse', 'bird', 'truck', 'ship', 'bird', 'deer', 'bird']Pred: ['truck', 'automobile', 'automobile', 'horse', 'bird', 'airplane', 'ship', 'bird', 'deer', 'bird']

用例3:情感文本分類

我們將從計(jì)算機(jī)視覺(jué)用例轉(zhuǎn)向自然語(yǔ)言處理,目的是展示PyTorch在不同領(lǐng)域的不同應(yīng)用。

在本節(jié)中,我們將利用基于RNN(遞歸神經(jīng)網(wǎng)絡(luò))和LSTM(長(zhǎng)短期記憶)層的Pyotch來(lái)完成文本分類任務(wù)。首先,加載包含兩個(gè)字段(文本和目標(biāo))的數(shù)據(jù)集。目標(biāo)包含兩個(gè)類:class1和class2,我們的任務(wù)是將每個(gè)文本分為其中一個(gè)類。

可以在下面的鏈接中下載數(shù)據(jù)集。

https://s3-ap-south-1.amazonaws.com/av-blog-media/wp-content/uploads/2019/01/train.csv

train = pd.read_csv("train.csv")x_train = train["text"].valuesy_train = train['target'].values

強(qiáng)烈建議在編碼之前先設(shè)置種子,它可以保證你看到的結(jié)果與我的相同-這是在學(xué)習(xí)新概念時(shí)非常有用(也很有益)的特征。

np.random.seed(123)torch.manual_seed(123)torch.cuda.manual_seed(123)torch.backends.cudnn.deterministic = True

在預(yù)處理步驟中,首先將文本數(shù)據(jù)轉(zhuǎn)換為tokens序列,之后便可以將其傳遞到嵌入層。我將利用Keras包中提供的實(shí)用程序來(lái)進(jìn)行預(yù)處理,利用torchtext包也同樣可以實(shí)現(xiàn)。

from keras.preprocessing import text, sequence## create tokenstokenizer = Tokenizer(num_words = 1000)tokenizer.fit_on_texts(x_train)word_index = tokenizer.word_index## convert texts to padded sequencesx_train = tokenizer.texts_to_sequences(x_train)x_train = pad_sequences(x_train, maxlen = 70)

接下來(lái),需要將tokens轉(zhuǎn)換成向量。為此,利用預(yù)先訓(xùn)練過(guò)的GloVe詞嵌入。我們將加載這些單詞嵌入,并創(chuàng)建一個(gè)包含單詞向量的嵌入矩陣。

GloVe:

https://github.com/stanfordnlp/GloVe

EMBEDDING_FILE = 'glove.840B.300d.txt'embeddings_index = {}for i, line in enumerate(open(EMBEDDING_FILE)): val = line.split() embeddings_index[val[0]] = np.asarray(val[1:], dtype='float32')embedding_matrix = np.zeros((len(word_index) + 1, 300))for word, i in word_index.items(): embedding_vector = embeddings_index.get(word) if embedding_vector is not None: embedding_matrix[i] = embedding_vector

使用嵌入層和LSTM層定義模型架構(gòu):

class Model(nn.Module): def __init__(self): super(Model, self).__init__() ## Embedding Layer, Add parameter self.embedding = nn.Embedding(max_features, embed_size) et = torch.tensor(embedding_matrix, dtype=torch.float32) self.embedding.weight = nn.Parameter(et) self.embedding.weight.requires_grad = False self.embedding_dropout = nn.Dropout2d(0.1) self.lstm = nn.LSTM(300, 40) self.linear = nn.Linear(40, 16) self.out = nn.Linear(16, 1) self.relu = nn.ReLU() def forward(self, x): h_embedding = self.embedding(x) h_lstm, _ = self.lstm(h_embedding) max_pool, _ = torch.max(h_lstm, 1) linear = self.relu(self.linear(max_pool)) out = self.out(linear) return outmodel = Model()

創(chuàng)建訓(xùn)練和驗(yàn)證集:

from torch.utils.data import TensorDataset## create training and validation splitsplit_size = int(0.8 * len(train_df))index_list = list(range(len(train_df)))train_idx, valid_idx = index_list[:split], index_list[split:]## create iterator objects for train and valid datasetsx_tr = torch.tensor(x_train[train_idx], dtype=torch.long)y_tr = torch.tensor(y_train[train_idx], dtype=torch.float32)train = TensorDataset(x_tr, y_tr)trainloader = DataLoader(train, batch_size=128)x_val = torch.tensor(x_train[valid_idx], dtype=torch.long)y_val = torch.tensor(y_train[valid_idx], dtype=torch.float32)valid = TensorDataset(x_val, y_val)validloader = DataLoader(valid, batch_size=128)

定義損失和優(yōu)化器:

loss_function = nn.BCEWithLogitsLoss(reduction='mean')optimizer = optim.Adam(model.parameters())

訓(xùn)練模型:

## run for 10 Epochsfor epoch in range(1, 11): train_loss, valid_loss = [], []## training part model.train() for data, target in trainloader: optimizer.zero_grad() output = model(data) loss = loss_function(output, target.view(-1,1)) loss.backward() optimizer.step() train_loss.append(loss.item()) ## evaluation part model.eval() for data, target in validloader: output = model(data) loss = loss_function(output, target.view(-1,1)) valid_loss.append(loss.item())

最后得到預(yù)測(cè)結(jié)果:

dataiter = iter(validloader)data, labels = dataiter.next()output = model(data)_, preds_tensor = torch.max(output, 1)preds = np.squeeze(preds_tensor.numpy())Actual: [0 1 1 1 1 0 0 0 0]Predicted: [0 1 1 1 1 1 1 1 0 0]

用例4:圖像樣式遷移

讓我們來(lái)看最后一個(gè)用例,在這里我們將執(zhí)行圖形樣式的遷移。這是我經(jīng)歷過(guò)的最有創(chuàng)意的項(xiàng)目之一,希望你也能玩得開(kāi)心。樣式遷移概念背后的基本理念是:

從一幅圖像中獲取對(duì)象/內(nèi)容

從另一幅圖像中獲取樣式/紋理

生成二者混合的最終圖像

“利用卷積網(wǎng)絡(luò)進(jìn)行圖像樣式遷移”這篇論文中對(duì)這一概念做了介紹,樣式遷移的一個(gè)例子如下:

太棒了,對(duì)吧?讓我們看看它在PyTorch中是如何實(shí)現(xiàn)的。這一進(jìn)程包括六個(gè)步驟:

從兩個(gè)輸入圖像中提取低層特征。這可以使用VGG 19這樣的預(yù)訓(xùn)練的深度學(xué)習(xí)模型。

from torchvision import models# get the features portion from VGG19vgg = models.vgg19(pretrained=True).features# freeze all VGG parametersfor param in vgg.parameters(): param.requires_grad_(False)# check if GPU is availabledevice = torch.device("cpu")if torch.cuda.is_available(): device = torch.device("cuda")vgg.to(device)

將這兩幅圖像加載到設(shè)備上,并從VGG中獲取特征。另外,也可以應(yīng)用以下轉(zhuǎn)換:調(diào)整張量的大小,以及值的歸一化。

from torchvision import transforms as tfdef transformation(img): tasks = tf.Compose([tf.Resize(400), tf.ToTensor(), tf.Normalize((0.44,0.44,0.44),(0.22,0.22,0.22))]) img = tasks(img)[:3,:,:].unsqueeze(0) return imgimg1 = Image.open("image1.jpg").convert('RGB')img2 = Image.open("image2.jpg").convert('RGB')img1 = transformation(img1).to(device)img2 = transformation(img2).to(device)

現(xiàn)在,我們需要獲得這兩幅圖像的相關(guān)特征。從第一個(gè)圖像中,我們需要提取內(nèi)容或與存在的對(duì)象相關(guān)的特征;從第二張圖像中,我們需要提取與樣式和紋理相關(guān)的特征。

對(duì)象相關(guān)特征:在最初的文章中,作者建議可以從網(wǎng)絡(luò)的初始層中提取更有價(jià)值的對(duì)象和內(nèi)容,這是因?yàn)樵谳^高層上,信息空間變得更為復(fù)雜,像素信息細(xì)節(jié)在高層往往會(huì)丟失。

樣式相關(guān)特征:為了從第二幅圖像中獲取樣式和紋理信息,作者在不同層次上使用了不同特征之間的相關(guān)性,下文第4點(diǎn)對(duì)此作了詳細(xì)解釋。

在實(shí)現(xiàn)這一目標(biāo)之前,讓我們來(lái)看看一個(gè)典型的VGG 19模型的結(jié)構(gòu):

對(duì)象信息提取用到的是CONV42層,它位于第4個(gè)卷積塊中,深度為512。對(duì)于樣式的表達(dá),用到的層是網(wǎng)絡(luò)中每個(gè)卷積塊的第一卷積層,即CONV11、CONV21、CONV31、CONV41和CONV51,這些層的選取純粹是根據(jù)作者的經(jīng)驗(yàn)來(lái)做出選擇,我僅在本文中復(fù)制它們的結(jié)果。

def get_features(image, model): layers = {'0': 'conv1_1', '5': 'conv2_1', '10': 'conv3_1', '19': 'conv4_1', '21': 'conv4_2', '28': 'conv5_1'} x = image features = {} for name, layer in model._modules.items(): x = layer(x) if name in layers: features[layers[name]] = x return featuresimg1_features = get_features(img1, vgg)img2_features = get_features(img2, vgg)

正如前面提到的,作者使用不同層次的相關(guān)性來(lái)獲得與樣式相關(guān)的特征。這些特征的相關(guān)性由Gram矩陣G給出,其中G中的每個(gè)單元(i,j)都是層中向量特征映射i和j之間的內(nèi)積。

def correlation_matrix(tensor): _, d, h, w = tensor.size() tensor = tensor.view(d, h * w) correlation = torch.mm(tensor, tensor.t()) return correlationcorrelations = {l: correlation_matrix(img2_features[l]) for l in img2_features}

最終,可以利用這些特征和相關(guān)性進(jìn)行樣式轉(zhuǎn)換。現(xiàn)在,為了將樣式從一個(gè)圖像轉(zhuǎn)換到另一個(gè)圖像,需要設(shè)置用于獲取樣式特征的每一層的權(quán)重。如上所述,由于初始層提供了更多的信息,因此可以為初始層設(shè)置更高的權(quán)重。此外,定義優(yōu)化器函數(shù)和目標(biāo)圖像,也即是圖像1的副本。

weights = {'conv1_1': 1.0, 'conv2_1': 0.8, 'conv3_1': 0.25, 'conv4_1': 0.21, 'conv5_1': 0.18}target = img1.clone().requires_grad_(True).to(device)optimizer = optim.Adam([target], lr=0.003)

啟動(dòng)損失最小化處理過(guò)程:即在循環(huán)中運(yùn)行大量步驟,來(lái)計(jì)算與對(duì)象特征提取和樣式特征提取相關(guān)的損失。利用最小化后的損失,更新網(wǎng)絡(luò)參數(shù),進(jìn)一步修正目標(biāo)圖像。經(jīng)過(guò)一些迭代之后,將生成更新后的圖像。

for ii in range(1, 2001): ## calculate the content loss (from image 1 and target) target_features = get_features(target, vgg) loss = target_features['conv4_2'] - img1_features['conv4_2'] content_loss = torch.mean((loss)**2) ## calculate the style loss (from image 2 and target) style_loss = 0 for layer in weights: target_feature = target_features[layer] target_corr = correlation_matrix(target_feature) style_corr = correlations[layer] layer_loss = torch.mean((target_corr - style_corr)**2) layer_loss *= weights[layer] _, d, h, w = target_feature.shape style_loss += layer_loss / (d * h * w) total_loss = 1e6 * style_loss + content_loss optimizer.zero_grad() total_loss.backward() optimizer.step()

最后,我們可以看到預(yù)測(cè)的結(jié)果,在這里我只運(yùn)行了一小部分迭代,還可以運(yùn)行多達(dá)3000次迭代(如果計(jì)算資源足夠多的話!)。

def tensor_to_image(tensor): image = tensor.to("cpu").clone().detach() image = image.numpy().squeeze() image = image.transpose(1, 2, 0) image *= np.array((0.22, 0.22, 0.22)) + np.array((0.44, 0.44, 0.44)) image = image.clip(0, 1) return imagefig, (ax1, ax2) = plt.subplots(1, 2, figsize=(20, 10))ax1.imshow(tensor_to_image(img1))ax2.imshow(tensor_to_image(target))

后記

PyTorch還可以實(shí)現(xiàn)大量的其他用例,它很快成為全球研究人員的寵兒。絕大多數(shù)PyTorch實(shí)現(xiàn)的開(kāi)源庫(kù)和開(kāi)發(fā)應(yīng)用可以在Github上看到。

在本文中,我闡述了什么是PyTorch,以及如何用PyTorch實(shí)現(xiàn)不同的用例,當(dāng)然,這個(gè)指南只是一個(gè)出發(fā)點(diǎn)。如果能提供更多的數(shù)據(jù),或進(jìn)行更多的網(wǎng)絡(luò)參數(shù)微調(diào),那么每個(gè)用例的性能都可以得到大幅度提高,最重要的是如果在構(gòu)建網(wǎng)絡(luò)體系架構(gòu)時(shí)應(yīng)用創(chuàng)新技能,也能提高用例的性能。感謝你的閱讀,并請(qǐng)?jiān)谙旅娴脑u(píng)論部分留下你的反饋。

參考文獻(xiàn)

1. 官方PyTorch指南:

https://pytorch.org/tutorials/

2. 用PyTorch進(jìn)行深度學(xué)習(xí)

https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html

3. Faizan在Analytics Vidhya上發(fā)表的文章:

https://www.analyticsvidhya.com/blog/2018/02/pytorch-tutorial/

4. 使用Pytorch的Udacity深度學(xué)習(xí):

https://github.com/udacity/deep-learning-v2-pytorch

5. 圖片樣式遷移原始論文:

https://www.cvfoundation.org/openaccess/content_cvpr_2016/papers/Gatys_Image_Style_Transfer_CVPR_2016_paper.pdf

你還可以在Analytics Vidhya的安卓APP上閱讀本文。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 神經(jīng)網(wǎng)絡(luò)

    關(guān)注

    42

    文章

    4814

    瀏覽量

    103486
  • 深度學(xué)習(xí)
    +關(guān)注

    關(guān)注

    73

    文章

    5560

    瀏覽量

    122762
  • pytorch
    +關(guān)注

    關(guān)注

    2

    文章

    809

    瀏覽量

    13930

原文標(biāo)題:手把手:教你用PyTorch快速準(zhǔn)確地建立神經(jīng)網(wǎng)絡(luò)(附4個(gè)學(xué)習(xí)用例)

文章出處:【微信號(hào):BigDataDigest,微信公眾號(hào):大數(shù)據(jù)文摘】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    【案例分享】ART神經(jīng)網(wǎng)絡(luò)與SOM神經(jīng)網(wǎng)絡(luò)

    今天學(xué)習(xí)了兩個(gè)神經(jīng)網(wǎng)絡(luò),分別是自適應(yīng)諧振(ART)神經(jīng)網(wǎng)絡(luò)與自組織映射(SOM)神經(jīng)網(wǎng)絡(luò)。整體感覺(jué)不是很難,只不過(guò)一些最基礎(chǔ)的概念容易理解不清。首先ART神經(jīng)網(wǎng)絡(luò)是競(jìng)爭(zhēng)學(xué)習(xí)的一個(gè)代表,
    發(fā)表于 07-21 04:30

    基于BP神經(jīng)網(wǎng)絡(luò)的PID控制

    神經(jīng)網(wǎng)絡(luò)可以建立參數(shù)Kp,Ki,Kd自整定的PID控制器?;贐P神經(jīng)網(wǎng)絡(luò)的PID控制系統(tǒng)結(jié)構(gòu)框圖如下圖所示:控制器由兩部分組成:經(jīng)典增量式PID控制器;BP神經(jīng)網(wǎng)絡(luò)...
    發(fā)表于 09-07 07:43

    輕量化神經(jīng)網(wǎng)絡(luò)的相關(guān)資料下載

    視覺(jué)任務(wù)中,并取得了巨大成功。然而,由于存儲(chǔ)空間和功耗的限制,神經(jīng)網(wǎng)絡(luò)模型在嵌入式設(shè)備上的存儲(chǔ)與計(jì)算仍然是一個(gè)巨大的挑戰(zhàn)。前面幾篇介紹了如何在嵌入式AI芯片上部署神經(jīng)網(wǎng)絡(luò):【嵌入式AI開(kāi)發(fā)】篇五|實(shí)戰(zhàn)篇一:STM32cubeIDE上部署
    發(fā)表于 12-14 07:35

    基于PyTorch的深度學(xué)習(xí)入門教程之使用PyTorch構(gòu)建一個(gè)神經(jīng)網(wǎng)絡(luò)

    PyTorch的自動(dòng)梯度計(jì)算 Part3:使用PyTorch構(gòu)建一個(gè)神經(jīng)網(wǎng)絡(luò) Part4:訓(xùn)練一個(gè)神經(jīng)網(wǎng)絡(luò)分類器 Part5:數(shù)據(jù)并行化 本文是關(guān)于Part3的內(nèi)容。 Part3:使
    的頭像 發(fā)表于 02-15 09:40 ?2317次閱讀

    PyTorch教程8.1之深度卷積神經(jīng)網(wǎng)絡(luò)(AlexNet)

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程8.1之深度卷積神經(jīng)網(wǎng)絡(luò)(AlexNet).pdf》資料免費(fèi)下載
    發(fā)表于 06-05 10:09 ?0次下載
    <b class='flag-5'>PyTorch</b>教程8.1之深度卷積<b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>(AlexNet)

    PyTorch教程之循環(huán)神經(jīng)網(wǎng)絡(luò)

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程之循環(huán)神經(jīng)網(wǎng)絡(luò).pdf》資料免費(fèi)下載
    發(fā)表于 06-05 09:52 ?0次下載
    <b class='flag-5'>PyTorch</b>教程之循環(huán)<b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>

    PyTorch教程之從零開(kāi)始的遞歸神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程之從零開(kāi)始的遞歸神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn).pdf》資料免費(fèi)下載
    發(fā)表于 06-05 09:55 ?0次下載
    <b class='flag-5'>PyTorch</b>教程之從零開(kāi)始的遞歸<b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>實(shí)現(xiàn)

    PyTorch教程9.6之遞歸神經(jīng)網(wǎng)絡(luò)的簡(jiǎn)潔實(shí)現(xiàn)

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程9.6之遞歸神經(jīng)網(wǎng)絡(luò)的簡(jiǎn)潔實(shí)現(xiàn).pdf》資料免費(fèi)下載
    發(fā)表于 06-05 09:56 ?0次下載
    <b class='flag-5'>PyTorch</b>教程9.6之遞歸<b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>的簡(jiǎn)潔實(shí)現(xiàn)

    PyTorch教程10.3之深度遞歸神經(jīng)網(wǎng)絡(luò)

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程10.3之深度遞歸神經(jīng)網(wǎng)絡(luò).pdf》資料免費(fèi)下載
    發(fā)表于 06-05 15:12 ?0次下載
    <b class='flag-5'>PyTorch</b>教程10.3之深度遞歸<b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>

    PyTorch教程10.4之雙向遞歸神經(jīng)網(wǎng)絡(luò)

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程10.4之雙向遞歸神經(jīng)網(wǎng)絡(luò).pdf》資料免費(fèi)下載
    發(fā)表于 06-05 15:13 ?0次下載
    <b class='flag-5'>PyTorch</b>教程10.4之雙向遞歸<b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>

    PyTorch教程16.2之情感分析:使用遞歸神經(jīng)網(wǎng)絡(luò)

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程16.2之情感分析:使用遞歸神經(jīng)網(wǎng)絡(luò).pdf》資料免費(fèi)下載
    發(fā)表于 06-05 10:55 ?0次下載
    <b class='flag-5'>PyTorch</b>教程16.2之情感分析:使用遞歸<b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>

    PyTorch教程16.3之情感分析:使用卷積神經(jīng)網(wǎng)絡(luò)

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程16.3之情感分析:使用卷積神經(jīng)網(wǎng)絡(luò).pdf》資料免費(fèi)下載
    發(fā)表于 06-05 10:56 ?0次下載
    <b class='flag-5'>PyTorch</b>教程16.3之情感分析:使用卷積<b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>

    使用PyTorch構(gòu)建神經(jīng)網(wǎng)絡(luò)

    PyTorch是一個(gè)流行的深度學(xué)習(xí)框架,它以其簡(jiǎn)潔的API和強(qiáng)大的靈活性在學(xué)術(shù)界和工業(yè)界得到了廣泛應(yīng)用。在本文中,我們將深入探討如何使用PyTorch構(gòu)建神經(jīng)網(wǎng)絡(luò),包括從基礎(chǔ)概念到高級(jí)特性的全面解析。本文旨在為讀者提供一個(gè)完整的
    的頭像 發(fā)表于 07-02 11:31 ?1079次閱讀

    PyTorch神經(jīng)網(wǎng)絡(luò)模型構(gòu)建過(guò)程

    PyTorch,作為一個(gè)廣泛使用的開(kāi)源深度學(xué)習(xí)庫(kù),提供了豐富的工具和模塊,幫助開(kāi)發(fā)者構(gòu)建、訓(xùn)練和部署神經(jīng)網(wǎng)絡(luò)模型。在神經(jīng)網(wǎng)絡(luò)模型中,輸出層是尤為關(guān)鍵的部分,它負(fù)責(zé)將模型的預(yù)測(cè)結(jié)果以合適的形式輸出。以下將詳細(xì)解析
    的頭像 發(fā)表于 07-10 14:57 ?903次閱讀

    pytorch中有神經(jīng)網(wǎng)絡(luò)模型嗎

    當(dāng)然,PyTorch是一個(gè)廣泛使用的深度學(xué)習(xí)框架,它提供了許多預(yù)訓(xùn)練的神經(jīng)網(wǎng)絡(luò)模型。 PyTorch中的神經(jīng)網(wǎng)絡(luò)模型 1. 引言 深度學(xué)習(xí)是一種基于人工
    的頭像 發(fā)表于 07-11 09:59 ?1812次閱讀