Deep learning 视频分类模型中覆盖stem方法改变滤波通道

Deep learning 视频分类模型中覆盖stem方法改变滤波通道,deep-learning,pytorch,resnet,Deep Learning,Pytorch,Resnet,我试图使用torchvision的视频分类模型,但我的数据是单通道(灰度视频),这些模型使用3通道输入,如果我试图覆盖stem类,请有人确认我所做的是否正确 对于R3D18和MC18stem=BasicStem 对于R(2+1)D: 从RGB切换到灰色时,最简单的方法是更改数据,而不是更改模型: 如果输入帧只有一个通道(灰色),则可以简单地将单通道尺寸标注设置为跨越三个通道。这很简单,允许您按原样使用预先训练的模型 如果您坚持修改模型,则可以在保留大部分预训练权重的同时进行修改: model=

我试图使用torchvision的视频分类模型,但我的数据是单通道(灰度视频),这些模型使用3通道输入,如果我试图覆盖stem类,请有人确认我所做的是否正确

对于R3D18和MC18
stem=BasicStem
对于R(2+1)D:
从RGB切换到灰色时,最简单的方法是更改数据,而不是更改模型:
如果输入帧只有一个通道(灰色),则可以简单地将单通道尺寸标注设置为跨越三个通道。这很简单,允许您按原样使用预先训练的模型


如果您坚持修改模型,则可以在保留大部分预训练权重的同时进行修改:

model=torchvision.models.video.mc3_18(预训练=True)#获得预训练
#仅修改第一个conv层
origc=model.stem[0]#orig conv层
#仅使用一个输入通道构建新层
c1=torch.nn.Conv3d(1,origc.out\u通道,内核大小=origc.kernel\u大小,跨距=origc.stride,padding=origc.padding,bias=origc.bias)
#这是很好的部分-使用原始权重初始化新权重
使用手电筒。无梯度()
c1.weight.data=origc.weight.data.sum(dim=1,keepdim=True)

通过进行此更改,您可以避免使用这些模型的预训练权重-这太可惜了。我只需要在我的数据上从头开始训练这些模型,这不是一开始的认知识别。预先训练的权重非常有用,即使您为不同的任务进行训练。您应该比较预训练和“从头开始”修改通道的性能和训练时间,在我的案例中,使用预训练权重是不幸的,我无法采取的方法,虽然我完全理解您的意思,但我使用的数据是堆叠的无损医学图像,保持它们的原样仍然是优先事项,数据集也使用不同的std偏差和平均值进行规范化,而不是建议用于预训练视频分类。谢谢你的这种方法,因为我没有使用这些模型进行动作识别,我想在我的数据上从头开始训练这些模型,这更具实验性,我也不想复制通道,但我赞赏这种做法。
class BasicStemModified(nn.Sequential):


    def __init__(self):
        super(BasicStemModified, self).__init__(
            nn.Conv3d(1, 45, kernel_size=(7, 7, 1),  #changing filter to 1 channel input
                      stride=(2, 2, 1), padding=(3, 3, 0),
                      bias=False),
            nn.BatchNorm3d(45),
            nn.ReLU(inplace=True),

            nn.Conv3d(45, 64, kernel_size=(1, 1, 3),
                      stride=(1, 1, 1), padding=(0, 0, 1),
                      bias=False),
            nn.BatchNorm3d(64),
            nn.ReLU(inplace=True))


model = torchvision.models.video.mc3_18(pretrained=False)

model.stem = BasicStemModified() #here assigning the modified stem


model.fc = nn.Sequential(
    nn.Dropout(0.3),
    nn.Linear(model.fc.in_features, num_classes)
)


model.to('cuda:0')
#For R(2+1)D model `stem=R2Plus1dStem`

class R2Plus1dStemModified(nn.Sequential):
    """R(2+1)D stem is different than the default one as it uses separated 3D convolution
    """
    def __init__(self):
        super(R2Plus1dStemModified, self).__init__(
            nn.Conv3d(3, 45, kernel_size=(1, 7, 7),   #changing filter to 1 channel input
                      stride=(1, 2, 2), padding=(0, 3, 3),
                      bias=False),
            nn.BatchNorm3d(45),
            nn.ReLU(inplace=True),
            nn.Conv3d(45, 64, kernel_size=(3, 1, 1),
                      stride=(1, 1, 1), padding=(1, 0, 0),
                      bias=False),
            nn.BatchNorm3d(64),
            nn.ReLU(inplace=True))

model = torchvision.models.video.mc3_18(pretrained=False)

model.stem = R2Plus1dStemModified() #here assigning the modified stem

model.fc = nn.Sequential(
    nn.Dropout(0.3),
    nn.Linear(model.fc.in_features, num_classes)
)


model.to('cuda:0')