pytorch(二)——基礎

  • 聲明

以下均基於置入以下包

import torch
import numpy as np
from torch.autograd import Variable
import torchvision
import torch.nn as nn
from torchvision import transforms
  • 變量Variable

x=torch.FloatTensor([1.,2.,3.])
# x=torch.randn(3)
print(x)
x_var = Variable(x,requires_grad =True)
y=x_var*2
print(y)
y.backward(torch.FloatTensor([1,0.1,0.01]))#原本三個維度的梯度都是2,使用參數聲明後梯度乘上了[1,0.1,0.01]
print(x_var.grad,x_var.data,y.grad_fn)#變量的三個屬性:梯度、值、得到變量的操作

#result:
# tensor([1., 2., 3.])
# tensor([2., 4., 6.], grad_fn=<MulBackward>)
# tensor([2.0000, 0.2000, 0.0200]) tensor([1., 2., 3.]) <MulBackward object at 0x7f7441fcb940>

 

  • 數據集載入

test_set = torchvision.datasets.ImageFolder('dataset/test', transform=test_input_transform)
data_loader = torch.utils.data.DataLoader(test_set, batch_size=8, num_workers=2, shuffle=True)

 

  • 自定義一個網絡

class mynet(nn.Module):
    def __init__(self, dim_in, dim_out):
        super(mynet, self).__init__()
        self.main = nn.Sequential(
            nn.Conv2d(dim_in, dim_out, kernel_size=3, stride=1, padding=1, bias=False),
            nn.InstanceNorm2d(dim_out, affine=True, track_running_stats=True),
            nn.ReLU(inplace=True),
            nn.Conv2d(dim_out, dim_out, kernel_size=3, stride=1, padding=1, bias=False),
            nn.InstanceNorm2d(dim_out, affine=True, track_running_stats=True))

    def forward(self, x):
        return x + self.main(x)

sequential實現網絡層的組合,還有一種增加塊的方式定義網絡,這個方法可以對每一層加名字。

layer1=nn.Sequential()
layer1.add_module('conv1',nn.Conv2d(3,32,3,1,1))
layer1.add_module('relu1',nn.ReLu(True))
layer1.add_module('pool1',nn.Maxpool2d(2,2))
self.layer1=layer1
  • 遍歷網絡/提取網絡層結構

在檢查文件夾的文件時,有os.listdir這種一層一層的,也有os.walk這種到底的,網絡的遍歷也同樣。

class mynet(nn.Module):
    def __init__(self):
        super(mynet, self).__init__()
        layer1 = nn.Sequential()
        layer1.add_module('conv1', nn.Conv2d(3, 32, 3, 1, 1))
        layer1.add_module('relu1', nn.ReLU(True))
        layer1.add_module('pool1', nn.MaxPool2d(2, 2))
        self.layer1 = layer1

        layer2 = nn.Sequential()
        layer2.add_module('conv2', nn.Conv2d(32, 64, 3, 1, 1))
        layer2.add_module('relu2', nn.ReLU(True))
        layer2.add_module('pool2', nn.MaxPool2d(2, 2))
        self.layer2 = layer2

        layer3 = nn.Sequential()
        layer3.add_module('fc', nn.Linear(64,10))
        self.layer3 = layer3


    def forward(self, x):
        x=self.layer1(x)
        x=self.layer2(x)
        x=self.layer3(x)
        return x

model=mynet()
#.children() 下一級模塊迭代器,這裏下一級就是三層網絡
a=list(model.children())
#.modules()返回所有模塊迭代器,有點os.walk的意思,整個網絡-第一層-第一層下面各個層=第二層-。。。
b=list(model.modules())
#.named_children() 返回網絡層名字及迭代器
c=list(model.named_children())
#.named_modules() 返回網絡層名字及所有模塊迭代器
d=list(model.named_modules())

for layer in model.modules():
    # print(layer)
    print(isinstance(layer,nn.Conv2d))

 

  • 常用的層

nn.Conv2d

nn.ReLu

nn.MaxPool2d

nn.Linear

nn.Dropout()#一般放在Relu後,Linear前

全連接層前的展平操作:

x = x.view(x.size(0), -1)#from ([[batch_size, 512, 1, 1]]) to ([batch_size, 512])
  • 損失

criterion = nn.CrossEntropyLoss()#交叉熵損失
criterion = nn.MSELoss()#均方誤差
criterion = BCELoss()#二分類損失,如sigmoid輸出
loss=criterion(out,target)
  • 優化

optimizer = torch.optim.SGD(model.parameters(),lr=0.01,momentum = 0.9)
optimizer.zero_grad()#optimizer.zeros()優化之前梯度清零
loss.backward()#反向傳播
optimizer.step()#參數更新
  • 模型加載與保存

#保存模型結構及參數
torch.save(model,model_path)
load_model = torch.load(model_path)

#保存模型參數
torch.save(model.state_dict(),model_path)
model.load_state_dict(torch.load(model_path))

#遷移一部分參數
pretrained_dict = torch.load(model_path)
model_dict = model.state_dict()
pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
model_dict.update(pretrained_dict)
model.load_state_dict(model_dict)
  • 網絡測試

model.eval()

例如Dropout、BN在訓練階段和測試階段不一樣,需要eval的操作來轉換這種層的操作。

BN:

訓練:

由於在訓練階段低層更新了參數,導致高層輸入數據變化,因此在高層輸入時,加入歸一化操作(比如把第三層歸一化到均值0,方差1)

使用到的兩個參數分別爲每一批數據的均值,每一批數據的標準差。

測試:

BN一般放在全連接層後面,非線性層前面

  • 數據擴充transforms

transforms.Compose(#Compose組合預處理操作,各個操作是以list的形式存放的
    [transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5))]
)

更多transforms方式:https://blog.csdn.net/u011995719/article/details/85107009

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章