先看了点花书,后来觉得有点枯燥去看了b站up主六二大人的pytorch深度学习实践的课,对深度学习的理解更深刻一点,顺便做点笔记,记录一些我认为重要的东西,便于以后查阅。

一、 机器学习基础

学习的定义:

对于某类任务T核性能度量P,一个程序被认为可以从经验E中学习是指,通过E改进后,在任务T上由P衡量的性能有所提升。

常见学习任务

一、分类
二、输入缺失分类
三、回归
四、转录

无监督学习和监督学习

1)无监督学习设计观察随机向量x的好几个样本,试图显示或隐式地学习出概率分布p(x),在无监督学习中,算法必须在没有指导的情况下理解数据。

2)监督学习包含观察随机向量x及其相关联的值或向量y,然后从x预测y,即存在“老师”,提供目标y给机器学习系统,指导其应该做什么。

传统上回归、分类、结构化输出问题称为监督学习

线性回归

线性回归解决回归问题,我们的目标是建立一个系统,将向量 x ∈ R n x\in R^n x∈Rn作为输入,预测标量 y ∈ R y\in R y∈R 作为输出。 y ^ \hat{y} y^​表示模型预测y应该取得值,定义
y ^ = ω ⊤ x \hat{y} = \omega^\top x y^​=ω⊤x
ω ∈ R n \omega \in R^n ω∈Rn是参数向量
ω \omega ω是一组权重,决定每个特征如何影响预测的权重。

测试集

我们有m个输入样本组成的设计矩阵,不用它来训练模型,而是用来评估模型性能如何。同样有每个样本对应的正确值y组成的回归目标向量。此为test set,将输入 的设计矩阵记作 X ( t e s t ) \mathbf{X}^{(test)} X(test),回归目标向量记作 y ( t e s t ) \mathbf{y}^{(test)} y(test)。而度量模型性能的一种方法是计算模型在测试集上的均方误差(mean squared error) , y ^ ( t e s t ) \mathbf{\hat{y}} ^{(test)} y^​(test)代表模型在测试集上的预测值,则MSE表示为
M S E t e s t = 1 m ∑ i ( y ^ ( t e s t ) − y ( t e s t ) ) i 2 MSE_{test}=\frac{1}{m}\sum_i(\mathbf{\hat{y}} ^{(test)}-\mathbf{y} ^{(test)})_i^2 MSEtest​=m1​i∑​(y^​(test)−y(test))i2​当预测值和目标值之间的欧几里得距离增加时,误差也增加。
为构建算法,需设计一个算法通过观察 X ( t r a i n ) \mathbf{X}^{(train)} X(train)和 y ( t r a i n ) \mathbf{y}^{(train)} y(train)获得经验,减少 M S E t e s t MSE_{test} MSEtest​以改进权重 ω \omega ω
线性回归会附加额外参数截距项b,此映射仍为线性函数。b通常被称为仿射变换的bias参数。
y ^ = ω ⊤ x + b \hat{y} = \omega^\top x +b y^​=ω⊤x+b

容量、过拟合、欠拟合

我们的算法必须在先前未观测到的新输入上表现良好,这种能力称为泛化(generalization)

梯度下降

用整个数据集效率低,使用随机梯度下降,效率高,但相应的时间复杂度高,因此采取折中使用batch,mini-batch,小批量的进行随机梯度下降。
w = w − α ∂ ( c o s t ) ∂ w w=w-\alpha \frac{\partial(cost)}{\partial{w}} w=w−α∂w∂(cost)​

反向传播

首先关于激活函数的由来,因为 y ^ = W 2 ( W 1 X + b 1 ) + b 2 \hat{y}=W_2(W_1X+b_1)+b2 y^​=W2​(W1​X+b1​)+b2可化简为 y ^ = W 2 W 1 X + W 2 b 1 + b 2 = W X + b \hat{y}=W_2W_1X+W_2b_1+b_2=WX+b y^​=W2​W1​X+W2​b1​+b2​=WX+b即使层数多,最后依然线性模型,并不能增加复杂程度,因此需要在每个结果后增加一个Nonlinear Function激活函数 σ \sigma σ

