【第2次作业】深度学习和 pytorch 基础

一. 深度学习心得

因为是github仓库做图床,如果部分图片加载不出,使用代理即可

曹阳:

1. 深度学习概述

1. 什么是机器学习?

"计算机系统能利用经验提高自身的性能"

"机器学习本质是一个基于经验数据的函数估计问题"

"提取重要模式,趋势,并理解数据,即从数据中学习"

2. 机器学习适合的场景

机器学习一般适合满足以下条件的问题

1.数据规模很大

2.准则复杂度高

3.有意义的模式

4.没有解析解的问题

没有解析解的模型

3. 机器学习的流程

**模型 ** 对要学习的问题映射的假设(问题建模,确定假设空间)

**策略 ** 从假设空间中学习选择最优模型的准则(确定目标函数)

算法 根据目标函数求解最优模型的具体计算方法(求解模型参数)

4.深度学习和传统机器学习的区别

传统机器学习通常只面向人手工设计的特征设计(有些时候人未必能很好地选择最有意义的特征)

深度学习则会自己去分析特征,判断哪些特征是有意义的,并把特征分层再进行学习(比手工设计的特征更客观)

5. 深度学习的缺点

算法输出不够稳定

模型复杂度高,难以调试

端到端的训练方式对数据依赖性强,模型增量型差

主要应用于感知类问题,不擅长开放推理问题

解释困难

2. 神经网络算法概述

灵感来源于生物神经元,不过随着神经网络算法的发展差异已经越来越大.

一个可视化的训练过程:

playground.tensorflow.org

M-P神经元

image-20201018191332354

1.多输入信号x乘以对应的权值进行累加

2.用权值的正负性来模拟兴奋或抑制,大小来模拟强度

3.当输入超过阈值θ的时候,神经元被激活,触发激活函数.

激活函数f

为什么需要激活函数?

如果没有激活函数,多层和单层一样最后的结果都是一个矩阵

只能拟合线性函数

我们一般期望激活函数提供非线性的拟合能力

比如:

image-20201018192219180

单层感知器

单层感知机可以来实现逻辑功能(与或非),从而完成分类

image-20201018193748058

多层感知器

组合使用单层感知机可以实现更复杂的逻辑功能(异或,同或)

万有逼近定理

如果一个隐层包含足够多的神经元,三层前馈神经网络(输入-隐层-输出)能够以任意精度逼近任意预定的连续函数

多隐层神经网络的问题:梯度消失

增加深度会造成梯度消失,误差无法传播,多层网络容易陷入局部极值,难以训练.一般主流做法是使用三层.

一些解决方法: 逐层训练,采用更好的激活函数,增加辅助损失函数等.

索欢:

一、视频学习心得及问题总结

  如今在世界的各个国家越来越重视人工智能的发展,人工智能和各个学科分支相结合可以涉及到我们生活的方方面面。在视频中,我浅尝了人工智能、机器学习和深度学习之间的关系,也感受到了深度学习较于传统的机器学习的优点以及今后机器学习要发展的方向。但是,机器学习的发展也到了一个瓶颈期,它也有一系列的缺点:稳定性低、可调式性差、参数不透明、机器有偏见、增量性差、推理能力差……如何高效的解决这些问题也成了我们现如今人工智能研究的目标。
  在深度学习中,有一个很重要的概念是神经网络。神经网络中有两个重要的概念:单层感知器和多层感知器。单层感知器是是首个可以学习的人工神经网络,但是解决不了非线性问题,于是就由单层感知器的线性任务组合推进到了多层感知器来实现相关非线性问题。在实验中,我们发现给一个隐层加入越多的神经元,三层前馈神经网络越逼近测试的连续函数,于是便得出了万有毕竟定理。如何训练我们的多层感知器,其中一个方法便是反向传播误差,就好比“从错误中学习”,监督者在人工神经网络犯错误时进行纠正。他的具体算法是:最初,所有的边权重都是随机分配的。对于所有训练数据集中的输入,人工神经网络都被激活,并且观察其输出。这些输出会和我们已知的、期望的输出进行比较,误差会“传播”回上一层。该误差会被标注,权重也会被相应的“调整”。该流程重复,直到输出误差低于制定的标准。上述算法结束后,我们就得到了一个学习过的人工神经网络,该网络被认为是可以接受“新”输入的。该人工神经网络可以说从几个样本(标注数据)和其错误(误差传播)中得到了学习。但是某些反向传播误差学习中,会出现梯度消失的问题:在每次训练的迭代中,神经网络权重的更新值与误差函数的偏导数成比例,然而在某些情况下,梯度值会几乎消失,使得权重无法得到有效更新,甚至神经网络可能完全无法继续训练。争对于上述问题,逐层预训练被提出,神经网络逐渐升级为机器学习,它的具体实现方法有自编码器和受限玻尔兹曼机,受限制玻尔兹曼机与自编码器是神经网络的两种基本结构,两个结构都能起到降维的作用,都可以用来对神经网络进行预训练,这种预训练都是无监督的,但是他们在结构上、原理上、训练优化上也有很多不同。

