pytorch、jupyter初识

前言

  如何逐渐掌握深度学习呢,是一个难题,网上参差不齐没有一个非常好非常全面的教程,只能一点一点自己累计,寻找例程来模仿主要理解他是怎么一步步完成任务的、思考一个普遍性的解决问题的过程,如何搭建深度学习的神经网络框架,现在暂时选择pytorch
  然后,目前推荐搭建框架过程使用jupyter notebook,所以也要学习如何使用它,那么我想在每一阶段都解决和思考一些问题记录下来,来一步步稳扎稳打的学习深度学习

个人思路

  其实,深度学习说难不难,说简单肯定不简单,你真的可以甚至1天快速入门、上手,只要你懂一些python语法,稍微看看比较通俗的神经网络的介绍文章,学一种搭建框架的方式就能让你用上你设计的网络结构,大批量的规则化的图像信息甚至也可以从网上获取,然后非常方便的使用、训练、测试。
  但是你想真正用神经网络来解决问题你自己的实际问题,那么这些将远远不够,至少我是这样认为的,所以我寻找了很多比较有顺序的深度学习教程(pytorch的),都需要一篇篇的仔细阅读,深化概念,让之后的进阶操作能更快理解。


学习阶段————初次接触

思考:

  • 如何将一大批尺寸不一、随机的图像统一标准化的作为深度学习的输入、以及同时集合这些输入的label–对应的解,即真实值(来和输出层的计算值比较损失)?
  • 神经网络的框架如何根据自己的要求、向适合解决问题的网络结构改进?
  • 学习如何使用GPU来训练模型?
  • jupyter notebook 中如何正常运行pytorch网络?

一、在Morvan莫烦的pytorch教程中,再次理解神经网络

1.1 神经网络是什么

  • 之前虽然理解了一种说法,好像没提出来,这里讲一讲,但不讲太多,没啥意义
  • 首先,人们希望模仿人类的大脑,即生物神经网络,人类如何形成条件反射?如何学习?如何记忆?大脑内神经元如何工作?神经元之间有什么样的联系?
  • 人工神经网络相比,相似,又不相似,所有神经元的连接在同一时间都是固定的,不会凭空产生新联结,它是一种逐次接近正确答案的训练手段,其中“误差反向传递”起到关键作用

1.2 神经网络的简单结构概念

  • Gradient Descent:梯度下降    Cost Function:损失函数
  • 输入层、隐含层(第1层。。。第n层)、输出层就对应着特征–>代表特征1–>…–>代表特征n–>输出,这些代表特征是越来越抽象的,人越来越无法理解,但计算机就对他比较敏感了
  • 迁移学习:即在当你现有的一般神经网络足够处理比如图片内容种类识别、字符识别的任务后。如果我们在输出层前再加入几层神经网络来训练,就能来完成进阶的任务,比如不仅识别数字,还能知道数字的书写字体。。等等

2.1 选择Pytorch

  • 好用、使用广泛、新颖、直观、动态建立框架
  • torchvision里已经有一些它搭建好的网络,比如resnet(可以可以,我知道例程是这样用的了),然后你用这个已有的网络来训练自己的任务

jupyter notebook工作目录更改为自定义,即在属性栏启动目录将userprofile/..双引号内的内容改为自己希望前往的目录地址,重启即可

2.2 什么是Variable

  •   它在神经网络的训练中是一个关键,为什么这么说?思考一下,神经网络的反向传播算法常用梯度下降法,那其中如何求梯度呢?
      大家都知道就是求偏导数,导数就是梯度,torch里求导数的小帮手就是variable,将tensor张量放进variable中,开启自动求梯度的配置

    1
    variable = Variable(tensor,requires_grad=True) #requires_grad = True

    那么,你以后含variable的运算就都和variable本身建立了某种联系,可以快速得到以后的结果相对variable的梯度

    1
    2
    v_out = torch.mean(variable*variable)  #例如求个平均数的运算
    v_out.backward() #求梯度
  • variable变量不同于tensor,但是variable.data可以得到tensor,如果想进行tensor和numpy_array的转换,那么就要xx.data先得到tensor

  • variable的运算和tensor相似,但不完全相同