反向传播:我们要得到 ∂ L o s s ∂ w \frac{\partial{Loss}}{\partial w} ∂w∂Loss​,需要利用链式法则,下图清晰的描述了反向传播的过程。


在pytorch中,需要用到tensor,tensor保存了data和grad,代表了权重本身的值,以及损失对于此权重的梯度,即导数。

最后附此视频本章作业答案。b站刘二大人 第四讲

import torch
import numpy as np
import matplotlib.pyplot as plt
x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]w1 = torch.Tensor([1.0])
w1.requires_grad = Truew2 = torch.Tensor([1.0])
w2.requires_grad = Trueb = torch.Tensor([1.0])
b.requires_grad = Truedef forward(x):return w1 * x **2 + w2 * x + bdef loss(x, y):y_pred = forward(x)return (y_pred-y) ** 2print("predict (before training)", 4, forward(4).item())  #item() 是为了取得标量mse_list=[]
for epoch in range(1000):for x, y in zip(x_data, y_data):l = loss(x,y)l.backward()print('\tgrad:',x, y, w1.grad.item(),w2.grad.item(),b.grad.item())w1.data = w1.data - 0.01 * w1.grad.data   #更新权重时,不能使用张量, 而要使用dataw2.data = w2.data - 0.01 * w2.grad.datab.data = b.data - 0.01 * b.grad.dataw1.grad.data.zero_()    #将w的梯度清零w2.grad.data.zero_()b.grad.data.zero_()print("progress:",epoch, l.item())mse_list.append(l.item())
print("predict (after training)",4,forward(4).item())
plt.plot(range(1000), mse_list)
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

第五讲 用Pytorch实现线性回归

线性回归就是只有一个神经元的神经网络

步骤
1、prepare dateset 准备数据集
2、design model using Class 设计模型(计算 y ^ \hat{y} y^​)
3、construct loss and optimizer 构建损失函数以及优化
4、training cycle 训练周期(前馈、反馈、更新)

一个 z = w x + b z=wx+b z=wx+b代表一个Linear Unit即线性单元

代码:

import torchx_data = torch.tensor([[1.0], [2.0], [3.0]])
y_data = torch.tensor([[2.0], [4.0], [6.0]])class LinearModel(torch.nn.Module):def __init__(self):super().__init__()self.linear = torch.nn. Linear(1, 1)def forward(self, x):y_pred = self.linear(x)return y_predmodel = LinearModel()  #模型criterion = torch.nn.MSELoss(size_average= False) #求损失,传入yhat和yoptimizer = torch.optim.SGD(model.parameters(), lr=0.01)    #优化器for epoch in range(1000):y_pred = model(x_data)loss = criterion(y_pred, y_data)print(epoch, loss.item())optimizer.zero_grad()    #梯度清零loss.backward()             #反向传播optimizer.step()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.item())

明显感觉,很多步骤pytorch都替我们弄好了,只需要调用函数即可,很方便。

第六讲 logistic regression (分类问题)

分类问题输出的是一个概率,对于数字0-9本身抽象类型不构成大小比较,满足分布。

tochvision 还提供了 CIFAR-10 dataset ,是一些图片比如车、飞机等

import torchvision
train_set = torchvision.datasets.MNIST(root='../dataset/mnist', train= True, download= True)
test_set = torchvision.datasets.MNIST(root='../dataset/mnist', train= False, download= True)

将mnist改为CIFA10即可

在分类中 输出的是 p ( y ^ ) p(\hat{y}) p(y^​)即此结果的概率。

sigmoid 函数:满足0-1且饱和函数
最出名的就是logistic function: σ ( x ) = 1 1 + e − x \sigma(x)=\frac{1}{1+e^{-x}} σ(x)=1+e−x1​

线性单元: y ^ = ω ⊤ x + b \hat{y} = \omega^\top x +b y^​=ω⊤x+b
logistic function 单元就是用sigma去作用即: y ^ = σ ( ω ⊤ x + b ) \hat{y} = \sigma(\omega^\top x +b) y^​=σ(ω⊤x+b)

同样的损失函数也不再是一个差,而是一个分布
l o s s = − ( y l o g y ^ + ( 1 − y ) l o g ( 1 − y ^ ) ) loss = -(ylog\hat{y}+(1-y)log(1-\hat{y})) loss=−(ylogy^​+(1−y)log(1−y^​))binary cross entropy
BCE损失函数,
KL散度、交叉熵(一堆概率论的知识点、还没学)