薛华丰:

一、绪论

  1. 人工智能:使一部机器像人一样进行感知、认知、决策、执行的人工程序或系统

  2. image-20201018202839957

  3. 人工智能第一个层面——计算智能
    人工智能第二个层面——感知智能
    人工智能第二个层面——认知智能

  4. 人工智能+
    金融
    内容创作
    机器人

  5. 逻辑演绎vs归纳总结

  6. 知识工程vs机器学习

    image-20201018202900973

  7. 机器学习的应用技术领域:计算机视觉、语音、自然语言处理

  8. 机器学习:计算机系统能够利用经验提高自身的性能,本质是一个基于经验数据的函数估计问题,也可理解为提取重要模式、趋势,并理解数据,即从数据中学习——从数据中自动提取知识

  9. 机器学习怎么学:模型、策略、算法

  10. 传统机器学习:人工设计特征

  11. 传统机器学习vs深度学习

  12. 神经网络结构的发展

  13. image-20201018202911120

  14. 深度学习的三个助推剂:大数据、算法、计算力

  15. image-20201018202937022

  16. 深度学习应用研究:视觉+语言
    深度学习理论研究:从“能”到“不能”
    深度学习的“不能”:
    (1)算法输出不稳定,容易被“攻击”
    (2)模型复杂度高,难以纠错和调试
    (3)模型层级复合程度高,参数不透明
    (4)端到端训练方式对数据依赖性强,模型增量性差
    (5)专注直观感知类问题,对开放性推理问题无能为力
    (6)人类知识无法有效引入进行监督,机器偏见难以避免

    image-20201018203000750

  17. 解释性vs泛化性

  18. 连接主义vs符号主义:从对立到合作

二、神经网络基础

1.浅层神经网络
起源:生物神经元->M-P神经元
单层感知器——首个可以学习的人工神经网络
单层->多层感知器
2.深层神经网络的问题:梯度消失
3.神经网路的参数学习:误差反向传播
4.逐层预训练、微调——受限泊尔兹曼机和自编码器

王宏基:

心得

  • 专家系统:输入->手动编制程序->输出
  • 传统机器学习:输入->手动指定特征->机器从特征映射(手动指定的特征可能不恰当,导致不佳的输出,可能需要返工)->输出
  • 简单的表示学习:输入->机器总结特征->机器从特征映射->输出
  • 深度学习:输入->机器提取简单特征->机器基于简单特征提取更复杂的特征(多层学习)->机器从特征映射->输出
  • 监督/无监督学习:数据标记/不标记
  • 强化学习:数据标记未知,但能获得相关反馈
  • 深度学习的“不能”:稳定性低、可调试性差、参数不透明、机器偏见、增量性差、推理能力差
  • M-P神经元:多输入单输出、空间整合、兴奋性/抑制性输入、阈值特性,权重预先设置,无法学习
  • 单隐层网络有足够多神经元,可逼近任意预定的连续函数
  • 双隐层网络有足够多神经元,可逼近任意预定的非连续函数
  • 网络深度的贡献是指数增长,宽度贡献是线性增长,但会有梯度消失问题,局部极小值(逐层预训练)

吴文敏:

1.绪论学习心得

​ 从专家学习到机器学习经过了三个阶段,分别是推理期、知识期和学习期。且这两大模式有非常不同的特点。其中专家系统依赖于专家的主观经验,而机器习的信息来源完全是基于现实数据。

