机器学习深度学习——预备知识(上)

news2024/11/23 21:20:26

深大的夏令营已经结束,筛选入营的保研er就筛选了1/3,280多的入营总人数里面双非只有30左右。
最终虽然凭借机试拿到offer了,但是我感受到了自己的明显短板,比如夏令营的舍友就都有一篇核心论文,甚至还有SCI一区一作的。
既然,学历和没过六级这件事在9月份之前都没办法弥补,现在也只有狂肝科研了,希望9月份预推免之前能够赶出来一点点成果也好。
首先把机器学习&&深度学习入门一下,里面包含了一些数学、线性代数、概率论的知识,这刚好也是将来9月预推免的面试中容易被问到的,所以就坚持着全复习完。

机器学习&&深度学习——预备知识(上)

  • 1 数据操作
    • 1.1 入门
    • 1.2 运算符
    • 1.3 广播机制
    • 1.4 索引和切片
    • 1.5 节省内存
  • 2 数据预处理
    • 2.1 读取数据集
    • 2.2 处理缺失值
  • 3 线性代数
    • 3.1 标量
    • 3.2 向量
    • 3.3 矩阵
    • 3.4 张量算法的基本性质
    • 3.5 降维
    • 3.6 点积
    • 3.7 矩阵-向量积
    • 3.8 矩阵-矩阵乘法
    • 3.9 范数

1 数据操作

无非就是两件事:
(1)获取数据
(2)处理并存储数据

1.1 入门

张量表示一个由数组组成的数组,可能有多个维度。一维的叫向量,二维的叫矩阵。
下列直接给出代码和注释查看pytorch对张量的操作:

import torch

# 使用arrange创建一个行向量
x = torch.arange(12)
print(x)

# 可以通过张量的shape属性来访问张量(沿每个轴的长度)的形状
print(x.shape)

# 张量中的元素总数
print(x.numel())

# 改变形状而不改变元素的数量和元素值
X = x.reshape(3, 4)
print(X)

# 输出全0、全1矩阵
print(torch.zeros(2, 3, 4))
print(torch.ones(2, 3, 4))

# 创建一个形状为(3,4)的张量,每个元素都是从均值为0,标准差为1的正态分布中随机采样
print(torch.randn(3, 4))

# 还可以直接创建Python列表
print(torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]]))

运行结果:

tensor([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
torch.Size([12])
12
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]])
tensor([[[0., 0., 0., 0.],
         [0., 0., 0., 0.],
         [0., 0., 0., 0.]],

        [[0., 0., 0., 0.],
         [0., 0., 0., 0.],
         [0., 0., 0., 0.]]])
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.]]])
tensor([[ 1.5651, -0.2855, -0.4439,  0.5795],
        [-1.3375, -1.3290, -0.1183, -1.0676],
        [ 0.0334, -2.0030, -1.0172,  0.7654]])
tensor([[2, 1, 4, 3],
        [1, 2, 3, 4],
        [4, 3, 2, 1]])

1.2 运算符

代码:

import torch

# 对于相同形状的张量,常见的标准算术运算符:加减乘除和指数
x = torch.tensor([1.0, 2, 4, 8])
y = torch.tensor([2, 2, 2, 2])
ans = (x + y, x - y, x * y, x / y, x ** y)
print(ans)

# 也可以实现求幂,如e^x
print(torch.exp(x))

# 张量也可以端对端的连接起来,只需要提供张量列表并给出沿哪个轴连结
# 下面给出的两个张量:
X = torch.arange(12, dtype=torch.float32).reshape((3,4))
Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
# 可以发现这是二维的,轴就有两个。轴0表示行,轴1表示列
# 按照轴0来连接,也就是连接行
print(torch.cat((X, Y), dim=0))
# 按照轴1来连接,也就是连接列
print(torch.cat((X, Y), dim=1))

# 通过逻辑运算符构建二元张量:
print(X == Y)

# 若对张量中的所有元素求和,会产生单元素张量
print(X.sum())

运行结果:

