DAY 1
参考视频:
1 - pytorch简介
Pytorch是torch的python版本,是由Facebook开源的神经网络框架,专门针对 GPU 加速的深度神经网络(DNN)编程。Torch 是一个经典的对多维矩阵数据进行操作的张量(tensor )库,在机器学习和其他数学密集型应用有广泛应用。与Tensorflow的静态计算图不同,pytorch的计算图是动态的,可以根据计算需要实时改变计算图。但由于Torch语言采用 Lua,导致在国内一直很小众,并逐渐被支持 Python 的 Tensorflow 抢走用户。作为经典机器学习库 Torch 的端口,PyTorch 为 Python 语言使用者提供了舒适的写代码选择。
2 - Tensor张量
1 - Tensor的基本概念
一个Tensor是一个包含单一数据类型的高维矩阵,简言之Tensor其实和Numpy里的array是一样的。单个元素叫标量(scalar),一个序列叫向量(vector),多个序列组成的平面叫矩阵(matrix),多个平面组成的立方体叫张量(tensor)。当然,就像矩阵有一维矩阵和二维矩阵乃至多维矩阵一样,张量也无需严格限制在三维以上才叫张量,在深度学习的范畴内,标量、向量和矩阵都统称为张量。
在深度学习领域中,为何要约定高维数组Tensor呢?
其实这是出于应用方向的实际需要,以深度学习当前最成熟的两大应用方向莫过于CV和NLP两大领域,前者面向图像和视频,后者面向语音和文本,二者分别以卷积神经网络和循环水神经网络为核心基础模块。而在这两个应用方向中,标准的输入数据集都至少是三维以上,例如
图像数据集至少包含三个维度:N×H×W,即样本数×图像高×图像宽;
如果是彩色图像,那么还要增加一个通道C,变为N×C×H×W;
如果是视频图像,那么可能还要再增加一个维度T;
文本数据集典型的输入包含三个维度:N×L×H,即样本数×序列长度×特征数
2 - Tensor代码实战
from __future__ import print_function
import torch
#创建一个未初始化矩阵
x = torch.empty(3,3)
print('x',x)
#创建随机初始化矩阵
y = torch.rand(3,3)
print('y',y)
#创建一个填满 0 且数据类型为 long 的矩阵
z = torch.zeros(3,3,dtype=torch.long)
print('z',z)
#直接从数据构造张量
a = torch.tensor([5,3.2])
print('a',a)
#根据现有的 tensor 建立新的 tensor
b = x.new_ones(3,3,dtype = torch.double)
print('b',b)
#张量的运算
#1:加法运算
print("z+y", z+y)
print("z+y2", torch.add(z,y))
print("z+y3", y.add_(z))
#2:形状变换
y = x.view(9)
z = x.view(-1, 9)
print(x.size(), y.size(), z.size())
3 - 线性回归问题分析
1 - 梯度下降算法
梯度是函数对它的各个自变量求偏导后,由偏导数组成的一个向量。梯度下降法的作用就是寻找一个极小值点,从而让函数的值尽可能地小。但是这么多个极值点,那么梯度下降法找到的是哪一个点呢?关于这个问题就要看运气了,算法的最开始会随机寻找一个位置然后开始搜索的最优解,如果运气好的话能够寻找到一个最小值的极值点,运气不好或许找到的就不是最小值的那个极小值点。
2 - 梯度下降代码演示
(看代码理解就行)
import matplotlib.pyplot as plt
import numpy as np
# 初始算法开始之前的坐标
# cur_x 和 cur_y
cur_x = 6
cur_y = (cur_x-1)**2 + 1
# 设置学习率 eta 为 0.05
eta = 0.05
# 变量 iter 用于存储迭代次数
# 这次我们迭代 1000 次
# 所以给它赋值 1000
iter = 1000
# 变量 cur_df 用于存储
# 当前位置的导数
# 一开始我给它赋值为 None
# 每一轮循环的时候为它更新值
cur_df = None
# all_x 用于存储
# 算法进行时所有点的横坐标
all_x = []
# all_y 用于存储
# 算法进行时所有点的纵坐标
all_y = []
# 把最一开始的坐标存储到
# all_x 和 all_y 中
all_x.append(cur_x)
all_y.append(cur_y)
# 循环结束也就意味着算法的结束
for i in range(iter):
# 每一次迭代之前先计算
# 当前位置的梯度 cur_df
# cur 是英文单词 current
cur_df = 2*cur_x - 2
# 更新 cur_x 到下一个位置
cur_x = cur_x - eta*cur_df
# 更新下一个 cur_x 对应的 cur_y
cur_y = (cur_x-1)**2 + 1
# 其实 cur_y 并没有起到实际的计算作用
# 在这里计算 cur_y 只是为了将每一次的
# 点的坐标存储到 all_x 和 all_y 中
# all_x 存储了二维平面上所有点的横坐标
# all_y 存储了二维平面上所欲点的纵坐标
# 使用 list 的 append 方法添加元素
all_x.append(cur_x)
all_y.append(cur_y)
# 这里的 x, y 值为了绘制二次函数
# 的那根曲线用的,和算法没有关系
# linspace 将会从区间 [-5, 7] 中
# 等距离分割出 100 个点并返回一个
# np.array 类型的对象给 x
x = np.linspace(-5, 7, 100)
# 计算出 x 中每一个横坐标对应的纵坐标
y = (x-1)**2 + 1
# plot 函数会把传入的 x, y
# 组成的每一个点依次连接成一个平滑的曲线
# 这样就是我们看到的二次函数的曲线了
plt.plot(x, y)
# axis 函数用来指定坐标系的横轴纵轴的范围
# 这样就表示了
# 横轴为 [-7, 9]
# 纵轴为 [0, 50]
plt.axis([-7, 9, 0, 50])
# scatter 函数是用来绘制散点图的
# scatter 和 plot 函数不同
# scatter 并不会将每个点依次连接
# 而是直接将它们以点的形式绘制出来
plt.scatter(np.array(all_x), np.array(all_y), color='red')
plt.show()
3 - 线性回归
这里推荐这篇博主的文章:
用人话讲明白线性回归LinearRegression - 知乎 (zhihu.com)