同样是四步

第七讲 处理多维特征的输入


这样的一些样本,每一行是一个record,每一列每个x是一个feature即特征。

没想到anaconda下还有数据库啊

D:\anaconda3\Lib\site-packages\sklearn\datasets\data

对于多维的,比如上面的一行一个记录
需要的模型则变成
y ^ ( i ) = σ ( ∑ n = 1 8 x n i ⋅ ω n + b ) = σ ( z i ) \hat{y}^{(i)}=\sigma(\sum_{n=1}^{8}x_n^{i}\cdot\omega_n+b)=\sigma(z_i) y^​(i)=σ(n=1∑8​xni​⋅ωn​+b)=σ(zi​)

当有N个样本时,参数w则可写为N×8的矩阵,b也需要写成8×1的矩阵。

代码只需将Linear(1,1) 改为Linear(8,1),即输入为8维,一个样本的纬度值,输出为1维

class Model(torch.nn.Module):def __init__(self):super().__init__()self.linear = torch.nn.Linear(8,1)self.sigmoid = torch.nn.Sigmoid()def forward(self, x):x = self.sigmoid(self.linear(x))return xmodel = Model()

将多个unit首位相连即可构造神经网络,本质就是进行矩阵的乘法运算。找到一个n维到1维的非线性空间变化,利用多层的运算来模拟非线性。

课中的例子用的的diabetes的数据集进行3个神经元的训练,整体的代码如下

import torch
import numpy as np
import matplotlib.pyplot as plt
xy = np.loadtxt('diabetes.csv.gz',delimiter=',', dtype=np.float32)
x_data = torch.from_numpy(xy[:, :-1])  #取出除了最后一列的数据
y_data = torch.from_numpy(xy[:, [-1]]) #只拿最后一列,且以矩阵的形式class Model(torch.nn.Module):def __init__(self):super().__init__()self.linear1 = torch.nn.Linear(8, 6)self.linear2 = torch.nn.Linear(6, 4)self.linear3 = torch.nn.Linear(4, 1)self.sigmoid = torch.nn.Sigmoid()def forward(self, x):x = self.sigmoid(self.linear1(x))x = self.sigmoid(self.linear2(x))x = self.sigmoid(self.linear3(x)) #一般最后一个使用sigmoid 其他可relureturn xmodel = Model()
criterion = torch.nn.BCELoss(size_average = False)  #交叉熵
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)for epoch in range(100): #训练基本不变#forwardy_pred = model(x_data)loss = criterion(y_pred, y_data)print(epoch, loss.item())#backwardoptimizer.zero_grad()loss.backward()#Updateoptimizer.step()

将epoch和loss作为x、y绘图后得,这里循环了5000次

第八讲 加载数据集

在梯度下降时,一种称为batch,需要用到全部的样本,另一种称为随机梯度下降,只用一个样本,随机性较好,可克服鞍点问题,batch的优点是利用向量计算的优势,提高计算的速度。
综合考虑,使用mini-batch

概念:Epoch、Batch-size、Iteations
#Training cycle
for epoch in range(training_epochs): //外层是训练周期#loop over all batchesfor i in range(total_batch):  //内层是batch的迭代

Epoch:所有的样本都参与了一次前馈传播和反馈传播
Batch-size:一次前馈和反馈的训练样本的数量
Iteration:内层的迭代次数 number of pass
举例,epoch10000次, batch-size大小为1000, 则iteration为10

DataLoader:batch_size=2 shuffle=True

将Dataset打乱后进行分组打包成batch

第九讲 多分类问题

最后一层归一化 softmax layer,目的是为了满足概率分布
softmax function:
P ( y = i ) = e z i ∑ j = 0 K − 1 e z j P(y=i)=\frac{e^{z_i}}{\sum_{j=0}^{K-1}e^{z_j}} P(y=i)=∑j=0K−1​ezj​ezi​​
其中 z i z_i zi​是最后一层的输出,此时保证了结果输出和为1.保证了概率分布的条件

对于损失函数loss: − Y l o g Y ^ -Ylog\hat{Y} −YlogY^

