个人认为神经网络的的搭建代码虽然很简单,但是确实最为重要的一部分。话不多说,开始介绍。
神经网络的定义其实很简单,就是两部分,这个是基本的套路。
1)_init_() 初始化网络,定义网络的一些参数,以及他的层结构
2)forward() 定义层结构之间的关系
可能没太看明白,没关系看了代码你就会很清晰了
小demo:
import torch
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module): #所有的模型都是Module的子类,都继承了他
def __init__(self): #类中定义的函数都有个参数self
super(Net,self).__init__()
self.conv1=nn.Conv2d(3,6,5)
#定义了一个卷积层,三个参数分别代表,输入的通道数,输出的#通道数(也就是过滤器的个数),还有过滤器的大小
self.pool=nn.MaxPool2d(2,2) #定义一个池化层,两个参数分别代表过滤器的大小和步长
self.conv2=nn.Conv2d(6,16,5)
self.fc1=nn.Linear(16*5*5,120) #定义一个全连接层
self.fc2=nn.Linear(120,84)
self.fc3=nn.Linear(84,10)
def forward(self,x): #定义各个层之间的关系
x=self.pool(F.relu(self.conv1(x))) #F.relu()是非线性激活函数
x=self.pool(F.relu(self.conv2(x)))
x=x.view(-1,16*5*5)
#x.view()是将数据展开在进入全连接层之前对数据进行处理,第一个参数-1表示这个参数由其他的参数决定,比如知道矩阵的总元素个数还有他的列数你就会知道他的行数,第二个参#数是全连接层的输入
x=F.relu(self.fc1(x))
x=F.relu(self.fc2(x))
x=self.fc3(x)
return x
#实例化,创建一个网络
net=Net()
print net
参考官方的文档你会发现在torch.nn这个模块中也有非线性激活函数,然而在上述代码中我们使用的是torch.nn.functinal 中的激活函数。二者的区别:
torch.nn中的激活函数是使用类定义的
torch.nn.functional中的激活函数是普通的def() 定义的函数。
如果我们需要保存每一步激活的数据的话,需要学习参数的话就需要使用torch.nn中的激活函数,其他情况下二者没有什么区别。
刚开始这块我没太明白,在一个同学的帮助下,得到了解决。
下边是他给我的解答过程。
通过类定义的对象在训练的过程里边是一直保留着的,里边的参数可以跟随学习调整,达到优化的目的,函数的话每次运算只留下运算结果,里边的参数不会记住这次运算的情况,不会变化,再调用都是一样的效果,里边不会有可以学习的参数。
比如那个卷积层,卷积核的参数保存在对象里,对象不销毁,里边的变量就一直保留在内存里,你可以迭代一次,就在之前的基础上更新下他们,函数的话,调用的时候即使修改了里边的变量,也留不下来,下次再调用跟上次没关系
加油,当你看到我的博客的时候,相信你一定在努力成为最好的自己的路上!
加油,别放弃,坚持,每天一点点,相信一年后的你一定会感谢现在的你!
如果你真的迷茫了,我愿当你的倾听者,但是你千万不能放弃,因为改变命运的机会真的不多呀!
QQ小号:1817780086