矩阵乘法
线性层的工作原理
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)
访问参数
for param in network.parameters():
print(param.shape)
for name,param in network.named_parameters():
print(name,'\t\t',param.shape)
线性层
fc=nn.Linear(in_features=4,out_features=3)#定义一个输入特征为4,输出特征为3的线性层
前向传播是指将输入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
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)
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)
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()
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()