​ 而在机器学习中,也是有传统机器学习和深度学习之分的。在传统机器学习中,数据会经过选择分类, 所以这其中会有人的参与,在一定程度上会对实验结果造成影响。但在深度学习中,数据是完全交给计算机,可以最大程度做到忠于原数据。

​ 机器学习的应用范围也十分广泛,可以用于计算机视觉,语音技术和自然语言处理,它的学习基于模型、策略和算法,所以不是所有问题都适合机器学习,比如对于开放性的推理问题无法提供有效的解决方案。

2.深度学习概论

​ 首先单层感知器是首个可以学习的人工智能网络。但单层的感应器存在很大的缺陷,首先它无法解决不可线性划分的问题,其次这需要巨大的计算量,所以在这之后神经网络研究陷入低潮。

​ 而多层感知器对单层感知器做了优化,从而解决非线性问题。

​ 这里的反向传播指的是误差的反向传播,输入数据在经过实际处理,由于隐含层的存在,会造成输出的一个误差。而这种误差可以实现神经网络的学习。

​ 梯度消失:梯度消失是指在增加神经网络的深度时出现误差无法传播的情况,由于误差通过梯度反向实现,故梯度消失导致误差无法传播。也即阻止了神经网络的学习。

​ 而这后面的便是深度学习的一些方法,这是针对神经网络深度过大时出现的一系列问题而提出的。

​ 逐层预训练便是对神经网络的每一层展开训练,最后将训练结果叠加,在这过程中可以实现监督信息的调整。

​ 而自编码器就是实现上述操作的具体途径,自编码器通过输入、隐层和输出监督信息以实现误差最小。

​ 而受限玻尔兹曼机便是一个具体模型,可使用梯度下降和反向传播算法优化。

戴铭瑞:

一. 视频学习心得及问题总结

通过学习视频了解到了:

  1. 人工智能(Artificial Intelligence) ,英文缩写为AI。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。 人工智能是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器,该领域的研究包括机器人、语言识别、图像识别、自然语言处理和专家系统等。

  2. 专家系统(expert system)是人工智能应用研究最活跃和最广泛的课题之一。运用特定领域的专门知识,通过推理来模拟通常由人类专家才能解决的各种复杂的、具体的问题,达到与专家具有同等解决问题能力的计算机智能程序系统。它能对决策的过程作出解释,并有学习功能,即能自动增长解决问题所需的知识。

  3. 机器学习和深度学习的关系:其实可以从特征提取的角度考虑问题,机器学习对数据的特征需要一定的洞察能力,到底什么是好的特征,这是ML要思考的问题。而深度学习相当于把数据放在了黑盒子中,然后”摇一摇“,就能自动学习到有用的特征,可以说DL是一种端到端的学习(end-to-end).

张子明:

一、视频学习

  1. 人工智能是研究、开发用于模拟、延伸和扩展人的智能的理论、方法及应用系统的一门新的技术科学。专家系统是早期人工智能的一个重要分支,它可以看作是一类具有专门知识和经验的计算机智能程序系统,一般采用人工智能中的知识表示和知识推理技术来模拟通常由领域专家才能解决的复杂问题。

  2. 传统机器学习是从一些观测样本出发,试图发现不能通过原理分析获得的规律,实现对未来数据行为或趋势的准确预测的学习技术。深度学习是用于建立、模拟人脑进行分析学习的神经网络,并模仿人脑的机制来解释数据的一种机器学习技术,通俗来讲就是深度学习是用于建立、模拟人脑进行分析学习的神经网络,并模仿人脑的机制来解释数据的一种机器学习技术。

  3. 深度学习和传统机器学习各有利弊:深度学习需要大量的数据支持,但传统机器学习通常不需要大量的数据。能用传统机器学习解决的,不需要耗费力气去搞深度学习。深度学习的“不能”:稳定性差,可调式省察,参数不透明,机器偏见,增量性差,推理能力差。

二. 问题总结

薛华丰:

  1. 人工智能是如何提取事物特征的?

王宏基:

  1. 对抗式生成网络、生成网络、判别式网络区别与联系
  2. 模拟脑结构=“使用概率矩阵来识别和归纳”?
  3. 强化学习的“反馈”通常怎么来?