import torch
y = torch.LongTensor([0])
z = torch.Tensor([[0.2, 0.1, -0.1]])
criterion = torch.nn.CossEntropyLoss()  #从softmax到求对数输出合起来写了个交叉熵函数
loss = criterion(z,y)
print(loss)

处理MNIST
图片以Pillow的格式存储,我们首先利用transform将PIL 图像转为Image
Z 28 × 28 , p i x e l ∈ { 0 , . . . , 255 } \mathbb{Z}^{28\times28}, pixel \in {\{ 0,...,255\}} Z28×28,pixel∈{0,...,255}变成 R 1 × 28 × 28 , p i x e l ∈ [ 0 , 1 ] \mathbb{R}^{1\times28\times28},pixel\in[0,1] R1×28×28,pixel∈[0,1]
其中1为通道,本数据集为单通道图片,彩色RGB则为3通道。28x28是图片高和宽

构建模型时,输入的是一个(N,1,28,28)的四阶张量,但因为神经网络中输入样本为矩阵,每个样本占一行,则首先将其变为1阶向量。即变成(N,784) x=x.view(-1,784)此处填-1可以自动算出N的值。

实现MNIST手写识别完整代码如下

import torch
from torchvision import datasets
from torchvision import transforms
import torch.optim as optim
batch_size = 64
from torch.utils.data import DataLoadertransform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307, ), (0.3081, ))])
#nomalize均一化,后面两个参数是均值和标准差,此处是前人已算好的
#处理图像张量,将数值压在0-1之间
#利用ToTensor将PIL Image 变成 Tensortrain_dataset = datasets.MNIST(root='../dataset/mnist', train=True, transform=transform, download=True) #训练集
test_dataset = datasets.MNIST(root='../dataset/mnist', train=False, transform=transform, download=True) #测试集train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)class Net(torch.nn.Module):def __init__(self):super().__init__()self.l1 = torch.nn.Linear(784, 512)  self.l2 = torch.nn.Linear(512, 256)self.l3 = torch.nn.Linear(256, 128)self.l4 = torch.nn.Linear(128, 64)self.l5 = torch.nn.Linear(64, 10)self.Relu = torch.nn.ReLU()   #激活函数采用reludef forward(self,x):x = x.view(-1, 784)x = self.Relu(self.l1(x))x = self.Relu(self.l2(x))x = self.Relu(self.l3(x))x = self.Relu(self.l4(x))return self.l5(x)  #最后一层输出不需要激活model = Net()criterion = torch.nn.CrossEntropyLoss()  #交叉熵损失
optimizer = optim.SGD(model.parameters(),lr=0.01, momentum=0.5)def train(epoch):  # 封装训练函数running_loss = 0.0   # 累计的lossfor batch_idx, data in enumerate(train_loader,0):inputs, target = dataoptimizer.zero_grad()   #清零#forward+backward+updateoutputs = model(inputs)loss = criterion(outputs, target)loss.backward()optimizer.step()running_loss += loss.item()if batch_idx %300 ==299:    print('[%d, %5d] loss: %3f' % (epoch + 1, batch_idx + 1, running_loss/300))running_loss = 0.0def test():   #封装测试函数correct = 0total = 0with torch.no_grad():  #不再计算梯度for data in test_loader:images, labels = dataoutputs = model(images)_, predicted = torch.max(outputs.data, dim=1)total +=labels.size(0)correct += (predicted == labels).sum().item()print('Accuracy on test set: %d %%' % (100*correct / total))if __name__ == '__main__':for epoch in range(10):train(epoch)test()

最后结果如下:

剩下四讲为卷积神经网络和循环神经网络准备重开一篇。