2.3 激励函数(AF–activation function)?

  •   激励函数广泛应用在各种层,各种用,可是为什么要激励函数呢?因为复杂问题中,输入输出往往都不是线性关系,不是线性,你就不能简单在他们中间乘个系数。
      进阶的操作就是,在输入做完简单线性处理(乘k)的结果代入一个非线性函数
  •   常用的非线性激活函数由relusigmoidtanh方程,甚至可以自己创造激励函数来求解,不过要注意,这些激励函数必须都是可以微分的,因为需要求梯度求导
  •   当隐藏层不多时,可以尝试任意一个激励函数;不过当隐藏层中含有非常多个layer,就有慎重选择,可能出现梯度爆炸梯度消失(我也不太懂,再学学)。其次,具体案例中,少量隐藏层可以有多种选择,卷积神经网络首选relu循环神经网络首选relutanh

如何应用activation function

  • 理解代码然后实验即可
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import torch
    import torch.nn.functional as F
    from torch.autograd import Variable
    import matplotlib.pyplot as plt

    # fake data

    x = torch.linspace(-5, 5, 200) # x data (tensor), shape=(100, 1)
    x = Variable(x)
    x_np = x.data.numpy() # numpy array for plotting

    # following are popular activation functions

    y_relu = torch.relu(x).data.numpy()
    y_sigmoid = torch.sigmoid(x).data.numpy()
    y_tanh = torch.tanh(x).data.numpy()
    y_softplus = F.softplus(x).data.numpy() # there's no softplus in torch

3.1 构建网络:回归

  • 利用Pytorch建立一个简单的神经网络

    1
    2
    3
    4
    5
    6
    7
    8
    class Net(torch.nn.Module):
    def __init__(self, xxx, xxx, xxx, ...):
    super(Net, self).__init__()
    # xxxxxxxx

    def forward(self, x):
    # xxxxxxxx
    return x
  • 定义一个实际的神经网络

    1
    net = Net(xxx=1, xxx=10, xxx=1, ...)
  • 定义优化器optimizer和损失函数loss function

    1
    2
    optimizer = torch.optim.SGD(net.parameters(), lr=0.2)  #net.parameters():包含了神经网络的所有参数  lr:学习率(步长)
    loss_func = torch.nn.MSELoss() # this is for regression mean squared loss
  • 那么在训练的时候

    • 首先定义网络的输出位置prediction,真正计算损失loss
    • 每次利用优化器清除掉网络中之前计算的梯度
    • 然后开始运行反向传播算法
    • 最后向正确方向迈出一步,用计算出的梯度再计算出新一轮的网络参数
    1
    2
    3
    4
    5
    prediction = net(x)     # input x and predict based on x
    loss = loss_func(prediction, y) # must be (1. nn output, 2. target)
    optimizer.zero_grad() # clear gradients for next train
    loss.backward() # backpropagation, compute gradients
    optimizer.step() # apply gradients

    当然本节是对于简单的回归问题,所以定义输出量的变量简单,损失计算也是简单的均方差算法

3.2 构建网络:分类

  • 与简单的回归神经网络不同的是,分类神经网络的输入量和输出量都不只有一个
  • 输入量可以是一组坐标,甚至可以是一张图片的一个三维张量,而输出则可以是一个输入张量对所有类别的概率判断
  • 分类的损失函数选择和回归是不一样的,教程中选择了loss_func = torch.nn.CrossEntropyLoss()
  • 当然,对于我要解决的字符识别问题而言,输入就要复杂得多,远不是一对坐标那么简单,输出的类别也会有很多,所以更透彻的学习将在第二阶段进行

图像识别与处理

