Pytorch-6:建立一个CNN

  1. 继承 nn.Module ,建立一个 network class
  2. 在 network class 的构造函数中定义== layers 为 类的属性(attributes)==
  3. 用 layers 属性和 nn.functional 的方法来定义forward()

torch.nn.Module 类

神经网络 和 神经网络的layers 都继承自 torch.nn.module 。

forward method 是 nn.module 类的一个 method。它指的是tensor进入network,通过所有 layers 直到 output 的过程。Forward method 可以是对应整个神经网络的提法,也可以是对一个 layer 的提法。forward method中经常使用 nn.functional 类下的内容。

Time to build one network

import torch.nn as nn

class Network(nn.Module):
	def __init__(self):
		super(Network, self).__init()##do not forget
		self.conv1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5)
		self.conv1 = nn.Conv2d(in_channels=6, out_channels=12, kernel_size=5)
		
		self.fc1 = nn.Linear(in_features=12*4*4, out_features=120)
		self.fc2 = nn.Linear(in_features=120, out_features=60)
		self.out = nn.Linear(in_features=120, out_features=10)
		
	def forward(self, t):
		#implement forward
		return t

注意,全连接层 fully connected layer = dense layer = linear layer,在pytorch 里,是 nn.Linear .

如何 implement forward() 呢?

先弄清 learnable parameters。Learnale parameters一般是随机指定的,神经网络在学习中获取适合的 learnable parameters 值,以获得更小的 loss。PyTorch中,learnable parameters 是 Parameter 类的对象。

Learnale parameters在哪儿?

network = Network()

print(network)					#-> 网络结构
print(network.conv1)			#-> conv1层结构
print(network.conv1.weight)		#-> conv1层的 learnable parameters

weight 的 shape 跟网络结构(超参数)有关,观察一下shape :

for name, param in network.named_parameters():
	print(name, '\t\t', param.shape)

观察得,卷积层 conv 的 learnable parameters 的 shape 是 torch.Size([out_channels, in_channels, kernel_size, kernel_size]),全连接层的learnable parameters 的 shape 是 torch.Size([out_features, in_features]),而且本示例网络每层都有bias,bias也是 learnable parameters ,shape 是 torch.Size([out_features])

Forward()

调用forward()时,直接将数据传入实例中来调用forward(t),而不是调用forward(),原理在 nn.module 类 源码中:

def __call__(self, *input, **kwargs):
   result = self.forward(*input, **kwargs)
   for hook in self._forward_hooks.values():
       #将注册的hook拿出来用
       hook_result = hook(self, input, result)
   ...
   return result

一个forward()的例子:

def forward(self, t):
	#input layer
	t=t
	
	#hidden conv layer
	t = sef.conv1(t)
	t = F.relu(t)
	t = F.max_pool2d(t, kernel_size=2, stride=2)

	#hidden conv layer
	t = sef.conv2(t)
	t = F.relu(t)
	t = F.max_pool2d(t, kernel_size=2, stride=2)

	#hidden linear layer
	t = t.reshape(-1, 12 * 4 * 4)
	t = self.fc1(t)
	t = F.relu(t)

	#hidden linear layer
	t = self.fc2(t)
	t = F.relu(t)

	#output layer
	t = self.out(y)
	#t = F.softmax(t) Softmax会在计算crossentropy时自动实现,不在输出层中实施

	return t

进行一次forward propagation测试

因为只是测试而已,我并不打算更新 learnable weights ,所以这里我要关闭梯度计算,节省内存。

torch.set_grad_enabled(False)

#创建网络实例
network = Network()

#传入一张图片,train_set 是 FashionMNIST 中 trainset 的dataloader实例化对象
sample = next(iter(train_set))
image, label = sample
image.shape 					#-> torch.Size([1, 28, 28])

#network总是接受一个batch的图像,即使这个batch只有一张图,所以输入的Rank必须是4
image.unsqueeze(0).shape 		#-> torch.Size([1, 1, 28, 28]),batchsize = 1

pred = network(image.unsqueeze(0))#-> torch.Size([1, 10]),输出的10个数对应十个类别的可能性

pred.argmax(dim=1)				#-> tensor([2])由于没训练,这个值随机

F.softmax(pred, dim=1)			#-> torch.Size([1, 10]),使 pred 的十个元素和为1,使输出对应可能性,并且能够使用crossenropy
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值