Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The reward goes down #51

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ This repo contains the Pytorch implementation of the AAAI'18 paper - [Deep Reinf

The main requirements are [pytorch](http://pytorch.org/) (`v0.4.0`) and python `2.7`. Some dependencies that may not be installed in your machine are [tabulate](https://pypi.org/project/tabulate/) and [h5py](https://github.com/h5py/h5py). Please install other missing dependencies.

## TODO
1. Edit README
2. Reconstruct Repository
3. ~~Add KTS(Kernel Temporal Segmentation)~~
4. Edit code for test

## Get started
1. Download preprocessed datasets
```bash
Expand All @@ -16,6 +22,11 @@ cd pytorch-vsumm-reinforce
wget http://www.eecs.qmul.ac.uk/~kz303/vsumm-reinforce/datasets.tar.gz
tar -xvzf datasets.tar.gz
```
* If can't download, open following link.(I loaded same dataset in my onedrive)
```
https://onedrive.live.com/?authkey=%21AO1tsqjDVCeakGg&cid=6FD3437627D709EE&id=6FD3437627D709EE%212809&parId=root&action=locate
```

2. Make splits
```bash
python create_split.py -d datasets/eccv16_dataset_summe_google_pool5.h5 --save-dir datasets --save-name summe_splits --num-splits 5
Expand All @@ -25,13 +36,23 @@ As a result, the dataset is randomly split for 5 times, which are saved as json
Train and test codes are written in `main.py`. To see the detailed arguments, please do `python main.py -h`.

## How to train
* Edit config/config.py ( see config/README.txt )

```bash
python main.py -d datasets/eccv16_dataset_summe_google_pool5.h5 -s datasets/summe_splits.json -m summe --gpu 0 --save-dir log/summe-split0 --split-id 0 --verbose
python video_summarization.py
```
## How to evaluate
* Edit config/config.py ( see config/README.txt )

```bash
python video_summarization.py
```

## How to test
* Edit config/config.py ( see config/README.txt )

```bash
python main.py -d datasets/eccv16_dataset_summe_google_pool5.h5 -s datasets/summe_splits.json -m summe --gpu 0 --save-dir log/summe-split0 --split-id 0 --evaluate --resume path_to_your_model.pth.tar --verbose --save-results
python video_summarization.py
```

If argument `--save-results` is enabled, output results will be saved to `results.h5` under the same folder specified by `--save-dir`. To visualize the score-vs-gtscore, simple do
Expand Down Expand Up @@ -73,6 +94,7 @@ Please remember to specify the naming format of your video frames on this [line]
## How to use your own data
We preprocess data by extracting image features for videos and save them to `h5` file. The file format looks like [this](https://github.com/KaiyangZhou/vsumm-reinforce/issues/1#issuecomment-363492711). After that, you can make split via `create_split.py`. If you wanna train policy network using the entire dataset, just do `train_keys = dataset.keys()`. [Here](https://github.com/KaiyangZhou/pytorch-vsumm-reinforce/blob/master/main.py#L75) is the code where we initialize dataset. If you have any problems, feel free to contact me by email or raise an `issue`.


## Citation
```
@article{zhou2017reinforcevsumm,
Expand All @@ -81,4 +103,4 @@ We preprocess data by extracting image features for videos and save them to `h5`
journal={arXiv:1801.00054},
year={2017}
}
```
```
34 changes: 34 additions & 0 deletions config/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Configuration README
====================

1. example config to train
# Dataset options
DATASET = 'datasets/eccv16_dataset_summe_google_pool5.h5'
SPLIT = 'datasets/summe_splits.json'
SPLIT_ID = 0
METRIC = 'summe'

# Misc
GPU = '0'
EVALUATE = False
TEST = False
VERBOSE = True
SAVE_DIR = 'log/summe-split0'

2. example config to evaluate
# Dataset options
DATASET = 'datasets/eccv16_dataset_summe_google_pool5.h5'
SPLIT = 'datasets/summe_splits.json'
SPLIT_ID = 0
METRIC = 'summe'

# Misc
GPU = '0'
EVALUATE = True
TEST = False
RESUME = 'log/summe-split0/model_epoch60.pth.tar'
VERBOSE = True
SAVE_DIR = 'log/summe-split0'
SAVE_RESULT = True

3. example config to test
1 change: 1 addition & 0 deletions config/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from config import *
32 changes: 32 additions & 0 deletions config/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# ============ TRAIN CONFIG ==============
# Dataset options
DATASET = 'datasets/eccv16_dataset_summe_google_pool5.h5' # path to h5 dataset (required)
SPLIT = 'datasets/summe_splits.json' # path to split file (required)
SPLIT_ID = 0 # split index (default: 0)
METRIC = 'summe' # evaluation metric ['tvsum', 'summe'])

# Model options
INPUT_DIM = 1024 # input dimension (default: 1024)
HIDDEN_DIM = 256 # hidden unit dimension of DSN (default: 256)
NUM_LAYERS = 1 # number of RNN layers (default: 1)
RNN_CELL = 'lstm' # RNN cell type (default: lstm)

# Optimization options
LR = 1e-05 # learning rate (default: 1e-05)
WEIGHT_DECAY = 1e-05 # weight decay rate (default: 1e-05)
MAX_EPOCH = 60 # maximum epoch for training (default: 60)
STEP_SIZE = 30 # how many steps to decay learning rate (default: 30)
GAMMA = 0.1 # learning rate decay (default: 0.1)
NUM_EPISODE = 5 # number of episodes (default: 5)
BETA = 0.01 # weight for summary length penalty term (default: 0.01)

# Misc
SEED = 1 # random seed (default: 1)
GPU = '0' # which gpu devices to use (default: 0)
USE_CPU = False # use cpu device
EVALUATE = False # whether to do evaluation only
TEST = False # whether to do evaluation only
RESUME = '' # path to resume file
VERBOSE = True # whether to show detailed test results
SAVE_DIR = 'log/summe-split0' # path to save output (default: log/)
SAVE_RESULTS = True # whether to save output results
38 changes: 22 additions & 16 deletions create_split.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
# Dataset Split

from __future__ import print_function

import os
import os.path as osp
import argparse
import h5py
import math
import numpy as np

from utils import write_json
from utils.file_process import write_json

parser = argparse.ArgumentParser("Code to create splits in json form")
parser.add_argument('-d', '--dataset', type=str, required=True, help="path to h5 dataset (required)")
parser.add_argument('--save-dir', type=str, default='datasets', help="path to save output json file (default: 'datasets/')")
parser.add_argument('--save-name', type=str, default='splits', help="name to save as, excluding extension (default: 'splits')")
parser.add_argument('--num-splits', type=int, default=5, help="how many splits to generate (default: 5)")
parser.add_argument('--train-percent', type=float, default=0.8, help="percentage of training data (default: 0.8)")
parser.add_argument("-d", "--dataset", type=str, required=True, help="path to h5 dataset (required)")
parser.add_argument("--save-dir", type=str, default='datasets', help="path to save output jon file (default: 'datasets/'")
parser.add_argument("--save-name", type=str, default="splits", help="name to save as, excluding extension (default: 'splits')")
parser.add_argument("--num-splits", type=int, default=5, help="how many splits to generate (default: 5)")
parser.add_argument("--train-percent", type=float, default=0.8, help="percentage of training data (default: 0.8)")

args = parser.parse_args()

def split_random(keys, num_videos, num_train):
"""Random split"""
""" Random split """
train_keys, test_keys = [], []
rnd_idxs = np.random.choice(range(num_videos), size=num_train, replace=False)

for key_idx, key in enumerate(keys):
if key_idx in rnd_idxs:
train_keys.append(key)
Expand All @@ -32,29 +35,32 @@ def split_random(keys, num_videos, num_train):
return train_keys, test_keys

def create():
print("==========\nArgs:{}\n==========".format(args))
print("===========\nArgs:{}\n=========".format(args))
print("Goal: randomly split data for {} times, {:.1%} for training and the rest for testing".format(args.num_splits, args.train_percent))
print("Loading dataset from {}".format(args.dataset))
print("Loading dataset from: {}".format(args.dataset))

dataset = h5py.File(args.dataset, 'r')
keys = dataset.keys()
num_videos = len(keys)
num_train = int(math.ceil(num_videos * args.train_percent))
num_test = num_videos - num_train
print("Split breakdown: # total videos {}. # train videos {}. # test videos {}".format(num_videos, num_train, num_test))
print("Split breakdown: # total videos {}. # train videos. # test videos {}".format(num_videos, num_train, num_test))
splits = []

for split_idx in range(args.num_splits):
train_keys, test_keys = split_random(keys, num_videos, num_train)

splits.append({
'train_keys': train_keys,
'test_keys': test_keys,
})
})

saveto = osp.join(args.save_dir, args.save_name + '.json')
write_json(splits, saveto)
print("Splits saved to {}".format(saveto))
save_path = os.path.join(args.save_dir, args.save_name + '.json')
write_json(splits, save_path)
print("Splits save to {}".format(save_path))

dataset.close()

if __name__ == '__main__':
create()
create()

Loading