第一周学习总结

目录

一、人工智能概述

1、什么是人工智能

2、人工智能的三个层面

1.2.1计算智能

1.2.2感知智能

1.2.3认知智能

3、实现人工智能的方式

1.3.1知识工程/专家系统

1.3.2机器学习

4、人工智能应用领域

二、机器学习概述

1、什么是机器学习

2、机器学习的学习过程

2.2.1确定模型:

2.2.2确定策略:

2.2.3、确定求解模型参数的算法:

3、机器学习应用领域

​三、深度学习概述 

 1、传统机器学习与深度学习的对比

2、深度学习三大助推器:

3、深度学习的不能

4、神经网络基础

3.4.1MP神经元

 3.4.2激活函数

 3.4.3单层感知机

3.4.4万有逼近定理

3.4.5深层神经网络的问题:梯度消失

四、pytorch基础练习

1、定义数据

2、定义操作

五、螺旋数据分类 

1、配置环境

 2、构建线性分类模型

3、使用非线性激活函数(relu函数)进行分类


一、人工智能概述

1、什么是人工智能

人工智能(Artificial Intelligence)是使机器像人一样感知、认知、决策、执行的人工程序或系统

2、人工智能的三个层面

1.2.1计算智能

得益于二进制计算和电子器件的不断更新迭代,计算机具有快速计算和记忆存储能力

1.2.2感知智能

人类通过眼睛、耳朵等器官感知外部世界,人们同样希望机器能听会说、能看会认(这就需要借助摄像头、传感器等一些部件来实现)

1.2.3认知智能

仅仅感知到周围的环境是不够的,机器还应该根据感知到的信息作出决策,这就需要机器能理解、思考、决策。

3、实现人工智能的方式

1.3.1知识工程/专家系统

下图是一个将文本进行分类的系统(可以理解为一个垃圾邮件检测系统),在人工智能早期阶段,由专家定义一些规则来实现对文本的分类,这些规则基于专家的经验。这个方法耗费大量人力,且规则是有限的。

1.3.2机器学习

机器学习是如今实现人工智能的主流方法,与专家系统不同的是,它从给定的训练数据集中自动学习出一些规则,并利用这些规则对新的文本进行分类。这些规则有一些或许不可解释。它的优点在于节约了时间和人力成本,同时也使整个系统只依赖与客观的数据,削弱了主观影响,提高了系统可信度。

4、人工智能应用领域

人工智能的兴起是为了方便人们的生活,如今人工智能在人们的日常生活已随处可见。

二、机器学习概述

1、什么是机器学习

最常用定义:计算机系统能够利用经验提高自身的性能

可操作定义:机器学习本质是一个基于经验数据的函数估计问题

统计学定义:提取重要模式、趋势,并理解数据,即从数据中学习

综合以上三种定义,机器学习是基于数据(称之为训练数据集),学习一个函数,对于给定的输入,这个函数可以输出人们想要的正确的结果。

2、机器学习的学习过程

2.2.1确定模型:

对要学习映射的假设(如它是一个线性问题,那么我们可以用线性模型解决)

模型按照数据标记情况可分为监督学习、无监督学习、半监督学习和强化学习

监督学习:数据标记已知(已知正确的输出),可以很方便地学习输入-输出映射函数,并对未知输入进行预测

无监督学习:数据标记未知,目的在于发现数据中的模式

半监督学习:部分数据标记已知,部分未知。(由于带有标记的样本较难获得)假设未标记样本与标记样本独立同分布,则可以得到有关数据分布的重要信息

强化学习:数据无标记。在学习的过程中得知是在靠近目标还是在远离目标

模型按照数据分布可分为参数模型和非参数模型

参数模型:数据的分布可以假设,模型可以用一组有限且数目固定的参数刻画(如线性回归、逻辑回归、感知机)

非参数模型:数据无规律,无法假设其分布。这是求解模型的时空复杂度较非参数模型会大很多,它自适应数据,模型参数随样本变化而变化。(如K近邻、SVM、决策树)