曹阳:

  1. 为什么使用GPU来跑深度学习比CPU更有优势

  2. 螺旋数据分类的实验中注意到了程序首先初始化了随机种子,各项参数.并且在不同的参数下进行计算,所得的结果也会有差异,类似的算法也会常常面临调参的问题,比如cnn中的宽度,深度,分辨率常常不知道怎么去调参.对神经网络算法进行调参的时候有什么原则和技巧?

张子明:

  1. 什么情况下用机器学习什么情况下用深度学习?

  2. 人工智能有无缺点?

三. 代码练习(整合)

>2.1 pytorch 基础练习

image-20201018170130717

image-20201018170100963

image-20201018170156442

image-20201018170250810

image-20201018170307796

image-20201018170333418

image-20201018170402463

image-20201018170716991

image-20201018170743356

>2.2 螺旋数据分类

image-20201018170842003

image-20201018171812168

image-20201018170920959

image-20201018171235162

image-20201018171154253

image-20201018171259920

image-20201018171323355

image-20201018171340262

image-20201018171409304

image-20201018171421762

image-20201018171439104

>2.3代码关键步骤

  • 通过设置随机数种子来保证复现性

    seed = 12345
    random.seed(seed)
    torch.manual_seed(seed)
    
  • 生成用于训练的三千个样本点

    X = torch.zeros(N * C, D).to(device)
    Y = torch.zeros(N * C, dtype=torch.long).to(device)
    for c in range(C):
        index = 0
        t = torch.linspace(0, 1, N) # 在[0,1]间均匀的取10000个数,赋给t
        # 下面的代码不用理解太多,总之是根据公式计算出三类样本(可以构成螺旋形)
        # torch.randn(N) 是得到 N 个均值为0,方差为 1 的一组随机数,注意要和 rand 区分开
        inner_var = torch.linspace( (2*math.pi/C)*c, (2*math.pi/C)*(2+c), N) + torch.randn(N) * 0.2
        
        # 每个样本的(x,y)坐标都保存在 X 里
        # Y 里存储的是样本的类别,分别为 [0, 1, 2]
        for ix in range(N * c, N * (c + 1)):
            X[ix] = t[index] * torch.FloatTensor((math.sin(inner_var[index]), math.cos(inner_var[index])))
            Y[ix] = c
            index += 1
    
  • 创建线性模型

    learning_rate = 1e-3
    lambda_l2 = 1e-5
    
    # nn 包用来创建线性模型
    # 每一个线性模型都包含 weight 和 bias
    model = nn.Sequential(
        nn.Linear(D, H),
        nn.Linear(H, C)
    )
    model.to(device) # 把模型放到GPU上
    
  • 使用交叉熵损失函数,并使用optim包进行随机梯度下降优化

    # nn 包含多种不同的损失函数,这里使用的是交叉熵(cross entropy loss)损失函数
    criterion = torch.nn.CrossEntropyLoss()
    
    # 这里使用 optim 包进行随机梯度下降(stochastic gradient descent)优化
    optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate, weight_decay=lambda_l2)
    
  • 开始构建线性模型分类

    for t in range(1000):
        # 把数据输入模型,得到预测结果
        y_pred = model(X)
        # 计算损失和准确率
        loss = criterion(y_pred, Y)
        score, predicted = torch.max(y_pred, 1)
        acc = (Y == predicted).sum().float() / len(Y)
        print('[EPOCH]: %i, [LOSS]: %.6f, [ACCURACY]: %.3f' % (t, loss.item(), acc))
        display.clear_output(wait=True)
    
        # 反向传播前把梯度置 0 
        optimizer.zero_grad()
        # 反向传播优化 
        loss.backward()
        # 更新全部参数
        optimizer.step()
    

    得到第一阶段结果

    • 在此基础上构建二层神经网络分类
nn.ReLU() #在两层中加入ReLu激活函数,其余同一层

从结果可以看到使用ReLu激活函数以后,准确性显著提高

>2.4 一个小问题

image-20201018210026066

可以看到tensor在初始化的时候如果输入数据是否有小数点将决定数据是float还是Int

int_num=torch.tensor(1)
print(int_num.type())
输出:torch.LongTensor
float_num = torch. tensor(1.0)
print(float_num.type())
输出:torch.FloatTensor

