Pytorch学习笔记(一)——简介
一、Tensor
Tensor是Pytorch中重要的数据结构,可以认为是一个高维数组。Tensor可以是一个标量、一维数组(向量)、二维数组(矩阵)或者高维数组等。Tensor和numpy的ndarrays相似。
import torch as t
构建矩阵:x = t.Tensor(m, n)
注意这种情况下只分配了空间,并没有初始化。
使用[0,1]均匀分布随机初始化矩阵:x = t.rand(m, n)
查看x的形状:x.size()
加法:
(1)x + y
(2)t.add(x, y)
(3)t.add(x, y, out = res)
(4)y.add(x) #不改变y的内容
(5)y.add_(x) #改变y的内容
注意,函数名后面带下划线_的函数会修改Tensor本身,而x.add(y)等则会返回一个新的Tensor,而x不变。
Tensor可以进行数学运算、线性代数、选择、切片等。而且Tensor与numpy的数组间互操作十分方便。对于Tensor不支持的操作可以先转为numpy处理,再转为Tensor。
a = t.ones(5)
b = a.numpy() # Tensor -> Numpy a = np.ones(5)
b = t.from_numpy(a) # Numpy -> Tensor
Tensor和numpy的对象是共享内存的,如果其中一个改变,那么另一个也会随之改变。
Tensor可以通过.cuda方法转为GPU的Tensor。GPU加速:
if t.cuda.is_available():
x = x.cuda()
y = y.cuda()
x + y
二、Autograd:自动微分
Pytorch的Autograd模块实现了求导功能,在Tensor上的所有操作,Autograd都能自动为它们提供微分。
autograd.Variable是Autograd的核心类,简单封装了Tensor,并几乎支持所有的Tensor操作。当Tensor被封装为Variable后,可以通过调用.backward实现反向传播,自动计算所有的梯度。
Variable包括三个属性:
(1)data:保存Variable包含的Tensor;
(2)grad:保存data对应的梯度,grad也是个Variable;
(3)grad_fn:指向一个Function对象,该Function用于反向传播计算输入的梯度。
from torch.autograd import Variable
x = Variable(t.ones(2, 2), requires_grad = True)
y = x.sum()
print(y.grad_fn)
y.backward()
print(x.grad)
y.backward()
print(x.grad)
注意,grad在反向传播中是累加的,也就是说每次运行反向传播时梯度都会累加之前的梯度,因此需要反向传播之前要把梯度清零。
x.grad.data.zero_() # inplace操作,把x的data对应的梯度值清零 Variable和Tensor的转换:
x = Variable(t.ones(4, 5))
y = t.cos(x)
x_tensor_cos = t.cos(x.data) # Variable x的data的cosine对应的Tensor
三、神经网络
torch.nn是专门为神经网络设计的模块化接口。nn.Module可以看做是一个网络的封装,包括网络各层的定义以及forward方法,调用forward(input)方法,可返回前向传播的结果。
LeNet网络结构如下图:

定义网络时,要继承nn.Module,并实现它的forward方法,把网络中具有可学习参数的层放在构造函数__init__中。如果某层不具有可学习的参数,则既可以放在构造函数中,也可以不放。
import torch.nn as nn
import torch.nn.functional as F class Net(nn.Module):
def __init__(self):
# nn.Module子类的函数必须在构造函数中执行父类的构造函数
# 下式等价于nn.Module.__init__(self)
super(Net, self).__init__()
# '1'表示输入图像为单通道,'6'表示输出通道数
# '5'表示卷积核大小为5*5
self.conv1 = nn.Conv2d(1, 6, 5)
# 卷积层
self.conv2 = nn.Conv2d(6, 16, 5)
# 仿射层/全连接层,y = Wx + b
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)
# reshape, '-1'表示自适应
x = x.view(x.size()[0], -1)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x) return x net = Net()
print(net)
运行结果:

只要在nn.Module的子类中定义了forward函数,backward函数就会被自动实现。网络的可学习参数通过net.parameters()返回,而net.named_parameters可同时返回可学习的参数及名称。
params = list(net.parameters())
print(len(params)) for name, parameters in net.named_parameters():
print(name, ':', parameters.size())
运行结果:

