深度学习之PyTorch实战计算机视觉1

python中的多为数组的基本操作

矩阵是不存在除法运算的,但是数组能够进行除法运算

#a是多维数组,将多维数组扁平化处理,转变成一维数组,以下方法可以用来迭代数组内的数据
for i in a.flat:
	print(i)

python中的Matplotlib

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

np.random.seed(42)
x = np.random.randn(30)
#传递给plot的参数r--o用于在线型图中标记每个参数点使用的形状、连接参数点使用的线条颜色和线型
plt.plot(x,"r--o")
plt.plot(a,"r--o",b,"")

深度学习之PyTorch实战计算机视觉1_第1张图片

PyTorch的基础——Tensor

torch.rand:用于生成数据类型为浮点型且维度指定的随机Tensor,和在NumPy中使用numpy.rand生成随机数的方法类似,随机生成的浮点数据在0~1区间均匀分布。

a = torch.rand(2,3)
print(a)

torch.randn:用于生成数据类型为浮点型且维度指定的随机ensor,和在NumPy中使用numpy.randn生成随机数的方法类似,随机生成的浮点数的取值满足均值为0、方差为1的正太分布。

import torch
a = torch.randn(2,3)
print(a)

torch.range:用于生成数据类型为浮点型且自定义起始范围和结束范围的Tensor,所以传递给torch.range的参数有三个,分别是范
围的起始值、范围的结束值和步长,其中,步长用于指定从起始值到结
束值的每步的数据间隔。

import torch
a = torch.range(1,20,1)
print(a)

torch.zeros:用于生成数据类型为浮点型且维度指定的Tensor,不过这个浮点型的Tensor中的元素值全部为0。

import torch
a = torch.zeros(2,3)
print(a)

Tensor的运算

torch.abs:将参数传递到torch.abs后返回输入参数的绝对值作为输出,输入参数必须是一个Tensor数据类型的变量.

import torch
a = torch.randn(2,3)
print(a)
b = torch.abs(a)
print(b)

torch.add:将参数传递到 torch.add后返回输入参数的求和结果作为输出,输入参数既可以全部是Tensor数据类型的变量,也可以一个是Tensor数据类型的变量,另一个是标量。

torch.clamp:对输入参数按照自定义的范围进行裁剪,最后将参数裁剪的结果作为输出。所以输入参数一共有三个,分别是需要进行裁剪的Tensor数据类型的变量、裁剪的上边界和裁剪的下边界,具体的裁剪过程是:使用变量中的每个元素分别和裁剪的上边界及裁剪的下边界的值进行比较,如果元素的值小于裁剪的下边界的值,该元素就被重写成裁剪的下边界的值;同理,如果元素的值大于裁剪的上边界的值,该元素就被重写成裁剪的上边界的值。

import torch
a = torch.randn(2,3)
print(a)
b = torch.clamp(a,-0.1,0.1)
print(b)

torch.div:将参数传递到torch.div后返回输入参数的求商结果作为输出,同样,参与运算的参数可以全部是Tensor数据类型的变量,也可以是Tensor数据类型的变量和标量的组合。

torch.mul:将参数传递到 torch.mul后返回输入参数求积的结果作为输出,参与运算的参数可以全部是Tensor数据类型的变量,也可以是Tensor数据类型的变量和标量的组合。

torch.pow:将参数传递到torch.pow后返回输入参数的求幂结果作为输出,参与运算的参数可以全部是Tensor数据类型的变量,也可以是Tensor数据类型的变量和标量的组合。

import torch
a = torch.randn(2,3)
print(a)
b = torch.pow(a,2)
print(b)

torch.mm:将参数传递到 torch.mm后返回输入参数的求积结果作为输出,不过这个求积的方式和之前的torch.mul运算方式不太一样,torch.mm运用矩阵之间的乘法规则进行计算,所以被传入的参数会被当作矩阵进行处理,参数的维度自然也要满足矩阵乘法的前提条件,前一个矩阵的行数必须和后一个矩阵的列数相等,否则不能进行计算.

import torch
a = torch.randn(2,3)
print(a)
b = torch.randn(3,2)
print(b)
c = torch.mm(a,b)
print(c)

torch.mv:将参数传递到torch.mv后返回输入参数的求积结果作为输出,torch.mv运用矩阵与向量之间的乘法规则进行计算,被传入的参数中的第1个参数代表矩阵,第2个参数代表向量,顺序不能颠倒。

