1、创建张量、自动梯度
import torch
a=torch.tensor([3,4])
a1=torch.zeros(2,5,dtype=torch.float)
print(a,a1)
b=torch.randn([4,4])
b=b.view(16) #改变维度
print(b)
#打印维度
print(torch.Size(a))
print(b.size())
print('=='*10)
x=torch.ones(2,2,requires_grad=True)
y=x+3
z=y*y*3
out=z.mean()
print(out)
##out.backward() #由于out为一个数,这里out.backward()等价于out.backward(torch.tensor(1.))
##print(x.grad)
#对z反向传播时,backward应该传入一个维度于z相同的向量,这里为2x2的矩阵
z.backward(torch.tensor([[1,1],[1,1]],dtype=torch.float))
print(x.grad)
2、神经网络
import torch
import torch.nn as nn
import torch.nn.functional as f
#定义一个Lenet手写数字识别的神经网络
#继承nn.Module,它包含层和方法forward(input)
class Net(nn.Module):
def __init__(self):
super(Net,self).__init__()
self.conv1=nn.Conv2d(1,6,5)
self.conv2=nn.Conv2d(6,16,5)
self.fc1=nn.Linear(16*5*5,120)
self.fc2=nn.Linear(120,84)
self.fc3=nn.Linear(84,10)
#前馈网络搭建
def forward(self,x):
x=f.max_pool2d(f.relu(self.conv1(x)),(2,2))
x=f.max_pool2d(f.relu(self.conv2(x)),(2,2))
#flatten
x=x.view(-1,self.count_demi(x))
x=f.relu(self.fc1(x))
x=f.relu(self.fc2(x))
x=self.fc3(x)
return x
def count_demi(self,y):
num=1
y_list=y.size()[1:] #剔除第0维(batch数)
for i in y_list:
num=num*i
return num
net=Net()
print(net)
'''
Net(
(conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
(conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
(fc1): Linear(in_features=400, out_features=120, bias=True)
(fc2): Linear(in_features=120, out_features=84, bias=True)
(fc3): Linear(in_features=84, out_features=10, bias=True)
)
'''
#使用net.parameters来查看网络参数
paras=list(net.parameters())
for i in range(len(paras)):
print(paras[i].size())
'''
torch.Size([6, 1, 5, 5]) #第一层卷积
torch.Size([6]) #池化层没有参数,这里应该是relu
torch.Size([16, 6, 5, 5]) #第二层卷积
torch.Size([16])
torch.Size([120, 400])
torch.Size([120])
torch.Size([84, 120])
torch.Size([84])
torch.Size([10, 84])
torch.Size([10])
'''
#这里只一次传播更新:
criterion=nn.MSELoss() #定义损失函数
inputs=torch.randn(1,1,32,32) #产生输入
label=torch.randn(1,10)
outputs=net(inputs) #由于继承了nn.module,可以直接输入图片
loss=criterion(outputs,label) #前向传播结束,并计算出Loss
print(loss) #前向传播得到误差
#误差的反向传播,先清空现存的梯度
net.zero_grad()
#参数更新,可直接调用torch的包
import torch.optim as optim
#这里使用SGD更新
optimizer=optim.SGD(net.parameters(),lr=0.01)
loss.backward() #反向传播
optimizer.step() #更新