Skip to content

Commit

Permalink
add PaddlePaddle demo (#91)
Browse files Browse the repository at this point in the history
* init paddle

* add image writer

* change sample numble to 4

* add image and conv image

* add histogram

* rename test file
  • Loading branch information
jacquesqiao authored Jan 12, 2018
1 parent 53a3c04 commit 2b614d3
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 8 deletions.
188 changes: 188 additions & 0 deletions demo/paddle/cifar10_image_classification_vgg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
from __future__ import print_function

import sys

import paddle.v2 as paddle
import paddle.v2.fluid as fluid
import paddle.v2.fluid.framework as framework
from paddle.v2.fluid.param_attr import ParamAttr
from paddle.v2.fluid.initializer import NormalInitializer
from visualdl import LogWriter
import numpy as np

logdir = "./tmp"
logwriter = LogWriter(logdir, sync_cycle=10)

with logwriter.mode("train") as writer:
loss_scalar = writer.scalar("loss")

with logwriter.mode("train") as writer:
acc_scalar = writer.scalar("acc")

num_samples = 4
with logwriter.mode("train") as writer:
conv_image = writer.image("conv_image", num_samples, 1)
input_image = writer.image("input_image", num_samples, 1)

with logwriter.mode("train") as writer:
param1_histgram = writer.histogram("param1", 100)


def resnet_cifar10(input, depth=32):
def conv_bn_layer(input, ch_out, filter_size, stride, padding, act='relu'):
tmp = fluid.layers.conv2d(
input=input,
filter_size=filter_size,
num_filters=ch_out,
stride=stride,
padding=padding,
act=None,
bias_attr=False)
return fluid.layers.batch_norm(input=tmp, act=act)

def shortcut(input, ch_in, ch_out, stride):
if ch_in != ch_out:
return conv_bn_layer(input, ch_out, 1, stride, 0, None)
else:
return input

def basicblock(input, ch_in, ch_out, stride):
tmp = conv_bn_layer(input, ch_out, 3, stride, 1)
tmp = conv_bn_layer(tmp, ch_out, 3, 1, 1, act=None)
short = shortcut(input, ch_in, ch_out, stride)
return fluid.layers.elementwise_add(x=tmp, y=short, act='relu')

def layer_warp(block_func, input, ch_in, ch_out, count, stride):
tmp = block_func(input, ch_in, ch_out, stride)
for i in range(1, count):
tmp = block_func(tmp, ch_out, ch_out, 1)
return tmp

assert (depth - 2) % 6 == 0
n = (depth - 2) / 6
conv1 = conv_bn_layer(
input=input, ch_out=16, filter_size=3, stride=1, padding=1)
res1 = layer_warp(basicblock, conv1, 16, 16, n, 1)
res2 = layer_warp(basicblock, res1, 16, 32, n, 2)
res3 = layer_warp(basicblock, res2, 32, 64, n, 2)
pool = fluid.layers.pool2d(
input=res3, pool_size=8, pool_type='avg', pool_stride=1)
return pool


def vgg16_bn_drop(input):
def conv_block(input, num_filter, groups, dropouts):
return fluid.nets.img_conv_group(
input=input,
pool_size=2,
pool_stride=2,
conv_num_filter=[num_filter] * groups,
conv_filter_size=3,
conv_act='relu',
conv_with_batchnorm=True,
conv_batchnorm_drop_rate=dropouts,
pool_type='max')

conv1 = conv_block(input, 64, 2, [0.3, 0])
conv2 = conv_block(conv1, 128, 2, [0.4, 0])
conv3 = conv_block(conv2, 256, 3, [0.4, 0.4, 0])
conv4 = conv_block(conv3, 512, 3, [0.4, 0.4, 0])
conv5 = conv_block(conv4, 512, 3, [0.4, 0.4, 0])

drop = fluid.layers.dropout(x=conv5, dropout_prob=0.5)
fc1 = fluid.layers.fc(input=drop, size=512, act=None)
bn = fluid.layers.batch_norm(input=fc1, act='relu')
drop2 = fluid.layers.dropout(x=bn, dropout_prob=0.5)
fc2 = fluid.layers.fc(input=drop2, size=512, act=None)
return fc2, conv1


classdim = 10
data_shape = [3, 32, 32]

images = fluid.layers.data(name='pixel', shape=data_shape, dtype='float32')
label = fluid.layers.data(name='label', shape=[1], dtype='int64')

net_type = "vgg"
if len(sys.argv) >= 2:
net_type = sys.argv[1]

if net_type == "vgg":
print("train vgg net")
net, conv1 = vgg16_bn_drop(images)
elif net_type == "resnet":
print("train resnet")
net = resnet_cifar10(images, 32)
else:
raise ValueError("%s network is not supported" % net_type)

predict = fluid.layers.fc(input=net, size=classdim, act='softmax',
param_attr=ParamAttr(name="param1", initializer=NormalInitializer()))
cost = fluid.layers.cross_entropy(input=predict, label=label)
avg_cost = fluid.layers.mean(x=cost)

optimizer = fluid.optimizer.Adam(learning_rate=0.001)
opts = optimizer.minimize(avg_cost)

accuracy = fluid.evaluator.Accuracy(input=predict, label=label)

BATCH_SIZE = 16
PASS_NUM = 1

train_reader = paddle.batch(
paddle.reader.shuffle(
paddle.dataset.cifar.train10(), buf_size=128 * 10),
batch_size=BATCH_SIZE)

place = fluid.CPUPlace()
exe = fluid.Executor(place)
feeder = fluid.DataFeeder(place=place, feed_list=[images, label])
exe.run(fluid.default_startup_program())

step = 0
sample_num = 0

start_up_program = framework.default_startup_program()

param1_var = start_up_program.global_block().var("param1")

for pass_id in range(PASS_NUM):
accuracy.reset(exe)
for data in train_reader():
loss, conv1_out, param1, acc = exe.run(fluid.default_main_program(),
feed=feeder.feed(data),
fetch_list=[avg_cost, conv1, param1_var] + accuracy.metrics)
pass_acc = accuracy.eval(exe)

if sample_num == 0:
input_image.start_sampling()
conv_image.start_sampling()

idx1 = input_image.is_sample_taken()
idx2 = conv_image.is_sample_taken()
assert idx1 == idx2
idx = idx1
if idx != -1:
image_data = data[0][0]
input_image_data = np.transpose(image_data.reshape(data_shape), axes=[1, 2, 0])
input_image.set_sample(idx, input_image_data.shape, input_image_data.flatten())

conv_image_data = conv1_out[0][0]
conv_image.set_sample(idx, conv_image_data.shape, conv_image_data.flatten())

sample_num += 1
if sample_num % num_samples == 0:
input_image.finish_sampling()
conv_image.finish_sampling()
sample_num = 0

loss_scalar.add_record(step, loss)
acc_scalar.add_record(step, acc)
param1_histgram.add_record(step, param1.flatten())

print("loss:" + str(loss) + " acc:" + str(acc) + " pass_acc:" + str(
pass_acc))
step += 1
# this model is slow, so if we can train two mini batch, we think it works properly.
# exit(0)
exit(1)
18 changes: 11 additions & 7 deletions visualdl/logic/sdk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,18 @@ struct is_same_type<T, T> {
void Image::SetSample(int index,
const std::vector<shape_t>& shape,
const std::vector<value_t>& data) {
std::vector<shape_t> new_shape = shape;
if (shape.size() == 2) {
new_shape.emplace_back(1);
}
// production
int size = std::accumulate(
shape.begin(), shape.end(), 1., [](int a, int b) { return a * b; });
new_shape.begin(), new_shape.end(), 1., [](int a, int b) { return a * b; });
CHECK_GT(size, 0);
CHECK_EQ(shape.size(), 3)
CHECK_LE(new_shape.size(), 3)
<< "shape should be something like (width, height, num_channel)";
CHECK_LE(shape.back(), 3);
CHECK_GE(shape.back(), 2);
CHECK_LE(new_shape.back(), 3);
CHECK_GE(new_shape.back(), 1);
CHECK_EQ(size, data.size()) << "image's shape not match data";
CHECK_LT(index, num_samples_);
CHECK_LE(index, num_records_);
Expand All @@ -116,8 +120,8 @@ void Image::SetSample(int index,
for (int i = 0; i < data.size(); i++) {
data_str[i] = data[i];
}
Uint8Image image(shape[2], shape[0] * shape[1]);
NormalizeImage(&image, &data[0], shape[0] * shape[1], shape[2]);
Uint8Image image(new_shape[2], new_shape[0] * new_shape[1]);
NormalizeImage(&image, &data[0], new_shape[0] * new_shape[1], new_shape[2]);
// entry.SetRaw(std::string(data_str.begin(), data_str.end()));
entry.SetRaw(
std::string(image.data(), image.data() + image.rows() * image.cols()));
Expand All @@ -127,7 +131,7 @@ void Image::SetSample(int index,
"value_t should not use int64_t field, this type is used to store shape");

// set meta.
entry.SetMulti(shape);
entry.SetMulti(new_shape);

// // set meta with hack
// Entry<shape_t> meta;
Expand Down
4 changes: 3 additions & 1 deletion visualdl/server/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,9 @@ def get_invididual_image(storage, mode, tag, step_index, max_size=80):

shape = record.shape()

data = np.array(record.data(), dtype='uint8').reshape(record.shape())
if shape[2] == 1:
shape = [shape[0], shape[1]]
data = np.array(record.data(), dtype='uint8').reshape(shape)
tempfile = NamedTemporaryFile(mode='w+b', suffix='.png')
with Image.fromarray(data) as im:
size = max(shape[0], shape[1])
Expand Down
1 change: 1 addition & 0 deletions visualdl/server/storage_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def add_image(writer,
image_writer.set_sample(index, shape, list(data))
image_writer.finish_sampling()


def add_histogram(writer, mode, tag, num_buckets):
with writer.mode(mode) as writer:
histogram = writer.histogram(tag, num_buckets)
Expand Down

0 comments on commit 2b614d3

Please sign in to comment.