cs231n assignment2 PyTorch

Barebones PyTorch

Three-Layer ConvNet

使用pytorch抽象等级1的方式实现卷积神经网络。

three_layer_convnet()

out1 = F.conv2d(x, conv_w1, bias=conv_b1, stride=1, padding=(2,2))
relu1 = F.relu(out1)
out2 = F.conv2d(relu1, conv_w2, bias=conv_b2, stride=1, padding=(1,1))
relu2 = F.relu(out2)
scores = torch.mm(flatten(relu2), fc_w) + fc_b

Training a ConvNet

使用上面完成的卷积神经网络,训练模型。下面需要完成初始化参数。

conv_w1 = random_weight((channel_1,3,5,5))
conv_b1 = zero_weight((channel_1,))
conv_w2 = random_weight((channel_2,channel_1,3,3))
conv_b2 = zero_weight((channel_2,))
fc_w = random_weight((32*32*channel_2,10))
fc_b = zero_weight((10,))

PyTorch Module API

接下来的代码使用nn.Module来完成,与上面的代码进行比较可以发现,使用nn.Module的代码更具有层次性,符合面向对象的编程思想。并且在上面的代码中,需要手动实现参数初始化,但是在下面的代码中可以直接通过nn的函数来实现。

class ThreeLayerConvNet

def __init__(self, in_channel, channel_1, channel_2, num_classes):
    super().__init__()
	self.conv1 = nn.Conv2d(in_channel, channel_1, kernel_size=5,stride=1, padding=2)
    nn.init.kaiming_normal_(self.conv1.weight)
    self.conv2 = nn.Conv2d(channel_1, channel_2, kernel_size=3, stride=1,padding=1)
    nn.init.kaiming_normal_(self.conv2.weight)
    self.fc = nn.Linear(channel_2 * 32 * 32, num_classes)
    nn.init.kaiming_normal_(self.fc.weight)
def forward(self, x):
	scores = None
	relu1 = F.relu(self.conv1(x))
	relu2 = F.relu(self.conv2(relu1))
	scores = self.fc(flatten(relu2)
	return scores

Module API: Train a Three-Layer ConvNet

使用已经写好的网络,训练一个模型,使之在CIFAR10的准确率达到45%以上。
PyTorch.ipynb

in_channel = 3
num_classes = 10
model = ThreeLayerConvNet(in_channel=in_channel, channel_1=channel_1, channel_2=channel_2, num_classes=num_classes)
optimizer = optim.SGD(model.parameters(), lr=learning_rate, momentum=0.9)

Part IV. PyTorch Sequential API

可以从上面的代码中发现,使用模块API需要完成在__init__中的定义,以及在forward函数中实现每一层的连接。下面使用Sequential API,它把所有步骤合成为一个了,这也就决定了他的灵活性不如Module API,但是对于绝大多数场景来说是够用了。

model = nn.Sequential(
    nn.Conv2d(3,channel_1,kernel_size=5, padding=2, bias=True),
    nn.ReLU(),
    nn.Conv2d(channel_1, channel_2, kernel_size=3, padding=1, bias=True),
    nn.ReLU(),
    Flatten(),
    nn.Linear(channel_2 * 32 * 32, 10, bias=True)
)
optimizer = optim.SGD(model.parameters(), momentum=0.9, lr=learning_rate, nesterov=True)

Part V. CIFAR-10 open-ended challenge

使用自定义的网络结构,完成对CIFAR-10数据集的训练和分类,使之准确率达到70%以上,我才用的结构为
[conv-relu-pool]xN -> [affine]xM -> [softmax or SVM]

channel_1 = 20
channel_2 = 30
learning_rate=0.001

model = nn.Sequential(
    nn.Conv2d(3, 32, kernel_size=5, stride=1, padding=2),
    nn.ReLU(),
    nn.MaxPool2d(2, 2),
    nn.Conv2d(32, 64, kernel_size=5, stride=1, padding=2),
    nn.ReLU(),
    nn.MaxPool2d(2, 2),
    nn.Conv2d(64, 128, kernel_size=5, stride=1, padding=2),
    nn.ReLU(),
    nn.MaxPool2d(2, 2),
    Flatten(),
    nn.Linear(128 * 4 * 4, 20),
    nn.Linear(20, 10)
)
optimizer = optim.Adam(model.parameters(), lr=learning_rate)

最后的准确率有76%


搭建卷积神经网络需要注意的事项

在搭建网络的过程中,要注意每一层的结构大小,需要按照一定的公式进行计算。

卷积层:

F为卷积核大小,W为图片的宽,H为图片的高,S为步长,P为padding大小
D:图像深度(通道数),N:卷积核(过滤器)个数

卷积层后输出的大小为:
	W' = (W - F + 2P)/S + 1
	H' = (H - F + 2P)/S + 1 
卷积后输出图像深度:
	N' = N

池化层:

    W:图像宽,H:图像高,D:图像深度(通道数)
    F:卷积核宽高,S:步长

池化后的大小为:
	 W=(W-F)/S+1
     H=(H-F)/S+1
池化后输出图像深度:
	 N' = D(保持上一层不变)
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值