模型根据判别对象可分为班别模型和生成模型

生成模型:对输入X和输出Y的联合分布P(X,Y)建模,利用贝叶斯公式求P(Y|X)

判别模型:直接学习P(Y|X),对于输入特征X,直接预测出最可能的Y。

2.2.2确定策略:

对于确定好的模型,选择一种度量准则,即确定目标函数(如我们用最小欧氏距离作为目标函数)

2.2.3、确定求解模型参数的算法:

根据目标函数和模型,确定一种算法来求解模型参数(如用梯度下降法求解线性模型的参数)

3、机器学习应用领域

机器学习广泛应用于计算机视觉、语音技术、自然语言处理等领域。

三、深度学习概述 

 1、传统机器学习与深度学习的对比

2、深度学习三大助推器:

1、大数据

2、算法

3、计算力

3、深度学习的不能

1、算法输出不稳定,容易被“攻击”。

2、模型复杂度高,难以纠错和调试

3、模型层级复合程度高,参数不透明。

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

5、专注直观感知类问题,对开放性推理问题无能为力。

6、人类知识无法有效引入进行监督,机器偏见难以避免

4、神经网络基础

3.4.1MP神经元

 3.4.2激活函数

激活函数的引入使得神经网络不再仅仅只能拟合线性函数,增加了网络的复杂性。下面给出几种激活函数的示例:

 3.4.3单层感知机

单层感知机是首个可以学习的人工神经网络,分别使用线性激活函数和非线性激活函数的示意图如下:

3.4.4万有逼近定理

1、如果一个隐层包含足够多的神经元,三层前馈神经网络(输入-隐层-输出)能以任意精度逼近任意预定的连续函数。增加节点数可以增加维度,提高线性转换能力。

2、当隐层足够宽时,双隐层感知器(输入-隐层1-隐层2-输出)可以逼近任意非连续函数:可以解决任何复杂的分类问题。增加层数可以增加激活函数的映射次数,可以增加非线性映射的能力。但这不意味着层数越多越好,解释如下。

3.4.5深层神经网络的问题:梯度消失

 增加深度会造成梯度消失,误差无法传播,多层网络容易陷入局部极值,难以训练。因此现在的主流网络结构为三层。

四、pytorch基础练习

pytorch是一个机器学习框架,提供了大量简单易用的接口。它的显著特点是提供了GPU加速的张量计算以及构建在反向自动求导系统上的深度神经网络。

1、定义数据

一般定义数据使用torch.Tensor , tensor的意思是张量,是数字各种形式的总称。

Tensor支持各种各样类型的数据,包括:

torch.float32, torch.float64, torch.float16, torch.uint8, torch.int8, torch.int16, torch.int32, torch.int64 。这里不过多描述。

创建Tensor有多种方法,包括:ones, zeros, eye, arange, linspace, rand, randn, normal, uniform, randperm, 

import torch

# 可以是一个数
x = torch.tensor(666)
print(x)
tensor(666)
# 可以是一维数组(向量)
x = torch.tensor([1,2,3,4,5,6])
print(x)
# 可以是二维数组(矩阵)
x = torch.ones(2,3)
print(x)
# 可以是任意维度的数组(张量)
x = torch.ones(2,3,4)
print(x)


tensor([1, 2, 3, 4, 5, 6])
tensor([[1., 1., 1.],
        [1., 1., 1.]])
tensor([[[1., 1., 1., 1.],
         [1., 1., 1., 1.],
         [1., 1., 1., 1.]],

        [[1., 1., 1., 1.],
         [1., 1., 1., 1.],
         [1., 1., 1., 1.]]])
# 创建一个空张量
x = torch.empty(5,3)
print(x)
tensor([[1.4178e-36, 0.0000e+00, 4.4842e-44],
        [0.0000e+00,        nan, 0.0000e+00],
        [1.0979e-05, 4.2008e-05, 2.1296e+23],
        [1.0386e+21, 4.4160e-05, 1.0742e-05],
        [2.6963e+23, 4.2421e-08, 3.4548e-09]])
