一、梯度

  • 导数是对某个自变量求导,得到一个标量。
  • 偏微分是在多元函数中对某一个自变量求偏导(将其他自变量看成常数)。
  • 梯度指对所有自变量分别求偏导,然后组合成一个向量,所以梯度是向量,有方向和大小。

上左图中,箭头的长度表示陡峭度,越陡峭的地方箭头越长,箭头指向的方向是y变大的方向,如果要使用梯度下降,则需要取负方向。

右图中,蓝色代表低点,红色代表高点,中间的箭头方向从蓝色指向红色,而且中间最陡峭的地方,箭头最长。

二、梯度下降

上图中分别使用梯度下降优化θ1和θ2的值,α表示学习率,即每次按梯度下降方向更新参数的一个乘数因子,可以控制参数调整的速度。

三、凸函数convex function、非凸函数non-convex function

上图为凸函数,即任意两个点 ( f(z1) + f(z2) ) / 2 > f( (z1 + z2) / 2 ) 。

上图为非凸函数,其中包含若干个局部最低和局部最高,还有一个全局最高和全局最低点。

四*、ResNet为什么效果好(直观)

ResNet利用残差块,相当于将Loss函数变得相对平滑,这样更利于深度网络找到最优解global minima(或相对比较好的局部最优解Local minima)。

五、鞍点saddle point

六、激活函数和梯度

sigmoid激活函数:

$$f(x)=\sigma(x)=\frac{1}{1+e^{-x}}$$

求导:

$$\begin{aligned} \frac{d}{d x} \sigma(x) &=\frac{d}{d x}\left(\frac{1}{1+e^{-x}}\right) \\ &=\frac{e^{-x}}{\left(1+e^{-x}\right)^{2}} \\ &=\frac{\left(1+e^{-x}\right)-1}{\left(1+e^{-x}\right)^{2}} \\ &=\frac{1+e^{-x}}{\left(1+e^{-x}\right)^{2}}-\left(\frac{1}{1+e^{-x}}\right)^{2} \\ &=\sigma(x)-\sigma(x)^{2} \\ \sigma^{\prime} &=\sigma(1-\sigma) \end{aligned}$$

tanh激活函数:

$$\begin{aligned} f(x) &=\tanh (x)=\frac{\left(e^{x}-e^{-x}\right)}{\left(e^{x}+e^{-x}\right)} \\ &=2 \operatorname{sigmoid}(2 x)-1 \end{aligned}$$

求导:

$$\begin{array}{l}{\frac{d}{d x} \tanh (x)=\frac{\left(e^{x}+e^{-x}\right)\left(e^{x}+e^{-x}\right)-\left(e^{x}-e^{-x}\right)\left(e^{x}-e^{-x}\right)}{\left(e^{x}+e^{-x}\right)^{2}}} \\ {=1-\frac{\left(e^{x}-e^{-x}\right)^{2}}{\left(e^{x}+e^{-x}\right)^{2}}=1-\tanh ^{2}(x)}\end{array}$$

import torch

z = torch.linspace(-1, 1, 10)
a = torch.tanh(z)
print(a)
# tensor([-0.7616, -0.6514, -0.5047, -0.3215, -0.1107, 0.1107, 0.3215, 0.5047,
# 0.6514, 0.7616])

Relu激活函数(Rectified Linear Unit,整流线性单元)

