修改C3D
刚跑起来就激动地发文了,只能跑起来,识别准确率还没有研究。
基本上就是修改
mypath.py
dataset.py
train.py
inference.py
ucf_labels.txt这几个文件
ucf_labels.txt
首先我是在ucf101基础之上修改的,所以我修改了ucf_labels.txt这个文件中的标签换成了我的分类标签。
mypath.py
然后更换mypath.py的路径,视频预处理的路径肯定要改:
预训练模型我没有加载,空着的,我发现这个预训练路径即使写错了找不到文件也不会报错,并且没有发现运行结果中有提到是否加载了预训练模型。
dataset.py
主要是数据如果已经预处理过了记得把preprocess改成False,不然每次都很麻烦要处理视频,当然第一次是要True的。
还有一个问题是我看到很多教程提到使用自己的数据集要重写len和getitem两个方法,这个我还没搞明白,还没改。
train.py
更改了这个分类,我的只有3类,不知道是否有用,后面改inference.py还是需要改num_classes。
inference.py
这个困我最久的文件,首先原来加载ucf101的init model部分是这样的
# init model
model = C3D_model.C3D(num_classes=101)
checkpoint = torch.load('./run/run_5/models/C3D-ucf101_epoch-24.pth.tar', map_location=lambda storage, loc: storage)
model.load_state_dict(checkpoint['state_dict'])#模型参数
# optimizer.load_state_dict(checkpoint['opt_dict'])#优化参数
model.to(device)
model.eval()
但是报错是这样的,
RuntimeError: Error(s) in loading state_dict for C3D:
size mismatch for fc8.weight: copying a param with shape torch.Size([3, 4096]) from checkpoint, the shape in current model is torch.Size([101, 4096]).
size mismatch for fc8.bias: copying a param with shape torch.Size([3]) from checkpoint, the shape in current model is torch.Size([101]).
我开始只知道百度RuntimeError: Error(s) in loading state_dict for C3D:,就是找不出问题,后来才知道这里重点在后面两行size,而且是在看过这位大佬的博文 Pytorch遇到权重不匹配的问题之后才猛然察觉3和101这两个数字多么巧合,哈哈之前怎么没发现。
发现源代码上有部分注释掉的应该就是这个作用,我先把注释取消掉运行了一下试试看
# init model
model = C3D_model.C3D(num_classes=101)
checkpoint = torch.load('./run/run_5/models/C3D-ucf101_epoch-24.pth.tar', map_location=lambda storage, loc: storage)
state_dict = model.state_dict()
for k1, k2 in zip(state_dict.keys(), checkpoint.keys()):
state_dict[k1] = checkpoint[k2]
model.load_state_dict(state_dict)
model.to(device)
model.eval()
报这个错
AttributeError: 'int' object has no attribute 'shape'
最后按照博文修改,这样
# init model
model = C3D_model.C3D(num_classes=3)
pretrained_dict = torch.load('./run/run_5/models/C3D-ucf101_epoch-24.pth.tar', map_location=lambda storage, loc: storage)
model_dict = model.state_dict()
# 重新制作预训练的权重,主要是减去参数不匹配的层,楼主这边层名为“fc”
pretrained_dict = {k: v for k, v in pretrained_dict.items() if (k in model_dict and 'fc' not in k)}
# 更新权重
model_dict.update(pretrained_dict)
model.load_state_dict(model_dict)
model.to(device)
model.eval()
终于可以运行,后来发现。。。。好像就是num_classes=3这个的问题。。。
另外,read video的路径一定要写对,写不对的话就会奇怪怎么运行也没报错但是就是没有result框呢!这个代码最让人难受的就是他没有can not find file类似的报错,预训练模型也是,就有点小小的恼火吧。
# read video
video = 'UCF-101/climb/climb7.mp4'
cap = cv2.VideoCapture(video)
retaining = True
使用tensorboard
终端输入tensorboard --logdir=run
即可,还能多个run进行对比,很好用