PyTorch,CNN笔记

  1. 对于MNIST数据集,如果用全连接层实现的话,大概需要390K参数;用CNN实现大概60K参数。基于图片的局部相关性,采用权值共享,大大减少了CNN训练所需的参数!权值共享(Weight Sharing)是目前CNN的一个核心!
  2. 卷积核
    PyTorch,CNN笔记_第1张图片
    用于锐化的卷积核
    PyTorch,CNN笔记_第2张图片
    用于模糊的卷积核
    PyTorch,CNN笔记_第3张图片
    用于边缘检测的卷积核
    每个kernel带一个偏置bias!
    卷积最后再连接一个全连接层:将feature map打平,再进行全连接操作!
  3. Batch Normalization
    目前神经网络的激活函数广泛使用的是ReLU,但有时必须要使用sigmoid激活函数,然而sigmoid函数的使用会造成梯度弥散(其导数在x<-4或者x>4时值接近于0),所以输入最好是在[-4,4]的有效空间内,不然梯度会得不到更新,所以需要进行一下等效变换,将输入值控制在某个范围内,使数据大小集中在0附近,方差有较小的范围变动。
    使用BatchNormalization的好处:
    1)梯度更大,收敛速度更快,能更容易搜索到最优解。
    2)性能更好
    3)变得更加稳定,更加健壮,可以更加方便的调整参数(但Deep Learning本身还需要很多trick),可以设置范围更大的learning_rate!
  4. 经典的卷积神经网络
    1. LeNet:注意LeNet的subsampling并不是目前常用的max_pooling和average_pooling.
    2. AlexNet:因为当时的GPU显存问题,所以他使用了两块3GB的GPU进行训练,将kernel手动设置在两块GPU上,但现在PyTorch, TensorFlow等已经可以进行分布式处理了。
    3. VGGNet有6个版本:VGG11, VGG16和VGG19等,最多的达到22层。AlexNet中大多使用的是11 x 11的kernel, kernel大能感受到更多视野,更接近于全连接层;现在的小窗口kernel,如3x3, 1x1等感受视野不仅减少了计算量,训练更快,而且没有精度损失。所以现在都用小窗口的kernel.
    4. GoogLeNet: 对同一层使用了不同尺寸的kernel,从而能够提取局部和全局的信息,最后再进行“级联”统一处理,从而能够应用于某些问题,不过要注意最后级联时feature map的大小要对应起来。
    5. ResNet: 目前应用最广、影响最深的网络。**不能简单的说网络层次越深,效果越好。20层是一个分水岭,20层以前层数越多效果越好;20层以后,由于training会变得非常困难,所以此时层数的叠加反而会导致性能的下降。**之前的神经网络其Unit是:conv -> BN -> Pooling -> ReLU,通过堆叠这样的Unit来形成更深的网络;而ResNet的Unit则是conv-> ReLU -> conv -> ReLU,注意第一个conv和最后一个ReLU有一个短路连接线,这其中可以有pooling也可以没有!
      当下可以直接使用ResNet和InceptionNet!
  5. 神经网络在训练时可能要耗费很长的时间,很可能会因为其他某些外部原因而停止,如果每次都重新开始训练的话,代价太大,所以在train时都是每隔一段时间(一个小时,一天或几个epoch)将中间状态保存为一个checkpoint。
保存:
torch.save(net.state_dict(), 'ckpt.mdl')
xx.state_dict()放回xx类的所有状态,再使用torch.save方法保存到"ckpt.mdl"文件中。
加载checkpoint:
在模型开始训练时如果已经有之前训练的checkpoint就将其加载:
net.load_state_dict(torch.load('ckpt.mdl'))
先用torch.load方法将ckpt.mdl将其加载为PyTorch的一个类,再使用ttorch.load_state_dict将数据加载到model里面去,将网络参数的值每个都初始化为已经训练好的值,这样就不用从头开始训练了!
  1. PyTorch中train和test的状态切换:
    对于dropout和batch normalization来说,train和test时行为是不一样的,这就要求对nn.Module的状态进行切换。
    train状态切换:net.train()
    test状态切换:net.eval()
  2. 用PyTorch实现自己的网络
    很多时候在进行全连接之前,需要进行打平flatten操作,但PyTorch没有提供,需要自己写,不然就得写成两个nn.Sequential,分别调用,太麻烦!
class Flatten(nn.Module):
    def __init__(self):
        super(Flatten, self).__init__()

    def forward(self, input):
        '''
        因为都是按照batch进行训练,而batch_size是第一个维度,所以可以直接这样展开
        '''
        return input.view(input.size(0), -1)

class TestNet(nn.Module):
    def __init__(self):
        super(TestNet, self).__init__()
        self.net = nn.Sequential(
            nn.Conv2d(1,16,stride=1,padding=1),
            nn.MaxPool2d(2,2),
            # 直接调用Flatten()方法
            Flatten(),
            nn.Linear(1*14*14, 10)
        )

    def forward(self, x):
        return self.net(x)
        
  1. 数据增强

你可能感兴趣的:(计算机视觉)