(tensor([ 3.,  4.,  6., 10.]), tensor([-1.,  0.,  2.,  6.]), tensor([ 2.,  4.,  8., 16.]), tensor([0.5000, 1.0000, 2.0000, 4.0000]), tensor([ 1.,  4., 16., 64.]))
tensor([2.7183e+00, 7.3891e+00, 5.4598e+01, 2.9810e+03])
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.],
        [ 2.,  1.,  4.,  3.],
        [ 1.,  2.,  3.,  4.],
        [ 4.,  3.,  2.,  1.]])
tensor([[ 0.,  1.,  2.,  3.,  2.,  1.,  4.,  3.],
        [ 4.,  5.,  6.,  7.,  1.,  2.,  3.,  4.],
        [ 8.,  9., 10., 11.,  4.,  3.,  2.,  1.]])
tensor([[False,  True, False,  True],
        [False, False, False, False],
        [False, False, False, False]])
tensor(66.)

1.3 广播机制

如果两个张量的形状不同,可以通过调用广播机制来执行按元素操作:
1、通过适当复制元素来扩展一个或两个数组,以便在转换之后,两个张量具有相同的形状;
2、对生成的数组执行按元素操作。
代码:

import torch
# a为3×1,b为1×2,那么就将a复制列,b复制行
a = torch.arange(3).reshape((3, 1))
b = torch.arange(2).reshape((1, 2))
print(a + b)

运行结果:

tensor([[0, 1],
        [1, 2],
        [2, 3]])

1.4 索引和切片

第一个元素的索引是0,最后一个元素索引是-1。这个没什么好说的

1.5 节省内存

运行一些操作可能会导致为新结果分配内存。 例如,如果我们用Y = X + Y,我们将取消引用Y指向的张量,而是指向新分配的内存处的张量。
用Python的id()函数演示了这一点, 它给我们提供了内存中引用对象的确切地址。 运行Y = Y + X后,我们会发现id(Y)指向另一个位置。 这是因为Python首先计算Y + X,为结果分配新的内存,然后使Y指向内存中的这个新位置。

before = id(Y)
Y = Y + X
print(id(Y) == before)

最终输出False
但是这并不可取,原因有二:
1、我们不想总是不必要地分配内存。通常情况下,我们希望原地执行这些更新;
2、如果我们不原地更新,其他引用仍然会指向旧的内存位置,这样我们的某些代码可能会无意中引用旧的参数。
执行原地操作代码:

# 使用切片表示法将操作的结果分配给先前分配的数组
Z = torch.zeros_like(Y)
print('id(Z):', id(Z))
Z[:] = X + Y
print('id(Z):', id(Z))

结果:

id(Z): 139931132035296
id(Z): 139931132035296

如果在后续计算中没有重复使用X, 我们也可以使用X[:] = X + Y或X += Y来减少操作的内存开销:

before = id(X)
X += Y
print(id(X) == before)

输出True

2 数据预处理

为了用深度学习解决现实问题,常要从预处理原始数据开始,而不是从准备好的张量格式数据开始。

2.1 读取数据集

代码如下:

import os
import pandas as pd

os.makedirs(os.path.join('D:/Pytorch', 'data'), exist_ok=True)
data_file = os.path.join('D:/Pytorch', 'data', 'house_tiny.csv')
with open(data_file, 'w') as f:
    f.write('NumRooms,Alley,Price\n') # 定义列(房间数量、巷子类型、房屋价格)
    f.write('NA,Pave,127500\n')  # 每行表示一个数据样本
    f.write('2,NA,106000\n')
    f.write('4,NA,178100\n')
    f.write('NA,NA,140000\n')

# 从创建的CSV文件中加载数据集,需要导入pandas包并调入read_csv函数。
data = pd.read_csv(data_file)
print(data)

运行结果:

   NumRooms Alley   Price
0       NaN  Pave  127500
1       2.0   NaN  106000
2       4.0   NaN  178100
3       NaN   NaN  140000

2.2 处理缺失值

