- import torch
- from torch import nn
- layer = nn.Conv2d(2, 3, kernel_size=3, stride=1, padding=0)
- layer.weight
可以看到输出的有三组(因为有三种卷积核),每组有两个3乘3的卷积核(因为输入有两个通道)。- """2维的卷积层,用于图片的卷积"""
- # 输入图像的通道数=1(灰度图像),卷积核的种类数=3
- # 卷积核的shape是3乘3的,扫描步长为1,不加padding
- layer = nn.Conv2d(1, 3, kernel_size=3, stride=1, padding=0)
-
- """使用上面定义的卷积层layer和输入x,完成一次卷积的前向运算"""
- out = layer.forward(x)
特别注意,在使用时应该直接使用layer(x)而不是layer.forward(x),因为前者实际是调用了__call__(),而PyTorch在这个函数中定义了一些hooks,如果要使用这些钩子的功能就只能用前者了!它会先运行hooks再运行.forward()函数。- print(layer.weight)
- print(layer.bias)
- print(layer.weight.shape)
- print(layer.bias.shape)
- """手动定义卷积核(weight)和偏置"""
- w = torch.rand(16, 3, 5, 5) # 16种3通道的5乘5卷积核
- b = torch.rand(16) # 和卷积核种类数保持一致(不同通道共用一个bias)
- """2D卷积得到输出"""
- out = F.conv2d(x, w, b, stride=1, padding=1) # 步长为1,外加1圈padding
- # 池化层(池化核为2*2,步长为2),最大池化
- layer = nn.MaxPool2d(2, stride=2)
- 使用函数式接口:# 池化运算(池化核为2*2,步长为2),平均池化
- out = F.avg_pool2d(x, 2, stride=2)
- # 向上采样,放大2倍,最近插值
- out = F.upsample(x, scale_factor=2, mode='nearest') # 旧的接口
- print(out.shape)
-
- out = F.interpolate(x, scale_factor=2, mode='nearest') # 新的接口
- # ReLU激活,inplace=True表示直接覆盖掉ReLU目标的内存空间
- layer = nn.ReLU(inplace=True)
- out = layer(x)
- # ReLU激活
- out = F.relu(x)
- # Batch Normalization层,因为输入是将高度H和宽度W合成了一个维度,所以这里用1d
- layer = nn.BatchNorm1d(16) # 传入通道数
- out = layer(x)
-
- # 全局的均值mu
- print(layer.running_mean)
- # 全局的方差sigma^2
- print(layer.running_var)
使用了Batch Normalization让Converge(收敛)的速度加快了,可以直观理解,使用了靠近0的部分的Sigmoid激活,其梯度信息更大了。并且能够得到一个更好的解。
提升了Robust(鲁棒性),这使得网络更加稳定,理解:如果参数有大有小,解空间像左边一样,那么稍微调整学习率可能就发生抖动,或者训练速度太慢,这让超参数的调整没有那么敏感。