2016年8月20日 星期六
[Tensorflow] Learning Note: Try to downsize graph.pb model
In this topic, I will introduce more details about how to downsize training model if we want to use it on device.
(NOTE: Tensorflow also supports the mobile version.
I have not studied yet, but I think it is a good reference for you. )
Downsize model by using freeze graph
Why freezing ?
In Tensorflow-tool-develop-freezing said that:"What this does is load the GraphDef, pull in the values for all the variables from the latest checkpoint file, and then replace each Variable op with a Const that has the numerical data for the weights stored in its attributes It then strips away all the extraneous nodes that aren't used for forward inference, and saves out the resulting GraphDef into an output file
How to freeze graph ?
Use the freez_graph.py, and run the following commands:bazel build tensorflow/python/tools:freeze_graph && \
bazel-bin/tensorflow/python/tools/freeze_graph \
--input_graph=some_graph_def.pb \
--input_checkpoint=model.ckpt-8361242 \
--output_graph=/tmp/frozen_graph.pb --output_node_names=softmax
In my example on github (https://github.com/JackyTung/tensorgraph)
I will use graph.pb and model.ckpt to generate freeze graph
bazel build tensorflow/python/tools:freeze_graph && \
bazel-bin/tensorflow/python/tools/freeze_graph \
--input_graph=graph.pb \
--input_checkpoint=model.ckpt \
--output_graph=/tmp/frozen_graph.pb --output_node_names=softmax
Note:The model size will have not so big different in the mnist example.
However, once using more complex example, you will see the power of freeze_graph.py.
How to extract tensors from ckpt file
Following steps:
$ cd tensorflow/tensorflow/python/tools // list all tensors $ python inspect_checkpoint.py --file_name=$your_ckpt_file_path // print the value from specific tensor $ python inspect_checkpoint.py --file_name=$your_ckpt_file_path --tensor_name=$specific_tensorFollowing demo is from my example:
python inspect_checkpoint.py --file_name=$your_ckpt_file_path
python inspect_checkpoint.py --file_name=$your_ckpt_file_path --tensor_name=$specific_tensor
Be honestly, I am a new beginner in machine learning.
If I wrote something wrong or have a better suggestion, leave message to me.
I'll revise and update my article :)
2016年6月21日 星期二
[Tensorflow]Loading a tensorflow graph with the C++ API by using Mnist
"Tensorflow is an open source software library for numerical computation using data flow graphs. "
Tensorflow provides python API and C++ API. However, the document about loading a graph with C++ API is few. In some case, we need a C++ level api to run tensorflow.
Thanks to Jim Fleming write a complete loading graph example (link), saving my plenty of times.
I am based on Jim Fleming's article and add the mnist example to show
- how to write datas into input tensors
- how to read datas from output tensors
- what need to be care when we initial input and output tensors
Requirement
- Install tensorflow from source code ,"GET STARTED" --> "installing from source"
- Install bazel
Source code can be checked on my github repository
https://github.com/JackyTung/tensorgraph
Create Graph
source code : gengraph/import tensorflow as tf
import time
from tensorflow.examples.tutorials.mnist import input_data
# === prepare tensorflow network === #
#config setting
imageDim = 784
outputDim = 10
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
# None means that a dimension can be any of any length
x = tf.placeholder(tf.float32, [None, imageDim], name="input")
# 784-dimensional image vectors by it to produce 10-dimensional vectors
W = tf.Variable(tf.zeros([imageDim, outputDim]), dtype=tf.float32, name="Weight")
# a shape of [10]
b = tf.Variable(tf.zeros([outputDim]), dtype=tf.float32, name="bias")
# softmax
y = tf.nn.softmax(tf.matmul(x, W)+b, name="softmax")
....
# Add ops to save and restore all the variables
saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
#Training
for i in range(1000):
if i % 100 == 0:
print "iteration num :", i
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_step,feed_dict={x: batch_xs, y_: batch_ys})
# Save checkpoint, graph.pb and tensorboard
saver.save(sess, "models/model.ckpt")
tf.train.write_graph(sess.graph.as_graph_def(), "models/", "graph.pb")
tf.train.SummaryWriter("board", sess.graph)
#Testing
.....
when we create graph, need to care about
1. good naming on tensor.
2. the dimension of the input tensor and output tensor
(in this case, input tensor is x, output tensor is y)
Creating a simple library
source code : loadgraph/If we create our own library, create a new folder like this : tensorflow/tensorflow/<my project name>.
In this case, I am going to call the project loadgraph.
In the folder loadgraph/, I create a file name mnist.cc (because it is a mnist example).
In mnist.cc, we do the following things:
1. Initialize a TensorFlow session.
2. Read in the graph we exported above.
3. Add the graph to the session.
4. Setup our inputs and outputs.
5. Write datas into input tensors
6. Run the graph, populating the outputs.
7. Read value from the outputs tensors.
8. Do the mnist prediction
Some steps is shown in Jim's article, in here, I show some different from his article.
cout << "preparing input data..." << endl;
// config setting
int imageDim = 784;
int nTests = 10000;
// Setup inputs and outputs:
Tensor x(DT_FLOAT, TensorShape({nTests, imageDim}));
MNIST mnist = MNIST("./MNIST_data/");
auto dst = x.flat<float>().data();
for (int i = 0; i < nTests; i++) {
auto img = mnist.testData.at(i).pixelData;
std::copy_n(img.begin(), imageDim, dst);
dst += imageDim;
}
cout << "data is ready" << endl;
vector<pair<string, Tensor>> inputs = {
{ "input", x}
};
// The session will initialize the outputs
vector<Tensor> outputs;
// Run the session, evaluating our "softmax" operation from the graph
status = session->Run(inputs, {"softmax"}, {}, &outputs);
if (!status.ok()) {
cout << status.ToString() << "\n";
return 1;
}else{
cout << "Success load graph !! " << "\n";
}
The input tensor and output tensor dimension should be the same as mnist.py.Besides, the name of input tensor {"input", x} and output tensor {"softmax"} should also be same as mnist.py.
// start compute the accuracy,
// arg_max is to record which index is the largest value after
// computing softmax, and if arg_max is equal to testData.label,
// means predict correct.
int nHits = 0;
for (vector<Tensor>::iterator it = outputs.begin() ; it != outputs.end(); ++it) {
auto items = it->shaped<float, 2>({nTests, 10}); // 10 represent number of class
for(int i = 0 ; i < nTests ; i++){
int arg_max = 0;
float val_max = items(i, 0);
for (int j = 0; j < 10; j++) {
if (items(i, j) > val_max) {
arg_max = j;
val_max = items(i, j);
}
}
if (arg_max == mnist.testData.at(i).label) {
nHits++;
}
}
}
float accuracy = (float)nHits/nTests;
cout << "accuracy is : " << accuracy << ", and Done!!" <<
Figure out the output dimension, in this case, the output dimension is (nTest, 10).
nTest: represent test numbers
10 : represent number of classes.
we use iterator it as a pointer to read the data from output tensor.
Now, we create BUILD file for our project, our src file contain mnist.cc and MNIST.h.
(MNIST.h is a mnist data loader.)
cc_binary(
name = "mnistpredict",
srcs = ["mnist.cc", "MNIST.h"],
deps = [
"//tensorflow/core:tensorflow",
],
);
Here is the final directory structure:
- tensorflow/tensorflow/loadgraph
- tensorflow/tensorflow/loadgraph/mnist.cc
- tensorflow/tensorflow/loadgraph/MNIST.h
- tensorflow/tensorflow/loadgraph/BUILD
Compile and Run
- From inside folder, run bazel build :mnistpredict
- From the repository root, go into bazel-bin/tensorflow/loadgraph
- Copy frozen_graph.pb and Mnist_data/ to loadgraph/
- run ./mnistpredict and check the output is the same as mnist.py or not
Note and Following tutorial
1. The build binary is 154MB, I think it is still a huge size if we want to put our model to applications.I will introduce what is going on in the build file "//tensorflow/core:tensorflow".
Choose the library we need, and then will reduce our binary size.
2. In loadgraph, we can notice that I use "frozen_graph.pb".
the frozen_graph.pb is combined from graph.pb and model.ckpt.
I will explain the reason why I want to combine these two files.
3. We use the mnist for our example in this article. I think it is a simple example in the machine learning. When we use more complicate example, we need to know network clearly, especially what are the input tensors and what are the output tensors. Because some redundant input tensors will be dropped out after freeze graph. If we do not know our network clearly, we may confused why input tensor is disappear.
Be honestly, I am a new beginner in machine learning.
If I wrote something wrong or have a better suggestion, leave message to me.
I'll revise and update my article :)
Check my next tutorial: Try to downsize graph.pb model
2013年9月16日 星期一
[Java]Jsoup test source code
請搭配Jsoup--好用的抓去網頁工具(HTML & XML)一起觀看下面附上我的原始碼
package URLConnection;
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
public class test {
public static void getpoint(String urlStr){
Document doc = null;
try {
doc = Jsoup.connect(urlStr).get();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Elements newsHeadlines1 = doc.select("start_location");
System.out.println(newsHeadlines1.size()); // know the tag size
System.out.println(newsHeadlines1.get(0));
System.out.println(newsHeadlines1.get(0).text()); // get the text
System.out.println(newsHeadlines1.get(0).tagName()); // print tag name
System.out.println(newsHeadlines1.get(0).empty()); // empty the text
}
public static void main(String[] args){
float start_lat = (float) 24.79608;
float start_lng = (float) 120.98709;
float end_lat = (float) 24.80237;
float end_lng = (float) 120.97206;
link(start_lat,start_lng,end_lat,end_lng);
}
public static void link(float start_lat,float start_lng,float end_lat,float end_lng)
{
System.out.println("http://maps.googleapis.com/maps/api/directions/xml?origin="+start_lat+","+start_lng+"&destination="+end_lat+","+end_lng+"&sensor=false&units=metric&mode=driving");
getpoint("http://maps.googleapis.com/maps/api/directions/xml?origin="+start_lat+","+start_lng+"&destination="+end_lat+","+end_lng+"&sensor=false&units=metric&mode=driving");
}
}
[Java]Jsoup--好用的抓取網頁工具(HTML & XML)
最近寫實驗室的這兩個月,一直需要會用到爬網頁(parser)的技術自己也上網找資料找了許久,慢慢研究Jsoup才研究出一些端倪
以下即將介紹的,昰我在寫爬網頁的時候比較經常使用到的一些方法
<好站連結>
附上三個我最常用的網站連結
想要更深入的研究"Jsoup"可以參考
1. Jsoup官網
2. 好用的HTML parser--jsoup
3. 使用jsoup對HTML文檔的解析和操作
<安裝環境>
1.首先先進入Jsoup的官網
2013年9月4日 星期三
[Java]read file(讀取檔案) & ArrayList(動態陣列) & String型態的轉換
為什麼標題會這樣下呢,因為最近再寫程式的時候常會做到這些流程
我的目的是要分析很多筆的資料
1.從txt檔讀取資料進來
2.因為不知道資料量的大小多少,會用一個動態的陣列儲存
3.動態陣列存的資料是String型態,必須轉為int,double,float,long型態的資料對我來說才有用
因為程式設計師經常需要用到數據來分析一些問題
綜合以上三點,才會需要使用到這些工具
待會兒會一一介紹
我使用的語言是Java
操作環境是安裝eclipse,很推這個編輯程式工具
強大又人性化,除了基本的關鍵字會標顏色之外,
如果Complie有錯誤,還會跟你說需要加上甚麼東西,會給你提示!!
所以可以省掉很多的麻煩,
台灣大學的eclispe教學連結
Get the Start ADK連結 -->下載這個除了可以在eclipse環境下寫java,也可以開發android程式
<demo範例>
我讀取的檔案名稱"test.txt"
檔案內容如下
2013年9月1日 星期日
[工具]Syntaxhighlighter程式碼編輯注意項目 & 客製化的介面設定補充
從昨天分享完Syntaxhighlighter的安裝文章之後本來今日要開始分享我的一些撰寫程式碼小心得
但是卻遇到了一個問題
就是我在寫for迴圈或是有寫到 "<" or ">" 的符號是,不知道為什麼總是無法編輯成功
我自己也相當的納悶,後來上網google大神查了一下
才發現有些特定的符號需要用另一種方式來編輯
難怪我在那編輯了老半天都無法編輯成功
ps :想要了解基本Syntaxhighlighter的設定步驟,請參考我上篇寫的
"Blogger如何利用Syntaxhighlighter將程式碼著色"
2013年8月31日 星期六
[工具]Blogger如何用Syntaxhighlighter來將程式碼著色
相信是程式設計師在寫有關coding分享文章時會為了程式碼的著色感到相當困擾
因為我們都知道,程式碼在閱讀的時候,最希望的就是將程式碼上色,讓程式碼的可讀性可以更高,所以網路上就有提供一個開發工具,可以讓我們在寫文章的時候,
也能將程式碼方便著色!
這項開發工具是 Syntaxhighlighter 3.0.83 官方網站連結
在網路上有許多人分享過此類的文章
但我搜尋找了好久才找到成功安裝的範例~相當苦惱呢
我的主要參考資料是這位部落客寫的 --> 參考資料按此連結
寫得很完整,我也來分享我這兩天找尋資料的一些心得
只要跟著步驟做,你也能安裝成功!
執行流程:
下載Syntaxhighlighter所提供的js檔案跟css檔,用上傳檔案的方式來連結路徑
或是直接用網站提供的官方路徑(不須下載檔案)
來編輯到自己部落格的HTML,編輯成功後即可使用
這邊主要介紹的是用官方路徑的設定方式
技術提供:Blogger.