”NaN“项代表缺失值,可使用插值法解决,用一个替代之弥补缺失值。
通过位置索引iloc,将data分成inputs和outputs,其中前者为data的前两列,后者为最后一列。对于inputs中缺少的数值,用同一列的值替换“NaN”项。
代码:

inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
inputs = inputs.fillna(inputs.mean())
print(inputs)

输出:

   NumRooms Alley
0       3.0  Pave
1       2.0   NaN
2       4.0   NaN
3       3.0   NaN

对于inputs中的类别值或离散值,我们将“NaN”视为一个类别。 由于“巷子类型”(“Alley”)列只接受两种类型的类别值“Pave”和“NaN”, pandas可以自动将此列转换为两列“Alley_Pave”和“Alley_nan”。 巷子类型为“Pave”的行会将“Alley_Pave”的值设置为1,“Alley_nan”的值设置为0。 缺少巷子类型的行会将“Alley_Pave”和“Alley_nan”分别设置为0和1。
代码:

inputs = pd.get_dummies(inputs, dummy_na=True)
print(inputs)

结果:

   NumRooms  Alley_Pave  Alley_nan
0       NaN        True      False
1       2.0       False       True
2       4.0       False       True
3       NaN       False       True

3 线性代数

3.1 标量

import torch

x = torch.tensor(3.0)
y = torch.tensor(2.0)

print(x + y, x * y, x / y, x ** y)

最终输出:

tensor(5.) tensor(6.) tensor(1.5000) tensor(9.)

3.2 向量

可以视为标量值组成的列表,具有一定现实意义。如:一个预测贷款风险的模型,可能会将每个申请人与一个向量相关联,其分量与其收入、工作年限、过往违约次数和其他因素相对应。
生成向量:

x = torch.arrange(4)

可以直接通过索引来访问任一元素:

x[3]

3.3 矩阵

import torch

# 输出矩阵A
A = torch.arange(20).reshape(5, 4)
print(A)

# 矩阵转置:若B为A的转置,则对于任意i,j都有B(i,j)=A(j,i)
# 输出A的转置
print(A.T)

# 如果是方阵,那么其转置与其相同
B = torch.tensor([[1, 2, 3], [2, 0, 4], [3, 4, 5]])
print(B == B.T)

结果:

tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11],
        [12, 13, 14, 15],
        [16, 17, 18, 19]])
tensor([[ 0,  4,  8, 12, 16],
        [ 1,  5,  9, 13, 17],
        [ 2,  6, 10, 14, 18],
        [ 3,  7, 11, 15, 19]])
tensor([[True, True, True],
        [True, True, True],
        [True, True, True]])

3.4 张量算法的基本性质

任何按元素的一元运算都不会改变其操作数的形状。
1、两个矩阵按元素乘法称为Hadamard积;
2、将张量乘以或加上一个标量不会改变张量的形状,其中张量的每个元素都将与标量相加或相乘。

3.5 降维

import torch

A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
# 直接得到矩阵A的和:
print(A.sum())

# 可以通过指定张量沿哪个轴来降维,如果通过求和所有的行元素来降维,则指定轴0
A_sum_axis0 = A.sum(axis=0)
print(A_sum_axis0, A_sum_axis0.shape)

# 汇总所有列的元素降维
A_sum_axis1 = A.sum(axis=1)
print(A_sum_axis1, A_sum_axis1.shape)

# 沿着行和列对矩阵求和,等价于对所有元素求和
print(A.sum(axis=[0, 1]))

# 求平均值,使用A.mean()或A.sum()/A.numer()
print(A.mean())

# 求平均值也可以沿指定轴降低张量维度
print(A.mean(axis=0))

结果

tensor(190.)
tensor([40., 45., 50., 55.]) torch.Size([4])
tensor([ 6., 22., 38., 54., 70.]) torch.Size([5])
tensor(190.)
tensor(9.5000)
tensor([ 8.,  9., 10., 11.])

3.6 点积

对于两个向量x,y,其点积为x的转置乘y,是相同位置的按元素乘积的和。

import torch

x = torch.arange(4, dtype=torch.float32)
y = torch.ones(4, dtype=torch.float32)
print(x, y, torch.dot(x, y))