# 创建一个随机初始化的张量
x = torch.rand(5,3)
print(x)
tensor([[0.3077, 0.0347, 0.3033],
        [0.9099, 0.2716, 0.4310],
        [0.8286, 0.3317, 0.0536],
        [0.9529, 0.4905, 0.1403],
        [0.6899, 0.8349, 0.4015]])
# 创建一个全0的张量,里面的数据类型为 long
x = torch.zeros(5,3,dtype=torch.long)
print(x)
tensor([[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]])
# 基于现有的tensor,创建一个新tensor,
# 从而可以利用原有的tensor的dtype,device,size之类的属性信息
y = x.new_ones(5,3)   #tensor new_* 方法,利用原来tensor的dtype,device
print(y)
tensor([[1, 1, 1],
        [1, 1, 1],
        [1, 1, 1],
        [1, 1, 1],
        [1, 1, 1]])
z = torch.randn_like(x, dtype=torch.float)    # 利用原来的tensor的大小,但是重新定义了dtype
print(z)
tensor([[ 1.4363, -2.1019,  0.4444],
        [-0.4706,  0.7441, -0.4631],
        [-1.3860, -1.8919,  1.8794],
        [ 1.8617,  0.6469,  0.5235],
        [-0.1271, -1.0755,  0.0359]])

2、定义操作

凡是用Tensor进行各种运算的,都是Function

最终,还是需要用Tensor来进行计算的,计算无非是

  • 基本运算,加减乘除,求幂求余
  • 布尔运算,大于小于,最大最小
  • 线性运算,矩阵乘法,求模,求行列式

基本运算包括: abs/sqrt/div/exp/fmod/pow ,及一些三角函数 cos/ sin/ asin/ atan2/ cosh,及 ceil/round/floor/trunc 等具体在使用的时候可以百度一下

布尔运算包括: gt/lt/ge/le/eq/ne,topk, sort, max/min

线性计算包括: trace, diag, mm/bmm,t,dot/cross,inverse,svd 等

# 创建一个 2x4 的tensor
m = torch.Tensor([[2, 5, 3, 7],
                  [4, 2, 1, 9]])

print(m.size(0), m.size(1), m.size(), sep=' -- ')
2 -- 4 -- torch.Size([2, 4])
# 返回 m 中元素的数量
print(m.numel())
8
# 返回 第0行,第2列的数
print(m[0][2])
tensor(3.)
# 返回 第1列的全部元素
print(m[:, 1])
tensor([5., 2.])
# 返回 第0行的全部元素
print(m[0, :])
tensor([2., 5., 3., 7.])
# Create tensor of numbers from 1 to 5
# 注意这里结果是1到4,没有5
v = torch.arange(1, 5)
print(v)
tensor([1, 2, 3, 4])
# Scalar product
m @ v
tensor([49., 47.])
# Calculated by 1*2 + 2*5 + 3*3 + 4*7
m[[0], :] @ v
tensor([49.])
# Add a random tensor of size 2x4 to m
m + torch.rand(2, 4)
tensor([[2.2495, 5.7699, 3.3819, 7.0271],
        [4.4853, 2.1948, 1.8039, 9.2615]])
# 转置,由 2x4 变为 4x2
print(m.t())

# 使用 transpose 也可以达到相同的效果,具体使用方法可以百度
print(m.transpose(0, 1))
tensor([[2., 4.],
        [5., 2.],
        [3., 1.],
        [7., 9.]])
tensor([[2., 4.],
        [5., 2.],
        [3., 1.],
        [7., 9.]])
# returns a 1D tensor of steps equally spaced points between start=3, end=8 and steps=20
torch.linspace(3, 8, 20)
tensor([3.0000, 3.2632, 3.5263, 3.7895, 4.0526, 4.3158, 4.5789, 4.8421, 5.1053,
        5.3684, 5.6316, 5.8947, 6.1579, 6.4211, 6.6842, 6.9474, 7.2105, 7.4737,
        7.7368, 8.0000])
