柚子快報(bào)邀請(qǐng)碼778899分享:算法 pytorch的學(xué)習(xí)筆記
柚子快報(bào)邀請(qǐng)碼778899分享:算法 pytorch的學(xué)習(xí)筆記
一 cuda
??2006年,NVIDIA公司發(fā)布了CUDA(Compute Unified Device Architecture),是一種新的操作GPU計(jì)算的硬件和軟件架構(gòu),是建立在NVIDIA的GPUs上的一個(gè)通用并行計(jì)算平臺(tái)和編程模型,它提供了GPU編程的簡易接口,基于CUDA編程可以構(gòu)建基于GPU計(jì)算的應(yīng)用程序。 ??CPU是用于負(fù)責(zé)邏輯性比較強(qiáng)的計(jì)算,GPU專注于執(zhí)行高度線程化的并行處理任務(wù)。所以在GPU執(zhí)行計(jì)算任務(wù)的時(shí)候GPU和CPU是聯(lián)合執(zhí)行任務(wù)的,并且GPU是作為CPU的“運(yùn)算輔助結(jié)構(gòu)”。 CPU所在位置稱為為主機(jī)端(host),而GPU所在位置稱為設(shè)備端(device)。 ??下面就是本機(jī)pytorch的cuda是否可以工作的代碼:
import torch
print(torch.cuda.is_available())
??結(jié)果為True,顯然是可以工作的
二 pytorch加載數(shù)據(jù)
(1)Dataset
??Dataset是里面的一個(gè)需要繼承以及重寫的類,這個(gè)類通常是用于提供一種方式去獲取每一個(gè)條數(shù)據(jù)以及對(duì)應(yīng)數(shù)據(jù)的label。在這個(gè)類當(dāng)中我們要寫三個(gè)方法
①__init__(self)
??這個(gè)方法用于構(gòu)造一些全局變量,便于接下來幾個(gè)方法的調(diào)用。如圖所示:
②__getitem__(self,index):
??getitem方法是python類編程里面的一種非常神奇的方法,如果給類定義了__getitem__方法,則當(dāng)按照鍵取值時(shí),可以直接返回__getitem__方法執(zhí)行的結(jié)果。如下圖所示: ??這里程序的輸出結(jié)果是
15
15
15,我們可以看出
s
[
5
]
s[5]
s[5]當(dāng)中的
5
5
5作為參數(shù)被傳了進(jìn)去,并且直接返回了__getitem__(5)執(zhí)行的結(jié)果 ??我們就要利用__getitem__方法這一個(gè)特性來返回?cái)?shù)據(jù)集里面每一條數(shù)據(jù)以及對(duì)應(yīng)的標(biāo)簽,如下圖所示:
③__len__(self,index):返回?cái)?shù)據(jù)集的大小
def __len__(self):
return len(self.imformation)
??一般在編程的時(shí)候先在__init__(self)里面就要分好類而后將其設(shè)置為全局變量,后面的方法不用再做類似的事情。后面的兩個(gè)方法就各司其職。
(2)DataLoader
??dataloader 是一個(gè)加載器,將數(shù)據(jù)加載到神經(jīng)網(wǎng)絡(luò)中。類比成手(神經(jīng)網(wǎng)絡(luò)),dataloader 每次從dataset 中去取數(shù)據(jù),怎么取,通過 dataloader 參數(shù)進(jìn)行設(shè)置??梢允褂靡韵聟?shù)進(jìn)行初始化, ??代碼如下所示:
test_loader = DataLoader(dataset=test_data, batch_size=64, shuffle=False)
for data in test_loader:
imgs, targets = data
??代碼中的每一個(gè)
d
a
t
a
data
data里面都有
64
64
64個(gè)加載的數(shù)據(jù)集里面的訓(xùn)練樣本
三 torch.nn(搭建網(wǎng)絡(luò)與傳播過程要用到)
??我們咋愛搭建網(wǎng)絡(luò)的時(shí)候一般要重寫兩種方法 ??①__init__()方法:這種方法是初始化全局變量便于調(diào)用,如下方代碼:
def __init__(self):
super().__init__()
self.Sigmoid=torch.nn.Sigmoid()
??在以后的
f
o
r
w
a
r
d
forward
forward函數(shù)里面
S
i
g
m
o
i
d
Sigmoid
Sigmoid就是非線性激活函數(shù)
S
i
g
m
o
i
d
Sigmoid
Sigmoid,方便還可以使用
n
n
.
S
e
q
u
e
n
t
i
a
l
nn.Sequential
nn.Sequential來把一堆結(jié)構(gòu)連起來當(dāng)作一個(gè)完整的架構(gòu)如下所示:
self.classifier=nn.Sequential(
nn.Linear(6*6*128,2048),
nn.ReLU(inplace=True),
nn.Dropout(0.5),
nn.Linear(2048,2048),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(2048,num_classes),
)
??在
f
o
r
w
a
r
d
forward
forward函數(shù)里面
c
l
a
s
s
i
f
i
e
r
classifier
classifier就是這幾個(gè)層的集合體。
??②forward(self,x):一個(gè)forward代表了一次前向傳播的過程,并且通過類是的實(shí)例化可以直接調(diào)用,如下代碼:
class Mynetwork(nn.Module):
def __init__(self):
super().__init__()
self.Sigmoid=torch.nn.Sigmoid()
def forward(self,x):
x=self.Sigmoid(x)
return x
A=Mynetwork()
x=[1,2,3,4]
x=torch.tensor(x)
B=Mynetwork()
x=B(x)
print(x)
輸出的結(jié)果為:
四 損失函數(shù)和反向傳播
??pytorch為我們封裝了許多的Loss函數(shù)和優(yōu)化器,我們?cè)谧龇聪騻鞑サ臅r(shí)候就首先要?jiǎng)?chuàng)建這兩個(gè)實(shí)例,具體的代碼如下:
loss_fun=MSELoss()
model=Mynetwork()
optim=SGD(model.parameters(),lr=0.01)#要把模型的參數(shù)傳進(jìn)來
for data in dataloader:
input,target=data #從加載的dataloader去除取出數(shù)據(jù)
output=model(input)#前向傳播
loss=loss_fun(output,target)#使用實(shí)例化的對(duì)象計(jì)算損失函數(shù)
optim.zero_grad()#調(diào)用backward方法計(jì)算梯度之前先調(diào)用優(yōu)化器實(shí)例的zero_grad()把梯度清零
loss.backward()#調(diào)用backward方法計(jì)算梯度
optim.step()#調(diào)用優(yōu)化器的step()方法來根據(jù)backward計(jì)算出來的梯度更新參數(shù)
五 使用GPU對(duì)模型進(jìn)行訓(xùn)練
??我們?nèi)绻岩粋€(gè)東西加載到GPU里面,會(huì)寫下面所示的代碼:
if torch.cuda.is_available():
model.cuda()
??意思是GPU存在的話就把代碼的東西調(diào)入GPU當(dāng)中 ??在模型訓(xùn)練的過程當(dāng)中只有三種東西可以被載入GPU當(dāng)中
①模型(在把模型對(duì)應(yīng)的類實(shí)例化之后再后面加上代碼就行)
class Mynetwork(nn.Module):
def __init__(self):
super().__init__()
self.Sigmoid=torch.nn.Sigmoid()
def forward(self,x):
x=self.Sigmoid(x)
return x
model=Mynetwork()
if torch.cuda.is_available():
model.cuda()
②數(shù)據(jù)和lable(在把數(shù)據(jù)從dataloader取出來的時(shí)候載入)
for data in dataloader:
input,target=data #從加載的dataloader去除取出數(shù)據(jù)
if torch.cuda.is_available():
input.cuda()
target.cuda()
output=model(input)#前向傳播
③損失函數(shù)
六 模型訓(xùn)練流程
??①數(shù)據(jù)準(zhǔn)備:寫Dataset類來組織數(shù)據(jù),然后將其加載到Dataloader類里面進(jìn)行數(shù)據(jù)的訓(xùn)練。很多數(shù)據(jù)都已經(jīng)被pytorch組織成Dataset類了。但是到?jīng)]有被組織的時(shí)候通常需要自己重寫一個(gè)Dataset類來組織自己的數(shù)據(jù) ??②模型準(zhǔn)備:繼承model類來寫一個(gè)模型,通常一般放在另外一個(gè)文件里面,還可以在那里測(cè)試網(wǎng)絡(luò)的輸出: ??③模型的正式訓(xùn)練 ??(1)模擬每一個(gè)樣本的訓(xùn)練過程(包括建立優(yōu)化器和損失函數(shù)。前向傳播,計(jì)算損失值,梯度清零,計(jì)算梯度,更新參數(shù),): ??(2)在訓(xùn)練的過程當(dāng)中可以設(shè)置一些數(shù)例如損失函數(shù),驗(yàn)證集的準(zhǔn)確率得到來反映模型在訓(xùn)練過程中的效果變化。 ??(3)模型保存
??(4)兩條特殊指令model.train()和model.eval ??1 model.train() ??啟用 Batch Normalization 和 Dropout。如果模型中有BN層(Batch Normalization)和Dropout,需要在訓(xùn)練時(shí)添加model.train()。model.train()作用:對(duì)BN層,保證BN層能夠用到每一批數(shù)據(jù)的均值和方差,并進(jìn)行計(jì)算更新;對(duì)于Dropout,model.train()是隨機(jī)取一部分網(wǎng)絡(luò)連接來訓(xùn)練更新參數(shù)。 ??2. model.eval() ??如果模型中有BN層(Batch Normalization)和Dropout,在測(cè)試時(shí)添加model.eval()。model.eval()是保證BN層直接利用之前訓(xùn)練階段得到的均值和方差,即測(cè)試過程中要保證BN層的均值和方差不變;對(duì)于Dropout,model.eval()是利用到了所有網(wǎng)絡(luò)連接,即不進(jìn)行隨機(jī)舍棄神經(jīng)元。
柚子快報(bào)邀請(qǐng)碼778899分享:算法 pytorch的學(xué)習(xí)筆記
參考文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。