寒假学习Day 6:PyTorch学习(三)

寒假学习Day 6:PyTorch学习(三)

PyTorch

访问CNN 参数

矩阵乘法
线性层的工作原理

in_features=torch.tensor([1,2,3,4],dtype=torch.float32)
weight_matrix=torch.tensor([
[1,2,3,4],
[2,3,4,5],
[3,4,5,6]
],dtype=torch.float32)
weight_matrix.matmul(in_features)

访问参数

  • first example
for param in network.parameters():
    print(param.shape)

  • second example
for name,param in network.named_parameters():
    print(name,'\t\t',param.shape)

线性层

fc=nn.Linear(in_features=4,out_features=3)#定义一个输入特征为4,输出特征为3的线性层

CNN Forward Method

前向传播是指将输入tensor转化成输出tensor
神经网络是将输入tensor映射到输出tensor的函数

import torch.nn.functional as F
class Network(nn.Module):
    def __init__(self):
        super(Network,self).__init__()
        self.conv1=nn.Conv2d(in_channels=1,out_channels=6,kernel_size=5)#复合层
        self.conv2=nn.Conv2d(in_channels=6,out_channels=12,kernel_size=5)
        
        self.fc1=nn.Linear(in_features=12*4*4,out_features=120)#线性/全连接层/dense
        self.fc2=nn.Linear(in_features=120,out_features=60)
        self.out=nn.Linear(in_features=60,out_features=10)
        
    def forward(self,t):
        #(1) input layer
        t=t
        
        #(2) hidden conv layer 
        t=self.conv1(t)
        t=F.relu(t)
        t=F.max_pool2d(t,kernel_size=2,stride=2)
        
        #(3)hidden conv layer
        t=self.conv2(t)
        t=F.relu(t)
        t=F.max_pool2d(t,kernel_size=2,stride=2)
        
        #(4)hidden liner layer
        t=t.reshape(-1,12*4*4)
        t.sel.fcl(t)
        t=F.relu(t)
        
        #(5) hidden linear layer
        t=self.fc2(t)
        t=F.relu(t)
        
        #(6) output layer
        t=self.out(t)
       # t=F.softmax(t,dim=1)
    #使用softmax操作进行训练,在训练过程完成后,不需要计算额外的操作
        return t
            

CNN Image Prediction

import torch
import torch.nn as nn
import torch.nn.functional as F

