Allen

写代码是热爱,写到世界充满爱

  • HomePage
  • Categories
  • Archives
  • Essay
  • Tags
总文章数 379
所有文章 友链 关于我

Allen

写代码是热爱,写到世界充满爱

  • HomePage
  • Categories
  • Archives
  • Essay
  • Tags

1-Pytorch的数据载体张量与线性回归

阅读数:23次 2022-09-28
字数统计: 5.6k字   |   阅读时长: 24分

文章导航

× 文章目录
  1. 1. 1. 张量的简介与创建
    1. 1.1. 1.1 张量的简介
    2. 1.2. 1.2 张量的创建
      1. 1.2.1. 1.2.1 直接创建张量
      2. 1.2.2. 1.2.2 通过numpy数组来创建
      3. 1.2.3. 1.2.3 依据数值创建
      4. 1.2.4. 1.2.4 依概率分布创建张量
  2. 2. 2. 张量的操作
    1. 2.1. 2.1 张量的基本操作
      1. 2.1.1. 2.1.1 张量的拼接
      2. 2.1.2. 2.1.2 张量的切分
      3. 2.1.3. 2.1.3 张量的索引
      4. 2.1.4. 2.1.4 张量的变换
    2. 2.2. 2.2 张量的数学运算
      1. 2.2.1. 2.2.1 标量运算
      2. 2.2.2. 2.2.2 向量运算
      3. 2.2.3. 2.2.3 矩阵运算
  3. 3. 3. 搭建一个线性回归模型
  4. 4. 4. 总结

Pytorch官方英文文档:https://pytorch.org/docs/stable/torch.html?
Pytorch中文文档:https://pytorch-cn.readthedocs.io/zh/latest/

1. 张量的简介与创建

这部分内容介绍pytorch中的数据结构——Tensor,Tensor是PyTorch中最基础的概念,其参与了整个运算过程,主要介绍张量的概念和属性,如data, device, dtype等,并介绍tensor的基本创建方法,如直接创建、依数值创建和依概率分布创建等。

1.1 张量的简介

1.张量的基本概念

张量其实是一个多维数组,它是标量、向量、矩阵的高维拓展

2.Tensor与Variable

在Pytorch0.4.0版本之后其实Variable已经并入Tensor, 但是Variable这个数据类型的了解,对于理解张量来说很有帮助, 这到底是个什么呢?

Variable是torch.autograd中的数据类型。

Variable有下面的5个属性:

  1. data: 被包装的Tensor
  2. grad: data的梯度
  3. grad_fn: fn表示function的意思,记录创建张量时用到的方法,比如说加法,乘法,这个操作在求导过程需要用到,Tensor的Function, 是自动求导的关键
  4. requires_grad: 指示是否需要梯度, 有的不需要梯度
  5. is_leaf: 指示是否是叶子节点(张量)

这些属性都是为了张量的自动求导而设置的, 从Pytorch0.4.0版开始,Variable并入了Tensor, 看看张量里面的属性:

可以发现,如今版本里面的Tensor共有8个属性,上面四个与数据本身相关,下面四个与梯度求导相关。 其中有五个是Variable并入过来的, 这些含义就不解释了, 而还有三个属性没有说:

  1. dtype: 张量的数据类型, 如torch.FloatTensor, torch.cuda.FloatTensor, 用的最多的一般是float32和int64(torch.long)
  2. shape: 张量的形状, 如(64, 3, 224, 224)
  3. device: 张量所在的设备, GPU/CPU, 张量放在GPU上才能使用加速。

知道了什么是张量,那么如何创建张量呢?

1.2 张量的创建

1.2.1 直接创建张量

torch.Tensor(): 功能: 从data创建Tensor

这里的data,就是我们的数据,可以是list,也可以是numpy。 dtype这个是指明数据类型, 默认与data的一致。 device是指明所在的设备, requires_grad是是否需要梯度, 在搭建神经网络的时候需要求导的那些参数这里要设置为true。 pin_memory是否存于锁页内存,这个设置为False就可以。下面就具体代码演示:

1
2
3
4
5
6
7
8
9
10
11
arr = np.ones((3, 3))
print('ndarry的数据类型:', arr.dtype)

t = torch.tensor(arr, device='cuda')
print(t)

## 结果如下:
ndarry的数据类型: float64
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], device='cuda:0', dtype=torch.float64)

1.2.2 通过numpy数组来创建

torch.from_numpy(ndarry): 从numpy创建tensor

注意:这个创建的Tensor与原ndarray共享内存, 当修改其中一个数据的时候,另一个也会被改动。

下面具体看代码演示(共享内存):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
arr = np.array([[1, 2, 3], [4, 5, 6]])
t = torch.from_numpy(arr)

print(arr, '\n',t)
arr[0, 0] = 0
print('*' * 10)
print(arr, '\n',t)
t[1, 1] = 100
print('*' * 10)
print(arr, '\n',t)

## 结果:
[[1 2 3]
[4 5 6]]
tensor([[1, 2, 3],
[4, 5, 6]], dtype=torch.int32)
**********
[[0 2 3]
[4 5 6]]
tensor([[0, 2, 3],
[4, 5, 6]], dtype=torch.int32)
**********
[[ 0 2 3]
[ 4 100 6]]
tensor([[ 0, 2, 3],
[ 4, 100, 6]], dtype=torch.int32)

1.2.3 依据数值创建

torch.zeros(): 依size创建全0的张量

这些参数都比较好理解,layout这个是内存中的布局形式, 一般采用默认就可以。 这个out,表示输出张量,就是再把这个张量赋值给别的一个张量,但是这两个张量是一样的,指的同一个内存地址。看代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
out_t = torch.tensor([1])
t = torch.zeros((3, 3), out=out_t)

print(out_t, '\n', t)
print(id(t), id(out_t), id(t) == id(out_t)) # 这个看内存地址

## 结果:
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
2575719258696 2575719258696 True

torch.zeros_like(input, dtype=None, layout=None, device=None, requires_grad=False) : 这个是创建与input同形状的全0张量

1
2
3
4
5
6
t = torch.zeros_like(out_t)   # 这里的input要是个张量
print(t)

tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])

除了全0张量, 还可以创建全1张量, 用法和上面一样,torch.ones(), torch.ones_like(), 还可以自定义数值张量:torch.full(), torch.full_like()

这里的fill_value就是要填充的值。

1
2
3
4
t = torch.full((3,3), 10)
tensor([[10., 10., 10.],
[10., 10., 10.],
[10., 10., 10.]])

torch.arange(): 创建等差的1维张量,数值区间 [start, end), 注意这是右边开,取不到最后的那个数。

这个和numpy的差不多,这里的step表示的步长。

1
t = torch.arange(2, 10, 2)  # tensor([2, 4, 6, 8])

torch.linspace(): 创建均分的1维张量, 数值区间[start, end] 注意这里都是闭区间,和上面的区分。

这里是右闭, 能取到最后的值,并且这里的steps是数列的长度而不是步长。

1
2
3
4
5
6
t = torch.linspace(2, 10, 5)   # tensor([2, 4, 6, 8, 10])

# 那么如果不是那么正好呢? 步长应该是多少?
t = torch.linspace(2, 10, 6) # tensor([2, 3.6, 5.2, 6.8, 8.4, 10])

# 这个步长是怎么算的? (end-start) / (steps-1)

除了创建均分数列,还可以创建对数均分数列:

这里的base表示以什么为底。

最后一个方法就是torch.eye(): 创建单位对角矩阵, 默认是方阵

n, m分别是矩阵的行数和列数。

1.2.4 依概率分布创建张量

torch.normal():生成正态分布(高斯分布), 这个使用的比较多

mean是均值,std是标准差。 但是这个地方要注意, 根据mean和std,分别各有两种取值,所以这里会有四种模式:

  • mean为标量, std为标量
  • mean为标量, std为张量
  • mean为张量, std为标量
  • mean为张量,std为张量

这个看代码来的直接:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 第一种模式 - 均值是标量, 方差是标量 - 此时产生的是一个分布, 从这一个分部种抽样相应的个数,所以这个必须指定size,也就是抽取多少个数
t_normal = torch.normal(0, 1, size=(4,))
print(t_normal) # 来自同一个分布

