Skip to content

Commit 6997238

Browse files
author
Aaron Wuwf
committed
SINGA-161 DLaaS
Wrap SINGA into a Docker image, which can run in a mesos cluster Can run in training and testing modes.
1 parent d547a86 commit 6997238

File tree

14 files changed

+620
-141
lines changed

14 files changed

+620
-141
lines changed

include/singa/neuralnet/neuron_layer.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ class DropoutLayer : public NeuronLayer {
112112
*/
113113
Blob<float> mask_;
114114
};
115+
115116
/**
116117
* This layer is dummy and do no real work.
117118
* It is used for testing purpose only.
@@ -126,7 +127,7 @@ class DummyLayer: public NeuronLayer {
126127
void Setup(const LayerProto& proto, const vector<Layer*>& srclayers) override;
127128
void ComputeFeature(int flag, const vector<Layer*>& srclayers) override;
128129
void ComputeGradient(int flag, const vector<Layer*>& srclayers) override;
129-
void Feed(int batchsize, vector<float>& data, vector<int>& aux_data);
130+
void Feed(vector<int> shape, vector<float>* data, int op);
130131
Layer* ToLayer() { return this;}
131132

132133
private:
@@ -278,7 +279,7 @@ class PoolingLayer : public NeuronLayer {
278279
int kernel_x_, pad_x_, stride_x_;
279280
int kernel_y_, pad_y_, stride_y_;
280281
int batchsize_, channels_, height_, width_, pooled_height_, pooled_width_;
281-
PoolingProto_PoolMethod pool_;
282+
PoolMethod pool_;
282283
};
283284
/**
284285
* Use book-keeping for BP following Caffe's pooling implementation

src/neuralnet/neuron_layer/dummy.cc

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,25 +78,53 @@ void DummyLayer::ComputeGradient(int flag, const vector<Layer*>& srclayers) {
7878
Copy(grad_, srclayers[0]->mutable_grad(this));
7979
}
8080

81-
void DummyLayer::Feed(int batchsize, vector<float>& data, vector<int>& aux_data){
81+
void DummyLayer::Feed(vector<int> shape, vector<float>* data, int op){
8282

83-
batchsize_ = batchsize;
84-
// input data
85-
if (data.size() > 0) {
86-
int size = data.size();
83+
//batchsize_ = batchsize;
84+
batchsize_ = shape[0];
85+
// dataset
86+
if (op == 0) {
87+
/*
88+
size_t hdim = 1;
89+
for (size_t i = 1; i < shape.size(); ++i)
90+
hdim *= shape[i];
91+
//data_.Reshape({batchsize, (int)hdim});
92+
//shape.insert(shape.begin(),batchsize);
93+
data_.Reshape(shape);
94+
*/
95+
//reshape data
96+
data_.Reshape(shape);
97+
CHECK_EQ(data_.count(), data->size());
98+
99+
int size = data->size();
87100
float* ptr = data_.mutable_cpu_data();
88101
for (int i = 0; i< size; i++) {
89-
ptr[i] = data.at(i);
102+
ptr[i] = data->at(i);
90103
}
91104
}
92-
// auxiliary data, e.g., label
93-
if (aux_data.size() > 0) {
105+
// label
106+
else {
94107
aux_data_.resize(batchsize_);
95108
for (int i = 0; i< batchsize_; i++) {
96-
aux_data_[i] = static_cast<int>(aux_data.at(i));
109+
aux_data_[i] = static_cast<int>(data->at(i));
97110
}
98111
}
112+
113+
return;
114+
115+
/* Wenfeng's input
116+
batchsize_ = batchsize;
117+
shape.insert(shape.begin(),batchsize);
118+
data_.Reshape(shape);
119+
120+
int size = data_.count() / batchsize_;
121+
CHECK_EQ(size, data->size());
122+
float* ptr = data_.mutable_cpu_data();
123+
for (int i = 0; i< size; i++)
124+
ptr[i] = data->at(i);
125+
99126
return;
127+
*/
100128
}
101129

102130
} // namespace singa

src/neuralnet/neuron_layer/pooling.cc

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ void PoolingLayer::Setup(const LayerProto& conf,
5858
}
5959

