Commit 72b4361c by Ting PAN

add examples/cifar10

1 parent 5c8da7f9
# Dragon Zoo
This page contains various implements for Dragon.
We demonstrate that our framework is much easier to make full use of the works that are already done,
which was described in our arXiv paper: [Dragon: A Computation Graph Virtual Machine Based Deep Learning Framework](https://arxiv.org/abs/1707.08265)
## <a name="list-of-examples"></a>List of examples
* [cifar10](https://github.com/neopenx/Dragon/tree/master/examples/cifar10) - How to train/infer a basic classification network [**Caffe1** Style]
CIFAR-10 [Caffe1 style]
=====================================
### Runtime Requirements for Python
0. Package: lmdb
1. Package: python-opencv
-----
Prepare the Dataset
-------------------
- download ``cifar-10-python.tar.gz`` from [http://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz](http://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz)
- copy to data folder
```Shell
cp cifar-10-python.tar.gz cifar/data
```
- gen db files
```Shell
cd cifar10
python gen_lmdb.py
```
Train "Quick/Full" Model
-------------------
- Quick
```Shell
cd cifar10
python solve_quick.py
```
- Full
```Shell
cd cifar10
python solve_full.py
```
Infer "Quick" Model after Training
-------------------
```Shell
cd cifar10
python infer.py
```
name: "CIFAR10_quick"
input: "data"
input_shape {dim: 1 dim: 3 dim: 32 dim: 32}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 32
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.0001
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 3
stride: 2
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "pool1"
top: "pool1"
}
layer {
name: "norm1"
type: "LRN"
bottom: "pool1"
top: "norm1"
lrn_param {
local_size: 3
alpha: 5e-05
beta: 0.75
norm_region: WITHIN_CHANNEL
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "norm1"
top: "conv2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 32
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu2"
type: "ReLU"
bottom: "conv2"
top: "conv2"
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: AVE
kernel_size: 3
stride: 2
}
}
layer {
name: "norm2"
type: "LRN"
bottom: "pool2"
top: "norm2"
lrn_param {
local_size: 3
alpha: 5e-05
beta: 0.75
norm_region: WITHIN_CHANNEL
}
}
layer {
name: "conv3"
type: "Convolution"
bottom: "norm2"
top: "conv3"
convolution_param {
num_output: 64
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu3"
type: "ReLU"
bottom: "conv3"
top: "conv3"
}
layer {
name: "pool3"
type: "Pooling"
bottom: "conv3"
top: "pool3"
pooling_param {
pool: AVE
kernel_size: 3
stride: 2
}
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool3"
top: "ip1"
param {
lr_mult: 1
decay_mult: 250
}
param {
lr_mult: 2
decay_mult: 0
}
inner_product_param {
num_output: 10
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
}
}
}
\ No newline at end of file
net: "cifar10_full_train_test.prototxt"
test_iter: 100
test_interval: 1000
test_initialization: false
base_lr: 0.001
momentum: 0.9
weight_decay: 0.004
lr_policy: "multistep"
stepvalue: 60000
stepvalue: 65000
gamma: 0.1
display: 200
max_iter: 70000
snapshot: 10000
snapshot_prefix: "snapshots/cifar10_full"
\ No newline at end of file
name: "CIFAR10_full"
layer {
name: "cifar"
type: "Data"
top: "data"
top: "label"
include {phase: TRAIN}
transform_param {
mean_value: 104.00698793
mean_value: 116.66876762
mean_value: 122.67891434
mirror: false
}
data_param {
source: "data/train_lmdb"
batch_size: 100
}
}
layer {
name: "cifar"
type: "Data"
top: "data"
top: "label"
include {phase: TEST}
transform_param {
mean_value: 104.00698793
mean_value: 116.66876762
mean_value: 122.67891434
}
data_param {
source: "data/test_lmdb"
batch_size: 100
}
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 32
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.0001
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 3
stride: 2
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "pool1"
top: "pool1"
}
layer {
name: "norm1"
type: "LRN"
bottom: "pool1"
top: "norm1"
lrn_param {
local_size: 3
alpha: 5e-05
beta: 0.75
norm_region: WITHIN_CHANNEL
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "norm1"
top: "conv2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 32
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu2"
type: "ReLU"
bottom: "conv2"
top: "conv2"
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: AVE
kernel_size: 3
stride: 2
}
}
layer {
name: "norm2"
type: "LRN"
bottom: "pool2"
top: "norm2"
lrn_param {
local_size: 3
alpha: 5e-05
beta: 0.75
norm_region: WITHIN_CHANNEL
}
}
layer {
name: "conv3"
type: "Convolution"
bottom: "norm2"
top: "conv3"
convolution_param {
num_output: 64
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu3"
type: "ReLU"
bottom: "conv3"
top: "conv3"
}
layer {
name: "pool3"
type: "Pooling"
bottom: "conv3"
top: "pool3"
pooling_param {
pool: AVE
kernel_size: 3
stride: 2
}
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool3"
top: "ip1"
param {
lr_mult: 1
decay_mult: 250
}
param {
lr_mult: 2
decay_mult: 0
}
inner_product_param {
num_output: 10
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "accuracy"
type: "Accuracy"
bottom: "ip1"
bottom: "label"
top: "accuracy"
include {
phase: TEST
}
}
layer {
name: "loss"
type: "SoftmaxWithLoss"
bottom: "ip1"
bottom: "label"
top: "loss"
}
name: "CIFAR10_quick"
input: "data"
input_shape {dim: 1 dim: 3 dim: 32 dim: 32}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 32
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.0001
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 3
stride: 2
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "pool1"
top: "pool1"
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 32
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu2"
type: "ReLU"
bottom: "conv2"
top: "conv2"
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: AVE
kernel_size: 3
stride: 2
}
}
layer {
name: "conv3"
type: "Convolution"
bottom: "pool2"
top: "conv3"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 64
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu3"
type: "ReLU"
bottom: "conv3"
top: "conv3"
}
layer {
name: "pool3"
type: "Pooling"
bottom: "conv3"
top: "pool3"
pooling_param {
pool: AVE
kernel_size: 3
stride: 2
}
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool3"
top: "ip1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 64
weight_filler {
type: "gaussian"
std: 0.1
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu4"
type: "ReLU"
bottom: "ip1"
top: "ip1"
}
layer {
name: "ip2"
type: "InnerProduct"
bottom: "ip1"
top: "ip2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 10
weight_filler {
type: "gaussian"
std: 0.1
}
bias_filler {
type: "constant"
}
}
}
\ No newline at end of file
net: "cifar10_quick_train_test.prototxt"
test_iter: 100
test_interval: 500
test_initialization: false
base_lr: 0.001
momentum: 0.9
weight_decay: 0.004
lr_policy: "step"
stepsize: 4000
gamma: 0.1
display: 100
max_iter: 5000
snapshot: 500
snapshot_prefix: "snapshots/cifar10_quick"
\ No newline at end of file
name: "CIFAR10_quick"
layer {
name: "cifar"
type: "Data"
top: "data"
top: "label"
include {phase: TRAIN}
transform_param {
mean_value: 104.00698793
mean_value: 116.66876762
mean_value: 122.67891434
mirror: false
}
data_param {
source: "data/train_lmdb"
batch_size: 100
}
}
layer {
name: "cifar"
type: "Data"
top: "data"
top: "label"
include {phase: TEST}
transform_param {
mean_value: 104.00698793
mean_value: 116.66876762
mean_value: 122.67891434
}
data_param {
source: "data/test_lmdb"
batch_size: 100
}
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 32
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.0001
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 3
stride: 2
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "pool1"
top: "pool1"
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 32
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu2"
type: "ReLU"
bottom: "conv2"
top: "conv2"
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: AVE
kernel_size: 3
stride: 2
}
}
layer {
name: "conv3"
type: "Convolution"
bottom: "pool2"
top: "conv3"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 64
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu3"
type: "ReLU"
bottom: "conv3"
top: "conv3"
}
layer {
name: "pool3"
type: "Pooling"
bottom: "conv3"
top: "pool3"
pooling_param {
pool: AVE
kernel_size: 3
stride: 2
}
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool3"
top: "ip1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 64
weight_filler {
type: "gaussian"
std: 0.1
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu4"
type: "ReLU"
bottom: "ip1"
top: "ip1"
}
layer {
name: "ip2"
type: "InnerProduct"
bottom: "ip1"
top: "ip2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 10
weight_filler {
type: "gaussian"
std: 0.1
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "accuracy"
type: "Accuracy"
bottom: "ip2"
bottom: "label"
top: "accuracy"
include {
phase: TEST
}
}
layer {
name: "loss"
type: "SoftmaxWithLoss"
bottom: "ip2"
bottom: "label"
top: "loss"
}
This directory holds (*after you download them*):
- cifar-10-python.tar.gz ([download link](http://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz))
- demo (folder contains demo images)
- extract (folder contains image files and labels, generated by **gen_lmdb.py**)
- train_lmdb (db file, generated by **gen_lmdb.py**)
- test_lmdb (db file, generated by **gen_lmdb.py**)
# --------------------------------------------------------
# Cifar-10 for Dragon
# Copyright(c) 2017 SeetaTech
# Written by Ting Pan
# --------------------------------------------------------
""" Generate database """
import os
import sys
import time
import shutil
import tarfile
import cv2
from dragon.tools.db import LMDB
from dragon.vm.caffe.proto import caffe_pb2
ZFILL = 8
def untar(tar_file):
t = tarfile.open(tar_file)
t.extractall(path='data')
def extract_images():
prefix = 'data/cifar-10-batches-py'
extract_path = 'data/extract'
if not os.path.exists(os.path.join(extract_path, 'JPEGImages')):
os.makedirs(os.path.join(extract_path, 'JPEGImages'))
if not os.path.exists(os.path.join(extract_path, 'ImageSets')):
os.makedirs(os.path.join(extract_path, 'ImageSets'))
batches = [os.path.join(prefix, 'data_batch_{}'.format(i)) for i in xrange(1, 6)]
batches += [os.path.join(prefix, 'test_batch')]
total_idx = 0
images_list = []
# process batches
for batch in batches:
with open(batch, 'rb') as f:
if sys.version_info >= (3, 0):
import pickle
with open(batch, 'rb') as f:
dict = pickle.load(f, encoding='bytes')
else:
import cPickle
with open(batch, 'rb') as f:
dict = cPickle.load(f)
for item_idx in xrange(len(dict['labels'])):
im = dict['data'][item_idx].reshape((3, 32, 32))
label = dict['labels'][item_idx]
im = im.transpose((1, 2, 0))
im = im[:, :, ::-1]
filename = str(total_idx).zfill(ZFILL) + '.jpg'
cv2.imwrite(os.path.join(extract_path, 'JPEGImages', filename), im)
images_list.append((filename, str(label)))
total_idx += 1
# make list
with open(os.path.join(extract_path, 'ImageSets', 'train.txt'), 'w') as f:
for i in xrange(50000):
item = images_list[i][0] + ' ' + images_list[i][1]
if i != 49999: item += '\n'
f.write(item)
with open(os.path.join(extract_path, 'ImageSets', 'test.txt'), 'w') as f:
for i in xrange(50000, 60000):
item = images_list[i][0] + ' ' + images_list[i][1]
if i != 59999: item += '\n'
f.write(item)
def make_db(image_path, label_path, database_path):
if os.path.isfile(label_path) is False:
raise ValueError('input path is empty or wrong.')
if os.path.isdir(database_path) is True:
raise ValueError('the database path is already exist.')
print 'start time: ', time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime())
db = LMDB(max_commit=10000)
db.open(database_path, mode='w')
total_line = sum(1 for line in open(label_path))
count = 0
zfill_flag = '{0:0%d}' % (ZFILL)
encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 95]
start_time = time.time()
with open(label_path, 'r') as input_file:
for record in input_file:
count += 1
if count % 10000 == 0:
now_time = time.time()
print '{0} / {1} in {2:.2f} sec'.format(
count, total_line, now_time - start_time)
db.commit()
record = record.split()
path = record[0]
label = record[1]
img = cv2.imread(os.path.join(image_path ,path))
result, imgencode = cv2.imencode('.jpg', img, encode_param)
datum = caffe_pb2.Datum()
datum.height, datum.width, datum.channels = img.shape
datum.label = int(label)
datum.encoded = True
datum.data = imgencode.tostring()
db.put(zfill_flag.format(count - 1), datum.SerializeToString())
now_time = time.time()
print '{0} / {1} in {2:.2f} sec'.format(count, total_line, now_time - start_time)
db.put('size', str(count))
db.put('zfill', str(ZFILL))
db.commit()
db.close()
shutil.copy(label_path, database_path + '/image_list.txt')
end_time = time.time()
print '{0} images have been stored in the database.'.format(total_line)
print 'This task finishes within {0:.2f} seconds.'.format(
end_time - start_time)
print 'The size of database is {0} MB.'.format(
float(os.path.getsize(database_path + '/data.mdb') / 1000 / 1000))
if __name__ == '__main__':
untar('data/cifar-10-python.tar.gz')
extract_images()
make_db('data/extract/JPEGImages',
'data/extract/ImageSets/train.txt',
'data/train_lmdb')
make_db('data/extract/JPEGImages',
'data/extract/ImageSets/test.txt',
'data/test_lmdb')
# --------------------------------------------------------
# Cifar-10 for Dragon
# Copyright(c) 2017 SeetaTech
# Written by Ting Pan
# --------------------------------------------------------
""" Infer for a single Image and show """
import dragon.vm.caffe as caffe
import numpy as np
import cv2
classes = ['airplane', 'automobile', 'bird', 'cat', 'deer',
'dog', 'frog', 'horse', 'ship', 'truck']
# init
caffe.set_mode_gpu()
# load net
net = caffe.Net("cifar10_quick_deploy.prototxt",
'snapshots/cifar10_quick_iter_5000.caffemodel', caffe.TEST)
def load_image(filename):
# load image, subtract mean, and make dims 1 x 1 x H x W
im = cv2.imread(filename)
im = cv2.resize(im, (32, 32))
im = np.array(im, dtype=np.float32)
im -= np.array((104.0, 116.0, 122.0))
im = im.transpose((2,0,1))
return im[np.newaxis, :, :, :]
def run(filename):
# infer
im = load_image(filename)
net.forward(**{'data': im})
score = net.blobs['ip2'].data.get_value()[0]
pred = score.argmax(0)
# show
print classes[pred]
if __name__ == '__main__':
run('data/demo/cat.jpg')
# --------------------------------------------------------
# Cifar-10 for Dragon
# Copyright(c) 2017 SeetaTech
# Written by Ting Pan
# --------------------------------------------------------
""" Train a cifar-10 net """
import dragon.vm.caffe as caffe
if __name__ == '__main__':
# init
caffe.set_mode_gpu()
# solve
solver = caffe.SGDSolver('cifar10_full_solver.prototxt')
solver.step(5000)
solver.snapshot()
\ No newline at end of file
# --------------------------------------------------------
# Cifar-10 for Dragon
# Copyright(c) 2017 SeetaTech
# Written by Ting Pan
# --------------------------------------------------------
""" Train a cifar-10 net """
import dragon.vm.caffe as caffe
if __name__ == '__main__':
# init
caffe.set_mode_gpu()
# solve
solver = caffe.SGDSolver('cifar10_quick_solver.prototxt')
solver.step(5000)
solver.snapshot()
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!