# 也可以先按元素乘法,然后进行求和来表示两个向量的点积
print(torch.sum(x * y))

结果:

tensor([0., 1., 2., 3.]) tensor([1., 1., 1., 1.]) tensor(6.)
tensor(6.)

3.7 矩阵-向量积

其实就是一种特殊的矩阵乘法,使用函数torch.mv(A,x)即可实现矩阵A和向量x的积

3.8 矩阵-矩阵乘法

使用torch.mm(A,B)即可实现矩阵A和B的相乘。3.7和3.8的矩阵乘法学过线代都知道,不讲解了。

3.9 范数

非正式的说,向量的范数表示一个向量多大。这里的大小不涉及维度,而是分量的大小。
现代中,向量范数是将向量映射到标量的函数f。给定任意向量x,向量范数要满足一些属性:
在这里插入图片描述
深度学习中常用L1、L2范数,都是Lp范数的特例。
在这里插入图片描述
函数:

L1范数:torch.abs(u).sum()
L2范数:torch.norm(u)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/777557.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mac应用程序因“来自身份不明的开发者”无法打开如何解决

相信不少mac电脑用户在安装应用程序时经常会遇到“xxx.app已损坏,打不开。这是mac系统的新的安全机制,安装 App 时提示: 常见的几种报错提示 xxx 已损坏,无法打开。您应该将它移到废纸篓打不开 xxx,因为它来自身份不明…

旋翼式水表安装注意事项

旋翼式水表是一种常用的水流计量设备,适用于小口径管道的单向水流总量的计量。如果你正在考虑安装旋翼式水表,以下是一些需要注意的事项: 1.安装位置的选择:旋翼式水表应该安装在管道的垂直方向上,并且水流方向必须与水…

探秘ArrayList源码:Java动态数组的背后实现

探秘ArrayList源码:Java动态数组的背后实现 一、成员变量二、构造器1、默认构造器2、带初始容量参数构造器3、指定collection元素参数构造器 三、add()方法扩容机制四、场景分析1、对于ensureExplicitCapacity()方法1.1 add 进第 1 个元素到 …

MQTT的理解和使用

MQTT是一种基于发布/订阅模式的轻量协议,该协议基于TCP/IP协议上,由IBM在1999年发布。 流程理解:订阅者在订阅时会选择主题(Topic)和服务质量(QoS),然后发布者发布消息&#xff0c…

matlab超前-滞后校正

1控制系统的校正 系统性能 稳定性、准确性、快速性 动态性能-超前校正 阶跃曲线、频域(bode图)、根轨迹(增加零点-根轨迹左移稳定性提高)、PID控制(PD) 静态性能-滞后校正 阶跃曲线、频域&#xff08…

Flink CDC MongoDB 联合实时数仓的探索实践

摘要:本文整理自 XTransfer 技术专家, Flink CDC Maintainer 孙家宝,在 Flink Forward Asia 2022 数据集成专场的分享。本篇内容主要分为四个部分: MongoDB 在实时数仓的探索 MongoDB CDC Connector 的实现原理和使用实践 FLIP-262 MongoDB…

Spring MVC拦截器和跨域请求

一、拦截器简介 SpringMVC的拦截器(Interceptor)也是AOP思想的一种实现方式。它与Servlet的过滤器(Filter)功能类似,主要用于拦截用户的请求并做相应的处理,通常应用在权限验证、记录请求信息的日志、判断用…

多肽试剂1801415-23-5,Satoreotide,UNII-S58172SSTS,应用在多肽标记及修饰上

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ Satoreotide,UNII-S58172SSTS Product structure Product specifications 1.CAS No:1801415-23-5 2.Molecular formula:C58H72ClN15O14S2 3.Molecular weight:1302.9 4.Packa…

【C++详解】——C++11

目录 C简介 统一的列表初始化 {}的初始化 initializer_list容器 声明 auto decltype nullptr 范围for C简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1),使得C03这个名字已经取代了 C98称为C11之前的最新C标准名称。 不过由于C03(TC1)主…