from matplotlib import pyplot as plt

# matlabplotlib 只能显示numpy类型的数据,下面展示了转换数据类型,然后显示
# 注意 randn 是生成均值为 0, 方差为 1 的随机数
# 下面是生成 1000 个随机数,并按照 100 个 bin 统计直方图
plt.hist(torch.randn(1000).numpy(), 100);
# 当数据非常非常多的时候,正态分布会体现的非常明显
plt.hist(torch.randn(10**6).numpy(), 100);

 

五、螺旋数据分类 

1、配置环境

!wget https://raw.githubusercontent.com/Atcold/pytorch-Deep-Learning/master/res/plot_lib.py

import random
import torch
from torch import nn, optim
import math
from IPython import display
from plot_lib import plot_data, plot_model, set_default

# 因为colab是支持GPU的,torch 将在 GPU 上运行
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print('device: ', device)

# 初始化随机数种子。神经网络的参数都是随机初始化的,
# 不同的初始化参数往往会导致不同的结果,当得到比较好的结果时我们通常希望这个结果是可以复现的,
# 因此,在pytorch中,通过设置随机数种子也可以达到这个目的
seed = 12345
random.seed(seed)
torch.manual_seed(seed)

N = 1000  # 每类样本的数量
D = 2  # 每个样本的特征维度
C = 3  # 样本的类别
H = 100  # 神经网络里隐层单元的数量

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

print("Shapes:")
print("X:", X.size())
print("Y:", Y.size())

# visualise the data
plot_data(X, Y)


输出结果:

device:  cuda:0
Shapes:
X: torch.Size([3000, 2])
y: torch.Size([3000])

 

 2、构建线性分类模型

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上

# 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()

输出:

[EPOCH]: 999, [LOSS]: 0.864019, [ACCURACY]: 0.500

 print(y_pred.shape) 可以看到模型的预测结果,为[3000, 3]的矩阵。每个样本的预测结果为3个,保存在 y_pred的一行里。值最大的一个,即为预测该样本属于的类别。

print(y_pred.shape)
print(y_pred[10, :])
print(score[10])
print(predicted[10])
结果:
torch.Size([3000, 3])
tensor([0.1070, 0.1738, 0.1800], device='cuda:0', grad_fn=<SliceBackward>)
tensor(0.1800, device='cuda:0', grad_fn=<SelectBackward>)
tensor(2, device='cuda:0')
# Plot trained model
print(model)
plot_model(X, Y, model)
结果:
Sequential(
  (0): Linear(in_features=2, out_features=100, bias=True)
  (1): Linear(in_features=100, out_features=3, bias=True)
)

从print(model) 输出结果中可以看到有两层:第一层输入为 2(因为特征维度为主2),输出为 100。第二层输入为 100 (上一层的输出),输出为 3(类别数)

从上面图示可以看出,线性模型的准确率最高只能达到 50% 左右,对于这样复杂的一个数据分布,线性模型难以实现准确分类。

3、使用非线性激活函数(relu函数)进行分类

learning_rate = 1e-3
lambda_l2 = 1e-5

# 这里可以看到,和上面模型不同的是,在两层之间加入了一个 ReLU 激活函数
model = nn.Sequential(
    nn.Linear(D, H),
    nn.ReLU(),
    nn.Linear(H, C)
)
model.to(device)


criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate, weight_decay=lambda_l2) # built-in 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)
    
    # zero the gradients before running the backward pass.
    optimizer.zero_grad()
    # Backward pass to compute the gradient
    loss.backward()
    # Update params
    optimizer.step()
# Plot trained model
print(model)
plot_model(X, Y, model)
结果:
Sequential(
  (0): Linear(in_features=2, out_features=100, bias=True)
  (1): ReLU()
  (2): Linear(in_features=100, out_features=3, bias=True)
)

 使用relu函数作为激活函数时,准确率大幅提高至92%,原因在于这一激活函数使得网络可以实现非线性映射。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值