前言:图像识别与处理的大实验,需要完成的任务是基于嵌入式的字符识别

我目前想到的方案:

  • 硬件方面:利用手里有的stm32f4开发板,再买一个ov2460的摄像头采集图像,最后借助手上的蓝牙模块传输信息到电脑上。
  • 算法部分:做基于python的程序编写,那么准备利用好github上的各种方法,将这一块的图像处理学透,比如得到一个原始图像的初步处理,后面的支持向量机(SVM)、深度学习等

CNN

一个通俗易懂的卷积神经网络的内容介绍

  • 这是一个非常容易理解的CNN卷积神经网络的入门介绍,一个图像的信息以RGB的形式输入,那么就是一个3维的且“厚度”为3阶(一个RGB像素点含三个数)的矩阵,经过

卷积层(矩阵样式的过滤器,很好理解)

激活函数(比如relu,对每一层后得到的矩阵处理)

池化层(分成中块对每个中块进行处理,来简化阶数)

全连接层(涉及传统的神经网络,这一层是每一个单元都和前一层的每一个单元相连接,所以称之为“全连接”)

  • 到了全连接层之后的操作,就跟普通的神经网络无异了,卷积神经网络比较于传统神经网络的优势在于:

1.参数共享机制:对于不同的区域,我们都共享同一个filter,因此就共享这同一组参数;有效地避免过拟合;由于filter的参数共享,即使图片进行了一定的平移操作,我们照样可以识别出特征,这叫做 “平移不变性”。因此,模型就更加稳健了

2.连接的稀疏性:传统神经网络中,由于都是全连接,所以输出的任何一个单元,都要受输入的所有的单元的影响。这样无形中会对图像的识别效果大打折扣。比较,每一个区域都有自己的专属特征,我们不希望它受到其他区域的影响



Logistic Regression

逻辑分析的理解

  • 逻辑分析的含义:
  1. 有一个列向量,其中包含着一张照片的所有有效信息,他可能有10个数据,也可能有10000个数据,通常是像素值;每一个数据都对应着一个权重,那么自然这些权重也会组成一个列向量。所有数据加权求和之后加上一个系数b就会有一个输出,可以理解成一张照片就会有一个总输出

x0w0+x1w1+…+x12287w12287+b=WTx+b

  1. 对于总输出的处理,他会作为一个激活函数(对于神经元的)(对于逻辑分析就指的是sigmoid函数)的变量输入,函数的输出就是这张照片的一个预测结果y’,sigmoid函数**输出在0-1范围内,对于图像处理最终结果的判断就在0-1中且分为了几个区间,y’在这个区间说明图片是“xx”,在那个区间又说明什么。。。

y’ = σ(WTx+b)

  1. 而其实这都是根据一个前置处理(加权求和、带入激活函数)得出的预测值,他就不会一定准,所以有一个损失函数来衡量y’与真实值y(比如sigmoid函数输出对应的0或1)的差距

L(y’,y) = -[y·log(y’)+(1-y)·log(1-y’)]

  1. 那么对于一个我们用来训练的图片集来说,每一张照片都有一个预测值y’。这些y’的损失函数的输出值的平均值尽量小,那就是综合了所有图片数据得到的模型。寻找W和b的较好的值,就靠这个平均值,也叫平均损失(其函数名称叫代价函数)求得,这个函数的导数为零的那一点应该是极小值,那损失就是极小值。

J(W,b) = 1/m·Σmi=1L(y’(i),y(i))

  1. 通常用梯度下降法,那么操作起来就是,求得函数在目前的W、b处对W的导数,如果梯度(导数)为正,说明曲线之后向上走,所以W的值应该减小才能往低处走,梯度为负那就往前走正好是往低了走,重复一次成为一个迭代,当然还有对b的偏导,一次次迭代,一次次更新W和b的参数。梯度下降法中学习率(α)相当于每次迭代步长

