深度学习:莫烦python:
torch&numpy很像,不过后者一开始要import里面会多出一个as np。除此之外,其有关数学的符号也是一致的,不过就是前缀不一样。矩阵相乘:maymul(data,data)mm(tensor,tensor)。其中torch中的dot是将数字展平,依次相乘。
细节内容,如何模拟,细节变化有哪些:
BP算法:刚刚在看的时候可以查看了一下该算法,我了解到其又名正向传播和误差反向传播的算法。也就是说,先正向传播,若是输出的实际值与期望值不符合就将其差值进行反向传播,分配到每一层的每一个单元进行匹配,其会发送误差信号,进而利用梯度下降法进行校正权值和阈值,使误差减小到最低()直至梯度为0)
介绍Variable(from torch.autograd import Variable,这是一种库和类的区别),这是一种变量,其实我们网络中所定义的参数就是一个个变量,利用这个能够使参数根据BP算法等各种梯度算法实现数值的调整。
其实tensor就是torch的数值。variable=Variable(tensor,requires_grad=True),这个句子就是指将v中的tensor进行映射,放到另一个篮子里,然后形成一定的关系,此关系是一个单元和另一个单元的关系。一个计算节点。requires_grad如果是true,那么就意味着要将所反向传播得到的误差进行梯度处理反馈到这个变量上,进行校正。
tensor和variable中,后者如果true可以反向传播 .由于variable中的值都为tensor,所以如果想要转化成numpy不能直接转化,如variable.numpy错误,需要变为variable.data.numpy
为什么需要激励函数?:
解决不能用线性方程解决的问题。给出一个线性方程,然后利用AF()将线性方程掰弯,使其变成非线性的方程,其中AF()可以有多种形式。activation function AF()就是激励函数。如果是少层的神经网络——多种选择;如果是卷积神经网络——Relu;如果是循环神经网络——Relu/tanh (激励函数的全部代码可以从莫烦python网站中找到所写的全部代码)
(普通神经网络出来结果)线性----->非线性(满足复杂性),条件是AF()激励函数。
nn是指神经网络import torch.nn.functional as F,后面as是一种简洁命名。
torch.linspace是将区间内分成多少个线段进行绘图。x=Variable(x)指的是将x放在V这个大篮子里,但是matplotlib不能直接识别tensor的数据,所以需要转化成numpy的数据,用到x_np=x.data.numpy() x.data是将tensor存放到data里面
激励函数的激活值(softmax是激励函数,但不是用来作图的,是用来做统计的)。在深度学习这一块,画图不是关键,所以其程序完全可以直接复制就好。
import matplotlib.pyplot as plt
二、做神经网络——回归&分类
dim=1指的就是维度为1。 torch.unsqueeze就是将一维转化成二维,torch只能处理二维的数据x=torch.unsqueeze(torch.linspace(-1,1,100),dim=1)。神经网络只能识别variable,所以将x,y=Variable(x),Variable(y) 变成variable的形式。#plt.scatter(x.data.numpy(),y.data.numpy())前面那个是生成散点图,但由于画图只能识别numpy的数据,所以将torch的数据转化成numpy的数据。plt.show()打印图#
class主要是用来定义的,此处定义了一个网络Net。括号里面就是主要的模块,可以直接调用Module里面的框架
1.calss Net(torch.nn.Module):
2. def _init_(self,n_feature,n_hidden,n_output): #_init_主要是存放我们需要的一些信息
3. super(Net,self)._init_() #1~3是官方操作;此句也就是将net调用再返回自身使用_init_#
4. self.hidden=torch.nn.Linear(n_feature,n_hidden) #每一层对应一种属性,此处n_xxxx指的是xxxx的数目#并且init中并没有搭建这些网络,不过是进行了一些参数的定义。
5. self.predict=torch.nn.Linear(n_hidden,n_output) #此处定义的是输出层
6. def forward(self,x): #是一个过程,调用前面init中提到的信息进行向前传播。 真正对于网络的搭建是在此处#此处x指的是输入个数/输入的量
7. x=F.relu(self.hidden(x)) #从里向外看,指的是将x输入到隐藏层,输出了n个神经节,将输出的n个神经节进行激活/使用激活函数.
8. x=self.predict(x) #此处的x是7中的x(隐藏层出来的),然后输入到输出层,进行输出.此处不用AF()的原因是因为 会将输出值进行截断一部分,使输出结果不全面,一般不用。
9. return x
上文1~9就是一个简易的网络被搭成。
优化神经网络optimizer
1.optimizer=torch.optim.SGD(net.parameters(),lr=0.5) #optim中有很多优化函数,此处选用了一个叫做SGD的。由于是优化嘛,所以我们此处要将神经网络的参数(net.parameters())放入,lr指的是学习效率,其值不能太高也不能太低,一般就小于1.
2.loss_func=torch.nn.MSELoss() #loss_func指的就是误差的计算,MSELoss指的是均方差计算,用来处理回归问题足够了。
3.for t in range(100): #训练的步数
4.loss=loss_func(prediction,y) #误差计算,一定要预测值在前,因为是预测—y
#接下来就是优化的步骤#
5.optimizer.zero_grad() #optimizer就是优化函数,zero_grad就是将net中上一节的参数进行梯度降为0
6.loss.backward() #将参数的梯度下降作为信号传递到各个节点上去
7.optimizer.step() #优化每一步,以学习效率0.5进行优化。将这些梯度施加到各个神经网络参数里面
#进行可视化的步骤,需要额外添加程序#
if t%5==0 #进行5次#
plt.cla()
plt.scatter(x.data.numpy(),y.data.numpy())
plt.plot(x.data.numpy(),prediction.data.numpy(),'r-','lw=5')
plt.text(0.5,0,'Loss=%.4f'%loss.data[0],fontdict={'size':20,'color':'red':})
plt.pause(0.1)
plt.ioff()
plt.show()
分类问题
分类的代码总体上和回归很像,只不过改变了数据那一块+网络输出和输入参数特征那一块(不再是1.而是多个,输入特征为多少,输出特征就为多少[0,1][1,0][0,0,1][1,0,0])
损失函数不用改变,但是优化函数需要变成ClassEntropy,向标签误差[0,0,1]进行优化,如变为[0.1,0.2,0.7]=1。学习效率也要进行改变,因为分类的只有进行慢才能看清,故改为0.02
输出也发生了一些改变,不再是参数,而是类似于[-2,0.12,17]这种形式。所以最后要转化成参数的形式[0.1,0.2,0.7],故而采用了prediction=torch.max(F.softmax(out),1)[1],所取形式为1的
快速搭建法
在前期我们利用了class定义了一个net1,如果我们要输出一个(2,10,2)的这样一个结构,我们只需要调用torch中的Sequential,然后层就用Linnear定义,其中要加一个torch.nn,nn便是指的神经层。其中关于激活函数ReLU,前者我们是定义了nn.functional,然后在这里面进行了F.relu的调用且relu为小写,没有进行命名,故而没有value,没有值。而后者的调用里面,直接用大写m,且是从nn.ReLU中进行调用,是一种类,所以有命名。
保存提取
编写+训练好,如何进行将神经网络保存和提取:
保留整个神经网络(架构+训练):
def save()
#save net1
net1=torch.nn.Sequential(
torch.nn.Linear(1,10)
torch.nn.ReLU()
torch.nn.Linear(10,1)
)
optimizer=torch.optim.SGD(net1.parameters(),lr=0.5) #训练它的所有参数,在下面训练100步
loss_fun=torch.nn.MSELoss() #↑是网络的框架
for t in range(100):
prediction=net1(x)
loss=loss_func(prediction,y)
optimizer.zero_grad()
loss.backward()
optimizer.step() #↑进行训练,训练100次
#巡连好以后,保存整个图+训练过程#
torch.save(net1,'net.pkl')#entire net
#不保留计算图或整个东西,只保留图节点的参数#
torch.save(net1.state_dict(),'net_params.pkl') # parameters
提取
def restore_net():
net2=torch.load('net.pkl') #首先先定义一个神经网络net2,进行提取网络
def restore_params():
net3=torch.nn.Sequential( #此处是将net1的参数进行提取,所以需要将net1的网络给先copy过来
torch.nn.Linear(1,10),
torch.nn.ReLU(),
torch.nn.Linear(10,1)
)
net3.load_state_dict(torch.load('net_params.pkl')) #此方法要比将网络提取更快一些,所以建议多采用这种提取参数的方法。
# entire save
save()
#restore entire net
restore_net()
#restore only the net parameters
restore_params()
批训练
数据大,只训练其中一小部分,一部分一部分训练,更快更有效率
import torch
import torch.utils,data as data #批训练的一部分数据
BATCH_SIZE=5 #从里面5个5个抽取
x=torch.linear(1,10,10)# 1-->10
y=
torch_datatest=Data.TensorDataset(data_tensor=x,target_tensor=y) #建立一个数据库,存放数据,data_tensor为进行训练的数据,target_tensor为进行算误差的数据
loader = Data.Dataloder(
dataset=torch_dataset,
batch_size=BATCH_SIZE,
shuffle=Ture, #是否将数据打乱进行随机抽取
num_workers=2 #有两种数据
) #使训练变成一小批一小批
for epoch in range(3): #训练3次,每次两份10/5
for step,(batch_x,batch_y) in enumerate(loader): #enumerate是给loader施加一个索引,按照step这样一步步来的
#training........打印需要显示的东西
print('Epoch:',epoch,'| Step:',step,'| batch x:',batch_x.numpy,'| batch_y',batch_y.numpy())
优化器Optimizer加速神经网络
SGD(Stochastic Gradient Descent)
其他训练,是在参数哪里动手脚,w+=-learning rate*rate(yuanxian)
momentum 就是一种在参数做手脚(下坡),m=b1*m-learning rate*dx,W+=m
AdaGrad在学习率上动手脚(不好走的鞋子),v+=dx^2,W+=-Learning rate*dx/根号v
RMSProp:
Adam: m=b1*m+(1-b1)*dx,v=b2*v+(1-b2)*dx^2,W+=-Learning rate*m/
优化器
神将网络中参数一个一个优化
#different nets,用不同优化器优化,for循环进行一个个训练
net_SGD= Net()
net_Momentum=Net()
net_RMSprop=Net()
net_Adam=Net()
opt_SGD = torch.optim.SGD(net_SGD.parameters(),lr=LR)
opt_Momentum =torch.optim.SGD(net_Momentum.parameters(),lr=LR,momentum=0.8)
opt_RMSprop =torch.optim.RMSprop(net_RMSprop.parameters(),lr=LR,alpha=0.9)
opt_Adam =torch.optim.Adam(net_Adam.parameters(),lr=LR,betas=(0.9,0.99))
optimizers =[opt_SGD,opt_Momentum,opt_RMSprop.opt_Adam]
#开始训练#
loss_func=torch.nn.MSELoss()#误差计算
losses_his=[[],[],[],[]] #record loss
for epoch in range(EPOCH):
print(epoch)
for step,(batch_x,batch_y) in enumerate(loader):
b_x=Variable(batch_x) #因为x都是tensor的形式,所以用variable将其包起来
b_y=Variable(batch_y)
for net,opt,l_his in zip(nets,optimizers,losses_his): #()里面的是三个不同的list,所以将它们每一个提取出来进行一个训练,分别训练几个不同网络。
output=net(b_x)
loss=loss_func(output,b_y) #get output for every net
opt,zero_grad() #clear gradients for next train
loss.backward() #backprogation,compute gradients
opt.step() #apply gradients
l_his.append(loss.data[0]) #loss recoder
#↑以上是训练的流程,适用于所有#
最后将其进行打印
什么是卷积神经网络CNN?
对图片中一小部分区域进行处理,然后累计。不是对整个像素进行处理。
批量过滤器——>在图片上滚动,将整合的信息处理得到更具体的一些信息,然后hi产生一些边缘信息,再不断不断滚动,得到更高级的图片,最后放入全连接层进行分类,得到图片。
图片有高度,因为颜色——卷积的过程就是将图片进行不断增高压缩的过程,会得到更多的边缘信息。为了更准确,很多时候卷积层不压缩,而是将压缩的过程交给池化。
CNN卷积神经网络
import torch
import torch.nn as nn #为了简化,直接利用nn.nn来进行构建神经层
from torch.autograd import Variable
import torch.utils.data as Data
import torchvision #一个库,里面包含了很多图片和数据的
import matplotlib.pyplot as plt
#Hyper Parameters
EPOCH=1 #train the training data n times,to save time,we just train 1 epoch
......
train_data=torchvision.datasets.MNIST( #MNIST是一个下载的代码,你可以去网上下载
root='./mnist', #将这个保存,保存到root里面