四. Google Colab的一些其他探索

​ 本次实验主要运行在Google Colab上面, Colaboratory 是一个 Google 研究项目,旨在帮助传播机器学习培训和研究成果。它是一个 Jupyter 笔记本环境,不需要进行任何设置就可以使用(但是国内需要梯子),并且完全在云端运行。相对于自己本地配置的Jupyter环境大概最大优势在于他免费提供了高性能GPU(似乎还会定期升级配置)
​ 同时如果在本地也安装了Anaconda Jupyter notebook的话还可以和Colab连接并互相访问,这样就可以在本地编写代码,运算的时候则放到云端用高性能GPU进行

本地Jupyter和Colab连接方法:

https://research.google.com/colaboratory/local-runtimes.html

挂载Google云硬盘

from google.colab import drive
drive.mount('/content/drive/')

就可以在colab的主机里直接在'/content/drive/'目录下访问云盘的文件

把Colab作为linux主机使用
Colab本质上是一台搭载了Jupyter环境的linux虚拟机,从测试的结果来看,每一个jupyter文件都对应一个虚拟机,彼此之间并不共用环境.

可以使用"!"+"命令"的方式向主机输入指令

比如:

!apt-get update
!apt-get install vim

image-20201018213209513

不过这样的交互方式效率比较低

于是可以打开shell

!sh

这样就获得了一个稍微友好一点的交互界面,不过无法发送ESC一类的快捷键指令,还是有局限性,不如ssh访问那么方便

image-20201018213759453

也可以安装一些软件比如vim之类的常用软件,配置java环境等,理论上一台虚拟机可以做的事情都可以做.比如也许可以拿来当云服务器跑爬虫脚本或者托管一些其他应用程序.
不过目前测试的结果来看,可以用这台虚拟机访问其他主机,但是外界ping不通这台主机,如果能用ssh来登录主机的话可以拓展更多的用途.
在自己各种尝试ssh colab主机无果的时候找到了一篇博客,作者提出可以用ngrok反向代理的方式来间接访问colab主机
博客:https://blog.csdn.net/u010986080/article/details/93505201
Ngrok:https://ngrok.com/

执行下面的一段代码

(这段代码主要做的事情就是安装并配置openssh服务,然后使用ngrok来把服务中继到ngrok的服务器上,从而其他主机就可以通过访问ngrok间接访问到主机,理论上http,https流量也可以通过这种方式访问因此可以在上面部署一个web应用服务,来做网站的服务器)

import random, string, urllib.request, json, getpass

#Generate root password
password = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(20))

#Download ngrok
! wget -q -c -nc https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip
! unzip -qq -n ngrok-stable-linux-amd64.zip

#Setup sshd
! apt-get install -qq -o=Dpkg::Use-Pty=0 openssh-server pwgen > /dev/null

#Set root password
! echo root:$password | chpasswd
! mkdir -p /var/run/sshd
! echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
! echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
! echo "LD_LIBRARY_PATH=/usr/lib64-nvidia" >> /root/.bashrc
! echo "export LD_LIBRARY_PATH" >> /root/.bashrc

#Run sshd
get_ipython().system_raw('/usr/sbin/sshd -D &')

#Ask token
print("Copy authtoken from https://dashboard.ngrok.com/auth")
authtoken = getpass.getpass()

#Create tunnel
get_ipython().system_raw('./ngrok authtoken $authtoken && ./ngrok tcp 22 &')

#Get public address and print connect command
with urllib.request.urlopen('http://localhost:4040/api/tunnels') as response:
  data = json.loads(response.read().decode())
  (host, port) = data['tunnels'][0]['public_url'][6:].split(':')
  print(f'SSH command: ssh -p{port} root@{host}')

#Print root password
print(f'Root password: {password}')

image-20201018231626295

在Xshell里配置连接

image-20201018234526876

运行一下Google云盘里的程序

image-20201018234422301

也许还可以用类似的方式来在这台主机上配置代理服务,这样就可以解决访问google困难的问题了
准备注册个新域名解析一下试试
成功的话再回来接着写

posted @ 2020-10-18 21:45  软件工程丨代号X  阅读(338)  评论(0)    收藏  举报