深度学习笔记(MNIST手写识别)相关推荐

  1. 深度学习笔记:手写一个单隐层的神经网络

    出处:数据科学家养成记 深度学习笔记2:手写一个单隐层的神经网络 笔记1中我们利用 numpy 搭建了神经网络最简单的结构单元:感知机.笔记2将继续学习如何手动搭建神经网络.我们将学习如何利用 num ...

  2. AI Studio 飞桨 零基础入门深度学习笔记6.3-手写数字识别之数据处理

    AI Studio 飞桨 零基础入门深度学习笔记6.3-手写数字识别之数据处理) 概述 前提条件 读入数据并划分数据集 扩展阅读:为什么学术界的模型总在不断精进呢? 训练样本乱序.生成批次数据 校验数 ...

  3. Tensorflow之基于MNIST手写识别的入门介绍

    Tensorflow是当下AI热潮下,最为受欢迎的开源框架.无论是从Github上的fork数量还是star数量,还是从支持的语音,开发资料,社区活跃度等多方面,他当之为superstar. 在前面介 ...

  4. 使用mllib完成mnist手写识别任务

    使用mllib完成mnist手写识别任务 小提示,通过restart命令重启已经退出了的容器 sudo docker restart <contain id> 完成识别任务准备工作 从以下 ...

  5. Mnist手写识别项目常见问题及解决方法

    环境搭建 问题1:在Visual Studio 2019中的"扩展"管理中搜索不到"AI工具" 解决方法:因为"AI工具"插件不支持Visu ...

  6. 深度学习数字仪表盘识别_【深度学习系列】手写数字识别实战

    上周在搜索关于深度学习分布式运行方式的资料时,无意间搜到了paddlepaddle,发现这个框架的分布式训练方案做的还挺不错的,想跟大家分享一下.不过呢,这块内容太复杂了,所以就简单的介绍一下padd ...

  7. 深度学习项目实战——手写数字识别项目

    摘要 本文将介绍的有关于的paddle的实战的相关的问题,并分析相关的代码的阅读和解释.并扩展有关于的python的有关的语言.介绍了深度学习步骤: 1. 数据处理:读取数据 和 预处理操作 2. 模 ...

  8. 深度学习入门实践学习——手写数字识别(百度飞桨平台)——上篇

    一.项目平台 百度飞桨 二.项目框架 1.数据处理: 2.模型设计:网络结构,损失函数: 3.训练配置:优化器,资源配置: 4.训练过程: 5.保存加载. 三.手写数字识别任务 1.构建神经网络流程: ...

  9. 【第一个深度学习模型应用-手写数字识别】

    基于BP神经网络的手写数字识别报告 基于BP神经网络的手写数字识别报告 一.任务描述 二.数据集来源 三.方法 3.1 数据集处理方法 3.2.模型结构设计 3.3.模型算法 四.实验 4.1.实验环 ...

最新文章

  1. 2020 年最强大的 10 门编程语言
  2. python读取excel部分值存入另一个excel-python3读取excel文件只提取某些行某些列的值方法...
  3. ubuntu16.04 npm安装
  4. deepin安装node,npm
  5. LeetCode之Power of Two
  6. 前端学习(1569):todoMVC准备工作
  7. php数组转换编码,PHP数组转换编码类
  8. java alert跳页面_JavaScript中通过提示框跳转页面的方法
  9. Mongodb java 例子
  10. AudioSwitcher for mac(音频控制工具)v3.08 版本支持M1芯片
  11. Linux网络服务-LAMP之Php基于Apache的模块实现
  12. DVWA教程详细的DVWA-CSRF全等级通关教程
  13. 通过DXGI实现高效抓屏
  14. SQL之CASE WHEN用法详解
  15. uni-app h5 扫一扫
  16. S2B2C模式有何优势?S2B2C电商系统赋能皮革企业渠道,提升供应链管理效率
  17. linux 该文件的owner,Linux修改文件/目录的owner/group方法(转载)
  18. WordpressCMS主题开发04-如何在首页调用各个分类下的文章以及图片栏目
  19. python统计元音字母个数_Quzh[python]统计元音字母——输入一个字符串,统计处其中元音字母的数量。...
  20. “春节游”还准备去海外猎食新鲜?麻烦!家门口明明啥都有!

热门文章

  1. This file's format is not supported or you don't specify a correct format. 解决办法
  2. git提交时windows验证凭据
  3. ThreadPool 线程池
  4. BLOCK层代码分析(6)IO下发之SGL聚散列表
  5. iOS 之倒计时 NSTimer 短信验证码 60秒 60分钟
  6. 【Pandas】datetime转换到string的三种方法
  7. getElementById的用法
  8. 【JSON】JSON 教程
  9. 在Ubuntu上安装使用PostgreSQL数据库
  10. dBm和mW之间的关系