注意,输入和输出都必须是Variable。
torch.nn只支持mini-batches,不支持一次只输入一个样本,也就是说一次必须是一个batch。如果只想输入一个样本,那么要用input.unsqueeze(0)将batch_size设为1。
损失函数:
(1)nn.MSELoss用于计算均方误差
(2)nn.CrossEntropyLoss用于计算交叉熵损失
output = net(input)
target = Variable(t.arange(0, 10))
target = target.float()
criterion = nn.MSELoss()
loss = criterion(output, target)
在反向传播计算所有参数的梯度后,还需要使用优化方法更新网络的权重和参数,如SGD:
weight = weight - lr * gradient
手工实现如下:
lr = 0.01
for f in net.parameters():
f.data.sub_(f.grad.data * lr)
torch.optim中实现了深度学习中的绝大多数优化方法,如RMSProp、Adam、SGD等。 # 新建一个优化器,指定要调整的参数和学习率
optimizer = optim.SGD(net.parameters(), lr = 0.01) # 训练过程中,先梯度清零
optimizer.zero_grad() # 计算损失
output = net(input)
loss = criterion(output, target) # 反向传播
loss.backward()
optimizer.step()
torchvision实现了常用的图像数据加载功能。
四、CIFAR-10 分类
import torch.nn as nn
import torch as t
from torch.autograd import Variable
import torch.nn.functional as F
import torch.optim as optim
import torchvision as tv
import torchvision.transforms as transforms
from torchvision.transforms import ToPILImage show = ToPILImage() # 把Tensor转换成Image,方便可视化 # 数据预处理
transform = transforms.Compose([transforms.ToTensor(), # 转为Tensor
transforms.Normalize((0.5, 0.5, 0.5), (0.5,0.5, 0.5)),]) # 训练集
trainset = tv.datasets.CIFAR10(root = 'F:/PycharmProjects/', train = True, download =
True, transform = transform)
trainloader = t.utils.data.DataLoader(trainset, batch_size = 4, shuffle = True, num_workers = 2) # 测试集
testset = tv.datasets.CIFAR10(root = 'F:/PycharmProjects/', train = False, download =
True, transform = transform)
testloader = t.utils.data.DataLoader(testset, batch_size = 4, shuffle = False, num_workers = 2) classes = ('plane', 'car', 'bird', 'cat',
'deer', 'dog', 'frog', 'horse', 'ship', 'truck') (data, label) = trainset[100]
print(classes[label]) show((data + 1) / 2).resize(100, 100) # 将dataset返回的每一条数据样本拼接成一个batch
dataiter = iter(trainloader)
images, labels = dataiter.next()
print(' '.join('%11s' % classes[labels[j]] for j in range(4)))
show(tv.utils.make_grid((images + 1) / 2)).resize((400, 100)) class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(3, 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)
x = x.view(x.size()[0], -1)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x net = Net()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr = 0.001, momentum = 0.9) for epoch in range(2):
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data
inputs, labels = Variable(inputs), Variable(labels) optimizer.zero_grad() outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
# 参数更新
optimizer.step() running_loss += loss.data[0]
if i % 2000 == 1999:
print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 2000))
running_loss = 0.0
print('Finished Training') dataiter = iter(testloader)
images, labels = dataiter.next()
outputs = net(Variable(images))
_, predicted = t.max(outputs.data, 1)
print('predicted result', ' '.join('%5s' % classes[predicted[j]] for j in range(4))) correct = 0
total = 0
for data in testloader:
images, labels = data
outputs = net(Variable(images))
_, predicted = t.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted ==labels).sum print('The accuracy is: %d %%' % (100 * correct / total)) #GPU加速操作:
if t.cuda.is_available():
net.cuda()
images = images.cuda()
labels = labels.cuda()
output = net(Variable(images))
loss = criterion(output, Variable(labels))
Pytorch学习笔记(一)——简介的更多相关文章
- Linux内核学习笔记-1.简介和入门
原创文章,转载请注明:Linux内核学习笔记-1.简介和入门 By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...
- React学习笔记 - JSX简介
React Learn Note 2 React学习笔记(二) 标签(空格分隔): React JavaScript 一.JSX简介 像const element = <h1>Hello ...
- CUBRID学习笔记 1 简介 cubrid教程
CUBRID 是一个全面开源,且完全免费的关系数据库管理系统.CUBRID为高效执行Web应用进行了高度优化,特别是需要处理大数据量和高并发请求的复杂商务服务.通过提供独特的最优化特性,CUBRID可 ...
- [PyTorch 学习笔记] 1.1 PyTorch 简介与安装
PyTorch 的诞生 2017 年 1 月,FAIR(Facebook AI Research)发布了 PyTorch.PyTorch 是在 Torch 基础上用 python 语言重新打造的一款深 ...
- shiro学习笔记_0100_shiro简介
前言:第一次知道shiro是2016年夏天,做项目时候我要写springmvc的拦截器,申哥看到后,说这个不安全,就给我捣鼓了shiro,我就看了下,从此认识了shiro.此笔记是根据网上的视频教程记 ...
- Mybatis-Plus 实战完整学习笔记(一)------简介
第一章 简介 1. 什么是MybatisPlus MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只 ...
- ElasticSearch学习笔记-01 简介、安装、配置与核心概念
一.简介 ElasticSearch是一个基于Lucene构建的开源,分布式,RESTful搜索引擎.设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便.支持通过HTTP使用JSON进 ...
- python学习笔记1--python简介和第一行代码编写
一.什么是python? python是一种面向对象,解释型语言,它语法简介,容易学习.本节博客就来说说本人学习python的心得体会. 二.python环境安装 目前python版本有python2 ...
- Pytorch学习笔记(二)---- 神经网络搭建
记录如何用Pytorch搭建LeNet-5,大体步骤包括:网络的搭建->前向传播->定义Loss和Optimizer->训练 # -*- coding: utf-8 -*- # Al ...
随机推荐
- IntelliJ IDEA开发golang环境配置
IntelliJ IDEA开发golang环境配置 首先把GO安装好...(自行安装,附上一篇我之前写的MAC安装GO) 安装IntelliJ IDEA,下载地址: https://www.jetbr ...
- AngularJs(v1)相关知识和经验的碎片化记录
1.利用angular指令监听ng-repeat渲染完成后执行脚本 http://www.cnblogs.com/wangmeijian/p/5141266.html 2.$http的POST请求中请 ...
- 在win10 + ie11上使用控件
1.1. 在Win10+IE11上提示创建文件错误的问题 解决方法: 1.打开Internet选项 2.取消勾选启用保护模式 选择"不再显示此消息"
- Java中的http(网络处理)相关的库:HttpClient,HttpCore(转载)
[背景] 最近和之前,折腾了这个: [教程]模拟登陆百度之Java代码版 然后,对于Java的HttpClient,有了点了解. 现在整理如下: Java本身没有Http相关的库 Java本身,没有内 ...
- struts2的validate输入验证
原创 struts2的输入验证有两种方式: 使用validate()方法实现验证 使用验证文件实现验证 下面通过一个例子介绍validate()方法验证——实现客户注册输入验证 设计的JSP页面代码: ...
- Lotus迁移到Exchange 2010 POC 之Domino Server的配置!
1. 在桌面点击安装完成的Domino 服务器配置:
- 【C#】泛型
泛型是一个非常有用的技术,在博客园里面有太多说到泛型的好文章,这里我推荐一篇我个人觉得非常全面,也非常齐全的文章. (重造轮子很傻!!!) C# -- 泛型(1) C# -- 泛型(2) C# -- ...
- [SIP00]SIP 概念总结
SIP --------------------------- Session Initiation Protocol --------------------------- create, ...
- jquery-tmpl 插件
做项目时页面上有处功能是:在页面有处列表.有添加,我添加修改或删除后要刷新这个列表,首先想到的是局部刷新,但我们一般说的局部刷新就是利于ajax去后台调用数据并显示,而这里是一整个列表就比较麻烦了,刷 ...
- C#+MVC+EF+LayUI框架的应用(附带源码和教程)
内容: 1.该框架主要用到的技术有MVC,EF,Layer,以及Razor语法和数据库有关的操作. 2.框架二次开发(增加,删除,修改,建库,以及维护查询等) 3.框架公用库更新要求与规范 4.本框架 ...