# 第二种模式 - 均值是标量, 方差是张量 - 此时会根据方差的形状大小,产生同样多个分布,每一个分布的均值都是那个标量
std = torch.arange(1, 5, dtype=torch.float)
print(std.dtype)
t_normal2 = torch.normal(1, std)
print(t_normal2) # 也产生来四个数,但是这四个数分别来自四个不同的正态分布,这些分布均值相等

# 第三种模式 - 均值是张量,方差是标量 - 此时也会根据均值的形状大小,产生同样多个方差相同的分布,从这几个分布中分别取一个值作为结果
mean = torch.arange(1, 5, dtype=torch.float)
t_normal3 = torch.normal(mean, 1)
print(t_normal3) # 来自不同的分布,但分布里面方差相等

# 第四种模式 - 均值是张量, 方差是张量 - 此时需要均值的个数和方差的个数一样多,分别产生这么多个正太分布,从这里面抽取一个值
mean = torch.arange(1, 5, dtype=torch.float)
std = torch.arange(1, 5, dtype=torch.float)
t_normal4 = torch.normal(mean, std)
print(t_normal4) # 来自不同的分布,各自有自己的均值和方差

下面一个是标准正态分布:torch.randn(), torch.randn_like()

生成均匀分布:torch.rand(), rand_like() 在[0,1)生成均匀分布
torch.randint(), torch.randint_like(): 区间[low,hight)生成整数均匀分布

下面看最后两个:

torch.randperm(n): 生成从0 - n-1的随机排列, n是张量的长度, 经常用来生成一个乱序索引。

torch.bernoulli(input): 以input为概率,生成伯努利分布(0-1分布,两点分布), input: 概率值

2. 张量的操作

这次整理张量的基本操作,比如张量的拼接,切分,索引和变换以及数学运算等,并基于所学习的知识,实现线性回归模型。

2.1 张量的基本操作

2.1.1 张量的拼接

  • torch.cat(tensors, dim=0, out=None): 将张量按维度dim进行拼接, tensors表示张量序列, dim要拼接的维度

  • torch.stack(tensors, dim=0, out=None): 在新创建的维度dim上进行拼接, tensors表示张量序列, dim要拼接的维度

这是啥意思, stack会新创建一个维度,然后完成拼接。还是看代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 张量的拼接
t = torch.ones((2, 3))
print(t)

t_0 = torch.cat([t, t], dim=0) # 行拼接
t_1 = torch.cat([t, t], dim=1) # 列拼接
print(t_0, t_0.shape)
print(t_1, t_1.shape)

# 结果:
tensor([[1., 1., 1.],
[1., 1., 1.]])
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]]) torch.Size([4, 3])
tensor([[1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1.]]) torch.Size([2, 6])

.cat是在原来的基础上根据行和列,进行拼接, 我发现一个问题,就是浮点数类型拼接才可以,long类型拼接会报错。 下面我们看看.stack方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
t_stack = torch.stack([t,t,t], dim=0)
print(t_stack)
print(t_stack.shape)

t_stack1 = torch.stack([t, t, t], dim=1)
print(t_stack1)
print(t_stack1.shape)

## 结果:
tensor([[[1., 1., 1.],
[1., 1., 1.]],

[[1., 1., 1.],
[1., 1., 1.]],

[[1., 1., 1.],
[1., 1., 1.]]])
torch.Size([3, 2, 3])
tensor([[[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]],

[[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]]])
torch.Size([2, 3, 3])

.stack是根据给定的维度新增了一个新的维度,在这个新维度上进行拼接,这个.stack与其说是从新维度上拼接,不太好理解,其实是新加了一个维度Z轴,只不过dim=0和dim=1的视角不同罢了。 dim=0的时候,是横向看,dim=1是纵向看。

所以这两个使用的时候要小心,看好了究竟是在原来的维度上拼接到一块,还是从新维度上拼接到一块。

2.1.2 张量的切分

torch.chunk(input, chunks, dim=0): 将张量按维度dim进行平均切分, 返回值是张量列表,注意,如果不能整除, 最后一份张量小于其他张量。 chunks代表要切分的维度。 下面看一下代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
a = torch.ones((2, 7))  # 7
list_of_tensors = torch.chunk(a, dim=1, chunks=3) # 第一个维度切成三块, 那么应该是(2,3), (2,3), (2,1) 因为7不能整除3,所以每一份应该向上取整,最后不够的有多少算多少
print(list_of_tensors)
for idx, t in enumerate(list_of_tensors):
print("第{}个张量:{}, shape is {}".format(idx+1, t, t.shape))

## 结果:
(tensor([[1., 1., 1.],
[1., 1., 1.]]), tensor([[1., 1., 1.],
[1., 1., 1.]]), tensor([[1.],
[1.]]))
第1个张量:tensor([[1., 1., 1.],
[1., 1., 1.]]), shape is torch.Size([2, 3])
第2个张量:tensor([[1., 1., 1.],
[1., 1., 1.]]), shape is torch.Size([2, 3])
第3个张量:tensor([[1.],
[1.]]), shape is torch.Size([2, 1])

torch.split(tensor, split_size_or_sections, dim=0): 这个也是将张量按维度dim切分,但是这个更加强大, 可以指定切分的长度, split_size_or_sections为int时表示每一份的长度, 为list时,按list元素切分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# split
t = torch.ones((2, 5))

list_of_tensors = torch.split(t, [2, 1, 2], dim=1) # [2 , 1, 2], 这个要保证这个list的大小正好是那个维度的总大小,这样才能切
for idx, t in enumerate(list_of_tensors):
print("第{}个张量:{}, shape is {}".format(idx+1, t, t.shape))

## 结果
第1个张量:tensor([[1., 1.],
[1., 1.]]), shape is torch.Size([2, 2])
第2个张量:tensor([[1.],
[1.]]), shape is torch.Size([2, 1])
第3个张量:tensor([[1., 1.],
[1., 1.]]), shape is torch.Size([2, 2])

所以切分,也有两个函数,.chunk和.split。

.chunk切分的规则就是提供张量,切分的维度和几份, 比如三份, 先计算每一份的大小,也就是这个维度的长度除以三,然后上取整,就开始沿着这个维度切,最后不够一份大小的,也就那样了。 所以长度为7的这个维度,3块,每块7/3上取整是3, 然后第一块3,第二块是3,第三块1。这样切

.split这个函数的功能更加强大,它可以指定每一份的长度,只要传入一个列表即可,或者也有一个整数,表示每一份的长度,这个就根据每一份的长度先切着, 看看能切几块算几块。 不过列表的那个好使,可以自己指定每一块的长度,但是注意一下,这个长度的总和必须是维度的那个总长度才用办法切。

2.1.3 张量的索引

torch.index_select(input, dim, index, out=None): 在维度dim上,按index索引数据,返回值,以index索引数据拼接的张量。

1
2
3
4
5
6
7
8
9
10
11
12
13
t = torch.randint(0, 9, size=(3, 3))     #  从0-8随机产生数组成3*3的矩阵
print(t)
idx = torch.tensor([0, 2], dtype=torch.long) # 这里的类型注意一下,要是long类型
t_select = torch.index_select(t, dim=1, index=idx) #第0列和第2列拼接返回
print(t_select)

## 结果:
tensor([[3, 7, 3],
[4, 3, 7],
[5, 8, 0]])
tensor([[3, 3],
[4, 7],
[5, 0]])

torch.masked_select(input, mask, out=None): 按mask中的True进行索引,返回值:一维张量。 input表示要索引的张量, mask表示与input同形状的布尔类型的张量。 这种情况在选择符合某些特定条件的元素的时候非常好使, 注意这个是返回一维的张量。下面看代码:

1
2
3
4
5
6
7
8
9
10
11
mask = t.ge(5)   # le表示<=5, ge表示>=5 gt >5  lt <5
print("mask: \n", mask)
t_select1 = torch.masked_select(t, mask) # 选出t中大于5的元素
print(t_select1)