import torch
a = torch.randn(2,3)
print(a)
b = torch.randn(3)
print(b)
c = torch.mv(a,b)
print(c)

搭建一个简易神经网络

import torch
batch_n = 100
hidden_layer = 100
input_data = 1000
output_data = 10

x = torch.randn(batch_n,input_data)
y = torch.randn(batch_n,output_data)
w1 = torch.randn(input_data,hidden_layer)
w2 = torch.randn(hidden_layer,output_data)

epoch_n=20
learning_rate = le-6

for epoch in range(epoch_n):
	h1 = x.mm(w1)#100*1000
	h1 = h1.clamp(min = 0)
	y_pred = h1.mm(w2)#100*10
	loss = (y_pred-y).pow(2).sum()
	print("Epoch:{},Loss:{:.4f}".format(epoch,loss))
	grad_y_pred = 2*(y_pred-y)
	grad_w2 = h1.t().mm(grad_y_pred)
	grad_h = grad_y_pred.clone()
	grad_h = grad_h.mm(w2.t())
	grad_h.clamp_(min=0)
	grad_w1 = x.t().mm(grad_h)
	w1-=learning_rate*grad_w1
	w2-=learning_rate*grad_w2
	

我们先通过import torch导入必要的包,然后定义4个整型变量,其中:batch_n是在一个批次中输入数据的数量,值是100,这意味着我们在一个批次中输入100个数据,同时,每个数据包含的数据特征有input_data个,因为input_data的值是1000,所以每个数据的数据特征就是1000个;hidden_layer用于定义经过隐藏层后保留的数据特征的个数,这里有100个,因为我们的模型只考虑一层隐藏层,所以在代码中仅定义了一个隐藏层的参数;output_data是输出的数据,值是10,我们可以将输出的数据看作一个分类结果值的数量,个数10表示我们最后要得到10个分类结果值。
一个批次的数据从输入到输出的完整过程是:先输入100个具有1000个特征的数据,经过隐藏层后变成100个具有100个特征的数据,再经过输出层后输出100个具有10个分类结果值的数据,在得到输出结果之后计算损失并进行后向传播,这样一次模型的训练就完成了,然后循环这个流程就可以完成指定次数的训练,并达到优化模型参数的目的。下面看看如何完成从输入层到隐藏层、从隐藏层到输出层的权重初始化定义工作。
在代码中定义的输入层维度为(100,1000),输出层维度为(100,10),同时,从输入层到隐藏层的权重参数维度为(1000,100),从隐藏层到输出层的权重参数维为100,10),这里我们可能会好奇权重参数的维度是怎么定义下来的,其实,只要我们把整个过程看作矩阵连续的乘法运算,就自然能够很快明白了。在代码中我们的真实值y也是通过随机的方式生成的,所以一开始在使用损失函数计算损失值时得到的结果会较大。
在此之前,我们还需要明确训练的总次数和学习速率。因为接下来会使用梯度下降的方法来优化神经网络的参数,所以必须定义后向传播的次数和梯度下降使用的学习速率。在以上代码中使用了epoch_n定义训练的次数,epoch_n的值为20,所以我们需要通过循环的方式让程序进行20次训练,来完成对初始化权重参数的优化和调整。在优化的过程中使用的学习速率learning_rate的值为1e-6,表示6110-×,即0.000001。接下来对模型进行正式训练并对参数进行优化。
以上代码通过最外层的一个大循环来保证我们的模型可以进行 20次训练,循环内的是神经网络模型具体的前向传播和后向传播代码,参数的优化和更新使用梯度下降来完成。在这个神经网络的前向传播中,通过两个连续的矩阵乘法计算出预测结果,在计算的过程中还对矩阵乘积的结果使用clamp方法进行裁剪,将小于零的值全部重新赋值为0,这就像加上了一个ReLU激活函数的功能。前向传播得到的预测结果通过 y_pred来表示,在得到了预测值后就可以使用预测值和真实值来计算误差值了。我们用loss来表示误差值,对误差值的计算使用了均方误差函数。之后的代码部分就是通过实现后向传播来对权重参数进行优化了,为了计算方便,我们的代码实现使用的是每个节点的链式求导结果,在通过计算之后,就能够得到每个权重参数对应的梯度分别是grad_w1和grad_w2。在得到参数的梯度值之后,按照之前定义好的学习速率对w1和w2的权重参数进行更新,在代码中每次训练时,我们都会对loss的值进行打印输出,以方便看到整个优化过程的效果,所以最后会有20个loss值被打印显示

你可能感兴趣的:(pytorch)