一、Overview

关于该学习哪个版本的问题

1、DL要了解框架
2、看文档

要求会:

1、线性代数+概率论
2、Python

吃什么的问题:

本教程-监督学习:有label 的
1、穷举
2、贪心
3、分治-快排
4、动态规划

DL 结构上是 NN,从目标上是 RL
Rules-based System:不咋地
Classic machine learning:手工特征,最终变成向量(张量Tensor)
Representing Learning:特征提取,
维度诅咒:每个Feature越多,对样本的需求就越多。
大数定律
我们想降维!
Manifold 流行:
image.png
Deep Learning(End2End):端到端的学习,原始特征(像素,语音······),额外的层,再到学习器(神经网络,Neural NetWork)
神经网络简史
Back Propagation 反向传播
核心:计算图
写深度神经网络较图简单一些。
流行的DL框架
Tensorflow(Kreas)、Theano
Caffe(Facebook)
Torch(和Caffe一起)

二、Linear Model

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. x_data = [1.0,2.0,3.0]
  4. y_data = [2.0,4.0,6.0]
  5. # 前向传播
  6. def forward(x):
  7. return x * w #model 线性模型
  8. # 损失
  9. def loss(x,y):
  10. y_pred = forward(x)
  11. return (y_pred-y)*(y_pred-y)
  12. w_list = [] # 权重
  13. mse_list = [] # 均方误差
  14. for w in np.arange(0.0, 4.1, 0.1):
  15. print('w=',w)
  16. l_sum = 0
  17. for x_val, y_val in zip(x_data,y_data):
  18. y_pred_val = forward(x_val)
  19. loss_val = loss(x_val,y_val)
  20. l_sum += loss_val
  21. print('\t',x_val,y_val,y_pred_val,loss_val)
  22. print('MSE=',l_sum/3)
  23. w_list.append(w) # 穷举的方式
  24. mse_list.append(l_sum/3)
  25. # 画图
  26. plt.plot(w_list,mse_list)
  27. plt.xlabel('w')
  28. plt.ylabel('loss')
  29. plt.show()

MSE 均方误差

Python zip() 函数

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

  1. >>>a = [1,2,3]
  2. >>> b = [4,5,6]
  3. >>> c = [4,5,6,7,8]
  4. >>> zipped = zip(a,b) # 打包为元组的列表
  5. [(1, 4), (2, 5), (3, 6)]
  6. >>> zip(a,c) # 元素个数与最短的列表一致
  7. [(1, 4), (2, 5), (3, 6)]
  8. >>> zip(*zipped) # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
  9. [(1, 2, 3), (4, 5, 6)]

三、Gradient Descent

The best model:
最简单:Linear Model ——穷举法
Gradient
《PyTorch深度学习实践》完结合集 笔记 - 图2
Update
《PyTorch深度学习实践》完结合集 笔记 - 图3
《PyTorch深度学习实践》完结合集 笔记 - 图4
α为学习率,取得比较小
每一次都在往下降最快的方向,前进一步。——贪心算法,局部最优。
image.png
上图就是局部最优,也是梯度下降算法的结果。

那么问题来了,为什么还要在DL中使用梯度下降算法捏?
DNN中,并没有非常多的局部最优点,但存在特殊点——鞍点,即梯度为零的点。

DNN中解决最大的问题:
就是鞍点的问题

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. x_data = [1.0,2.0,3.0]
  4. y_data = [2.0,4.0,6.0]
  5. w = 1
  6. # 前向传播
  7. def forward(x):
  8. return x * w #model 线性模型
  9. # 损失——MSE均方误差
  10. def loss(xs,ys):
  11. loss = 0
  12. for x,y in zip(xs,ys):
  13. y_pred_val = forward(x)
  14. loss += (y_pred_val-y)**2
  15. return loss/len(xs)
  16. # 梯度下降
  17. def gradient(xs,ys):
  18. grad = 0
  19. for x,y in zip(xs,ys):
  20. y_pred = forward(x)
  21. grad += 2*x*(y_pred-y)
  22. return grad/len(xs)
  23. print('Predict(before training)',4,forward(4))
  24. epoch_list = []
  25. loss_list = []
  26. # epoch 作循环用
  27. for epoch in range(100):
  28. loss_val = loss(x_data,y_data)
  29. grad_val = gradient(x_data,y_data) # 计算出梯度
  30. w -= 0.01 * grad_val # 0.01为学习率
  31. print('Epoch',epoch,'w= ',w,'loss',loss_val)
  32. epoch_list.append(epoch)
  33. loss_list.append(loss_val)
  34. print('Predict(after training)',4,forward(4))
  35. # 画图
  36. plt.plot(epoch_list,loss_list)
  37. plt.xlabel('loss')
  38. plt.ylabel('epoch')
  39. plt.show()

