Skip to content

Commit a708cd3

Browse files
authored
Add LRW-1000 inference code
1 parent e5cdf6d commit a708cd3

File tree

8 files changed

+1610
-0
lines changed

8 files changed

+1610
-0
lines changed

eval_lrw1000/cvtransforms.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# coding: utf-8
2+
import random
3+
import cv2
4+
import numpy as np
5+
import torch
6+
7+
8+
def ColorNormalize(img):
9+
mean = 0.413621
10+
std = 0.1700239
11+
img = (img - mean) / std
12+
13+
return img
14+
15+
16+
def SeqCutout(seq, n_holes=1):
17+
h = seq.shape[-2]
18+
w = seq.shape[-1]
19+
20+
# length = h // 8
21+
length = 3 * h // 16
22+
23+
for n in range(n_holes):
24+
y = np.random.randint(h)
25+
x = np.random.randint(w)
26+
27+
y1 = np.clip(y - length, 0, h)
28+
y2 = np.clip(y + length, 0, h)
29+
x1 = np.clip(x - length, 0, w)
30+
x2 = np.clip(x + length, 0, w)
31+
32+
seq[:, :, y1: y2, x1: x2] = 0.
33+
34+
return seq

eval_lrw1000/eval_lrw1000.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# coding: utf-8
2+
import os, sys
3+
import time
4+
5+
import argparse
6+
import numpy as np
7+
8+
import torch
9+
import torch.nn as nn
10+
from torch.utils.data import DataLoader
11+
12+
from models.classifier import C3D_ResNet
13+
from word_dataset import *
14+
from cvtransforms import *
15+
16+
17+
def get_dataloader(args):
18+
dsets = {x: LRW1000FaceDataset(x, args.dataset, args.color_space, args.max_timesteps)
19+
for x in ['test', 'val']}
20+
dset_loaders = {x: DataLoader(dsets[x], batch_size=args.batch_size, shuffle=True, num_workers=args.workers, pin_memory=True, drop_last=(x == 'train')) for x in ['test', 'val']}
21+
dset_sizes = {x: len(dsets[x]) for x in ['test', 'val']}
22+
23+
return dset_loaders, dset_sizes
24+
25+
26+
def test(args, use_gpu):
27+
dset_loaders, dset_sizes = get_dataloader(args)
28+
29+
model = C3D_ResNet(mode=args.mode, inputDim=512, hiddenDim=args.hidden_num, nLayers=args.rnn_layers, nClasses=1000, frameLen=args.max_timesteps, backend=args.backend, every_frame=args.every_frame, color_space=args.color_space, use_cbam=args.cbam)
30+
criterion = nn.CrossEntropyLoss()
31+
32+
if use_gpu:
33+
torch.backends.cudnn.benchmark = True
34+
model = model.cuda()
35+
criterion = criterion.cuda()
36+
37+
pretrained_dict = torch.load(args.ckpt_path)
38+
model = nn.DataParallel(model)
39+
model.load_state_dict(pretrained_dict['state_dict'], strict=False)
40+
model.eval()
41+
42+
# Evaluation loop.
43+
running_loss, running_corrects, running_all = 0., 0., 0.
44+
phase = 'test'
45+
with torch.no_grad():
46+
for batch_idx, (inputs, targets) in enumerate(dset_loaders[phase]):
47+
inputs = inputs.float()
48+
if use_gpu:
49+
inputs, targets = inputs.cuda(), targets.cuda()
50+
51+
outputs = model(inputs)
52+
if args.every_frame:
53+
outputs = torch.mean(outputs, 1)
54+
preds = torch.argmax(outputs, dim=1)
55+
loss = criterion(outputs, targets)
56+
57+
cur_loss = loss.item()
58+
running_loss += cur_loss * inputs.size(0)
59+
running_corrects += torch.sum(preds == targets).item()
60+
running_all += inputs.size(0)
61+
running_acc = running_corrects / running_all
62+
63+
if batch_idx == 0:
64+
since = time.time()
65+
elif batch_idx % 100 == 0 or batch_idx == len(dset_loaders[phase]) - 1:
66+
print ('Process: [{:5.0f}/{:5.0f} ({:.0f}%)]\tLoss: {:.4f}\tAcc: {:.4f}\tElapsed: {:5.0f}s\tETA: {:5.0f}s\r'.format(
67+
running_all,
68+
len(dset_loaders[phase].dataset),
69+
100. * batch_idx / (len(dset_loaders[phase])-1),
70+
running_loss / running_all,
71+
running_acc,
72+
time.time()-since,
73+
(time.time()-since)*(len(dset_loaders[phase])-1) / batch_idx - (time.time()-since)))
74+
75+
epoch_loss = running_loss / len(dset_loaders[phase].dataset)
76+
epoch_acc = running_corrects / len(dset_loaders[phase].dataset)
77+
print ('Test loss: {:.4f}\tAcc: {:.4f}'.format(epoch_loss, epoch_acc) + '\n')
78+
79+
80+
def main():
81+
# Settings
82+
parser = argparse.ArgumentParser(description='LRW-1000 Face VSR Evaluation Code')
83+
parser.add_argument('--gpus', default='0', help='device to use')
84+
parser.add_argument('--ckpt_path', default='lrw1000_cutout_rgb_gru.pt', help='path to pretrained model')
85+
parser.add_argument('--dataset', default='/scratch/zhangyuanhang/LRW1000_v2', help='path to dataset')
86+
87+
parser.add_argument('--mode', default='finetuneCE', help='backendCE, finetuneCE')
88+
parser.add_argument('--backend', default='gru', help='gru, tcn')
89+
parser.add_argument('--color_space', default='rgb', help='color space: rgb, gray')
90+
parser.add_argument('--every_frame', default=False, action='store_true', help='prediction based on every frame')
91+
parser.add_argument('--cbam', default=False, action='store_true', help='use CBAM in ResNet blocks')
92+
93+
parser.add_argument('--max_timesteps', default=30, type=int, help='maximum number of timesteps')
94+
parser.add_argument('--hidden_num', default=512, type=int, help='number of hidden units in the RNN')
95+
parser.add_argument('--rnn_layers', default=2, type=int, help='number of hidden layers in the RNN')
96+
97+
parser.add_argument('--batch_size', default=36, type=int, help='mini-batch size (default: 36)')
98+
parser.add_argument('--workers', default=16, type=int, help='number of data loader workers (default: 16)')
99+
100+
args = parser.parse_args()
101+
print (vars(args))
102+
103+
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpus
104+
use_gpu = torch.cuda.is_available()
105+
test(args, use_gpu)
106+
107+
108+
if __name__ == '__main__':
109+
110+
main()
111+
# Usage:
112+
# python3 eval_lrw1000.py --gpus 2,3 --dataset /scratch/zhangyuanhang/LRW1000_v2 --mode finetuneCE --backend gru --batch_size 128
113+

0 commit comments

Comments
 (0)