w := w - α(dJ/dw)

  1. 最后那这对(W、b)就可以用来检验对于图像识别的准确率了

一个对逻辑回归分析更清晰的介绍

  1. 简单来说, 逻辑回归(Logistic Regression)是一种用于解决二分类(0 or 1)问题的机器学习方法,用于估计某种事物的可能性。
  2. 上文所提到的代价函数称之为交叉熵,是对「出乎意料」(译者注:原文使用suprise)的度量。那么,交叉熵衡量的是我们在知道y的真实值时的平均「出乎意料」程度。当输出是我们期望的值,我们的「出乎意料」程度比较低;当输出不是我们期望的,我们的「出乎意料」程度就比较高。
  3. sigmoid函数为决策边境,他是线性的。


NNS

传统神经网络的基础入门

  1. 作为对前面碎片化学习的延申。我认为只能说一次逻辑回归可能只能应用于线性问题,而有多个计算层的神经网络是可以解决非线性问题的。这是由于每一个计算层,或者说每一个单元的处理都是线性的,但是前一个计算层将数据空间扭曲了(两层间的权重矩阵是转换的关键),使得下一个计算层就算是线性的,也可以很好的划分出决策边境。因此,多层的神经网络的本质就是复杂函数拟合

  2. 神经网络通常有

输入层(包含已知的若干特征)

隐藏层(对输入特征一层层的抽象,获得更深一层的含义)

输出层(希望获得的目标,可以是单一值,也可以是向量)

偏置单元:它本质上是一个只含有存储功能,且存储值永远为1的单元。在神经网络的每个层次中,除了输出层以外,都会含有这样一个偏置单元。正如线性回归模型与逻辑回归模型中的一样。

  1. 对于只有输入层和输出层的神经网络称为感知器,它只能做线性的分类任务;而多层神经网络(深度学习)就能更深入的表示特征,以及拥有更强的函数模拟能力

  2. 传统神经网络中一个单元(节点 or 神经元)的处理基本上可以陈述为:上一层所有节点的输出向量矩阵乘上两层之间的权重矩阵,得到的结果矩阵,再作为激活函数转移函数)的变量输入。函数输出值作为这个节点的输出向下一层传递、或者作为目标直接输出

  3. 在单层神经网络时,我们使用的激活函数是sgn函数。到了两层神经网络时,我们使用的最多的是sigmoid函数。而到了多层神经网络时,通过一系列的研究发现,ReLU函数在训练多层神经网络时,更容易收敛,并且预测性能更好。因此,目前在深度学习中,最流行的非线性函数是ReLU函数。

ReLU函数:不是传统的非线性函数,而是分段线性函数。其表达式非常简单,就是y=max(x,0)。简而言之,在x大于0,输出就是输入,而在x小于0时,输出就保持为0。这种函数的设计启发来自于生物神经元对于激励的线性响应,以及当低于某个阈值后就不再响应的模拟。

  1. 训练:训练的主题仍然是优化泛化

优化梯度下降算法以及反向传播算法(BP)在多层神经网络中的训练中仍然工作的很好。目前学术界主要的研究既在于开发新的算法,也在于对这两个算法进行不断的优化。

反向传播算法:即由后层向前层一层层的递推,递推什么呢,就是代价函数对于这些个权重的偏导数,由于高等数学中的偏导数中的链式法则

泛化:在深度学习中,泛化技术变的比以往更加的重要。这主要是因为神经网络的层数增加了,参数也增加了,表示能力大幅度增强,很容易出现过拟合现象。因此正则化技术就显得十分重要。目前,Dropout技术,以及数据扩容(Data-Augmentation)技术是目前使用的最多的正则化技术。

神经网络的类别

深度学习就是多层神经网络,而机器学习则不同,他大概是人工智能算法的一个总称,他的算法包含了回归算法、神经网络、SVM等等,是一个宽泛的课题

深度学习之卷积神经网络经典模型

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×