import torchvision
import torchvision.transforms as transforms
torch.set_printoptions(linewidth=120)
train_set=torchvision.datasets.FashionMNIST(
    root='./data/FashionMNIST'
    ,train=True
    ,download=True
    ,transform=transforms.Compose([
        transforms.ToTensor()
    ])
)
class Network(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1=nn.Conv2d(in_channels=1,out_channels=6,kernel_size=5)#复合层
        self.conv2=nn.Conv2d(in_channels=6,out_channels=12,kernel_size=5)
        
        self.fc1=nn.Linear(in_features=12*4*4,out_features=120)#线性/全连接层/dense
        self.fc2=nn.Linear(in_features=120,out_features=60)
        self.out=nn.Linear(in_features=60,out_features=10)
        
    def forward(self,t):
        #(1) input layer
        t=t
        
        #(2) hidden conv layer 
        t=self.conv1(t)
        t=F.relu(t)
        t=F.max_pool2d(t,kernel_size=2,stride=2)
        
        #(3)hidden conv layer
        t=self.conv2(t)
        t=F.relu(t)
        t=F.max_pool2d(t,kernel_size=2,stride=2)
        
        #(4)hidden liner layer
        t=t.reshape(-1,12*4*4)
        t=self.fc1(t)
        t=F.relu(t)
        
        #(5) hidden linear layer
        t=self.fc2(t)
        t=F.relu(t)
        
        #(6) output layer
        t=self.out(t)
       # t=F.softmax(t,dim=1)
    #使用softmax操作进行训练,在训练过程完成后,不需要计算额外的操作
        return t

对单个图像进行预测

torch.set_grad_enabled(False)#关闭计算权重的特征
network=Network()   
sample=next(iter(train_set))
image,label=sample
print(image.shape)
pred=network(image.unsqueeze(0))
print(pred.shape)
print(pred)
print(label)
print(pred.argmax(dim=1))

将预测值转化为概率

F.softmax(pred,dim=1)

对一批图像进行预测

data_loader=torch.utils.data.DataLoader(train_set,batch_size=10)
batch=next(iter(data_loader))
images,labels=batch
print(images.shape)
print(preds.shape)
print(preds)

用Argmax输出最大值的索引

preds.argmax(dim=1)

输出实际的索引

labels

进行比较

preds.argmax(dim=1).eq(labels)
preds.argmax(dim=1).eq(labels).sum()

将以上写到一个函数里

def get_num_correct(preds,labels):
    return preds.argmax(dim=1).eq(labels).sum().item()
get_num_correct(preds,labels) 

Training a PyTorch CNN

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim #将用这个来更新权重

import torchvision
import torchvision.transforms as transforms

torch.set_printoptions(linewidth=120)#display options for output
torch.set_grad_enabled(True)#Already on by default
train_set=torchvision.datasets.FashionMNIST(
    root='./data/FashionMNIST'
    ,train=True
    ,download=True
    ,transform=transforms.Compose([
        transforms.ToTensor()
    ])
)
class Network(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1=nn.Conv2d(in_channels=1,out_channels=6,kernel_size=5)#复合层
        self.conv2=nn.Conv2d(in_channels=6,out_channels=12,kernel_size=5)
        
        self.fc1=nn.Linear(in_features=12*4*4,out_features=120)#线性/全连接层/dense
        self.fc2=nn.Linear(in_features=120,out_features=60)
        self.out=nn.Linear(in_features=60,out_features=10)
        
    def forward(self,t):
        #(1) input layer
        t=t
        
        #(2) hidden conv layer 
        t=self.conv1(t)
        t=F.relu(t)
        t=F.max_pool2d(t,kernel_size=2,stride=2)
        
        #(3)hidden conv layer
        t=self.conv2(t)
        t=F.relu(t)
        t=F.max_pool2d(t,kernel_size=2,stride=2)
        
        #(4)hidden liner layer
        t=t.reshape(-1,12*4*4)
        t=self.fc1(t)
        t=F.relu(t)
        
        #(5) hidden linear layer
        t=self.fc2(t)
        t=F.relu(t)
        
        #(6) output layer
        t=self.out(t)
       # t=F.softmax(t,dim=1)
    #使用softmax操作进行训练,在训练过程完成后,不需要计算额外的操作
        return t
network=Network()
train_loader=torch.utils.data.DataLoader(train_set,batch_size=100)
batch=next(iter(train_loader))
images,labels=batch

Calculate the Loss

preds=network(images)
loss=F.cross_entropy(preds,labels)#用交叉熵损失函数计算损失
loss.item()

calculate the gradients

#计算梯度
loss.backward()

更新权重

optimizer=optim.Adam(network.parameters(),lr=0.01)
print(loss.item)
print(get_num_correct(preds,labels))
optimizer.step()

构建训练循环

network=Network()
train_loader=torch.utils.data.DataLoader(train_set,batch_size=100)
optimizer=optim.Adam(network.parameters(),lr=0.01)

total_loss=0
total_correct=0

for batch in train_loader:
    images,labels=batch
    preds=network(images)
    loss=F.cross_entropy(preds,labels)#用交叉熵损失函数计算损失
    
    optimizer.zero_grad()#在计算梯度前清零
    loss.backward()
    optimizer.step()
    
    total_loss += loss.item()
    total_correct += get_num_correct(preds,labels)
    
print("epoch:",0"total_correct",total_correct,"loss:",total_loss)

计算准确率

total_correct/len(train_set)

再次构造循环,尝试调试参数

network=Network()
train_loader=torch.utils.data.DataLoader(train_set,batch_size=100)
optimizer=optim.Adam(network.parameters(),lr=0.01)
for epoch in range(5):
    
    total_loss=0
    total_correct=0

    for batch in train_loader:
        images,labels=batch
        preds=network(images)
        loss=F.cross_entropy(preds,labels)#用交叉熵损失函数计算损失
    
        optimizer.zero_grad()#在计算梯度前清零
        loss.backward()
        optimizer.step()
    
        total_loss += loss.item()
        total_correct += get_num_correct(preds,labels)
    
    print("epoch:",epoch,"total_correct",total_correct,"loss:",total_loss)

观察准确率 当遇到“高原反应”时,尝试调参

得到没有梯度跟踪时的预测

with torch.no_grad():
    prediction_loader=torch.utils.data.DataLoader(train_set,batch_size=10000)
    train_preds=get_all_preds(network,prediction_loader)

构建混淆矩阵分析预测结果

方法一

stacked=torch.stack(
    (
        train_set.targets
        ,train_preds.argmax(dim=1)
     )
    ,dim=1
)
cmt=torch.zeros(10,10,dtype=torch.int32)
for p in stacked:
    tl,pl=p.tolist()
    cmt[tl,pl]=cmt[tl,pl]+1
cmt

方法二

import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
from resources.plotcm import plot_confusion_matrix
cm=confusion_matrix(train_set.targets,train_preds.argmax(dim=1))
names=('T-shirt/top','Trouser','Pullover','Dress','Coat','Sandal','Shirt','Sneaker','Bag','Ankle boot')
plt.figure(figsize=(10,10))
plot_confusion_matrix(cmt,names)

TensorBoard

  • example 1
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim #将用这个来更新权重

import torchvision
import torchvision.transforms as transforms

torch.set_printoptions(linewidth=120)#display options for output
torch.set_grad_enabled(True)#Already on by default
from torch.utils.tensorboard import SummaryWriter#可以轻松地把数据发送给到tensorboard文件中
train_loader=torch.utils.data.DataLoader(train_set,batch_size=100,shuffle=True)
tb=SummaryWriter()

network=Network()
images,labels=next(iter(train_loader))
grid=torchvision.utils.make_grid(images)

tb.add_image('image',grid)
tb.add_graph(network,images)
tb.close()
  • example 2
network=Network()
train_loader=torch.utils.data.DataLoader(train_set,batch_size=100,shuffle=True)
optimizer=optim.Adam(network.parameters(),lr=0.01)

images,labels=next(iter(train_loader))
grid=torchvision.utils.make_grid(images)

tb=SummaryWriter()
tb.add_image('image',grid)
tb.add_graph(network,images)

for epoch in range(5):
    
    total_loss=0
    total_correct=0

    for batch in train_loader:
        images,labels=batch
        preds=network(images)
        loss=F.cross_entropy(preds,labels)#用交叉熵损失函数计算损失
    
        optimizer.zero_grad()#在计算梯度前清零
        loss.backward()
        optimizer.step()
    
        total_loss += loss.item()
        total_correct += get_num_correct(preds,labels)
    
    tb.add_scalar('Loss',total_loss,epoch)
    tb.add_scalar('Number Correct',total_correct,epoch)
    tb.add_scalar('Accuracy',total_correct/len(train_set),epoch)
    
  tb.add_histogram('conv1.bias',network.conv1.bias,epoch)
    tb.add_histogram('conv1.weight',network.conv1.weight,epoch)
    tb.add_histogram('conv1.weight.grad',network.conv1.weight.grad,epoch)
   
     print("epoch:",epoch,"total_correct",total_correct,"loss:",total_loss)

在cmd使用tensorboard --logdir=runs获得网页

进一步升级

batch_size=100
lr=0.1
network=Network()
train_loader=torch.utils.data.DataLoader(train_set,batch_size=batch_size,shuffle=True)
optimizer=optim.Adam(network.parameters(),lr=lr)

images,labels=next(iter(train_loader))
grid=torchvision.utils.make_grid(images)

comment=f'batch_size={batch_size} lr={lr}'
tb=SummaryWriter(comment=comment)
tb.add_image('image',grid)
tb.add_graph(network,images)

for epoch in range(5):
    
    total_loss=0
    total_correct=0

    for batch in train_loader:
        images,labels=batch
        preds=network(images)
        loss=F.cross_entropy(preds,labels)#用交叉熵损失函数计算损失
    
        optimizer.zero_grad()#在计算梯度前清零
        loss.backward()
        optimizer.step()
    
        total_loss += loss.item()+batch_size
        total_correct += get_num_correct(preds,labels)
    
    tb.add_scalar('Loss',total_loss,epoch)
    tb.add_scalar('Number Correct',total_correct,epoch)
    tb.add_scalar('Accuracy',total_correct/len(train_set),epoch)
    
    for name,weight in network.name_parameters():
        tb.add_histogram(name,weight,epoch)
        tb.add_histogram(f'{name}.grad',weight.grad,epoch)
    print("epoch:",epoch,"total_correct",total_correct,"loss:",total_loss)
tb.close()
   

你可能感兴趣的:(深度学习,深度学习,神经网络)