STM32 串口 DMA 接收任意长度数据

DMA 局限性 DMA 传输完成会产生中断告知 CPU,这对于固定长度的数据是没什么问题的。但是对于不定长的数据就不行了,DMA 一定要接收到足够多(设定的长度)的数据时才产生完成中断,如果接收到的数据量小于设定的长度&…

Linux的基础配置

配置篇 前置步骤:先租一个服务器或装个Linux再或者虚拟机都可以 1.安装gcc,g,gdb 在Linux下我们能用什么工具来编译所编写好的代码呢,其实Linux下这样的工具有很多,但我们只介绍两款常用的工具,它们分别是gcc和g. gcc和g的主要…

解决端口占用

解决办法: 1、换一个其它未被占用的端口 2、端口被占用了,先看下是哪个程序再用,停掉就OK了 下面演示结束端口被占用的程序的过程: 1、查看被占用的端口的进程 netstat -aon|findstr 端口号2、根据PID找到占用此端口的进程 ta…

Redis单机伪集群配置与搭建

目录 1. 复制6个redis配置文件到当前目录下 2. 启动每个节点 3. 判断集群是否可用 4. 初始化集群 5. 查看集群信息 6. 获取与插槽对应的节点 (1)手动重定向 (2)自动重定向 7. 故障恢复 需求:配置一个三主三从的集…

为什么ConcurrentHashMap不允许插入null值而HashMap可以?

为什么ConcurrentHashMap不允许插入null值而HashMap可以? 文章目录 为什么ConcurrentHashMap不允许插入null值而HashMap可以?HashMap源码ConcurrentHashMap源码为什么ConcurrentHashMap需要加空值校验呢?二义性问题测试代码代码分析测试结果结…

纯css3实现水波纹从中心向四周扩散动画

纯css3实现水波纹从中心向四周扩散动画 效果可用于pc端或移动端,引导用户点击,间接带来一定的转化率 示例效果 示例代码 <template><div class"zanbtn-wrap"><div click"handleClick(https://pay.aikelaidev.cn/paypage/?merchant35bdYxSx7dCUr…

子网划分路由网卡

1."IPv4 CIDR" "IPv4 CIDR" 是与互联网协议地址&#xff08;IP address&#xff09;和网络的子网划分有关的概念。 - "IPv4" 代表 "Internet Protocol version 4"&#xff0c;也就是第四版互联网协议&#xff0c;这是互联网上最广泛使…

IPv4 与 IPv6:网络协议的差异和转换方法

在网络的世界里&#xff0c;IPv4 和 IPv6 这两个协议就像是两个不同的王国&#xff0c;各自拥有着独特的领土和规则。虽然它们都是为了互联网的发展而存在&#xff0c;但它们之间究竟有哪些差异&#xff0c;以及如何在这两个王国之间穿梭&#xff0c;仍然是很多网络小白们的困惑…

Spring使用注解存储Bean对象

文章目录 一. 配置扫描路径二. 使用注解储存Bean对象1. 使用五大类注解储存Bean2. 为什么要有五大类注解&#xff1f;3.4有关获取Bean参数的命名规则 三. 使用方法注解储存Bean对象1. 方法注解储存对象的用法2. Bean的重命名 在前一篇博客中&#xff08; Spring项目创建与Bean…

Excel中Vlookup

VLOOKUP($A:$A,Sheet3!$A:$D,COLUMN(Sheet3!B1),FALSE) ps: 1.按F4&#xff0c;锁定第一个和第二个参数 2.第二个参数&#xff0c;要选择全部范围(包括被查找列&#xff0c;以及查找内容) 2.第三个参数用column&#xff08;&#xff09;函数&#xff0c;第三列不要锁定 3.…

【Linux】自动化构建工具-make/Makefile详解

前言 大家好吖&#xff0c;欢迎来到 YY 滴 Linux系列 &#xff0c;热烈欢迎&#xff01;本章主要内容面向接触过Linux的老铁&#xff0c;主要内容含 欢迎订阅 YY 滴Linux专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; 订阅专栏阅读&#xff1a;YY的《…