image.png
梯度下降用的挺少,用随机梯度下降多一些。
image.png

Batch

image.png

五、用Pytorch实现线性回归

前向传播求损失,后向传播求梯度,更新权重
1、准备数据集:后面会介绍
2、设计模型:用来计算y
3、计算损失和优化:使用pytorch的api
4、循环训练

5.1 准备数据

mini-batch风格:一次性求出结果

5.2 设计模型

numpy的广播机制:扩充,使两矩阵相同大小
image.png
重点目标:构造计算图
权重的大小:知道输入和输出的维度,就可以推出w。
loss必须是标量,所以对于loss的矩阵loss1,loss2,loss3求和。

将模型定义为类class:以后方便扩展,都要继承自torch.nn.Modle
初始化函数 init(self):
Linera对象:w权重 b偏置
它的行数表示的featur的数量,列数表示的是样本数量,相当于做个了转置!!!
目的是:把维度给她拼出来啊。
前向传播函数 forward(self,x):
y_pred = selft.linear(x)
在对象后面加括号,这是啥么意思呢?我们实现了一个可调用的对象。
(Modle帮你反向传播求梯度)

5.3 构造损失函数和优化器

criterion = torch.nn.MSELoss(size_average=False)
optimizer = torch.optim.SGD(model.parameters(),lr=0.01)
SGD是一个类,lr:learning rate 学习率
学习率过大:loss函数直接越过全局最优点
学习率过小:loss函数的变化超慢的

5.4 训练过程

for epoch in range(100): # 循环100次
y_pred = model(x_data)
loss = criterion(y_pred, y_data) # 此处loss是一个对象
print(epoch,loss)

optimizer.zero_grad() # 梯度归零
loss.backward() # 进行反向传播
optimizer.step() # 更新

5.5 打印和测试预测效果

print(‘w = ‘,model.linear.weight.item())
print(‘b = ‘,model.linear.bias.item())

x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print(‘y_pred = ‘,y_test.data)

不光要观察训练集,也要观察测试集。

  1. import torch
  2. x_data = torch.Tensor([[1.0], [2.0], [3.0]]) # 输入数据
  3. y_data = torch.Tensor([[2.0], [4.0], [6.0]]) # 输出数据
  4. class LinearModel(torch.nn.Module):
  5. def __init__(self):
  6. super(LinearModel, self).__init__() # 调用父类的初始化函数
  7. self.linear = torch.nn.Linear(1, 1)
  8. def forward(self, x):
  9. y_pred = self.linear(x)
  10. return y_pred
  11. model = LinearModel() # 实例化线性模型类
  12. criterion = torch.nn.MSELoss(size_average=False) # 均方差
  13. optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 随机的梯度下降
  14. # epoch 时期
  15. for epoch in range(100): # 循环100次
  16. y_pred = model(x_data)
  17. loss = criterion(y_pred, y_data) # 此处loss是一个对象
  18. print(epoch, loss)
  19. optimizer.zero_grad() # 梯度归零
  20. loss.backward() # 进行反向传播
  21. optimizer.step() # 更新
  22. print('w = ', model.linear.weight.item())
  23. print('b = ', model.linear.bias.item())
  24. x_test = torch.Tensor([[4.0]])
  25. y_test = model(x_test)
  26. print('y_pred = ', y_test.data)

六、逻辑回归

logistic regression
分类问题:输出的是属于每一个分类的概率,0.4或者0.6的时候,不确定
要计算的是P(y=1)和P(y=0)的概率
image.png
下面的y是逻辑回归方程(sigmoid 函数中最出名)的x。
图像是上图的形状,但为啥是这样的函数呢?
先别急,还有其他的sigmoid函数:
1、增函数 2、饱和函数
image.png

MINIST 手写数字的数据集
线性回归:
torchvision:pytorch提供的工具包,提供相应的数据集。

十、卷积神经网络

Convolusion Neural Network