6060
pool_ = conf.pooling_conf().pool();
61-
CHECK(pool_ == PoolingProto_PoolMethod_AVG
62-
|| pool_ == PoolingProto_PoolMethod_MAX)
61+
CHECK(pool_ == PoolMethod::AVG
62+
|| pool_ == PoolMethod::MAX)
6363
<< "Padding implemented only for average and max pooling.";
6464
const auto& srcshape = srclayers[0]->data(this).shape();
6565
int dim = srcshape.size();
@@ -83,9 +83,9 @@ void PoolingLayer::Setup(const LayerProto& conf,
8383
void PoolingLayer::ComputeFeature(int flag, const vector<Layer*>& srclayers) {
8484
auto src = Tensor4(srclayers[0]->mutable_data(this));
8585
auto data = Tensor4(&data_);
86-
if (pool_ == PoolingProto_PoolMethod_MAX)
86+
if (pool_ == PoolMethod::MAX)
8787
data = expr::pool<red::maximum>(src, kernel_x_, stride_x_);
88-
else if (pool_ == PoolingProto_PoolMethod_AVG)
88+
else if (pool_ == PoolMethod::AVG)
8989
data = expr::pool<red::sum>(src, kernel_x_, stride_x_)
9090
* (1.0f / (kernel_x_ * kernel_x_));
9191
}
@@ -99,9 +99,9 @@ void PoolingLayer::ComputeGradient(int flag, const vector<Layer*>& srclayers) {
9999
auto gsrc = Tensor4(srclayers[0]->mutable_grad(this));
100100
auto data = Tensor4(&data_);
101101
auto grad = Tensor4(&grad_);
102-
if (pool_ == PoolingProto_PoolMethod_MAX)
102+
if (pool_ == PoolMethod::MAX)
103103
gsrc = expr::unpool<red::maximum>(src, data, grad, kernel_x_, stride_x_);
104-
else if (pool_ == PoolingProto_PoolMethod_AVG)
104+
else if (pool_ == PoolMethod::AVG)
105105
gsrc = expr::unpool<red::sum>(src, data, grad, kernel_x_, stride_x_)
106106
* (1.0f / (kernel_x_ * kernel_x_));
107107
}
@@ -111,16 +111,16 @@ void PoolingLayer::ComputeGradient(int flag, const vector<Layer*>& srclayers) {
111111
void CPoolingLayer::Setup(const LayerProto& conf,
112112
const vector<Layer*>& srclayers) {
113113
PoolingLayer::Setup(conf, srclayers);
114-
if (pool_ == PoolingProto_PoolMethod_MAX)
114+
if (pool_ == PoolMethod::MAX)
115115
mask_.ReshapeLike(data_);
116116
}
117117
void CPoolingLayer::ComputeFeature(int flag, const vector<Layer*>& srclayers) {
118-
if (pool_ == PoolingProto_PoolMethod_MAX)
118+
if (pool_ == PoolMethod::MAX)
119119
ForwardMaxPooling(srclayers[0]->mutable_data(this)->mutable_cpu_data(),
120120
batchsize_, channels_, height_, width_, kernel_y_, kernel_x_,
121121
pad_y_, pad_y_, stride_y_, stride_x_,
122122
data_.mutable_cpu_data(), mask_.mutable_cpu_data());
123-
else if (pool_ == PoolingProto_PoolMethod_AVG)
123+
else if (pool_ == PoolMethod::AVG)
124124
ForwardAvgPooling(srclayers[0]->mutable_data(this)->mutable_cpu_data(),
125125
batchsize_, channels_, height_, width_, kernel_y_, kernel_x_,
126126
pad_y_, pad_x_, stride_y_, stride_y_, data_.mutable_cpu_data());
@@ -129,12 +129,12 @@ void CPoolingLayer::ComputeFeature(int flag, const vector<Layer*>& srclayers) {
129129
}
130130

131131
void CPoolingLayer::ComputeGradient(int flag, const vector<Layer*>& srclayers) {
132-
if (pool_ == PoolingProto_PoolMethod_MAX)
132+
if (pool_ == PoolMethod::MAX)
133133
BackwardMaxPooling(grad_.cpu_data(), mask_.cpu_data(), batchsize_,
134134
channels_, height_, width_, kernel_y_, kernel_x_, pad_y_, pad_x_,
135135
stride_y_, stride_y_,
136136
srclayers[0]->mutable_grad(this)->mutable_cpu_data());
137-
else if (pool_ == PoolingProto_PoolMethod_AVG)
137+
else if (pool_ == PoolMethod::AVG)
138138
BackwardAvgPooling(grad_.cpu_data(), batchsize_,
139139
channels_, height_, width_, kernel_y_, kernel_x_, pad_y_, pad_x_,
140140
stride_y_, stride_x_,

src/proto/job.proto

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -522,15 +522,15 @@ message LRNProto {
522522
// offset
523523
optional float knorm = 34 [default = 1.0];
524524
}
525-
525+
enum PoolMethod {
526+
MAX = 0;
527+
AVG = 1;
528+
}
529+
526530
message PoolingProto {
527531
// The kernel size (square)
528532
optional int32 kernel= 1 [default = 3];
529-
enum PoolMethod {
530-
MAX = 0;
531-
AVG = 1;
532-
}
533-
// The pooling method
533+
// The pooling method
534534
optional PoolMethod pool = 30 [default = MAX];
535535
// The padding size
536536
optional uint32 pad = 31 [default = 0];

thirdparty/install.sh

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -256,19 +256,19 @@ function install_protobuf()
256256
echo "install protobuf in $1";
257257
./configure --prefix=$1;
258258
make && make install;
259-
#cd python;
260-
#python setup.py build;
261-
#python setup.py install --prefix=$1;
262-
#cd ..;
259+
cd python;
260+
python setup.py build;
261+
python setup.py install --prefix=$1;
262+
cd ..;
263263
elif [ $# == 0 ]
264264
then
265265
echo "install protobuf in default path";
266266
./configure;
267267
make && sudo make install;
268-
#cd python;
269-
#python setup.py build;
270-
#sudo python setup.py install;
271-
#cd ..;
268+
cd python;
269+
python setup.py build;
270+
sudo python setup.py install;
271+
cd ..;
272272
else
273273
echo "wrong commands";
274274
fi

tool/dlaas/main.py

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
#!/usr/bin/env python
2+
3+
#/************************************************************
4+
#*
5+
#* Licensed to the Apache Software Foundation (ASF) under one
6+
#* or more contributor license agreements. See the NOTICE file
7+
#* distributed with this work for additional information
8+
#* regarding copyright ownership. The ASF licenses this file
9+
#* to you under the Apache License, Version 2.0 (the
10+
#* "License"); you may not use this file except in compliance
11+
#* with the License. You may obtain a copy of the License at
12+
#*
13+
#* http://www.apache.org/licenses/LICENSE-2.0
14+
#*
15+
#* Unless required by applicable law or agreed to in writing,
16+
#* software distributed under the License is distributed on an
17+
#* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18+
#* KIND, either express or implied. See the License for the
19+
#* specific language governing permissions and limitations
20+
#* under the License.
21+
#*
22+
#*************************************************************/
23+
24+
import os, sys
25+
import numpy as np
26+
27+
current_path_ = os.path.dirname(__file__)
28+
singa_root_=os.path.abspath(os.path.join(current_path_,'../..'))
29+
sys.path.append(os.path.join(singa_root_,'thirdparty','protobuf-2.6.0','python'))
30+
sys.path.append(os.path.join(singa_root_,'tool','python'))
31+
32+
from model import neuralnet, updater
33+
from singa.driver import Driver
34+
from singa.layer import *
35+
from singa.model import save_model_parameter, load_model_parameter
36+
from singa.utils.utility import swap32
37+
38+
from PIL import Image
39+
import glob,random, shutil, time
40+
from flask import Flask, request, redirect, url_for
41+
from singa.utils import kvstore, imgtool
42+
app = Flask(__name__)
43+
44+
def train(batchsize,disp_freq,check_freq,train_step,workspace,checkpoint=None):
45+
print '[Layer registration/declaration]'
46+
# TODO change layer registration methods
47+
d = Driver()
48+
d.Init(sys.argv)
49+
50+
print '[Start training]'
51+
52+
#if need to load checkpoint
53+
if checkpoint:
54+
load_model_parameter(workspace+checkpoint, neuralnet, batchsize)
55+
56+
for i in range(0,train_step):
57+
58+
for h in range(len(neuralnet)):
59+
#Fetch data for input layer
60+
if neuralnet[h].layer.type==kDummy:
61+
neuralnet[h].FetchData(batchsize)
62+
else:
63+
neuralnet[h].ComputeFeature()
64+
65+
neuralnet[h].ComputeGradient(i+1, updater)
66+
67+
if (i+1)%disp_freq == 0:
68+
print ' Step {:>3}: '.format(i+1),
69+
neuralnet[h].display()
70+
71+
if (i+1)%check_freq == 0:
72+
save_model_parameter(i+1, workspace, neuralnet)
73+
74+
75+
print '[Finish training]'
76+
77+
78+
def product(workspace,checkpoint):
79+
80+
print '[Layer registration/declaration]'
81+
# TODO change layer registration methods
82+
d = Driver()
83+
d.Init(sys.argv)
84+
85+
load_model_parameter(workspace+checkpoint, neuralnet,1)
86+
87+
app.debug = True
88+
app.run(host='0.0.0.0', port=80)
89+
90+
91+
@app.route("/")
92+
def index():
93+
return "Hello World! This is SINGA DLAAS! Please send post request with image=file to '/predict' "
94+
95+
def allowed_file(filename):
96+
allowd_extensions_ = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
97+
return '.' in filename and \
98+
filename.rsplit('.', 1)[1] in allowd_extensions_
99+
100+
@app.route('/predict', methods=['POST'])
101+
def predict():
102+
size_=(32,32)
103+
pixel_length_=3*size_[0]*size_[1]
104+
label_num_=10
105+
if request.method == 'POST':
106+
file = request.files['image']
107+
if file and allowed_file(file.filename):
108+
im = Image.open(file).convert("RGB")
109+
im = imgtool.resize_to_center(im,size_)
110+
pixel = floatVector(pixel_length_)
111+
byteArray = imgtool.toBin(im,size_)
112+
data = np.frombuffer(byteArray, dtype=np.uint8)
113+
data = data.reshape(1, pixel_length_)
114+
#dummy data Layer
115+
shape = intVector(4)
116+
shape[0]=1
117+
shape[1]=3
118+
shape[2]=size_[0]
119+
shape[3]=size_[1]
120+
121+
for h in range(len(neuralnet)):
122+
#Fetch data for input layer
123+
if neuralnet[h].is_datalayer:
124+
if not neuralnet[h].is_label:
125+
neuralnet[h].Feed(data,3)
126+
else:
127+
neuralnet[h].FetchData(1)
128+
else:
129+
neuralnet[h].ComputeFeature()
130+
131+
#get result
132+
#data = neuralnet[-1].get_singalayer().data(neuralnet[-1].get_singalayer())
133+
#prop =floatArray_frompointer(data.mutable_cpu_data())
134+
prop = neuralnet[-1].GetData()
135+
print prop
136+
result=[]
137+
for i in range(label_num_):
138+
result.append((i,prop[i]))
139+
140+
result.sort(key=lambda tup: tup[1], reverse=True)
141+
print result
142+
response=""
143+
for r in result:
144+
response+=str(r[0])+":"+str(r[1])
145+
146+
return response
147+
return "error"
148+
149+
150+
if __name__=='__main__':
151+
152+
if sys.argv[1]=="train":
153+
if len(sys.argv) < 6:
154+
print "argv should be more than 6"
155+
exit()
156+
if len(sys.argv) > 6:
157+
checkpoint = sys.argv[6]
158+
else:
159+
checkpoint = None
160+
#training
161+
train(
162+
batchsize = int(sys.argv[2]),
163+
disp_freq = int(sys.argv[3]),
164+
check_freq = int(sys.argv[4]),
165+
train_step = int(sys.argv[5]),
166+
workspace = '/workspace',
167+
checkpoint = checkpoint,
168+
)
169+
else:
170+
if len(sys.argv) < 3:
171+
print "argv should be more than 2"
172+
exit()
173+
checkpoint = sys.argv[2]
174+
product(
175+
workspace = '/workspace',
176+
checkpoint = checkpoint
177+
)
178+

0 commit comments

Comments
 (0)