## 结果:
mask:
tensor([[False, True, False],
[False, False, True],
[ True, True, False]])
tensor([7, 7, 5, 8])

所以张量的索引,有两种方式:.index_select和.masked_select

  • .index_select: 按照索引查找 需要先指定一个Tensor的索引量,然后指定类型是long的
  • .masked_select: 就是按照值的条件进行查找,需要先指定条件作为mask

2.1.4 张量的变换

torch.reshape(input, shape): 变换张量的形状,这个很常用,input表示要变换的张量,shape表示新张量的形状。 但注意,当张量在内存中是连续时, 新张量与input共享数据内存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# torch.reshape
t = torch.randperm(8) # randperm是随机排列的一个函数
print(t)

t_reshape = torch.reshape(t, (-1, 2, 2)) # -1的话就是根据后面那两个参数,计算出-1这个值,然后再转
print("t:{}\nt_reshape:\n{}".format(t, t_reshape))

t[0] = 1024
print("t:{}\nt_reshape:\n{}".format(t, t_reshape))
print("t.data 内存地址:{}".format(id(t.data)))
print("t_reshape.data 内存地址:{}".format(id(t_reshape.data))) # 这个注意一下,两个是共内存的

## 结果:
tensor([2, 4, 3, 1, 5, 6, 7, 0])
t:tensor([2, 4, 3, 1, 5, 6, 7, 0])
t_reshape:
tensor([[[2, 4],
[3, 1]],

[[5, 6],
[7, 0]]])
t:tensor([1024, 4, 3, 1, 5, 6, 7, 0])
t_reshape:
tensor([[[1024, 4],
[ 3, 1]],

[[ 5, 6],
[ 7, 0]]])
t.data 内存地址:1556953167336
t_reshape.data 内存地址:1556953167336

上面这两个是共内存的, 一个改变另一个也会改变。这个要注意一下。

torch.transpose(input, dim0, dim1): 交换张量的两个维度, 矩阵的转置常用, 在图像的预处理中常用, dim0要交换的维度, dim1表示要交换的问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# torch.transpose
t = torch.rand((2, 3, 4)) # 产生0-1之间的随机数
print(t)
t_transpose = torch.transpose(t, dim0=0, dim1=2) # c*h*w w*h*c, 这表示第0维和第2维进行交换
print("t shape:{}\nt_transpose shape: {}".format(t.shape, t_transpose.shape))

## 结果:
tensor([[[0.7480, 0.5601, 0.1674, 0.3333],
[0.4648, 0.6332, 0.7692, 0.2147],
[0.7815, 0.8644, 0.6052, 0.3650]],

[[0.2536, 0.1642, 0.2833, 0.3858],
[0.8337, 0.6173, 0.3923, 0.1878],
[0.8375, 0.2109, 0.4282, 0.4974]]])
t shape:torch.Size([2, 3, 4])
t_transpose shape: torch.Size([4, 3, 2])
tensor([[[0.7480, 0.2536],
[0.4648, 0.8337],
[0.7815, 0.8375]],

[[0.5601, 0.1642],
[0.6332, 0.6173],
[0.8644, 0.2109]],

[[0.1674, 0.2833],
[0.7692, 0.3923],
[0.6052, 0.4282]],

[[0.3333, 0.3858],
[0.2147, 0.1878],
[0.3650, 0.4974]]])

torch.t(input): 2维张量的转置, 对矩阵而言,相当于torch.transpose(inpuot, 0,1)

torch.squeeze(input, dim=None, out=None): 压缩长度为1的维度, dim若为None,移除所有长度为1的轴,若指定维度,当且仅当该轴长度为1时可以被移除

1
2
3
4
5
6
7
8
9
# torch.squeeze
t = torch.rand((1, 2, 3, 1))
t_sq = torch.squeeze(t)
t_0 = torch.squeeze(t, dim=0)
t_1 = torch.squeeze(t, dim=1)
print(t.shape) # torch.Size([1, 2, 3, 1])
print(t_sq.shape) # torch.Size([2, 3])
print(t_0.shape) # torch.Size([2, 3, 1])
print(t_1.shape) # torch.Size([1, 2, 3, 1])

torch.unsqueeze(input, dim, out=None): 依据dim扩展维度

2.2 张量的数学运算

2.2.1 标量运算

Pytorch中提供了丰富的数学运算,可以分为三大类: 加减乘除, 对数指数幂函数,三角函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
t_0 = torch.randn((3, 3))
t_1 = torch.ones_like(t_0)
t_add = torch.add(t_0, 10, t_1)

print("t_0:\n{}\nt_1:\n{}\nt_add_10:\n{}".format(t_0, t_1, t_add))

## 结果:
t_0:
tensor([[-0.4133, 1.4492, -0.1619],
[-0.4508, 1.2543, 0.2360],
[ 1.0054, 1.2767, 0.9953]])
t_1:
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
t_add_10:
tensor([[ 9.5867, 11.4492, 9.8381],
[ 9.5492, 11.2543, 10.2360],
[11.0054, 11.2767, 10.9953]])

2.2.2 向量运算

向量运算符只在一个特定轴上运算,将一个向量映射到一个标量或者另外一个向量。

1
2
3
4
5
6
7
8
9
10
11
#统计值

a = torch.arange(1,10).float()
print(torch.sum(a))
print(torch.mean(a))
print(torch.max(a))
print(torch.min(a))
print(torch.prod(a)) #累乘
print(torch.std(a)) #标准差
print(torch.var(a)) #方差
print(torch.median(a)) #中位数

cum扫描

1
2
3
4
5
6
7
8
#cum扫描
a = torch.arange(1,10)

print(torch.cumsum(a,0)) # 累加
print(torch.cumprod(a,0)) # 累乘
print(torch.cummax(a,0).values)
print(torch.cummax(a,0).indices)
print(torch.cummin(a,0))

张量排序

1
2
3
4
5
6
7
#torch.sort和torch.topk可以对张量排序
a = torch.tensor([[9,7,8],[1,3,2],[5,6,4]]).float()
print(torch.topk(a,2,dim = 0),"\n")
print(torch.topk(a,2,dim = 1),"\n")
print(torch.sort(a,dim = 1),"\n")

#利用torch.topk可以在Pytorch中实现KNN算法

2.2.3 矩阵运算

矩阵必须是二维的。类似torch.tensor([1,2,3])这样的不是矩阵。

矩阵运算包括:矩阵乘法,矩阵转置,矩阵逆,矩阵求迹,矩阵范数,矩阵行列式,矩阵求特征值,矩阵分解等运算。

1.矩阵乘法

1
2
3
4
#矩阵乘法
a = torch.tensor([[1,2],[3,4]])
b = torch.tensor([[2,0],[0,2]])
print(a@b) #等价于torch.matmul(a,b) 或 torch.mm(a,b)

2.转置

1
2
3
#矩阵转置
a = torch.tensor([[1.0,2],[3,4]])
print(a.t())

3.矩阵求逆

1
2
3
#矩阵逆,必须为浮点类型
a = torch.tensor([[1.0,2],[3,4]])
print(torch.inverse(a))

4.矩阵求迹

1
2
3
#矩阵求trace
a = torch.tensor([[1.0,2],[3,4]])
print(torch.trace(a))

5.求范数和行列式

1
2
3
4
5
6
7
#矩阵求范数
a = torch.tensor([[1.0,2],[3,4]])
print(torch.norm(a))

#矩阵行列式
a = torch.tensor([[1.0,2],[3,4]])
print(torch.det(a))

6.特征值和特征向量

1
2
3
4
5
#矩阵特征值和特征向量
a = torch.tensor([[1.0,2],[-5,4]],dtype = torch.float)
print(torch.eig(a,eigenvectors=True))

#两个特征值分别是 -2.5+2.7839j, 2.5-2.7839j

7.QR分解

1
2
3
4
5
6
7
8
#矩阵QR分解, 将一个方阵分解为一个正交矩阵q和上三角矩阵r
#QR分解实际上是对矩阵a实施Schmidt正交化得到q

