神经网络举例(含卷积)------Pytorch

from torch.autograd import Variable as V
# Variable用于反向传播
x = V(t.ones(2,2),requires_grad = True)
y = V(t.zeros(3,6))

# 把图片转换为tensor
'''
from PIL import Image
from torchvision.transforms import ToTensor, ToPILImage
to_tensor = ToTensor() # img->tensor
to_pil = ToPILImage
lean = Image.open('imgs/lena.png')
# 将batch_size设置为1,input.unsqueeze(0)
input = to_tensor(lean).unsqueeze(0)
'''


# 首先要引入相关的包
import torch
# 包含的函数具有可学习参数(如Convd,Linear)
import torch.nn as nn
# 包含的函数不具有可学习参数(如ReLU,pool,DropOut等)
import torch.nn.functional as F
# 优化器更新权重
import torch.optim
# 定义神经网络
'''
PyTorch中已经准备好了现成的网络模型
只要继承nn.Module,并实现它的forward方法
PyTorch会根据autograd,自动实现backward函数
'''
class Net(nn.Module):
    def __init__(self):
        # nn.Module子类的函数必须在构造函数中执行父类的构造函数
        super(Net, self).__init__()
        # 卷积层 '1'表示输入图片为单通道, '6'表示输出通道数,'3'表示卷积核为3*3
        self.conv1 = nn.Conv2d(1, 6, 3) 
        # 线性层,输入1350个特征,输出10个特征
        self.fc1 = nn.Linear(1350, 10)  #这里的1350是如何计算的呢?这就要看后面的forward函数
    #正向传播 
    def forward(self, x): 
        print(x.size()) # 结果:[1, 1, 32, 32],nSamples*nChannels*Height*Width
        # 卷积 -> 激活 -> 池化 
        x = self.conv1(x) #根据卷积的尺寸计算公式,计算结果是30
        x = F.relu(x)
        print(x.size()) # 结果:[1, 6, 30, 30]
        x = F.max_pool2d(x, (2, 2)) #我们使用池化层,计算结果是15
        x = F.relu(x)
        print(x.size()) # 结果:[1, 6, 15, 15]
        # reshape,‘-1’表示自适应
        #这里做的就是压扁的操作 就是把后面的[1, 6, 15, 15]压扁,变为 [1, 1350]
        x = x.view(x.size()[0], -1) 
        print(x.size()) # 这里就是fc1层的的输入1350 
        x = self.fc1(x)        
        return x
net = Net()
# 输出网络结构
print(net)
# 返回网络参数
'''
for name,parameters in net.named_parameters():
    print(name,':',parameters.size())
'''

# forward函数的输入和输出都是Tensor
input = torch.randn(1, 1, 32, 32) # 这里的对应前面forward的输入是32
# 把batchsize(nSamples)设置为1
# input.unsqueeze(0)
out = net(input) # 这里调用的时候会打印出我们在forword函数中打印的x的大小

# torch.arange(0,10).size() == torch.Size([10])
# y = torch.arange(0,10).view(1,10) == torch.Size([1, 10])
# torch.arange左闭右开,整型
# torch.range左闭右闭,字符型
# range()左闭右开
y = torch.arange(0,10).view(1,10).float()
criterion = nn.MSELoss()
loss = criterion(out, y)
#loss是个scalar,我们可以直接用item获取到他的python类型的数值
# print(loss.item())

#新建一个优化器更新权重,SGD只需要要调整的参数和学习率
optimizer = torch.optim.SGD(net.parameters(), lr = 0.01)
# 在反向传播前,先要将所有参数的梯度清零
# 与net.zero_grad()效果一样
optimizer.zero_grad() 
# 求所有张量的梯度
loss.backward()
#更新参数
optimizer.step()

 

你可能感兴趣的:(PyTorch)