$$f(x)=\left\{\begin{array}{ll}{0} & {\text { for } x<0} \\ {x} & {\text { for } x \geq 0}\end{array}\right.$$

求导:

$$f^{\prime}(x)=\left\{\begin{array}{ll}{0} & {\text { for } x<0} \\ {1} & {\text { for } x \geq 0}\end{array}\right.$$

import torch

z = torch.linspace(-1,1,10)
a = torch.relu(z)
print(a)
# tensor([0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.1111, 0.3333, 0.5556, 0.7778,
# 1.0000])

七、Loss函数及梯度

均方差误差(MSE:Mean squared Error):

$$\text { loss }=\sum\left[y-f_{\theta}(x)\right]^{2}$$

求导:

$$\frac{\nabla \text{loss}}{\nabla \theta}=2 \sum\left[y-f_{\theta}(x)\right] * \frac{\nabla f_{\theta}(x)}{\nabla \theta}$$

# -*- coding:utf-8 -*-
__author__ = 'Leo.Z' import torch
import torch.nn.functional as F x = torch.ones(1)
w = torch.tensor([2.], requires_grad=True)
# w = torch.full([1], 2.)
# 如果在定义w的时候没有说明需要计算梯度,则使用下面语句指定
# w.requires_grad_() mse = F.mse_loss(torch.ones(1), x * w) # 梯度计算方法1,假设里面又N个w需要求导,则参数列表[w1,w2,w3,...,wn,b],返回的是[dw1,dw2,dw3,...,dwn,db]
# dw = torch.autograd.grad(mse, [w])
# print(dw) # 梯度计算方法2,计算出w的梯度会直接赋给w1.grad,w2.grad,...,wn.grad,b.grad
mse.backward()
print(w.grad)

 Softmax误差:

# -*- coding:utf-8 -*-
__author__ = 'Leo.Z' import torch
import torch.nn.functional as F # L层计算结果z
z = torch.tensor([3., 2., 1.], requires_grad=True)
print(z)
# z经过softmax激活函数
y_hat = F.softmax(z, dim=0)
print(y_hat)
# 假设标签是y
y = torch.tensor([1., 0., 0.])
# 损失值loss为交叉熵函数结果
loss = -torch.sum(y * torch.log(y_hat))
print(loss) # 方法一
loss.backward()
print(z.grad)
# 方法二
# dz = torch.autograd.grad(loss, [z], retain_graph=True)
# print(dz) # tensor([-0.3348, 0.2447, 0.0900])
import torch
import torch.nn.functional as F z = torch.linspace(-100, 100, 10) # 新版api
a = torch.softmax(z, dim=0)
# 或 a = F.softmax(z,dim=0)
print(a)
# 输出tensor([0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 2.4891e-39,
# 1.1144e-29, 4.9890e-20, 2.2336e-10, 1.0000e+00])

八、初步使用梯度下降优化参数

# -*- coding:utf-8 -*-
__author__ = 'Leo.Z' import torch # 该函数有4个局部最优解,但值是一样的,都是0
def func(x, y):
return (x ** 2 + y - 11) ** 2 + (x + y ** 2 - 7) ** 2 # 当初始化改变时,通过梯度下降找到的局部最优解也时不同的
# 初始化x=4,y=4时,局部最优x=3.0,y=2.0
# 初始化x=0,y=4时,局部最优x=-2.8051,y=3.1313
x = torch.tensor(0., requires_grad=True)
y = torch.tensor(4., requires_grad=True)

# 这里使用的优化方法是Adam
optimizer = torch.optim.Adam([x, y], lr=1e-3)
for step in range(20000):
optimizer.zero_grad() pred = func(x, y)
pred.backward()
optimizer.step()
if step % 2000 == 0:
print("step:", x, y)

上述代码中,我们优化的是函数z = func(),优化对象x和y。

如果用到深度学习中,我们优化的目标函数为loss函数,优化对象为w和b(如果使用BN等,则还要优化γβ等)。

九、使用cross_entropy实现多分类

# -*- coding:utf-8 -*-
__author__ = 'Leo.Z' import torch
import torch.nn.functional as F x = torch.randn(5, 784)
w = torch.randn(10, 784, requires_grad=True) # L层计算结果z
z = x @ w.t()
z.requires_grad_()
print(z.size()) # 注意,这里没有使用one-hot编码
y = torch.tensor([1, 4, 6, 2, 4]) # Adam优化器
optimizer = torch.optim.Adam([w], lr=1e-3) for step in range(100000):
# 每次更新w,重新计算z
z = x @ w.t()
optimizer.zero_grad()
# 使用cross_entropy,z为输入[B,C],B为batch_size,C为classes。y输入标签,但不是one-hot
loss = F.cross_entropy(z, y)
# 反向传播
loss.backward(retain_graph=True)
# 优化一次
optimizer.step()
if step % 2000 == 0:
print("step:", loss)
# 看看结果是否和标签一致
print(torch.softmax(z, dim=1))

可以用一下cross_entropy的分解步骤代替:

# -*- coding:utf-8 -*-
__author__ = 'Leo.Z' import torch
import torch.nn.functional as F x = torch.randn(5, 784)
w = torch.randn(10, 784, requires_grad=True) # L层计算结果z
z = x @ w.t()
z.requires_grad_()
print(z.size()) # 注意,这里没有使用one-hot编码
y = torch.tensor([1, 4, 6, 2, 4]) # Adam优化器
optimizer = torch.optim.Adam([w], lr=1e-3) for step in range(100000):
# 每次更新w,重新计算z
z = x @ w.t()
optimizer.zero_grad()
# 先计算softmax的log,即-ylog(y_hat)中的log(y_hat)
pred = torch.log_softmax(z, dim=1)
# 然后再计算整个-ylog(y_hat),并在各class上求和,然后batch平均
loss = F.nll_loss(pred, y)
loss.backward(retain_graph=True)
# 优化一次
optimizer.step()
if step % 2000 == 0:
print("step:", loss)
# 看看结果是否和标签一致
print(torch.softmax(z, dim=1))

十、Mnist数据分类

low-level api版

# -*- coding:utf-8 -*-
__author__ = 'Leo.Z' import torch
import torch.nn.functional as F
from torchvision import datasets, transforms
from torch.utils.data import DataLoader import time batch_size = 200
learning_rate = 0.001
epochs = 10 train_loader = DataLoader(
datasets.MNIST('../data', train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=batch_size, shuffle=True)
test_loader = DataLoader(
datasets.MNIST('../data', train=False,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=batch_size, shuffle=True) w1, b1 = torch.randn(200, 784, requires_grad=True), torch.zeros(200, requires_grad=True)
w2, b2 = torch.randn(200, 200, requires_grad=True), torch.zeros(200, requires_grad=True)
w3, b3 = torch.randn(10, 200, requires_grad=True), torch.zeros(10, requires_grad=True) # 使用何凯明的参数初始化方法,初始化很重要
torch.nn.init.kaiming_normal_(w1)
torch.nn.init.kaiming_normal_(w2)
torch.nn.init.kaiming_normal_(w3) # 网络结构
def forward(x):
x = x @ w1.t() + b1
x = F.relu(x)
x = x @ w2.t() + b2
x = F.relu(x)
x = x @ w3.t() + b3
# 因为后面会用softmax激活函数,这里的relu可有可无,但一定不要是sigmoid和tanh
x = F.relu(x)
return x # 选择一个优化器,指定需要优化的参数,以及学习率
optimizer = torch.optim.SGD([w1, b1, w2, b2, w3, b3], lr=learning_rate) s_time = 0
for epoch in range(epochs): for batch_idx, (data, target) in enumerate(train_loader):
# data转换维度为[200,784],target的维度为[200]
data = data.view(-1, 28 * 28)
# 跑一次网络,得到z,维度为[200,10],200是batch_size,10是类别
z = forward(data)
# 使用cross_entropy计算损失值,参数为z和label(target)
loss = F.cross_entropy(z, target)
# 每次迭代前将梯度置0
optimizer.zero_grad()
# 反向传播,计算梯度
loss.backward()
# 相当于执行w = w - dw,也就是更新权值
optimizer.step()
if batch_idx % 100 == 0:
e_time = time.time()
if s_time != 0:
print("time:", e_time - s_time)
s_time = time.time()
print(loss)

high-level api版:

# -*- coding:utf-8 -*-
__author__ = 'Leo.Z' import torch
import torch.nn.functional as F
from torch.nn import Module, Sequential, Linear, LeakyReLU
from torchvision import datasets, transforms
from torch.utils.data import DataLoader import time batch_size = 200
learning_rate = 0.001
epochs = 10 train_loader = DataLoader(
datasets.MNIST('../data', train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=batch_size, shuffle=True)
test_loader = DataLoader(
datasets.MNIST('../data', train=False,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=batch_size, shuffle=True) # 网络结构
class MLP(Module):
def __init__(self):
super(MLP, self).__init__() self.model = Sequential(
Linear(784, 200),
LeakyReLU(inplace=True),
Linear(200, 200),
LeakyReLU(inplace=True),
Linear(200, 10),
LeakyReLU(inplace=True)
) def forward(self, x):
x = self.model(x)
return x # 定义GPU设备
device = torch.device('cuda:0')
# model放到GPU
net = MLP().to(device) # 选择一个优化器,指定需要优化的参数,以及学习率
optimizer = torch.optim.SGD(net.parameters(), lr=learning_rate) for epoch in range(epochs): for batch_idx, (data, target) in enumerate(train_loader):
# data转换维度为[200,784],target的维度为[200]
data = data.view(-1, 28 * 28)
# 将data和target放到GPU
data, target = data.to(device), target.to(device)
# data为输入,net()直接执行forward
# 跑一次网络,得到z,维度为[200,10],200是batch_size,10是类别
# 由于net在GPU,data也在GPU,计算出的z就在GPU
# 调用net(data)的时候相当于调用Module类的__call__方法
z = net(data)
# 将loss放到GPU
loss = F.cross_entropy(z, target).to(device)
# 每次迭代前将梯度置0
optimizer.zero_grad()
# 反向传播,计算梯度
loss.backward()
# 相当于执行w = w - dw,也就是更新权值
optimizer.step()
if batch_idx % 100 == 0:
print(loss) # -*- coding:utf-8 -*-

十一、使用GPU

在上述代码中:

# 搬移一个model到GPU,net是对应更新的,也就是相当于剪切到GPU
net = MLP()
net2 = net.to(device)
print(net is net2) # 输出True # 搬移一个数据到GPU,相当于复制一份到GPU,两者是完全不同的
data2, target2 = data.to(device), target.to(device)
print(data is data2) # 输出False

[深度学习] pytorch学习笔记(2)(梯度、梯度下降、凸函数、鞍点、激活函数、Loss函数、交叉熵、Mnist分类实现、GPU)的更多相关文章

  1. [深度学习] Pytorch学习(一)—— torch tensor

    [深度学习] Pytorch学习(一)-- torch tensor 学习笔记 . 记录 分享 . 学习的代码环境:python3.6 torch1.3 vscode+jupyter扩展 #%% im ...

  2. [深度学习] pytorch学习笔记(3)(visdom可视化、正则化、动量、学习率衰减、BN)

    一.visdom可视化工具 安装:pip install visdom 启动:命令行直接运行visdom 打开WEB:在浏览器使用http://localhost:8097打开visdom界面 二.使 ...

  3. 【深度学习】softmax回归——原理、one-hot编码、结构和运算、交叉熵损失

    1. softmax回归是分类问题 回归(Regression)是用于预测某个值为"多少"的问题,如房屋的价格.患者住院的天数等. 分类(Classification)不是问&qu ...

  4. [深度学习] pytorch学习笔记(4)(Module类、实现Flatten类、Module类作用、数据增强)

    一.继承nn.Module类并自定义层 我们要利用pytorch提供的很多便利的方法,则需要将很多自定义操作封装成nn.Module类. 首先,简单实现一个Mylinear类: from torch ...

  5. [深度学习] pytorch学习笔记(1)(数据类型、基础使用、自动求导、矩阵操作、维度变换、广播、拼接拆分、基本运算、范数、argmax、矩阵比较、where、gather)

    一.Pytorch安装 安装cuda和cudnn,例如cuda10,cudnn7.5 官网下载torch:https://pytorch.org/ 选择下载相应版本的torch 和torchvisio ...

  6. [深度学习] Pytorch学习(二)—— torch.nn 实践:训练分类器(含多GPU训练CPU加载预测的使用方法)

    Learn From: Pytroch 官方Tutorials Pytorch 官方文档 环境:python3.6 CUDA10 pytorch1.3 vscode+jupyter扩展 #%% #%% ...

  7. loss函数学习笔记

    一直对机器学习里的loss函数不太懂,这里做点笔记. 符号表示的含义,主要根据Andrew Ng的课程来的,\(m\)个样本,第\(i\)个样本为\(\vec x^{(i)}\),对应ground t ...

  8. 强化学习读书笔记 - 13 - 策略梯度方法(Policy Gradient Methods)

    强化学习读书笔记 - 13 - 策略梯度方法(Policy Gradient Methods) 学习笔记: Reinforcement Learning: An Introduction, Richa ...

  9. 【PyTorch深度学习】学习笔记之PyTorch与深度学习

    第1章 PyTorch与深度学习 深度学习的应用 接近人类水平的图像分类 接近人类水平的语音识别 机器翻译 自动驾驶汽车 Siri.Google语音和Alexa在最近几年更加准确 日本农民的黄瓜智能分 ...

随机推荐

  1. SQL注入之手工注入

    手工注入 用的是墨者学院的靶场:传送门 涉及以下数据库: MySQL.Access.SqlServer(MSSQL).SQLite.MongoDB.Db2(IBM).PostgreSQL.Sybase ...

  2. python 爬虫--下载图片,下载音乐

    #下载图片 imgUrl='http://www.pptbz.com/pptpic/UploadFiles_6909/201211/2012111719294197.jpg' r=requests.g ...

  3. 建立分表sql执行语句批量生成工具(自创)

    public void addTable (){ String add=""; for(int i=1;i<13;i++){      for(int j=0;j<60 ...

  4. api返回数据

    控制器里调用方法 <?php namespace app\admin\controller; use app\admin\controller\Base; class Index extends ...

  5. composer命令介绍之install和update及其区别

    composer 是 php 的一个依赖管理工具.它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们. 然而,对于如何『安装他们』,新手可能并不清楚.网上的答案有的说 composer in ...

  6. 使用Keras基于RCNN类模型的卫星/遥感地图图像语义分割

    遥感数据集 1. UC Merced Land-Use Data Set 图像像素大小为256*256,总包含21类场景图像,每一类有100张,共2100张. http://weegee.vision ...

  7. Bash Plays with Functions CodeForces - 757E (积性函数dp)

    大意: 定义函数$f_r(n)$, $f_0(n)$为pq=n且gcd(p,q)=1的有序对(p,q)个数. $r \ge 1$时, $f_r(n)=\sum\limits_{uv=n}\frac{f ...

  8. 数据结构(四) 图(Graph)

    在图形结构中,结点之间的关系可以是任意的. 一.图 图由定点(vertex)和边(edge)两个有限集合组成: Graph=(V,R) V是定点集,R={E},E是边集. 有向图(directed n ...

  9. Spring配置redis及使用

    一.redis简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库 Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用. ...

  10. 03 Linux下运行Django项目

    1.安装windows和linux传输文件的工具 pip install lrzsz 提供两个命令 一个是上传一个是下载 rz 接收 直接rz sz 上传 直接sz 或者直接拖拽 2.在线下载资源的命 ...