a = torch.tensor([[1.0,2.0],[3.0,4.0]])
q,r = torch.qr(a)
print(q,"\n")
print(r,"\n")
print(q@r)

8.SVD分解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#矩阵svd分解
#svd分解可以将任意一个矩阵分解为一个正交矩阵u,一个对角阵s和一个正交矩阵v.t()的乘积
#svd常用于矩阵压缩和降维
a=torch.tensor([[1.0,2.0],[3.0,4.0],[5.0,6.0]])

u,s,v = torch.svd(a)

print(u,"\n")
print(s,"\n")
print(v,"\n")

print(u@torch.diag(s)@v.t())

#利用svd分解可以在Pytorch中实现主成分分析降维

下面基于上面的这些方法玩一个线性回归模型。

3. 搭建一个线性回归模型

这就是我上面说的叫做代码逻辑的一种思路, 写代码往往习惯先有一个这样的一种思路,然后再去写代码的时候,就比较容易了。 而如果不系统的学一遍Pytorch, 一上来直接上那种复杂的CNN, LSTM这种,往往这些代码逻辑不好形成,因为好多细节我们根本就不知道。 所以这次学习先从最简单的线性回归开始,然后慢慢的到复杂的那种网络。下面我们开始写一个线性回归模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 首先我们得有训练样本X,Y, 这里我们随机生成
x = torch.rand(20, 1) * 10
y = 2 * x + (5 + torch.randn(20, 1))

# 构建线性回归函数的参数
w = torch.randn((1), requires_grad=True)
b = torch.zeros((1), requires_grad=True) # 这俩都需要求梯度

for iteration in range(100):
# 前向传播
wx = torch.mul(w, x)
y_pred = torch.add(wx, b)

# 计算loss
loss = (0.5 * (y-y_pred)**2).mean()

# 反向传播
loss.backward()

# 更新参数
b.data.sub_(lr * b.grad) # 这种_的加法操作时从自身减,相当于-=
w.data.sub_(lr * w.grad)

# 梯度清零
w.grad.data.zero_()
b.grad.data.zero_()

print(w.data, b.data)

我们看一下结果:

4. 总结

今天的学习内容结束, 下面简单的梳理一遍,其实小东西还是挺多的, 首先我们从Pytorch最基本的数据结构开始,认识了张量到底是个什么东西,说白了就是个多维数组,然后张量本身有很多的属性, 有关于数据本身的data, dtype, shape, dtype, 也有关于求导的requires_grad, grad, grad_fn, is_leaf。 然后学习了张量的创建方法, 比如直接创建,从数组创建,数值创建,按照概率创建等。 这里面涉及到了很多的创建函数tensor(), from_numpy(), ones(), zeros(), eye(), full(), arange(), linspace(), normal(), randn(), rand(), randint(), randperm()等等吧。

接着就是张量的操作部分, 有基本操作和数学运算, 基本操作部分有张量的拼接两个函数(.cat, .stack), 张量的切分两个函数(.chunk, .split), 张量的转置(.reshape, .transpose, .t), 张量的索引两个函数(.index_select, .masked_select)。 数学运算部分,也是很多数学函数,有加减乘除的,指数底数幂函数的,三角函数的很多。

最后基于上面的所学完成了一个简单的线性回归。 下面以一张思维导图把这一篇文章的内容拎起来:

这次整理了很多的函数,每个函数的用法不同,具体用法先不用刻意记住,先知道哪些函数具体完成什么功能,到时候用的时,边查边用,慢慢的多练才能熟。

Ok, 下一次学习Pytorch的动态图机制以及自动求导机制, 然后基于前面的这两篇再玩一个逻辑回归, 我们从最简单的模型开始 😉

  • 人工智能
  • PyTorch

扫一扫,分享到微信

微信分享二维码
2-Pytorch的动态图-自动求导及逻辑回归
Pytorch与词向量
  1. 1. 1. 张量的简介与创建
    1. 1.1. 1.1 张量的简介
    2. 1.2. 1.2 张量的创建
      1. 1.2.1. 1.2.1 直接创建张量
      2. 1.2.2. 1.2.2 通过numpy数组来创建
      3. 1.2.3. 1.2.3 依据数值创建
      4. 1.2.4. 1.2.4 依概率分布创建张量
  2. 2. 2. 张量的操作
    1. 2.1. 2.1 张量的基本操作
      1. 2.1.1. 2.1.1 张量的拼接
      2. 2.1.2. 2.1.2 张量的切分
      3. 2.1.3. 2.1.3 张量的索引
      4. 2.1.4. 2.1.4 张量的变换
    2. 2.2. 2.2 张量的数学运算
      1. 2.2.1. 2.2.1 标量运算
      2. 2.2.2. 2.2.2 向量运算
      3. 2.2.3. 2.2.3 矩阵运算
  3. 3. 3. 搭建一个线性回归模型
  4. 4. 4. 总结

Related Issues not found

Please contact @JavaSsun to initialize the comment

© 2018-2024 Allen
Hexo Theme Yilia by Litten
本站总访问量72488次 | 本站访客数65126人
  • 所有文章
  • 友链
  • 关于我

tag:

  • Elasticsearch
  • 面试
  • MQ
  • Redis
  • Nginx
  • Docker
  • Git
  • Dubbo
  • 论文
  • MySql
  • Tools
  • 日志
  • Linux
  • 系统架构
  • Java
  • 源码解析
  • Hexo-yilia
  • Jvm
  • MyBatis
  • SpringBoot
  • Swagger2
  • 算法
  • 分布式
  • Photo
  • HTTP
  • Hystrix
  • SSL
  • ELK
  • IDEA
  • Jwt
  • 定时任务
  • BigData
  • Maven
  • Quartz
  • 人工智能
  • 地图坐标转换
  • 网络编程
  • Python
  • SpringCloud
  • 搬砖结晶
  • OpenCV
  • 推荐系统
  • 目标检测
  • SkLearn
  • 图神经网络
  • PyTorch
  • TensorFlow
  • 数据挖掘
  • 研究生课题-AD检测
  • 研究生成果

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 研究生总结

    2024-05-09

    #论文#人工智能#搬砖结晶#图神经网络#研究生课题-AD检测#研究生成果

  • 12-ROI文件分析

    2023-11-22

    #Tools#人工智能#研究生课题-AD检测

  • 11-DTI预处理

    2023-11-16

    #Tools#人工智能#研究生课题-AD检测

  • 10-GRETNA处理fMRI

    2023-11-05

    #Tools#人工智能#研究生课题-AD检测

  • 9-(图)利用Matlab的spm12工具处理fMRI为ROI

    2023-10-28

    #Tools#人工智能#研究生课题-AD检测

  • 9-(文)利用Matlab的spm12工具处理fMRI为ROI

    2023-10-26

    #Tools#人工智能#研究生课题-AD检测

  • 8-7-FSL软件使用

    2023-10-20

    #Tools#人工智能#研究生课题-AD检测

  • 8-6-FreeSurfer软件使用

    2023-10-16

    #Tools#人工智能#研究生课题-AD检测

  • 8-5-SPM软件使用

    2023-10-10

    #Tools#人工智能#研究生课题-AD检测

  • 8-4-MRI预处理

    2023-09-16

    #Tools#人工智能#研究生课题-AD检测

  • 8-3-UNet提取海马体

    2023-09-10

    #人工智能#研究生课题-AD检测

  • 8-2-ADNI论文数据预处理

    2023-09-02

    #论文#Tools#人工智能#研究生课题-AD检测

  • 8-1-数据预处理工具

    2023-08-05

    #Tools#人工智能#研究生课题-AD检测

  • 7-2-GNN For AD

    2023-07-25

    #论文#人工智能#图神经网络#研究生课题-AD检测

  • 7-1-GNN For Medical Diagnosis

    2023-06-28

    #论文#人工智能#图神经网络#研究生课题-AD检测

  • 6-2-SCI一区论文精读

    2023-05-25

    #论文#人工智能#研究生课题-AD检测

  • 6-1-MRI成像及ADNI简介

    2023-05-10

    #人工智能#研究生课题-AD检测

  • 5-ADNI-实验数据筛选与下载

    2023-04-25

    #人工智能#研究生课题-AD检测

  • 4-AD文献的阅读记录

    2023-04-20

    #论文#人工智能#研究生课题-AD检测

  • 3-指标特征选择

    2023-04-05

    #人工智能#研究生课题-AD检测

  • 2-AD有关课题

    2023-03-25

    #人工智能#研究生课题-AD检测

  • 1-阿尔茨海默病

    2023-03-20

    #人工智能#研究生课题-AD检测

  • 7-SHAP

    2023-03-15

    #人工智能#数据挖掘

  • 6-模型的融合技术大总结与结果部署

    2023-02-25

    #人工智能#数据挖掘

  • 5-模型建立与调参

    2023-02-20

    #人工智能#数据挖掘

  • 4-特征工程

    2023-02-12

    #人工智能#数据挖掘

  • 3-数据清洗和转换技巧

    2023-02-09

    #人工智能#数据挖掘

  • 2-数据的探索性-EDA分析

    2023-02-06

    #人工智能#数据挖掘

  • 1-赛题理解

    2023-02-04

    #人工智能#数据挖掘

  • 0-零基础入门数据挖掘学习路径

    2023-02-03

    #人工智能#数据挖掘

  • 重温深度学习优化算法

    2023-01-28

    #人工智能

  • 重温归一化(MinMaxScaler)和标准化(StandardScaler)

    2023-01-20

    #人工智能

  • 重温Batch Normalization

    2023-01-15

    #人工智能

  • 交叉熵损失函数和平方损失的区别

    2023-01-12

    #人工智能

  • loss不下降的解决方法

    2023-01-10

    #人工智能

  • 重温Seq2Seq和Attention机制

    2023-01-05

    #人工智能

  • 重温LSTM和GRU

    2022-12-28

    #人工智能

  • 重温RNN

    2022-12-25

    #人工智能

  • pytorch_geometric离线安装

    2022-12-19

    #人工智能#图神经网络#PyTorch

  • pytorch_geometric安装

    2022-12-18

    #人工智能#图神经网络#PyTorch

  • 生成式对抗网络GAN的工作原理

    2022-12-13

    #人工智能

  • Ubuntu查看cuda-cudnn等版本命令

    2022-12-10

    #Tools#人工智能

  • CUDA和CuDNN安装

    2022-12-08

    #Tools#人工智能

  • GPU之nvidia-smi命令详解

    2022-12-05

    #Tools#人工智能

  • 1-TensorFlow简介及安装

    2022-12-01

    #人工智能#TensorFlow

  • 入门图神经网络

    2022-11-25

    #人工智能#图神经网络

  • 10-模型的保存加载-模型微调-GPU使用及Pytorch常见报错

    2022-11-06

    #人工智能#PyTorch

  • 9-正则化与标准化大总结

    2022-10-28

    #人工智能#PyTorch

  • 8-Tensorboard可视化与Hook机制

    2022-10-25

    #人工智能#PyTorch

  • 7-优化器和学习率调整策略

    2022-10-23

    #人工智能#PyTorch

  • 6-模型的权值初始化与损失函数介绍

    2022-10-20

    #人工智能#PyTorch

  • 5-nn各网络层介绍

    2022-10-17

    #人工智能#PyTorch

  • Pytorch提取神经网络层结构-层参数及自定义初始化

    2022-10-14

    #人工智能#PyTorch

  • 4-模型创建Module-模型容器Containers及AlexNet网络搭建

    2022-10-12

    #人工智能#PyTorch

  • 3-Pytorch数据读取机制(DataLoader)与图像预处理模块(transforms)

    2022-10-09

    #人工智能#PyTorch

  • 2-Pytorch的动态图-自动求导及逻辑回归

    2022-10-02

    #人工智能#PyTorch

  • 1-Pytorch的数据载体张量与线性回归

    2022-09-28

    #人工智能#PyTorch

  • Pytorch与词向量

    2022-09-25

    #人工智能#PyTorch

  • Pytorch基础理论和简单的神经网络实现

    2022-09-23

    #人工智能#PyTorch

  • Windows下的Pytorch环境搭建

    2022-09-20

    #人工智能#PyTorch

  • 图卷积网络-GCN

    2022-09-15

    #人工智能#图神经网络

  • GCN使用的数据集Cora等

    2022-09-10

    #人工智能#图神经网络

  • 图网络属性介绍

    2022-09-08

    #人工智能#图神经网络

  • 图神经网络理论基础

    2022-09-05

    #人工智能#图神经网络

  • 5-AI上推荐之AutoRec与Deep Crossing模型(改变神经网络的复杂程度)

    2022-08-28

    #人工智能#推荐系统

  • 4-AI上推荐之FM和FFM(九九归一)

    2022-08-17

    #人工智能#推荐系统

  • 梯度提升树GBDT的理论学习与细节补充

    2022-08-05

    #人工智能#推荐系统

  • 梯度下降算法的细节补充(凸函数, 导数, 偏导数,梯度, 方向导数以及负梯度下降最快背后的泰勒身影)

    2022-07-28

    #人工智能#推荐系统

  • 逻辑回归、优化算法和正则化的幕后细节补充

    2022-07-24

    #人工智能#推荐系统

  • 3-AI上推荐之逻辑回归模型与GBDT+LR(特征工程模型化的开端)

    2022-07-20

    #人工智能#推荐系统

  • 奇异值分解(SVD)的原理详解及推导

    2022-07-13

    #人工智能#推荐系统

  • 2-AI上推荐之隐语义模型(LFM)和矩阵分解(MF)

    2022-07-10

    #人工智能#推荐系统

  • 1-AI上推荐之协同过滤

    2022-07-02

    #人工智能#推荐系统

  • R-CNN and Fast R-CNN and Faster R-CNN and SPP

    2022-06-15

    #人工智能#目标检测

  • 10-Harris和Shi-Tomas算法

    2022-06-06

    #人工智能#OpenCV

  • 9-角点特征

    2022-06-03

    #人工智能#OpenCV

  • 8-图像变换-傅里叶变换

    2022-05-29

    #人工智能#OpenCV

  • 7-模板匹配与霍夫变换

    2022-05-15

    #人工智能#OpenCV

  • 6-边缘检测

    2022-05-08

    #人工智能#OpenCV

  • 5-直方图

    2022-04-28

    #人工智能#OpenCV

  • 4-图像平滑

    2022-04-26

    #人工智能#OpenCV

  • 3-形态学操作

    2022-04-22

    #人工智能#OpenCV

  • 2-几何变换

    2022-04-20

    #人工智能#OpenCV

  • 1-图像的基础操作

    2022-04-18

    #人工智能#OpenCV

  • 0-OpenCV简介

    2022-04-15

    #人工智能#OpenCV

  • Ubuntu18.04下安装OpenCV3.4

    2022-04-01

    #人工智能#OpenCV

  • 后 R-CNN时代, Faster R-CNN、SSD、YOLO 各类变体统治下的目标检测综述:Faster R-CNN系列胜了吗?

    2022-03-28

    #人工智能#目标检测

  • SKLearn学习总结

    2022-03-20

    #人工智能#SkLearn

  • 详细了解PyCharm支持的4种Python Interpreter和配置方法

    2022-03-02

    #Tools

  • Pycharm远程连接

    2022-02-26

    #Tools

  • JupyterLab学习总结

    2022-02-19

    #Tools#人工智能

  • Anaconda学习总结

    2022-02-13

    #Tools#人工智能

  • Ubuntu下安装lrzsz工具

    2022-02-08

    #Tools

  • 13-RNN

    2022-02-05

    #人工智能

  • 12-加速深度学习的算法和硬件-讲座

    2022-01-10

    #人工智能

  • 11-深度学习硬件算力基础-GPU与TPU与英特尔神经棒

    2021-12-26

    #人工智能

  • 10-经典卷积神经网络架构案例分析

    2021-12-16

    #人工智能

  • 9-迁移学习与fine-tuning

    2021-12-11

    #人工智能

  • 8-CNNS in Practice-卷积神经网络工程实践技巧

    2021-11-28

    #人工智能

  • 7-训练神经网络-下

    2021-11-09

    #人工智能

  • 6-训练神经网络-上

    2021-11-05

    #人工智能

  • 5-可视化并理解卷积神经网络

    2021-10-25

    #人工智能

  • 4-Convolutional-Neural-Networks

    2021-10-18

    #人工智能

  • 3-神经网络与反向传播

    2021-10-10

    #人工智能

  • 2-损失函数和梯度下降

    2021-09-25

    #人工智能

  • 1-KNN&线性分类器

    2021-09-20

    #人工智能

  • 0-机器学习基础

    2021-09-15

    #人工智能

  • 入门人工智能算法工程师-先来碗毒鸡汤

    2021-07-30

    #人工智能

  • 3-如何高效阅读机器学习顶会论文

    2021-07-15

    #论文

  • 2-论文ABC类与一二区的区别

    2021-06-10

    #论文

  • 1-学术小白

    2021-06-06

    #论文

  • 领域驱动设计在互联网业务开发中的实践

    2020-09-13

    #系统架构

  • 领域驱动设计

    2020-07-12

    #系统架构

  • DDD模式-从天书到实践

    2020-06-28

    #系统架构

  • DDD-马什么梅

    2020-06-14

    #系统架构

  • FaaS-又一个为未来

    2020-05-17

    #系统架构

  • 分布式ID的花拳绣腿

    2020-04-19

    #面试#系统架构#分布式

  • 4-Dockerfile上

    2020-04-08

    #Docker

  • 3-Docker存储卷

    2020-04-07

    #Docker

  • 2-Docker容器网络

    2020-04-06

    #Docker

  • 1-安装_使用Docker

    2020-04-05

    #Docker

  • 45-自增ID用完怎么办

    2020-03-11

    #MySql

  • 44-一些常见问题

    2020-03-09

    #MySql

  • 43-要不要使用分区表

    2020-03-08

    #MySql

  • 42-grant之后要跟着flush privileges吗

    2020-03-07

    #MySql

  • 41-如何最快的复制一张表

    2020-03-06

    #MySql

  • 40-insert语句的锁为什么这么多

    2020-03-04

    #MySql

  • 39-自增主键为什么不是连续的

    2020-03-03

    #MySql

  • 38-都说InnoDB好_那还要不要使用Memory引擎

    2020-03-02

    #MySql

  • 37-什么时候会使用内部临时表

    2020-03-01

    #MySql

  • SpringBoot_RabbitMQ配置参数详解

    2020-02-26

    #MQ

  • RabbitMQ安装

    2020-02-26

    #MQ

  • ELK日志平台-中

    2020-02-11

    #日志#ELK

  • ELK日志平台-上

    2020-02-10

    #日志#ELK

  • Java8新特性

    2020-02-08

    #Java

  • 1-Hystrix知多少

    2020-01-01

    #面试#Hystrix

  • 25-Nginx变量原理-应用

    2019-12-13

    #Nginx

  • 24-详解HTTP过滤模块

    2019-12-12

    #Nginx

  • 23-详解HTTP请求的11个阶段

    2019-12-11

    #Nginx

  • 22-如何找到处理请求的Server指令块

    2019-12-10

    #Nginx

  • 21-Nginx中的正则表达式

    2019-12-09

    #Nginx

  • 20-处理HTTP请求头部流程

    2019-12-09

    #Nginx

  • 19-Nginx中Listen指令用法

    2019-12-08

    #Nginx

  • 18-Nginx冲突的配置指令以谁为准

    2019-12-08

    #Nginx

  • 17-Nginx动态模块

    2019-12-07

    #Nginx

  • 16-Nginx容器

    2019-12-06

    #Nginx

  • 15-Worker集成协同工作的关键

    2019-12-06

    #Nginx

  • 14-Nginx连接池处理网络请求-内存池对性能的影响

    2019-12-05

    #Nginx

  • 13-Nginx模块

    2019-12-04

    #Nginx

  • 12-网络收发与Nginx事件模型

    2019-12-03

    #Nginx

  • 11-Nginx架构_相关流程

    2019-12-02

    #Nginx

  • LinkedHashMap实现原理_探险

    2019-11-28

    #Java#源码解析

  • HashTable实现原理_探险

    2019-11-22

    #Java#源码解析

  • HashMap实现原理_探险

    2019-11-20

    #Java#源码解析

  • LinkList实现原理_探险

    2019-11-17

    #Java#源码解析

  • ArrayList实现原理_探险

    2019-11-16

    #Java#源码解析

  • 10-OpenResty用Lua语言实现简单服务

    2019-11-12

    #Nginx

  • 9-SSL-Nginx

    2019-11-11

    #Nginx#SSL

  • 8-Nginx配置文件简易解析

    2019-11-10

    #Nginx

  • 7-Nginx安装详解

    2019-11-09

    #Nginx

  • 6-GoAccess实现可视化并实时监控access日志

    2019-11-08

    #Nginx#Tools#日志

  • 5-Nginx搭建具备缓存功能的反向代理

    2019-11-05

    #Nginx

  • 4-Nginx搭建静态资源Web服务器

    2019-11-01

    #Nginx

  • SpringBoot中jar为什么可以直接运行

    2019-10-30

    #面试#SpringBoot

  • SpringBoot全局异常处理

    2019-10-29

    #面试#SpringBoot

  • SpringBoot事件和监听器

    2019-10-29

    #面试#SpringBoot

  • SpringBoot启动原理

    2019-10-29

    #面试#SpringBoot

  • 36-为什么临时表可以重名

    2019-10-28

    #MySql

  • 35-join语句如何优化

    2019-10-27

    #MySql

  • 34-到底可不可以使用join

    2019-10-26

    #MySql

  • 33-我查这么多数据_会不会把数据库内存打爆

    2019-10-24

    #MySql

  • 32-为什么有kill不掉的语句

    2019-10-23

    #MySql

  • 31-误删数据后除了跑路_还能怎么办

    2019-10-22

    #MySql

  • 3-Nginx命令行演示-重载-热部署-切割

    2019-10-20

    #Nginx

  • 2-Nginx配置语法

    2019-10-17

    #Nginx

  • 1-Nginx的前世今生

    2019-10-15

    #Nginx

  • 0-Nginx访问日志配置及信息详解

    2019-10-11

    #Nginx

  • 分布式事务

    2019-09-19

    #面试#系统架构#分布式

  • 分布式锁

    2019-09-18

    #面试#系统架构#分布式

  • 分布式锁与事务

    2019-09-16

    #面试#系统架构#分布式

  • 数据结构与算法第四阶段学习图

    2019-09-16

    #算法

  • 数据结构与算法第三阶段学习图

    2019-09-16

    #算法

  • 数据结构与算法第二阶段学习图

    2019-09-16

    #算法

  • 数据结构与算法第一阶段学习图

    2019-09-16

    #算法

  • 2018-2019工作总结

    2019-09-15

    #搬砖结晶

  • 开发常见问题

    2019-09-14

    #Java

  • 52-算法实战(五)_如何用学过的数据结构和算法实现一个短网址系统

    2019-09-14

    #算法

  • 30-用动态的观点看加锁

    2019-09-13

    #MySql

  • 29-如何判断一个数据库是不是出问题了

    2019-09-12

    #MySql

  • 28-读写分离有哪些坑

    2019-09-11

    #MySql

  • 51-算法实战(四)_剖析微服务接口鉴权限流背后的数据结构和算法

    2019-09-09

    #算法

  • 50-算法实战(三)_剖析高性能队列Disruptor背后的数据结构和算法

    2019-09-06

    #算法

  • 49-算法实战(二)_剖析搜索引擎背后的经典数据结构和算法

    2019-09-02

    #算法

  • 27-主库出问题了_从库怎么办

    2019-08-29

    #MySql

  • 26-备库为什么会延迟好几个小时

    2019-08-28

    #MySql

  • 25-MySQL是怎么保证高可用的

    2019-08-27

    #MySql

  • 24-MySQL是怎么保证主备一致的

    2019-08-26

    #MySql

  • 48-算法实战(一)_剖析Redis常用数据类型对应的数据结构

    2019-08-25

    #算法

  • 47-并行算法_如何利用并行处理提高算法的执行效率

    2019-08-20

    #算法

  • 46-索引_如何在海量数据中快速查找某个数据

    2019-08-16

    #算法

  • 45-搜索_如何用A*搜索算法实现游戏中的寻路功能

    2019-08-13

    #算法

  • 44-B+树_MySQL数据库索引是如何实现的

    2019-08-10

    #算法

  • 43-向量空间_如何实现一个简单的音乐推荐系统

    2019-08-08

    #算法

  • 42-概率统计_如何利用朴素贝叶斯算法过滤垃圾短信

    2019-08-05

    #算法

  • 41-位图_如何实现网页爬虫中的URL去重功能

    2019-08-02

    #算法

  • 40-最短路径_地图软件是如何计算出最优出行路径的

    2019-07-28

    #算法

  • 39-拓扑排序_如何确定代码源文件的编译依赖关系

    2019-07-24

    #算法

  • 38-动态规划实战_如何实现搜索引擎中的拼写纠错功能

    2019-07-20

    #算法

  • 23-MySQL是如何保证数据不丢的

    2019-07-19

    #MySql

  • 22-MySQL有哪些“饮鸩止渴”提高性能的方法

    2019-07-18

    #MySql

  • 21-为什么我只改一行的语句_锁还这么多

    2019-07-17

    #MySql

  • 20-幻读是什么_幻读有什么问题

    2019-07-16

    #MySql

  • 19-只查一行的语句为何执行这么慢

    2019-07-15

    #MySql

  • 37-动态规划理论_一篇文章带你彻底搞懂最优子结结构_无后效性_重复子问题

    2019-07-13

    #算法

  • 36-初识动态规划_如何巧妙解解决“双十一”购物时的凑单问题

    2019-07-09

    #算法

  • 35-回溯算法_从电影《蝴蝶效应》中学习回溯算法的核心思想

    2019-07-06

    #算法

  • 34-分治算法_谈一谈大规模计算框架MapReduce中的分治思想

    2019-07-04

    #算法

  • 33-贪心算法_如何用贪心算法实现Huffman压缩编码

    2019-07-01

    #算法

  • 32-AC自动机_如何用多模式串匹配实现敏感词过滤功能

    2019-06-25

    #算法

  • 18-SQL语句逻辑相同_性能却为何差异巨大

    2019-06-23

    #MySql

  • 17-如何正确的显示随机消息

    2019-06-22

    #MySql

  • 16-MySQL中order by是如何工作的

    2019-06-20

    #MySql

  • 15-日志和索引有关问题

    2019-06-18

    #MySql

  • RocketMQ探索

    2019-06-17

    #MQ

  • 14-count(\*)为什么这么慢

    2019-06-16

    #MySql

  • 13-为什么表数据删掉一半而表文件大小不变

    2019-06-15

    #MySql

  • 12-为什么我的MySQL会“抖”一下

    2019-06-13

    #MySql

  • 11-怎么给字符串字段加索引

    2019-06-12

    #MySql

  • 10-MySQL为什么有时候会选错索引

    2019-06-11

    #MySql

  • 3-3-Docker容器用法

    2019-06-10

    #Docker

  • RabbitMQ详解

    2019-06-08

    #MQ

  • 5-分布式会话_锁_事务_高并发系统设计

    2019-06-07

    #面试

  • 3.2-Docker镜像用法

    2019-06-05

    #Docker

  • 4-Zookeeperer使用场景

    2019-06-04

    #面试

  • Dubbo知多少

    2019-06-03

    #面试#Dubbo

  • 3-分布式系统中接口调用顺序性如何保证

    2019-06-03

    #面试#Dubbo

  • 2-分布式系统中接口的幂等性该如何保证_比如不能重复扣款

    2019-06-02

    #面试#Dubbo

  • 1-分布式系统连环炮_Dubbo有关知识点

    2019-06-01

    #面试#Dubbo

  • 9-普通索引和唯一索引如何选择

    2019-05-30

    #MySql

  • 8-事务到底是隔离的还是不隔离的

    2019-05-29

    #MySql

  • 7-行锁功过_怎么减少行锁对性能的影响

    2019-05-28

    #MySql

  • 6-全局锁和表锁_给表加个字段怎么有这么多阻碍

    2019-05-27

    #MySql

  • 5-深入浅出索引(下)

    2019-05-26

    #MySql

  • 4-深入浅出索引(上)

    2019-05-25

    #MySql

  • 3.1-Docker用法

    2019-05-24

    #Docker

  • 2.2-Docker启动报错

    2019-05-23

    #Docker

  • 3-事务隔离_为什么你改了我还看不见

    2019-05-21

    #MySql

  • MySQL重要日志

    2019-05-20

    #面试#MySql

  • 2-日志系统_一条SQL更新语句是如何执行的

    2019-05-20

    #MySql

  • 1-基础架构_一条SQL查询语句是如何执行的

    2019-05-19

    #MySql

  • 2.1-Docker安装与部署

    2019-05-18

    #Docker

  • 1-Docker缘由

    2019-05-12

    #Docker

  • 0-Docker配置国内免费registry_mirror

    2019-05-08

    #Docker

  • 5-分布式搜索引擎如何部署

    2019-04-26

    #Elasticsearch#面试

  • 4-ES如何在几十亿数据场景下优化查询性能

    2019-04-23

    #Elasticsearch#面试

  • 3-ES读写数据的工作原理

    2019-04-22

    #Elasticsearch#面试

  • 2-分布式搜索引擎的架构是如何设计的

    2019-04-21

    #Elasticsearch#面试

  • 1-面试官对分布式搜索引擎的4个连环炮

    2019-04-20

    #Elasticsearch#面试

  • 8-如何设计一个消息队列

    2019-04-10

    #面试#MQ

  • 7-消息队列如何解决延迟_过期失效_积压消息等问题

    2019-04-10

    #面试#MQ

  • JWT学习

    2019-04-09

    #Java#Jwt

  • 6-消息队列如何保证消息的顺序性

    2019-04-08

    #面试#MQ

  • 5-消息队列如何保证可靠性传输(消息丢了怎么办)

    2019-04-07

    #面试#MQ

  • 4-消息队列消费到重复数据怎么办

    2019-04-06

    #面试#MQ

  • 3-消息队列如何保证高可用性

    2019-04-03

    #面试#MQ

  • 2-消息队列引入原原因_优缺点_应用场景_技术选型

    2019-04-02

    #面试#MQ

  • 1-面试官对消息队列的10个连环炮

    2019-04-01

    #面试#MQ

  • Git常见200+条命令

    2019-03-28

    #Git

  • 8-GitLab简单操作

    2019-03-25

    #Git

  • 31-Trie树_如何实现搜索引擎的搜索关键词提示功能

    2019-03-12

    #算法

  • 7-基于GitHub进行团队协作

    2019-03-09

    #Git

  • 30-字符串匹配基础下_如何借助BM算法轻松理解KMP算法

    2019-03-06

    #算法

  • 29-字符串匹配基础中_如何实现文本编辑器中的查找功能

    2019-03-03

    #算法

  • 28-字符串匹配基础上_如何借助哈希算法实现高效字符串匹配

    2019-03-01

    #算法

  • 6-GitHub的认识与使用

    2019-02-25

    #Git

  • 5-Git集成使用禁忌

    2019-02-15

    #Git

  • 27-深度和广度优先搜索_如何找出社交网络中的三度好友关系

    2019-02-13

    #算法

  • 26-图的表示_如何存储微博微信等社交网络中的好友关系

    2019-02-10

    #算法

  • 国内地图坐标系转换

    2019-02-08

    #地图坐标转换

  • 4-Git多人单分支集成协作时的常见场景

    2019-02-08

    #Git

  • 微服务架构-下篇

    2019-02-06

    #系统架构

  • 微服务架构-中篇

    2019-02-03

    #系统架构

  • 微服务架构-上篇

    2019-02-01

    #系统架构

  • Python数据分析工具

    2019-01-30

    #Python

  • Python高级篇

    2019-01-29

    #Python

  • Python中级篇_下

    2019-01-28

    #Python

  • Python中级篇_上

    2019-01-27

    #Python

  • Python初级篇

    2019-01-26

    #Python

  • Python前世今生

    2019-01-25

    #Python

  • 源码分析-MyBatis数据源与连接池

    2019-01-23

    #MyBatis

  • MyBatis初始化做了什么

    2019-01-21

    #MyBatis

  • 3-Git与GitHub简单同步

    2019-01-20

    #Git

  • 2-Git常用场景

    2019-01-18

    #Git

  • 1-Git安装及简单操作

    2019-01-15

    #Git

  • SpringCloud探索与实战

    2019-01-13

    #SpringCloud

  • MyBatis架构与原理

    2019-01-09

    #MyBatis

  • MyBatis原理概括

    2019-01-08

    #MyBatis

  • MyBatis多数据源配置

    2019-01-07

    #MyBatis

  • JVM(八):Jvm知识点概览

    2019-01-06

    #Jvm

  • JVM(七):Jvm调优-工具

    2019-01-05

    #Tools#Jvm

  • JVM(六):Java服务GC参数调优案例

    2019-01-03

    #Jvm

  • JVM(五):GC分析

    2019-01-02

    #Jvm

  • JVM(四):Jvm调优-命令

    2019-01-01

    #Jvm

  • JVM(三):GC算法_垃圾收集器

    2019-01-01

    #Jvm

  • 25-堆的应用_如何获取Top10最热门的搜索关键词

    2018-12-30

    #算法

  • 24-堆和堆排序_为什么说堆排序没有快速排序快

    2018-12-29

    #算法

  • 23-递归树_如何借助树来求解递归算法的时间复杂度

    2018-12-27

    #算法

  • 22-红黑树下_实现红黑树的技巧

    2018-12-25

    #算法

  • 21-红黑树上_为什么工程中都用红黑树这种二叉树

    2018-12-23

    #算法

  • 应用架构演变过程

    2018-12-20

    #Photo

  • MyBatis常用插件

    2018-12-14

    #MyBatis

  • JVM(二):Jvm内存结构

    2018-12-11

    #Jvm

  • JVM(一):Java类加载机制

    2018-12-10

    #Jvm

  • Map-Reduce学习

    2018-11-20

    #BigData

  • 20-二叉树基础下_有了如此高效的散列表—_为什么还需要二叉树

    2018-11-18

    #算法

  • 19-二叉树基础上_什么样的二叉树适合用数组来存储

    2018-11-16

    #算法

  • 18-哈希算法下_哈希算法在分布式系统中有哪些应用

    2018-11-15

    #算法

  • 17-哈希算法上_如何防止数据库中的用户信息被脱库

    2018-11-13

    #算法

  • Hadoop学习

    2018-11-10

    #BigData

  • 16-散列表下_为什么散列表和链表经常一起使用

    2018-11-09

    #算法

  • 15-散列表中_如何打造一个工业级水平的散列表

    2018-11-09

    #算法

  • 14-散列表上_Word文档中的单词拼写检查功能如何实现

    2018-11-08

    #算法

  • 13-跳表_为什么Redis一定要用跳表来实现有序集合

    2018-11-06

    #算法

  • 12-二分查找下_如何快速定位IP对应的省份地址

    2018-11-04

    #算法

  • 11-二分查找上_如何用最省内存的方式实现快速查找功能

    2018-11-02

    #算法

  • 10-排序优化_如何实现一个通用的高性能的排序函数

    2018-11-01

    #算法

  • 9-线性排序_如何根据年龄给100万用户数据排序

    2018-10-28

    #算法

  • 8-排序下_如何用快排思想在O(n)内查找第K大元素

    2018-10-24

    #算法

  • 7-排序上_为什么插入排序比冒泡排序更受欢迎

    2018-10-22

    #算法

  • 6-递归_如何用三行代码找到最终推荐人

    2018-10-20

    #算法

  • 高性能队列-Disruptor

    2018-10-18

    #MQ#Java

  • 5-队列_队列在线程池等有限资源池中的应用

    2018-10-16

    #算法

  • 4-栈_如何实现浏览器的前进和后退功能

    2018-10-13

    #算法

  • Quartz学习

    2018-10-09

    #Java#定时任务#Quartz

  • 3-链表下_如何轻松写出正确的链表代码

    2018-10-06

    #算法

  • 2-链表上_如何实现LRU缓存淘汰算法

    2018-10-06

    #算法

  • 1-数组_为什么很多编程语言中数组都从0开始编号

    2018-10-02

    #算法

  • 复杂度分析-下部

    2018-09-29

    #算法

  • 复杂度分析-上部

    2018-09-28

    #算法

  • 数据结构与算法概览

    2018-09-26

    #算法

  • 请求与响应

    2018-09-17

    #HTTP

  • TextRank基本了解

    2018-09-01

    #算法

  • (5)Hexo踩坑_主题优化

    2018-08-21

    #Hexo-yilia

  • (4)Hexo撰写文章

    2018-08-19

    #Hexo-yilia

  • (3)Hexo常用命令详解

    2018-08-19

    #Hexo-yilia

  • (2)Hexo配置文件详解

    2018-08-17

    #Hexo-yilia

  • 关于Firewalld二三事

    2018-08-15

    #Linux

  • (1)Hexo博客搭建

    2018-08-11

    #Hexo-yilia

  • 修改Vim_tab为4个空格

    2018-08-06

    #Linux

  • CentOs7防火墙开端口测试

    2018-08-01

    #Linux

  • 10-Redis的并发竞争问题及生产环境集群部署架构

    2018-07-30

    #面试#Redis

  • 9-如何保证缓存与数据库双写时的数据一致性

    2018-07-29

    #面试#Redis

  • 8-如何应对缓存雪崩及穿透问题

    2018-07-28

    #面试#Redis

  • 7-Redis集群模式原理

    2018-07-26

    #面试#Redis

  • Redis所需安装包及各种依赖

    2018-07-25

    #Redis

  • 6-Redis挂掉重启后数据如何进行恢复

    2018-07-24

    #面试#Redis

  • 5-Redis高并发高可用有关问题

    2018-07-21

    #面试#Redis

  • 4-Redis过期策略_手写LRU

    2018-07-19

    #面试#Redis

  • 3-Redis常用数据类型及使用场景

    2018-07-18

    #面试#Redis

  • 2-Redis线程模型_单线程效率高的原因

    2018-07-17

    #面试#Redis

  • 1-项目中缓存如何使用

    2018-07-16

    #面试#Redis

  • AWK三剑客

    2018-07-15

    #Linux

  • Maven插件-assembly插件基本使用

    2018-06-28

    #Java#Maven

  • Maven知多少

    2018-06-27

    #Java#Maven

  • 1-分库分表知多少

    2018-06-25

    #面试#MySql

  • MySQL基本用法

    2018-06-21

    #MySql

  • MySQL安装

    2018-06-20

    #MySql

  • Swagger2学习与集成

    2018-05-20

    #SpringBoot#Swagger2

  • SpringBoot面试

    2018-05-16

    #面试#SpringBoot

  • SpringBoot+Docker简单配置

    2018-05-15

    #Docker#SpringBoot

  • Java定时任务

    2018-05-13

    #Java#定时任务

  • Netty知多少

    2018-05-05

    #网络编程

  • Java编程瞎侃

    2018-04-18

    #Java

  • Vim常用操作

    2018-03-25

    #Linux

  • Linux定时任务Crontab详解

    2018-03-23

    #Linux

  • Linux常用插件及乱码

    2018-03-20

    #Linux

  • Linux安装常用软件

    2018-03-19

    #Linux

  • Idea常用插件及个性化配置

    2018-03-18

    #Tools#IDEA

  • Host-Vm相互ping不同到的解决办法

    2018-03-16

    #Linux

  • GitHub
  • 廖雪峰
  • 纯洁的微笑
  • 我没有三颗心脏
  • 阿里巴巴开源镜像网站
一个脱离了高级趣味的人!