├── .gitignore ├── README.md ├── cpp ├── Makefile ├── bin │ └── tfcpp_demo ├── ckpt │ ├── checkpoint │ ├── nn_model.ckpt.data-00000-of-00001 │ ├── nn_model.ckpt.index │ └── nn_model.ckpt.meta ├── model │ ├── nn_model.pbtxt │ └── nn_model_frozen.pb ├── run.sh ├── scripts │ ├── build.sh │ ├── freeze_graph.py │ └── nn_model.py └── src │ ├── ann_model_loader.cpp │ ├── ann_model_loader.h │ ├── main.cpp │ └── model_loader_base.h ├── google270b3db49723c3d4.html └── mnist ├── convolutional.py ├── convolutional_graph_partitioned.py └── convolutional_multithread.py /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Tensorflow CPP API demo 2 | -------------------------------------- 3 | Tensorflow cpp API 调用python预训练模型 4 | 5 | ###Python定义NN模型训练 6 | 7 | ```python 8 | 9 | cd cpp/scripts 10 | 11 | python nn_model.py # 训练nn模型对Iris数据集分类 12 | 13 | sh build.sh # 运行 freeze_graph.py 将*.ckpt 参数文件和 nn_model.pbtxt 模型定义文件绑定, 输出 nn_model_frozen.pb 14 | 15 | # 成功标志: 16 | # Converted 2 variables to const ops. 17 | # 9 ops in the final graph. 18 | 19 | ``` 20 | 21 | ###编译CPP项目进行预测 22 | 23 | ```python 24 | cd ../ 25 | 26 | make # 编译cpp代码的demo, 编译好的可执行文件在 ./bin/tfcpp_demo 文件夹下 27 | 28 | sh run.sh # 运行可执行文件 tfcpp_demo, 读取python预训练好的模型 ./model/nn_model_frozen.pb 进行预测 29 | 30 | ``` 31 | 32 | ==================================================== 33 | 34 | # Related 35 | ==================================================== 36 | 37 | ## References 38 | [DeepNLP Blog](http://www.deepnlp.org/blog)
39 | [DeepNLP Equation](http://www.deepnlp.org/equation)
40 | [DeepNLP Search](http://www.deepnlp.org/search)
41 | [DeepNLP AI Courses](http://www.deepnlp.org/workspace/ai_courses)
42 | [DeepNLP AIGC Chart](http://www.deepnlp.org/workspace/aigc_chart)
43 | [DeepNLP AI Writer](http://www.deepnlp.org/workspace/ai_writer)
44 | [DeepNLP Workspace](http://www.deepnlp.org/workspace/detail)
45 | [DeepNLP AI App Store](http://www.deepnlp.org/store)
46 | [AI IMAGE GENERATOR](http://www.deepnlp.org/store/image-generator)
47 | [AI Search Engine](http://www.deepnlp.org/store/search-engine)
48 | [AI Chatbot Assistant](http://www.deepnlp.org/store/chatbot-assistant)
49 | [AI VIDEO GENERATOR Reviews](http://www.deepnlp.org/store/video-generator)
50 | [AI for ELDERLY](http://www.deepnlp.org/store/elderly)
51 | [AI for KIDS](http://www.deepnlp.org/store/kids)
52 | [AI in LAW](http://www.deepnlp.org/store/law)
53 | [AI in FINANCE](http://www.deepnlp.org/store/finance)
54 | [AI in HEALTHCARE](http://www.deepnlp.org/store/healthcare)
55 | [AI in BUSINESS](http://www.deepnlp.org/store/business)
56 | [AI in EDUCATION](http://www.deepnlp.org/store/education)
57 | [AI in PRODUCTIVITY TOOL](http://www.deepnlp.org/store/productivity-tool)
58 | [AI in POLITICS](http://www.deepnlp.org/store/politics)
59 | [AI in ENTERTAINMENT](http://www.deepnlp.org/store/entertainment)
60 | [AI in NEWS](http://www.deepnlp.org/store/news)
61 | [AI in ART AND SPORTS](http://www.deepnlp.org/store/art-and-sports)
62 | [AI in LIFESTYLE](http://www.deepnlp.org/store/lifestyle)
63 | [AI in PAYMENT](http://www.deepnlp.org/store/payment)
64 | [AI in SOCIAL](http://www.deepnlp.org/store/social)
65 | [AI in AGRICULTURE](http://www.deepnlp.org/store/agriculture)
66 | [AI in SCIENCE](http://www.deepnlp.org/store/science)
67 | [AI in TECHNOLOGY](http://www.deepnlp.org/store/technology)
68 | [AI in TRAVEL](http://www.deepnlp.org/store/travel)
69 | [AI in TRANSPORTATION](http://www.deepnlp.org/store/transportation)
70 | [AI in CAR](http://www.deepnlp.org/store/car)
71 | [AI in CHARITY](http://www.deepnlp.org/store/charity)
72 | [AI in PUBLIC SERVICE](http://www.deepnlp.org/store/public-service)
73 | [AI in HOUSING](http://www.deepnlp.org/store/housing)
74 | [AI in COMMUNICATION](http://www.deepnlp.org/store/communication)
75 | [AI in FOOD](http://www.deepnlp.org/store/food)
76 | [Robot Quadruped Robot Reviews](http://www.deepnlp.org/store/quadruped-robot)
77 | [Robot Humanoid Robot Reviews](http://www.deepnlp.org/store/humanoid-robot)
78 | [Robotaxi Reviews](http://www.deepnlp.org/store/robotaxi)
79 | [Electric Vehicle Reviews](http://www.deepnlp.org/store/electric-vehicle)
80 | [ChatGPT User Reviews](http://www.deepnlp.org/store/pub/pub-chatgpt-openai)
81 | [Gemini User Reviews](http://www.deepnlp.org/store/pub/pub-gemini-google)
82 | [Perplexity User Reviews](http://www.deepnlp.org/store/pub/pub-perplexity)
83 | [Claude User Reviews](http://www.deepnlp.org/store/pub/pub-claude-anthropic)
84 | [Midjourney User Reviews](http://www.deepnlp.org/store/pub/pub-midjourney)
85 | [Stable Diffusion User Reviews](http://www.deepnlp.org/store/pub/pub-stable-diffusion)
86 | [Runway User Reviews](http://www.deepnlp.org/store/pub/pub-runway)
87 | [GPT-5 Forecast](http://www.deepnlp.org/store/pub/pub-gpt-5)
88 | [Generative AI Search Engine Optimization](http://www.deepnlp.org/blog/generative-ai-search-engine-optimization-how-to-improve-your-content) 89 | 90 | ## DeepNLP AI & Robots Community Communities 91 | 92 | [DeepNLP AI & Robots Community for AI Practitioner](http://www.deepnlp.org/question)
93 | [Would you share your experience using AI Productivity Tools such as AI Writing Coding CoPilot](http://www.deepnlp.org/question/would-you-share-your-experience-using-ai-productivity-tools-such-as-ai-writing-coding-copilot)
94 | [What are the features you need for AI Video Generator apps and tools](http://www.deepnlp.org/question/what-are-the-features-you-need-for-ai-video-generator-apps-and-tools)
95 | [Which one is the best AI Video Generator Runway Luma Pika Kling and Why](http://www.deepnlp.org/question/which-one-is-the-best-ai-video-generator-runway-luma-pika-kling-and-why)
96 | [What are the typical use scenarios of Quadruped Robot Dogs](http://www.deepnlp.org/question/what-are-the-typical-use-scenarios-of-quadruped-robot-dogs)
97 | [Humanoid Robot Husband Vote for the most popular appearance of Humanoid Robot Husband](http://www.deepnlp.org/question/humanoid-robot-husband-vote-for-the-most-popular-appearance-of-humanoid-robot-husband)
98 | [Humanoid Robot Wife Who would you choose your humanoid robot wife to look like human females](http://www.deepnlp.org/question/humanoid-robot-wife-who-would-you-choose-your-humanoid-robot-wife-to-look-like-human-females)
99 | [What are the most important features Humanoid Robot should have in the future](http://www.deepnlp.org/question/what-are-the-most-important-features-humanoid-robot-should-have-in-the-future)
100 | [What are the typical use cases of Humanoid Robots](http://www.deepnlp.org/question/what-are-the-typical-use-cases-of-humanoid-robots)
101 | 102 | ## AI Agents Multi-Agents Reasoning 103 | [AI Agent Visualization Review Asynchronous Multi-Agent Simulation](http://www.deepnlp.org/blog/ai-agent-visualization-review-asynchronous-multi-agent-simulation)
104 | [Dialogue Visualization Agent Multimodal Visualization Tools for AI Systems A Review](http://www.deepnlp.org/blog/dialogue-agent-multimodal-visualization-tools-for-ai-systems)
105 | 106 | ## AI Service Reviews and Ratings 107 | ##### Chatbot 108 | [OpenAI o1 Reviews](http://www.deepnlp.org/store/pub/pub-openai-o1)
109 | [ChatGPT User Reviews](http://www.deepnlp.org/store/pub/pub-chatgpt-openai)
110 | [Gemini User Reviews](http://www.deepnlp.org/store/pub/pub-gemini-google)
111 | [Perplexity User Reviews](http://www.deepnlp.org/store/pub/pub-perplexity)
112 | [Claude User Reviews](http://www.deepnlp.org/store/pub/pub-claude-anthropic)
113 | [Qwen AI Reviews](http://www.deepnlp.org/store/pub/pub-qwen-alibaba)
114 | [Doubao Reviews](http://www.deepnlp.org/store/pub/pub-doubao-douyin)
115 | [ChatGPT Strawberry](http://www.deepnlp.org/store/pub/pub-chatgpt-strawberry)
116 | [Zhipu AI Reviews](http://www.deepnlp.org/store/pub/pub-zhipu-ai)
117 | ##### AI Image Generation 118 | [Midjourney User Reviews](http://www.deepnlp.org/store/pub/pub-midjourney)
119 | [Stable Diffusion User Reviews](http://www.deepnlp.org/store/pub/pub-stable-diffusion)
120 | [Runway User Reviews](http://www.deepnlp.org/store/pub/pub-runway)
121 | [GPT-5 Forecast](http://www.deepnlp.org/store/pub/pub-gpt-5)
122 | [Flux AI Reviews](http://www.deepnlp.org/store/pub/pub-flux-1-black-forest-lab)
123 | [Canva User Reviews](http://www.deepnlp.org/store/pub/pub-canva)
124 | ##### AI Video Generation 125 | [Luma AI](http://www.deepnlp.org/store/pub/pub-luma-ai)
126 | [Pika AI Reviews](http://www.deepnlp.org/store/pub/pub-pika)
127 | [Runway AI Reviews](http://www.deepnlp.org/store/pub/pub-runway)
128 | [Kling AI Reviews](http://www.deepnlp.org/store/pub/pub-kling-kwai)
129 | [Dreamina AI Reviews](http://www.deepnlp.org/store/pub/pub-dreamina-douyin)
130 | ##### AI Education 131 | [Coursera Reviews](http://www.deepnlp.org/store/pub/pub-coursera)
132 | [Udacity Reviews](http://www.deepnlp.org/store/pub/pub-udacity)
133 | [Grammarly Reviews](http://www.deepnlp.org/store/pub/pub-grammarly)
134 | #### Robotics 135 | [Tesla Cybercab Robotaxi](http://www.deepnlp.org/store/pub/pub-tesla-cybercab)
136 | [Tesla Optimus](http://www.deepnlp.org/store/pub/pub-tesla-optimus)
137 | [Figure AI](http://www.deepnlp.org/store/pub/pub-figure-ai)
138 | [Unitree Robotics Reviews](http://www.deepnlp.org/store/pub/pub-unitree-robotics)
139 | [Waymo User Reviews](http://www.deepnlp.org/store/pub/pub-waymo-google)
140 | [ANYbotics Reviews](http://www.deepnlp.org/store/pub/pub-anybotics)
141 | [Boston Dynamics](http://www.deepnlp.org/store/pub/pub-boston-dynamic)
142 | #### AI Tools 143 | [DeepNLP AI Tools](http://www.deepnlp.org/store/pub/pub-deepnlp-ai)
144 | #### AI Widgets 145 | [Apple Glasses](http://www.deepnlp.org/store/pub/pub-apple-glasses)
146 | [Meta Glasses](http://www.deepnlp.org/store/pub/pub-meta-glasses)
147 | [Apple AR VR Headset](http://www.deepnlp.org/store/pub/pub-apple-ar-vr-headset)
148 | [Google Glass](http://www.deepnlp.org/store/pub/pub-google-glass)
149 | [Meta VR Headset](http://www.deepnlp.org/store/pub/pub-meta-vr-headset)
150 | [Google AR VR Headsets](http://www.deepnlp.org/store/pub/pub-google-ar-vr-headset)
151 | #### Social 152 | [Character AI](http://www.deepnlp.org/store/pub/pub-character-ai)
153 | #### Self-Driving 154 | [BYD Seal](http://www.deepnlp.org/store/pub/pub-byd-seal)
155 | [Tesla Model 3](http://www.deepnlp.org/store/pub/pub-tesla-model-3)
156 | [BMW i4](http://www.deepnlp.org/store/pub/pub-bmw-i4)
157 | [Baidu Apollo Reviews](http://www.deepnlp.org/store/pub/pub-baidu-apollo)
158 | [Hyundai IONIQ 6](http://www.deepnlp.org/store/pub/pub-hyundai-ioniq-6)
159 | 160 | ## Related Blog 161 | [Statistics Equation Formula](http://www.deepnlp.org/blog/statistics-equations-latex-code)
162 | [Machine Learning Equation Formula](http://www.deepnlp.org/blog/latex-code-machine-learning-equations)
163 | [Introduction to multimodal generative models](http://www.deepnlp.org/blog/introduction-to-multimodal-generative-models)
164 | [Generative AI Search Engine Optimization: How to Improve Your Content](http://www.deepnlp.org/blog/generative-ai-search-engine-optimization-how-to-improve-your-content)
165 | [AI Courses for Kids](http://www.deepnlp.org/blog/how-to-use-generative-ai-to-draw-paw-patrol-dog-skye)
166 | [AI in Fashion: Tell IWC Schaffhausen Watches Real or Fake](http://www.deepnlp.org/blog/how-to-tell-iwc-schaffhausen-watches-real-or-fake-20-steps)
167 | [AI in Fashion: Tell Fendi bags real or fake](http://www.deepnlp.org/blog/how-to-tell-fendi-bags-real-or-fake-20-steps)
168 | [AI in Fashion: Tell Coach bags real or fake](http://www.deepnlp.org/blog/how-to-tell-coach-bags-real-or-fake-20-steps)
169 | [AI in Fashion: Tell Prada bags real or fake](http://www.deepnlp.org/blog/how-to-tell-prada-bags-real-or-fake-20-steps)
170 | [AI in Fashion: Tell Gucci bags real or fake](http://www.deepnlp.org/blog/20-tricks-to-tell-gucci-bags-real-or-fake)
171 | [AI in Fashion: Tell Dior bags real or fake](http://www.deepnlp.org/blog/tell-dior-bags-real-or-fake-20-steps)
172 | [AI in Fashion: Tell Hermes bags real or fake](http://www.deepnlp.org/blog/20-tricks-to-tell-hermes-bags-real-or-fake)
173 | [AI in Fashion: Tell Chanel bags real or fake](http://www.deepnlp.org/blog/20-tricks-to-tell-chanel-bags-real-or-fake)
174 | [AI in Fashion: Tell Louis Vuitton bags real or fake](http://www.deepnlp.org/blog/20-tricks-to-tell-louis-vuitton-bags-real-or-fake)
175 | [AI in Fashion: Tell Omega Watches real or fake](http://www.deepnlp.org/blog/20-tricks-to-tell-if-omega-watch-is-real-or-fake)
176 | [AI in Fashion: Tell Rolex Watches real or fake](http://www.deepnlp.org/blog/20-tricks-to-tell-if-rolex-watch-is-real-or-fake)
177 | [DeepNLP Review Panel](http://www.deepnlp.org/review)
178 | [DeepNLP Car Review Panel](http://www.deepnlp.org/review/car)
179 | [DeepNLP Ecommerce Review Panel](http://www.deepnlp.org/review/ecommerce)
180 | [DeepNLP Ecommerce Bags Review Panel](http://www.deepnlp.org/review/ecommerce/bag)
181 | [DeepNLP Watch Bags Review Panel](http://www.deepnlp.org/review/ecommerce/watch)
182 | [DeepNLP Review Ecommerce Brand List](http://www.deepnlp.org/review/ecommerce/pub)
183 | [DeepNLP Review Car Brand List](http://www.deepnlp.org/review/car/pub)
184 | [AI Agent Visualization Review Asynchronous Multi-Agent Simulation](http://www.deepnlp.org/blog/ai-agent-visualization-review-asynchronous-multi-agent-simulation)
185 | [Dialogue Visualization Agent Multimodal Visualization Tools for AI Systems A Review](http://www.deepnlp.org/blog/dialogue-agent-multimodal-visualization-tools-for-ai-systems)
186 | -------------------------------------------------------------------------------- /cpp/Makefile: -------------------------------------------------------------------------------- 1 | ### Makefile for building tensorflow application 2 | # link pre-build libtensorflow_cc.so to your personal build project 3 | # param: 4 | # INCLUDES: -I, remember to include eigen3 and tf libs 5 | # LDLIBS : -L path of folder where libtensorflow_cc.so exist 6 | # ACTUAL_LIBS: -l name of actual lib(name).so 7 | 8 | 9 | SOURCE_DIR =./src 10 | BIN_DIR = ./bin 11 | 12 | CPP = g++ -std=c++11 13 | LDFLAGS = -g -Wall -D_DEBUG -Wshadow -Wno-sign-compare -w 14 | LDLIBS = -L/usr/local/lib 15 | INCLUDES = -I/usr/local/include/tf -I/usr/local/include/eigen3 16 | ACTUAL_LIBS = `pkg-config --cflags --libs protobuf` -ltensorflow_cc 17 | 18 | INPUT_FILE = $(SOURCE_DIR)/main.cpp $(SOURCE_DIR)/ann_model_loader.cpp 19 | OBJET_FILE = $(BIN_DIR)/tfcpp_demo 20 | 21 | tfcpp_demo: 22 | $(CPP) -o $(OBJET_FILE) $(INCLUDES) $(LDFLAGS) $(LDLIBS) $(ACTUAL_LIBS) $(INPUT_FILE) 23 | -------------------------------------------------------------------------------- /cpp/bin/tfcpp_demo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rockingdingo/tensorflow-tutorial/2e24d98a10750a91e129f0fc296b21c0ccc9bc2d/cpp/bin/tfcpp_demo -------------------------------------------------------------------------------- /cpp/ckpt/checkpoint: -------------------------------------------------------------------------------- 1 | model_checkpoint_path: "/Users/Desktop/project/github/test/tensorflow-tutorial/cpp/ckpt/nn_model.ckpt" 2 | all_model_checkpoint_paths: "/Users/Desktop/project/github/test/tensorflow-tutorial/cpp/ckpt/nn_model.ckpt" 3 | -------------------------------------------------------------------------------- /cpp/ckpt/nn_model.ckpt.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rockingdingo/tensorflow-tutorial/2e24d98a10750a91e129f0fc296b21c0ccc9bc2d/cpp/ckpt/nn_model.ckpt.data-00000-of-00001 -------------------------------------------------------------------------------- /cpp/ckpt/nn_model.ckpt.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rockingdingo/tensorflow-tutorial/2e24d98a10750a91e129f0fc296b21c0ccc9bc2d/cpp/ckpt/nn_model.ckpt.index -------------------------------------------------------------------------------- /cpp/ckpt/nn_model.ckpt.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rockingdingo/tensorflow-tutorial/2e24d98a10750a91e129f0fc296b21c0ccc9bc2d/cpp/ckpt/nn_model.ckpt.meta -------------------------------------------------------------------------------- /cpp/model/nn_model.pbtxt: -------------------------------------------------------------------------------- 1 | node { 2 | name: "inputs" 3 | op: "Placeholder" 4 | attr { 5 | key: "dtype" 6 | value { 7 | type: DT_FLOAT 8 | } 9 | } 10 | attr { 11 | key: "shape" 12 | value { 13 | shape { 14 | dim { 15 | size: -1 16 | } 17 | dim { 18 | size: 5 19 | } 20 | } 21 | } 22 | } 23 | } 24 | node { 25 | name: "target" 26 | op: "Placeholder" 27 | attr { 28 | key: "dtype" 29 | value { 30 | type: DT_FLOAT 31 | } 32 | } 33 | attr { 34 | key: "shape" 35 | value { 36 | shape { 37 | dim { 38 | size: -1 39 | } 40 | dim { 41 | size: 3 42 | } 43 | } 44 | } 45 | } 46 | } 47 | node { 48 | name: "random_normal/shape" 49 | op: "Const" 50 | attr { 51 | key: "dtype" 52 | value { 53 | type: DT_INT32 54 | } 55 | } 56 | attr { 57 | key: "value" 58 | value { 59 | tensor { 60 | dtype: DT_INT32 61 | tensor_shape { 62 | dim { 63 | size: 2 64 | } 65 | } 66 | tensor_content: "\005\000\000\000@\000\000\000" 67 | } 68 | } 69 | } 70 | } 71 | node { 72 | name: "random_normal/mean" 73 | op: "Const" 74 | attr { 75 | key: "dtype" 76 | value { 77 | type: DT_FLOAT 78 | } 79 | } 80 | attr { 81 | key: "value" 82 | value { 83 | tensor { 84 | dtype: DT_FLOAT 85 | tensor_shape { 86 | } 87 | float_val: 0.0 88 | } 89 | } 90 | } 91 | } 92 | node { 93 | name: "random_normal/stddev" 94 | op: "Const" 95 | attr { 96 | key: "dtype" 97 | value { 98 | type: DT_FLOAT 99 | } 100 | } 101 | attr { 102 | key: "value" 103 | value { 104 | tensor { 105 | dtype: DT_FLOAT 106 | tensor_shape { 107 | } 108 | float_val: 0.10000000149 109 | } 110 | } 111 | } 112 | } 113 | node { 114 | name: "random_normal/RandomStandardNormal" 115 | op: "RandomStandardNormal" 116 | input: "random_normal/shape" 117 | attr { 118 | key: "T" 119 | value { 120 | type: DT_INT32 121 | } 122 | } 123 | attr { 124 | key: "dtype" 125 | value { 126 | type: DT_FLOAT 127 | } 128 | } 129 | attr { 130 | key: "seed" 131 | value { 132 | i: 42 133 | } 134 | } 135 | attr { 136 | key: "seed2" 137 | value { 138 | i: 5 139 | } 140 | } 141 | } 142 | node { 143 | name: "random_normal/mul" 144 | op: "Mul" 145 | input: "random_normal/RandomStandardNormal" 146 | input: "random_normal/stddev" 147 | attr { 148 | key: "T" 149 | value { 150 | type: DT_FLOAT 151 | } 152 | } 153 | } 154 | node { 155 | name: "random_normal" 156 | op: "Add" 157 | input: "random_normal/mul" 158 | input: "random_normal/mean" 159 | attr { 160 | key: "T" 161 | value { 162 | type: DT_FLOAT 163 | } 164 | } 165 | } 166 | node { 167 | name: "Variable" 168 | op: "VariableV2" 169 | attr { 170 | key: "container" 171 | value { 172 | s: "" 173 | } 174 | } 175 | attr { 176 | key: "dtype" 177 | value { 178 | type: DT_FLOAT 179 | } 180 | } 181 | attr { 182 | key: "shape" 183 | value { 184 | shape { 185 | dim { 186 | size: 5 187 | } 188 | dim { 189 | size: 64 190 | } 191 | } 192 | } 193 | } 194 | attr { 195 | key: "shared_name" 196 | value { 197 | s: "" 198 | } 199 | } 200 | } 201 | node { 202 | name: "Variable/Assign" 203 | op: "Assign" 204 | input: "Variable" 205 | input: "random_normal" 206 | attr { 207 | key: "T" 208 | value { 209 | type: DT_FLOAT 210 | } 211 | } 212 | attr { 213 | key: "_class" 214 | value { 215 | list { 216 | s: "loc:@Variable" 217 | } 218 | } 219 | } 220 | attr { 221 | key: "use_locking" 222 | value { 223 | b: true 224 | } 225 | } 226 | attr { 227 | key: "validate_shape" 228 | value { 229 | b: true 230 | } 231 | } 232 | } 233 | node { 234 | name: "Variable/read" 235 | op: "Identity" 236 | input: "Variable" 237 | attr { 238 | key: "T" 239 | value { 240 | type: DT_FLOAT 241 | } 242 | } 243 | attr { 244 | key: "_class" 245 | value { 246 | list { 247 | s: "loc:@Variable" 248 | } 249 | } 250 | } 251 | } 252 | node { 253 | name: "random_normal_1/shape" 254 | op: "Const" 255 | attr { 256 | key: "dtype" 257 | value { 258 | type: DT_INT32 259 | } 260 | } 261 | attr { 262 | key: "value" 263 | value { 264 | tensor { 265 | dtype: DT_INT32 266 | tensor_shape { 267 | dim { 268 | size: 2 269 | } 270 | } 271 | tensor_content: "@\000\000\000\003\000\000\000" 272 | } 273 | } 274 | } 275 | } 276 | node { 277 | name: "random_normal_1/mean" 278 | op: "Const" 279 | attr { 280 | key: "dtype" 281 | value { 282 | type: DT_FLOAT 283 | } 284 | } 285 | attr { 286 | key: "value" 287 | value { 288 | tensor { 289 | dtype: DT_FLOAT 290 | tensor_shape { 291 | } 292 | float_val: 0.0 293 | } 294 | } 295 | } 296 | } 297 | node { 298 | name: "random_normal_1/stddev" 299 | op: "Const" 300 | attr { 301 | key: "dtype" 302 | value { 303 | type: DT_FLOAT 304 | } 305 | } 306 | attr { 307 | key: "value" 308 | value { 309 | tensor { 310 | dtype: DT_FLOAT 311 | tensor_shape { 312 | } 313 | float_val: 0.10000000149 314 | } 315 | } 316 | } 317 | } 318 | node { 319 | name: "random_normal_1/RandomStandardNormal" 320 | op: "RandomStandardNormal" 321 | input: "random_normal_1/shape" 322 | attr { 323 | key: "T" 324 | value { 325 | type: DT_INT32 326 | } 327 | } 328 | attr { 329 | key: "dtype" 330 | value { 331 | type: DT_FLOAT 332 | } 333 | } 334 | attr { 335 | key: "seed" 336 | value { 337 | i: 42 338 | } 339 | } 340 | attr { 341 | key: "seed2" 342 | value { 343 | i: 14 344 | } 345 | } 346 | } 347 | node { 348 | name: "random_normal_1/mul" 349 | op: "Mul" 350 | input: "random_normal_1/RandomStandardNormal" 351 | input: "random_normal_1/stddev" 352 | attr { 353 | key: "T" 354 | value { 355 | type: DT_FLOAT 356 | } 357 | } 358 | } 359 | node { 360 | name: "random_normal_1" 361 | op: "Add" 362 | input: "random_normal_1/mul" 363 | input: "random_normal_1/mean" 364 | attr { 365 | key: "T" 366 | value { 367 | type: DT_FLOAT 368 | } 369 | } 370 | } 371 | node { 372 | name: "Variable_1" 373 | op: "VariableV2" 374 | attr { 375 | key: "container" 376 | value { 377 | s: "" 378 | } 379 | } 380 | attr { 381 | key: "dtype" 382 | value { 383 | type: DT_FLOAT 384 | } 385 | } 386 | attr { 387 | key: "shape" 388 | value { 389 | shape { 390 | dim { 391 | size: 64 392 | } 393 | dim { 394 | size: 3 395 | } 396 | } 397 | } 398 | } 399 | attr { 400 | key: "shared_name" 401 | value { 402 | s: "" 403 | } 404 | } 405 | } 406 | node { 407 | name: "Variable_1/Assign" 408 | op: "Assign" 409 | input: "Variable_1" 410 | input: "random_normal_1" 411 | attr { 412 | key: "T" 413 | value { 414 | type: DT_FLOAT 415 | } 416 | } 417 | attr { 418 | key: "_class" 419 | value { 420 | list { 421 | s: "loc:@Variable_1" 422 | } 423 | } 424 | } 425 | attr { 426 | key: "use_locking" 427 | value { 428 | b: true 429 | } 430 | } 431 | attr { 432 | key: "validate_shape" 433 | value { 434 | b: true 435 | } 436 | } 437 | } 438 | node { 439 | name: "Variable_1/read" 440 | op: "Identity" 441 | input: "Variable_1" 442 | attr { 443 | key: "T" 444 | value { 445 | type: DT_FLOAT 446 | } 447 | } 448 | attr { 449 | key: "_class" 450 | value { 451 | list { 452 | s: "loc:@Variable_1" 453 | } 454 | } 455 | } 456 | } 457 | node { 458 | name: "MatMul" 459 | op: "MatMul" 460 | input: "inputs" 461 | input: "Variable/read" 462 | attr { 463 | key: "T" 464 | value { 465 | type: DT_FLOAT 466 | } 467 | } 468 | attr { 469 | key: "transpose_a" 470 | value { 471 | b: false 472 | } 473 | } 474 | attr { 475 | key: "transpose_b" 476 | value { 477 | b: false 478 | } 479 | } 480 | } 481 | node { 482 | name: "Sigmoid" 483 | op: "Sigmoid" 484 | input: "MatMul" 485 | attr { 486 | key: "T" 487 | value { 488 | type: DT_FLOAT 489 | } 490 | } 491 | } 492 | node { 493 | name: "MatMul_1" 494 | op: "MatMul" 495 | input: "Sigmoid" 496 | input: "Variable_1/read" 497 | attr { 498 | key: "T" 499 | value { 500 | type: DT_FLOAT 501 | } 502 | } 503 | attr { 504 | key: "transpose_a" 505 | value { 506 | b: false 507 | } 508 | } 509 | attr { 510 | key: "transpose_b" 511 | value { 512 | b: false 513 | } 514 | } 515 | } 516 | node { 517 | name: "output_node" 518 | op: "Softmax" 519 | input: "MatMul_1" 520 | attr { 521 | key: "T" 522 | value { 523 | type: DT_FLOAT 524 | } 525 | } 526 | } 527 | node { 528 | name: "ArgMax/dimension" 529 | op: "Const" 530 | attr { 531 | key: "dtype" 532 | value { 533 | type: DT_INT32 534 | } 535 | } 536 | attr { 537 | key: "value" 538 | value { 539 | tensor { 540 | dtype: DT_INT32 541 | tensor_shape { 542 | } 543 | int_val: 1 544 | } 545 | } 546 | } 547 | } 548 | node { 549 | name: "ArgMax" 550 | op: "ArgMax" 551 | input: "output_node" 552 | input: "ArgMax/dimension" 553 | attr { 554 | key: "T" 555 | value { 556 | type: DT_FLOAT 557 | } 558 | } 559 | attr { 560 | key: "Tidx" 561 | value { 562 | type: DT_INT32 563 | } 564 | } 565 | } 566 | node { 567 | name: "Rank" 568 | op: "Const" 569 | attr { 570 | key: "dtype" 571 | value { 572 | type: DT_INT32 573 | } 574 | } 575 | attr { 576 | key: "value" 577 | value { 578 | tensor { 579 | dtype: DT_INT32 580 | tensor_shape { 581 | } 582 | int_val: 2 583 | } 584 | } 585 | } 586 | } 587 | node { 588 | name: "Shape" 589 | op: "Shape" 590 | input: "output_node" 591 | attr { 592 | key: "T" 593 | value { 594 | type: DT_FLOAT 595 | } 596 | } 597 | attr { 598 | key: "out_type" 599 | value { 600 | type: DT_INT32 601 | } 602 | } 603 | } 604 | node { 605 | name: "Rank_1" 606 | op: "Const" 607 | attr { 608 | key: "dtype" 609 | value { 610 | type: DT_INT32 611 | } 612 | } 613 | attr { 614 | key: "value" 615 | value { 616 | tensor { 617 | dtype: DT_INT32 618 | tensor_shape { 619 | } 620 | int_val: 2 621 | } 622 | } 623 | } 624 | } 625 | node { 626 | name: "Shape_1" 627 | op: "Shape" 628 | input: "output_node" 629 | attr { 630 | key: "T" 631 | value { 632 | type: DT_FLOAT 633 | } 634 | } 635 | attr { 636 | key: "out_type" 637 | value { 638 | type: DT_INT32 639 | } 640 | } 641 | } 642 | node { 643 | name: "Sub/y" 644 | op: "Const" 645 | attr { 646 | key: "dtype" 647 | value { 648 | type: DT_INT32 649 | } 650 | } 651 | attr { 652 | key: "value" 653 | value { 654 | tensor { 655 | dtype: DT_INT32 656 | tensor_shape { 657 | } 658 | int_val: 1 659 | } 660 | } 661 | } 662 | } 663 | node { 664 | name: "Sub" 665 | op: "Sub" 666 | input: "Rank_1" 667 | input: "Sub/y" 668 | attr { 669 | key: "T" 670 | value { 671 | type: DT_INT32 672 | } 673 | } 674 | } 675 | node { 676 | name: "Slice/begin" 677 | op: "Pack" 678 | input: "Sub" 679 | attr { 680 | key: "N" 681 | value { 682 | i: 1 683 | } 684 | } 685 | attr { 686 | key: "T" 687 | value { 688 | type: DT_INT32 689 | } 690 | } 691 | attr { 692 | key: "axis" 693 | value { 694 | i: 0 695 | } 696 | } 697 | } 698 | node { 699 | name: "Slice/size" 700 | op: "Const" 701 | attr { 702 | key: "dtype" 703 | value { 704 | type: DT_INT32 705 | } 706 | } 707 | attr { 708 | key: "value" 709 | value { 710 | tensor { 711 | dtype: DT_INT32 712 | tensor_shape { 713 | dim { 714 | size: 1 715 | } 716 | } 717 | int_val: 1 718 | } 719 | } 720 | } 721 | } 722 | node { 723 | name: "Slice" 724 | op: "Slice" 725 | input: "Shape_1" 726 | input: "Slice/begin" 727 | input: "Slice/size" 728 | attr { 729 | key: "Index" 730 | value { 731 | type: DT_INT32 732 | } 733 | } 734 | attr { 735 | key: "T" 736 | value { 737 | type: DT_INT32 738 | } 739 | } 740 | } 741 | node { 742 | name: "concat/values_0" 743 | op: "Const" 744 | attr { 745 | key: "dtype" 746 | value { 747 | type: DT_INT32 748 | } 749 | } 750 | attr { 751 | key: "value" 752 | value { 753 | tensor { 754 | dtype: DT_INT32 755 | tensor_shape { 756 | dim { 757 | size: 1 758 | } 759 | } 760 | int_val: -1 761 | } 762 | } 763 | } 764 | } 765 | node { 766 | name: "concat/axis" 767 | op: "Const" 768 | attr { 769 | key: "dtype" 770 | value { 771 | type: DT_INT32 772 | } 773 | } 774 | attr { 775 | key: "value" 776 | value { 777 | tensor { 778 | dtype: DT_INT32 779 | tensor_shape { 780 | } 781 | int_val: 0 782 | } 783 | } 784 | } 785 | } 786 | node { 787 | name: "concat" 788 | op: "ConcatV2" 789 | input: "concat/values_0" 790 | input: "Slice" 791 | input: "concat/axis" 792 | attr { 793 | key: "N" 794 | value { 795 | i: 2 796 | } 797 | } 798 | attr { 799 | key: "T" 800 | value { 801 | type: DT_INT32 802 | } 803 | } 804 | attr { 805 | key: "Tidx" 806 | value { 807 | type: DT_INT32 808 | } 809 | } 810 | } 811 | node { 812 | name: "Reshape" 813 | op: "Reshape" 814 | input: "output_node" 815 | input: "concat" 816 | attr { 817 | key: "T" 818 | value { 819 | type: DT_FLOAT 820 | } 821 | } 822 | attr { 823 | key: "Tshape" 824 | value { 825 | type: DT_INT32 826 | } 827 | } 828 | } 829 | node { 830 | name: "Rank_2" 831 | op: "Const" 832 | attr { 833 | key: "dtype" 834 | value { 835 | type: DT_INT32 836 | } 837 | } 838 | attr { 839 | key: "value" 840 | value { 841 | tensor { 842 | dtype: DT_INT32 843 | tensor_shape { 844 | } 845 | int_val: 2 846 | } 847 | } 848 | } 849 | } 850 | node { 851 | name: "Shape_2" 852 | op: "Shape" 853 | input: "target" 854 | attr { 855 | key: "T" 856 | value { 857 | type: DT_FLOAT 858 | } 859 | } 860 | attr { 861 | key: "out_type" 862 | value { 863 | type: DT_INT32 864 | } 865 | } 866 | } 867 | node { 868 | name: "Sub_1/y" 869 | op: "Const" 870 | attr { 871 | key: "dtype" 872 | value { 873 | type: DT_INT32 874 | } 875 | } 876 | attr { 877 | key: "value" 878 | value { 879 | tensor { 880 | dtype: DT_INT32 881 | tensor_shape { 882 | } 883 | int_val: 1 884 | } 885 | } 886 | } 887 | } 888 | node { 889 | name: "Sub_1" 890 | op: "Sub" 891 | input: "Rank_2" 892 | input: "Sub_1/y" 893 | attr { 894 | key: "T" 895 | value { 896 | type: DT_INT32 897 | } 898 | } 899 | } 900 | node { 901 | name: "Slice_1/begin" 902 | op: "Pack" 903 | input: "Sub_1" 904 | attr { 905 | key: "N" 906 | value { 907 | i: 1 908 | } 909 | } 910 | attr { 911 | key: "T" 912 | value { 913 | type: DT_INT32 914 | } 915 | } 916 | attr { 917 | key: "axis" 918 | value { 919 | i: 0 920 | } 921 | } 922 | } 923 | node { 924 | name: "Slice_1/size" 925 | op: "Const" 926 | attr { 927 | key: "dtype" 928 | value { 929 | type: DT_INT32 930 | } 931 | } 932 | attr { 933 | key: "value" 934 | value { 935 | tensor { 936 | dtype: DT_INT32 937 | tensor_shape { 938 | dim { 939 | size: 1 940 | } 941 | } 942 | int_val: 1 943 | } 944 | } 945 | } 946 | } 947 | node { 948 | name: "Slice_1" 949 | op: "Slice" 950 | input: "Shape_2" 951 | input: "Slice_1/begin" 952 | input: "Slice_1/size" 953 | attr { 954 | key: "Index" 955 | value { 956 | type: DT_INT32 957 | } 958 | } 959 | attr { 960 | key: "T" 961 | value { 962 | type: DT_INT32 963 | } 964 | } 965 | } 966 | node { 967 | name: "concat_1/values_0" 968 | op: "Const" 969 | attr { 970 | key: "dtype" 971 | value { 972 | type: DT_INT32 973 | } 974 | } 975 | attr { 976 | key: "value" 977 | value { 978 | tensor { 979 | dtype: DT_INT32 980 | tensor_shape { 981 | dim { 982 | size: 1 983 | } 984 | } 985 | int_val: -1 986 | } 987 | } 988 | } 989 | } 990 | node { 991 | name: "concat_1/axis" 992 | op: "Const" 993 | attr { 994 | key: "dtype" 995 | value { 996 | type: DT_INT32 997 | } 998 | } 999 | attr { 1000 | key: "value" 1001 | value { 1002 | tensor { 1003 | dtype: DT_INT32 1004 | tensor_shape { 1005 | } 1006 | int_val: 0 1007 | } 1008 | } 1009 | } 1010 | } 1011 | node { 1012 | name: "concat_1" 1013 | op: "ConcatV2" 1014 | input: "concat_1/values_0" 1015 | input: "Slice_1" 1016 | input: "concat_1/axis" 1017 | attr { 1018 | key: "N" 1019 | value { 1020 | i: 2 1021 | } 1022 | } 1023 | attr { 1024 | key: "T" 1025 | value { 1026 | type: DT_INT32 1027 | } 1028 | } 1029 | attr { 1030 | key: "Tidx" 1031 | value { 1032 | type: DT_INT32 1033 | } 1034 | } 1035 | } 1036 | node { 1037 | name: "Reshape_1" 1038 | op: "Reshape" 1039 | input: "target" 1040 | input: "concat_1" 1041 | attr { 1042 | key: "T" 1043 | value { 1044 | type: DT_FLOAT 1045 | } 1046 | } 1047 | attr { 1048 | key: "Tshape" 1049 | value { 1050 | type: DT_INT32 1051 | } 1052 | } 1053 | } 1054 | node { 1055 | name: "SoftmaxCrossEntropyWithLogits" 1056 | op: "SoftmaxCrossEntropyWithLogits" 1057 | input: "Reshape" 1058 | input: "Reshape_1" 1059 | attr { 1060 | key: "T" 1061 | value { 1062 | type: DT_FLOAT 1063 | } 1064 | } 1065 | } 1066 | node { 1067 | name: "Sub_2/y" 1068 | op: "Const" 1069 | attr { 1070 | key: "dtype" 1071 | value { 1072 | type: DT_INT32 1073 | } 1074 | } 1075 | attr { 1076 | key: "value" 1077 | value { 1078 | tensor { 1079 | dtype: DT_INT32 1080 | tensor_shape { 1081 | } 1082 | int_val: 1 1083 | } 1084 | } 1085 | } 1086 | } 1087 | node { 1088 | name: "Sub_2" 1089 | op: "Sub" 1090 | input: "Rank" 1091 | input: "Sub_2/y" 1092 | attr { 1093 | key: "T" 1094 | value { 1095 | type: DT_INT32 1096 | } 1097 | } 1098 | } 1099 | node { 1100 | name: "Slice_2/begin" 1101 | op: "Const" 1102 | attr { 1103 | key: "dtype" 1104 | value { 1105 | type: DT_INT32 1106 | } 1107 | } 1108 | attr { 1109 | key: "value" 1110 | value { 1111 | tensor { 1112 | dtype: DT_INT32 1113 | tensor_shape { 1114 | dim { 1115 | size: 1 1116 | } 1117 | } 1118 | int_val: 0 1119 | } 1120 | } 1121 | } 1122 | } 1123 | node { 1124 | name: "Slice_2/size" 1125 | op: "Pack" 1126 | input: "Sub_2" 1127 | attr { 1128 | key: "N" 1129 | value { 1130 | i: 1 1131 | } 1132 | } 1133 | attr { 1134 | key: "T" 1135 | value { 1136 | type: DT_INT32 1137 | } 1138 | } 1139 | attr { 1140 | key: "axis" 1141 | value { 1142 | i: 0 1143 | } 1144 | } 1145 | } 1146 | node { 1147 | name: "Slice_2" 1148 | op: "Slice" 1149 | input: "Shape" 1150 | input: "Slice_2/begin" 1151 | input: "Slice_2/size" 1152 | attr { 1153 | key: "Index" 1154 | value { 1155 | type: DT_INT32 1156 | } 1157 | } 1158 | attr { 1159 | key: "T" 1160 | value { 1161 | type: DT_INT32 1162 | } 1163 | } 1164 | } 1165 | node { 1166 | name: "Reshape_2" 1167 | op: "Reshape" 1168 | input: "SoftmaxCrossEntropyWithLogits" 1169 | input: "Slice_2" 1170 | attr { 1171 | key: "T" 1172 | value { 1173 | type: DT_FLOAT 1174 | } 1175 | } 1176 | attr { 1177 | key: "Tshape" 1178 | value { 1179 | type: DT_INT32 1180 | } 1181 | } 1182 | } 1183 | node { 1184 | name: "Const" 1185 | op: "Const" 1186 | attr { 1187 | key: "dtype" 1188 | value { 1189 | type: DT_INT32 1190 | } 1191 | } 1192 | attr { 1193 | key: "value" 1194 | value { 1195 | tensor { 1196 | dtype: DT_INT32 1197 | tensor_shape { 1198 | dim { 1199 | size: 1 1200 | } 1201 | } 1202 | int_val: 0 1203 | } 1204 | } 1205 | } 1206 | } 1207 | node { 1208 | name: "Mean" 1209 | op: "Mean" 1210 | input: "Reshape_2" 1211 | input: "Const" 1212 | attr { 1213 | key: "T" 1214 | value { 1215 | type: DT_FLOAT 1216 | } 1217 | } 1218 | attr { 1219 | key: "Tidx" 1220 | value { 1221 | type: DT_INT32 1222 | } 1223 | } 1224 | attr { 1225 | key: "keep_dims" 1226 | value { 1227 | b: false 1228 | } 1229 | } 1230 | } 1231 | node { 1232 | name: "gradients/Shape" 1233 | op: "Const" 1234 | attr { 1235 | key: "dtype" 1236 | value { 1237 | type: DT_INT32 1238 | } 1239 | } 1240 | attr { 1241 | key: "value" 1242 | value { 1243 | tensor { 1244 | dtype: DT_INT32 1245 | tensor_shape { 1246 | dim { 1247 | } 1248 | } 1249 | } 1250 | } 1251 | } 1252 | } 1253 | node { 1254 | name: "gradients/Const" 1255 | op: "Const" 1256 | attr { 1257 | key: "dtype" 1258 | value { 1259 | type: DT_FLOAT 1260 | } 1261 | } 1262 | attr { 1263 | key: "value" 1264 | value { 1265 | tensor { 1266 | dtype: DT_FLOAT 1267 | tensor_shape { 1268 | } 1269 | float_val: 1.0 1270 | } 1271 | } 1272 | } 1273 | } 1274 | node { 1275 | name: "gradients/Fill" 1276 | op: "Fill" 1277 | input: "gradients/Shape" 1278 | input: "gradients/Const" 1279 | attr { 1280 | key: "T" 1281 | value { 1282 | type: DT_FLOAT 1283 | } 1284 | } 1285 | } 1286 | node { 1287 | name: "gradients/Mean_grad/Reshape/shape" 1288 | op: "Const" 1289 | attr { 1290 | key: "dtype" 1291 | value { 1292 | type: DT_INT32 1293 | } 1294 | } 1295 | attr { 1296 | key: "value" 1297 | value { 1298 | tensor { 1299 | dtype: DT_INT32 1300 | tensor_shape { 1301 | dim { 1302 | size: 1 1303 | } 1304 | } 1305 | int_val: 1 1306 | } 1307 | } 1308 | } 1309 | } 1310 | node { 1311 | name: "gradients/Mean_grad/Reshape" 1312 | op: "Reshape" 1313 | input: "gradients/Fill" 1314 | input: "gradients/Mean_grad/Reshape/shape" 1315 | attr { 1316 | key: "T" 1317 | value { 1318 | type: DT_FLOAT 1319 | } 1320 | } 1321 | attr { 1322 | key: "Tshape" 1323 | value { 1324 | type: DT_INT32 1325 | } 1326 | } 1327 | } 1328 | node { 1329 | name: "gradients/Mean_grad/Shape" 1330 | op: "Shape" 1331 | input: "Reshape_2" 1332 | attr { 1333 | key: "T" 1334 | value { 1335 | type: DT_FLOAT 1336 | } 1337 | } 1338 | attr { 1339 | key: "out_type" 1340 | value { 1341 | type: DT_INT32 1342 | } 1343 | } 1344 | } 1345 | node { 1346 | name: "gradients/Mean_grad/Tile" 1347 | op: "Tile" 1348 | input: "gradients/Mean_grad/Reshape" 1349 | input: "gradients/Mean_grad/Shape" 1350 | attr { 1351 | key: "T" 1352 | value { 1353 | type: DT_FLOAT 1354 | } 1355 | } 1356 | attr { 1357 | key: "Tmultiples" 1358 | value { 1359 | type: DT_INT32 1360 | } 1361 | } 1362 | } 1363 | node { 1364 | name: "gradients/Mean_grad/Shape_1" 1365 | op: "Shape" 1366 | input: "Reshape_2" 1367 | attr { 1368 | key: "T" 1369 | value { 1370 | type: DT_FLOAT 1371 | } 1372 | } 1373 | attr { 1374 | key: "out_type" 1375 | value { 1376 | type: DT_INT32 1377 | } 1378 | } 1379 | } 1380 | node { 1381 | name: "gradients/Mean_grad/Shape_2" 1382 | op: "Const" 1383 | attr { 1384 | key: "dtype" 1385 | value { 1386 | type: DT_INT32 1387 | } 1388 | } 1389 | attr { 1390 | key: "value" 1391 | value { 1392 | tensor { 1393 | dtype: DT_INT32 1394 | tensor_shape { 1395 | dim { 1396 | } 1397 | } 1398 | } 1399 | } 1400 | } 1401 | } 1402 | node { 1403 | name: "gradients/Mean_grad/Const" 1404 | op: "Const" 1405 | attr { 1406 | key: "dtype" 1407 | value { 1408 | type: DT_INT32 1409 | } 1410 | } 1411 | attr { 1412 | key: "value" 1413 | value { 1414 | tensor { 1415 | dtype: DT_INT32 1416 | tensor_shape { 1417 | dim { 1418 | size: 1 1419 | } 1420 | } 1421 | int_val: 0 1422 | } 1423 | } 1424 | } 1425 | } 1426 | node { 1427 | name: "gradients/Mean_grad/Prod" 1428 | op: "Prod" 1429 | input: "gradients/Mean_grad/Shape_1" 1430 | input: "gradients/Mean_grad/Const" 1431 | attr { 1432 | key: "T" 1433 | value { 1434 | type: DT_INT32 1435 | } 1436 | } 1437 | attr { 1438 | key: "Tidx" 1439 | value { 1440 | type: DT_INT32 1441 | } 1442 | } 1443 | attr { 1444 | key: "keep_dims" 1445 | value { 1446 | b: false 1447 | } 1448 | } 1449 | } 1450 | node { 1451 | name: "gradients/Mean_grad/Const_1" 1452 | op: "Const" 1453 | attr { 1454 | key: "dtype" 1455 | value { 1456 | type: DT_INT32 1457 | } 1458 | } 1459 | attr { 1460 | key: "value" 1461 | value { 1462 | tensor { 1463 | dtype: DT_INT32 1464 | tensor_shape { 1465 | dim { 1466 | size: 1 1467 | } 1468 | } 1469 | int_val: 0 1470 | } 1471 | } 1472 | } 1473 | } 1474 | node { 1475 | name: "gradients/Mean_grad/Prod_1" 1476 | op: "Prod" 1477 | input: "gradients/Mean_grad/Shape_2" 1478 | input: "gradients/Mean_grad/Const_1" 1479 | attr { 1480 | key: "T" 1481 | value { 1482 | type: DT_INT32 1483 | } 1484 | } 1485 | attr { 1486 | key: "Tidx" 1487 | value { 1488 | type: DT_INT32 1489 | } 1490 | } 1491 | attr { 1492 | key: "keep_dims" 1493 | value { 1494 | b: false 1495 | } 1496 | } 1497 | } 1498 | node { 1499 | name: "gradients/Mean_grad/Maximum/y" 1500 | op: "Const" 1501 | attr { 1502 | key: "dtype" 1503 | value { 1504 | type: DT_INT32 1505 | } 1506 | } 1507 | attr { 1508 | key: "value" 1509 | value { 1510 | tensor { 1511 | dtype: DT_INT32 1512 | tensor_shape { 1513 | } 1514 | int_val: 1 1515 | } 1516 | } 1517 | } 1518 | } 1519 | node { 1520 | name: "gradients/Mean_grad/Maximum" 1521 | op: "Maximum" 1522 | input: "gradients/Mean_grad/Prod_1" 1523 | input: "gradients/Mean_grad/Maximum/y" 1524 | attr { 1525 | key: "T" 1526 | value { 1527 | type: DT_INT32 1528 | } 1529 | } 1530 | } 1531 | node { 1532 | name: "gradients/Mean_grad/floordiv" 1533 | op: "FloorDiv" 1534 | input: "gradients/Mean_grad/Prod" 1535 | input: "gradients/Mean_grad/Maximum" 1536 | attr { 1537 | key: "T" 1538 | value { 1539 | type: DT_INT32 1540 | } 1541 | } 1542 | } 1543 | node { 1544 | name: "gradients/Mean_grad/Cast" 1545 | op: "Cast" 1546 | input: "gradients/Mean_grad/floordiv" 1547 | attr { 1548 | key: "DstT" 1549 | value { 1550 | type: DT_FLOAT 1551 | } 1552 | } 1553 | attr { 1554 | key: "SrcT" 1555 | value { 1556 | type: DT_INT32 1557 | } 1558 | } 1559 | } 1560 | node { 1561 | name: "gradients/Mean_grad/truediv" 1562 | op: "RealDiv" 1563 | input: "gradients/Mean_grad/Tile" 1564 | input: "gradients/Mean_grad/Cast" 1565 | attr { 1566 | key: "T" 1567 | value { 1568 | type: DT_FLOAT 1569 | } 1570 | } 1571 | } 1572 | node { 1573 | name: "gradients/Reshape_2_grad/Shape" 1574 | op: "Shape" 1575 | input: "SoftmaxCrossEntropyWithLogits" 1576 | attr { 1577 | key: "T" 1578 | value { 1579 | type: DT_FLOAT 1580 | } 1581 | } 1582 | attr { 1583 | key: "out_type" 1584 | value { 1585 | type: DT_INT32 1586 | } 1587 | } 1588 | } 1589 | node { 1590 | name: "gradients/Reshape_2_grad/Reshape" 1591 | op: "Reshape" 1592 | input: "gradients/Mean_grad/truediv" 1593 | input: "gradients/Reshape_2_grad/Shape" 1594 | attr { 1595 | key: "T" 1596 | value { 1597 | type: DT_FLOAT 1598 | } 1599 | } 1600 | attr { 1601 | key: "Tshape" 1602 | value { 1603 | type: DT_INT32 1604 | } 1605 | } 1606 | } 1607 | node { 1608 | name: "gradients/zeros_like" 1609 | op: "ZerosLike" 1610 | input: "SoftmaxCrossEntropyWithLogits:1" 1611 | attr { 1612 | key: "T" 1613 | value { 1614 | type: DT_FLOAT 1615 | } 1616 | } 1617 | } 1618 | node { 1619 | name: "gradients/SoftmaxCrossEntropyWithLogits_grad/ExpandDims/dim" 1620 | op: "Const" 1621 | attr { 1622 | key: "dtype" 1623 | value { 1624 | type: DT_INT32 1625 | } 1626 | } 1627 | attr { 1628 | key: "value" 1629 | value { 1630 | tensor { 1631 | dtype: DT_INT32 1632 | tensor_shape { 1633 | } 1634 | int_val: -1 1635 | } 1636 | } 1637 | } 1638 | } 1639 | node { 1640 | name: "gradients/SoftmaxCrossEntropyWithLogits_grad/ExpandDims" 1641 | op: "ExpandDims" 1642 | input: "gradients/Reshape_2_grad/Reshape" 1643 | input: "gradients/SoftmaxCrossEntropyWithLogits_grad/ExpandDims/dim" 1644 | attr { 1645 | key: "T" 1646 | value { 1647 | type: DT_FLOAT 1648 | } 1649 | } 1650 | attr { 1651 | key: "Tdim" 1652 | value { 1653 | type: DT_INT32 1654 | } 1655 | } 1656 | } 1657 | node { 1658 | name: "gradients/SoftmaxCrossEntropyWithLogits_grad/mul" 1659 | op: "Mul" 1660 | input: "gradients/SoftmaxCrossEntropyWithLogits_grad/ExpandDims" 1661 | input: "SoftmaxCrossEntropyWithLogits:1" 1662 | attr { 1663 | key: "T" 1664 | value { 1665 | type: DT_FLOAT 1666 | } 1667 | } 1668 | } 1669 | node { 1670 | name: "gradients/Reshape_grad/Shape" 1671 | op: "Shape" 1672 | input: "output_node" 1673 | attr { 1674 | key: "T" 1675 | value { 1676 | type: DT_FLOAT 1677 | } 1678 | } 1679 | attr { 1680 | key: "out_type" 1681 | value { 1682 | type: DT_INT32 1683 | } 1684 | } 1685 | } 1686 | node { 1687 | name: "gradients/Reshape_grad/Reshape" 1688 | op: "Reshape" 1689 | input: "gradients/SoftmaxCrossEntropyWithLogits_grad/mul" 1690 | input: "gradients/Reshape_grad/Shape" 1691 | attr { 1692 | key: "T" 1693 | value { 1694 | type: DT_FLOAT 1695 | } 1696 | } 1697 | attr { 1698 | key: "Tshape" 1699 | value { 1700 | type: DT_INT32 1701 | } 1702 | } 1703 | } 1704 | node { 1705 | name: "gradients/output_node_grad/mul" 1706 | op: "Mul" 1707 | input: "gradients/Reshape_grad/Reshape" 1708 | input: "output_node" 1709 | attr { 1710 | key: "T" 1711 | value { 1712 | type: DT_FLOAT 1713 | } 1714 | } 1715 | } 1716 | node { 1717 | name: "gradients/output_node_grad/Sum/reduction_indices" 1718 | op: "Const" 1719 | attr { 1720 | key: "dtype" 1721 | value { 1722 | type: DT_INT32 1723 | } 1724 | } 1725 | attr { 1726 | key: "value" 1727 | value { 1728 | tensor { 1729 | dtype: DT_INT32 1730 | tensor_shape { 1731 | dim { 1732 | size: 1 1733 | } 1734 | } 1735 | int_val: 1 1736 | } 1737 | } 1738 | } 1739 | } 1740 | node { 1741 | name: "gradients/output_node_grad/Sum" 1742 | op: "Sum" 1743 | input: "gradients/output_node_grad/mul" 1744 | input: "gradients/output_node_grad/Sum/reduction_indices" 1745 | attr { 1746 | key: "T" 1747 | value { 1748 | type: DT_FLOAT 1749 | } 1750 | } 1751 | attr { 1752 | key: "Tidx" 1753 | value { 1754 | type: DT_INT32 1755 | } 1756 | } 1757 | attr { 1758 | key: "keep_dims" 1759 | value { 1760 | b: false 1761 | } 1762 | } 1763 | } 1764 | node { 1765 | name: "gradients/output_node_grad/Reshape/shape" 1766 | op: "Const" 1767 | attr { 1768 | key: "dtype" 1769 | value { 1770 | type: DT_INT32 1771 | } 1772 | } 1773 | attr { 1774 | key: "value" 1775 | value { 1776 | tensor { 1777 | dtype: DT_INT32 1778 | tensor_shape { 1779 | dim { 1780 | size: 2 1781 | } 1782 | } 1783 | tensor_content: "\377\377\377\377\001\000\000\000" 1784 | } 1785 | } 1786 | } 1787 | } 1788 | node { 1789 | name: "gradients/output_node_grad/Reshape" 1790 | op: "Reshape" 1791 | input: "gradients/output_node_grad/Sum" 1792 | input: "gradients/output_node_grad/Reshape/shape" 1793 | attr { 1794 | key: "T" 1795 | value { 1796 | type: DT_FLOAT 1797 | } 1798 | } 1799 | attr { 1800 | key: "Tshape" 1801 | value { 1802 | type: DT_INT32 1803 | } 1804 | } 1805 | } 1806 | node { 1807 | name: "gradients/output_node_grad/sub" 1808 | op: "Sub" 1809 | input: "gradients/Reshape_grad/Reshape" 1810 | input: "gradients/output_node_grad/Reshape" 1811 | attr { 1812 | key: "T" 1813 | value { 1814 | type: DT_FLOAT 1815 | } 1816 | } 1817 | } 1818 | node { 1819 | name: "gradients/output_node_grad/mul_1" 1820 | op: "Mul" 1821 | input: "gradients/output_node_grad/sub" 1822 | input: "output_node" 1823 | attr { 1824 | key: "T" 1825 | value { 1826 | type: DT_FLOAT 1827 | } 1828 | } 1829 | } 1830 | node { 1831 | name: "gradients/MatMul_1_grad/MatMul" 1832 | op: "MatMul" 1833 | input: "gradients/output_node_grad/mul_1" 1834 | input: "Variable_1/read" 1835 | attr { 1836 | key: "T" 1837 | value { 1838 | type: DT_FLOAT 1839 | } 1840 | } 1841 | attr { 1842 | key: "transpose_a" 1843 | value { 1844 | b: false 1845 | } 1846 | } 1847 | attr { 1848 | key: "transpose_b" 1849 | value { 1850 | b: true 1851 | } 1852 | } 1853 | } 1854 | node { 1855 | name: "gradients/MatMul_1_grad/MatMul_1" 1856 | op: "MatMul" 1857 | input: "Sigmoid" 1858 | input: "gradients/output_node_grad/mul_1" 1859 | attr { 1860 | key: "T" 1861 | value { 1862 | type: DT_FLOAT 1863 | } 1864 | } 1865 | attr { 1866 | key: "transpose_a" 1867 | value { 1868 | b: true 1869 | } 1870 | } 1871 | attr { 1872 | key: "transpose_b" 1873 | value { 1874 | b: false 1875 | } 1876 | } 1877 | } 1878 | node { 1879 | name: "gradients/MatMul_1_grad/tuple/group_deps" 1880 | op: "NoOp" 1881 | input: "^gradients/MatMul_1_grad/MatMul" 1882 | input: "^gradients/MatMul_1_grad/MatMul_1" 1883 | } 1884 | node { 1885 | name: "gradients/MatMul_1_grad/tuple/control_dependency" 1886 | op: "Identity" 1887 | input: "gradients/MatMul_1_grad/MatMul" 1888 | input: "^gradients/MatMul_1_grad/tuple/group_deps" 1889 | attr { 1890 | key: "T" 1891 | value { 1892 | type: DT_FLOAT 1893 | } 1894 | } 1895 | attr { 1896 | key: "_class" 1897 | value { 1898 | list { 1899 | s: "loc:@gradients/MatMul_1_grad/MatMul" 1900 | } 1901 | } 1902 | } 1903 | } 1904 | node { 1905 | name: "gradients/MatMul_1_grad/tuple/control_dependency_1" 1906 | op: "Identity" 1907 | input: "gradients/MatMul_1_grad/MatMul_1" 1908 | input: "^gradients/MatMul_1_grad/tuple/group_deps" 1909 | attr { 1910 | key: "T" 1911 | value { 1912 | type: DT_FLOAT 1913 | } 1914 | } 1915 | attr { 1916 | key: "_class" 1917 | value { 1918 | list { 1919 | s: "loc:@gradients/MatMul_1_grad/MatMul_1" 1920 | } 1921 | } 1922 | } 1923 | } 1924 | node { 1925 | name: "gradients/Sigmoid_grad/SigmoidGrad" 1926 | op: "SigmoidGrad" 1927 | input: "Sigmoid" 1928 | input: "gradients/MatMul_1_grad/tuple/control_dependency" 1929 | attr { 1930 | key: "T" 1931 | value { 1932 | type: DT_FLOAT 1933 | } 1934 | } 1935 | } 1936 | node { 1937 | name: "gradients/MatMul_grad/MatMul" 1938 | op: "MatMul" 1939 | input: "gradients/Sigmoid_grad/SigmoidGrad" 1940 | input: "Variable/read" 1941 | attr { 1942 | key: "T" 1943 | value { 1944 | type: DT_FLOAT 1945 | } 1946 | } 1947 | attr { 1948 | key: "transpose_a" 1949 | value { 1950 | b: false 1951 | } 1952 | } 1953 | attr { 1954 | key: "transpose_b" 1955 | value { 1956 | b: true 1957 | } 1958 | } 1959 | } 1960 | node { 1961 | name: "gradients/MatMul_grad/MatMul_1" 1962 | op: "MatMul" 1963 | input: "inputs" 1964 | input: "gradients/Sigmoid_grad/SigmoidGrad" 1965 | attr { 1966 | key: "T" 1967 | value { 1968 | type: DT_FLOAT 1969 | } 1970 | } 1971 | attr { 1972 | key: "transpose_a" 1973 | value { 1974 | b: true 1975 | } 1976 | } 1977 | attr { 1978 | key: "transpose_b" 1979 | value { 1980 | b: false 1981 | } 1982 | } 1983 | } 1984 | node { 1985 | name: "gradients/MatMul_grad/tuple/group_deps" 1986 | op: "NoOp" 1987 | input: "^gradients/MatMul_grad/MatMul" 1988 | input: "^gradients/MatMul_grad/MatMul_1" 1989 | } 1990 | node { 1991 | name: "gradients/MatMul_grad/tuple/control_dependency" 1992 | op: "Identity" 1993 | input: "gradients/MatMul_grad/MatMul" 1994 | input: "^gradients/MatMul_grad/tuple/group_deps" 1995 | attr { 1996 | key: "T" 1997 | value { 1998 | type: DT_FLOAT 1999 | } 2000 | } 2001 | attr { 2002 | key: "_class" 2003 | value { 2004 | list { 2005 | s: "loc:@gradients/MatMul_grad/MatMul" 2006 | } 2007 | } 2008 | } 2009 | } 2010 | node { 2011 | name: "gradients/MatMul_grad/tuple/control_dependency_1" 2012 | op: "Identity" 2013 | input: "gradients/MatMul_grad/MatMul_1" 2014 | input: "^gradients/MatMul_grad/tuple/group_deps" 2015 | attr { 2016 | key: "T" 2017 | value { 2018 | type: DT_FLOAT 2019 | } 2020 | } 2021 | attr { 2022 | key: "_class" 2023 | value { 2024 | list { 2025 | s: "loc:@gradients/MatMul_grad/MatMul_1" 2026 | } 2027 | } 2028 | } 2029 | } 2030 | node { 2031 | name: "GradientDescent/learning_rate" 2032 | op: "Const" 2033 | attr { 2034 | key: "dtype" 2035 | value { 2036 | type: DT_FLOAT 2037 | } 2038 | } 2039 | attr { 2040 | key: "value" 2041 | value { 2042 | tensor { 2043 | dtype: DT_FLOAT 2044 | tensor_shape { 2045 | } 2046 | float_val: 0.00999999977648 2047 | } 2048 | } 2049 | } 2050 | } 2051 | node { 2052 | name: "GradientDescent/update_Variable/ApplyGradientDescent" 2053 | op: "ApplyGradientDescent" 2054 | input: "Variable" 2055 | input: "GradientDescent/learning_rate" 2056 | input: "gradients/MatMul_grad/tuple/control_dependency_1" 2057 | attr { 2058 | key: "T" 2059 | value { 2060 | type: DT_FLOAT 2061 | } 2062 | } 2063 | attr { 2064 | key: "_class" 2065 | value { 2066 | list { 2067 | s: "loc:@Variable" 2068 | } 2069 | } 2070 | } 2071 | attr { 2072 | key: "use_locking" 2073 | value { 2074 | b: false 2075 | } 2076 | } 2077 | } 2078 | node { 2079 | name: "GradientDescent/update_Variable_1/ApplyGradientDescent" 2080 | op: "ApplyGradientDescent" 2081 | input: "Variable_1" 2082 | input: "GradientDescent/learning_rate" 2083 | input: "gradients/MatMul_1_grad/tuple/control_dependency_1" 2084 | attr { 2085 | key: "T" 2086 | value { 2087 | type: DT_FLOAT 2088 | } 2089 | } 2090 | attr { 2091 | key: "_class" 2092 | value { 2093 | list { 2094 | s: "loc:@Variable_1" 2095 | } 2096 | } 2097 | } 2098 | attr { 2099 | key: "use_locking" 2100 | value { 2101 | b: false 2102 | } 2103 | } 2104 | } 2105 | node { 2106 | name: "GradientDescent" 2107 | op: "NoOp" 2108 | input: "^GradientDescent/update_Variable/ApplyGradientDescent" 2109 | input: "^GradientDescent/update_Variable_1/ApplyGradientDescent" 2110 | } 2111 | node { 2112 | name: "save/Const" 2113 | op: "Const" 2114 | attr { 2115 | key: "dtype" 2116 | value { 2117 | type: DT_STRING 2118 | } 2119 | } 2120 | attr { 2121 | key: "value" 2122 | value { 2123 | tensor { 2124 | dtype: DT_STRING 2125 | tensor_shape { 2126 | } 2127 | string_val: "model" 2128 | } 2129 | } 2130 | } 2131 | } 2132 | node { 2133 | name: "save/SaveV2/tensor_names" 2134 | op: "Const" 2135 | attr { 2136 | key: "dtype" 2137 | value { 2138 | type: DT_STRING 2139 | } 2140 | } 2141 | attr { 2142 | key: "value" 2143 | value { 2144 | tensor { 2145 | dtype: DT_STRING 2146 | tensor_shape { 2147 | dim { 2148 | size: 2 2149 | } 2150 | } 2151 | string_val: "Variable" 2152 | string_val: "Variable_1" 2153 | } 2154 | } 2155 | } 2156 | } 2157 | node { 2158 | name: "save/SaveV2/shape_and_slices" 2159 | op: "Const" 2160 | attr { 2161 | key: "dtype" 2162 | value { 2163 | type: DT_STRING 2164 | } 2165 | } 2166 | attr { 2167 | key: "value" 2168 | value { 2169 | tensor { 2170 | dtype: DT_STRING 2171 | tensor_shape { 2172 | dim { 2173 | size: 2 2174 | } 2175 | } 2176 | string_val: "" 2177 | string_val: "" 2178 | } 2179 | } 2180 | } 2181 | } 2182 | node { 2183 | name: "save/SaveV2" 2184 | op: "SaveV2" 2185 | input: "save/Const" 2186 | input: "save/SaveV2/tensor_names" 2187 | input: "save/SaveV2/shape_and_slices" 2188 | input: "Variable" 2189 | input: "Variable_1" 2190 | attr { 2191 | key: "dtypes" 2192 | value { 2193 | list { 2194 | type: DT_FLOAT 2195 | type: DT_FLOAT 2196 | } 2197 | } 2198 | } 2199 | } 2200 | node { 2201 | name: "save/control_dependency" 2202 | op: "Identity" 2203 | input: "save/Const" 2204 | input: "^save/SaveV2" 2205 | attr { 2206 | key: "T" 2207 | value { 2208 | type: DT_STRING 2209 | } 2210 | } 2211 | attr { 2212 | key: "_class" 2213 | value { 2214 | list { 2215 | s: "loc:@save/Const" 2216 | } 2217 | } 2218 | } 2219 | } 2220 | node { 2221 | name: "save/RestoreV2/tensor_names" 2222 | op: "Const" 2223 | attr { 2224 | key: "dtype" 2225 | value { 2226 | type: DT_STRING 2227 | } 2228 | } 2229 | attr { 2230 | key: "value" 2231 | value { 2232 | tensor { 2233 | dtype: DT_STRING 2234 | tensor_shape { 2235 | dim { 2236 | size: 1 2237 | } 2238 | } 2239 | string_val: "Variable" 2240 | } 2241 | } 2242 | } 2243 | } 2244 | node { 2245 | name: "save/RestoreV2/shape_and_slices" 2246 | op: "Const" 2247 | attr { 2248 | key: "dtype" 2249 | value { 2250 | type: DT_STRING 2251 | } 2252 | } 2253 | attr { 2254 | key: "value" 2255 | value { 2256 | tensor { 2257 | dtype: DT_STRING 2258 | tensor_shape { 2259 | dim { 2260 | size: 1 2261 | } 2262 | } 2263 | string_val: "" 2264 | } 2265 | } 2266 | } 2267 | } 2268 | node { 2269 | name: "save/RestoreV2" 2270 | op: "RestoreV2" 2271 | input: "save/Const" 2272 | input: "save/RestoreV2/tensor_names" 2273 | input: "save/RestoreV2/shape_and_slices" 2274 | attr { 2275 | key: "dtypes" 2276 | value { 2277 | list { 2278 | type: DT_FLOAT 2279 | } 2280 | } 2281 | } 2282 | } 2283 | node { 2284 | name: "save/Assign" 2285 | op: "Assign" 2286 | input: "Variable" 2287 | input: "save/RestoreV2" 2288 | attr { 2289 | key: "T" 2290 | value { 2291 | type: DT_FLOAT 2292 | } 2293 | } 2294 | attr { 2295 | key: "_class" 2296 | value { 2297 | list { 2298 | s: "loc:@Variable" 2299 | } 2300 | } 2301 | } 2302 | attr { 2303 | key: "use_locking" 2304 | value { 2305 | b: true 2306 | } 2307 | } 2308 | attr { 2309 | key: "validate_shape" 2310 | value { 2311 | b: true 2312 | } 2313 | } 2314 | } 2315 | node { 2316 | name: "save/RestoreV2_1/tensor_names" 2317 | op: "Const" 2318 | attr { 2319 | key: "dtype" 2320 | value { 2321 | type: DT_STRING 2322 | } 2323 | } 2324 | attr { 2325 | key: "value" 2326 | value { 2327 | tensor { 2328 | dtype: DT_STRING 2329 | tensor_shape { 2330 | dim { 2331 | size: 1 2332 | } 2333 | } 2334 | string_val: "Variable_1" 2335 | } 2336 | } 2337 | } 2338 | } 2339 | node { 2340 | name: "save/RestoreV2_1/shape_and_slices" 2341 | op: "Const" 2342 | attr { 2343 | key: "dtype" 2344 | value { 2345 | type: DT_STRING 2346 | } 2347 | } 2348 | attr { 2349 | key: "value" 2350 | value { 2351 | tensor { 2352 | dtype: DT_STRING 2353 | tensor_shape { 2354 | dim { 2355 | size: 1 2356 | } 2357 | } 2358 | string_val: "" 2359 | } 2360 | } 2361 | } 2362 | } 2363 | node { 2364 | name: "save/RestoreV2_1" 2365 | op: "RestoreV2" 2366 | input: "save/Const" 2367 | input: "save/RestoreV2_1/tensor_names" 2368 | input: "save/RestoreV2_1/shape_and_slices" 2369 | attr { 2370 | key: "dtypes" 2371 | value { 2372 | list { 2373 | type: DT_FLOAT 2374 | } 2375 | } 2376 | } 2377 | } 2378 | node { 2379 | name: "save/Assign_1" 2380 | op: "Assign" 2381 | input: "Variable_1" 2382 | input: "save/RestoreV2_1" 2383 | attr { 2384 | key: "T" 2385 | value { 2386 | type: DT_FLOAT 2387 | } 2388 | } 2389 | attr { 2390 | key: "_class" 2391 | value { 2392 | list { 2393 | s: "loc:@Variable_1" 2394 | } 2395 | } 2396 | } 2397 | attr { 2398 | key: "use_locking" 2399 | value { 2400 | b: true 2401 | } 2402 | } 2403 | attr { 2404 | key: "validate_shape" 2405 | value { 2406 | b: true 2407 | } 2408 | } 2409 | } 2410 | node { 2411 | name: "save/restore_all" 2412 | op: "NoOp" 2413 | input: "^save/Assign" 2414 | input: "^save/Assign_1" 2415 | } 2416 | node { 2417 | name: "init" 2418 | op: "NoOp" 2419 | input: "^Variable/Assign" 2420 | input: "^Variable_1/Assign" 2421 | } 2422 | versions { 2423 | producer: 22 2424 | } 2425 | -------------------------------------------------------------------------------- /cpp/model/nn_model_frozen.pb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rockingdingo/tensorflow-tutorial/2e24d98a10750a91e129f0fc296b21c0ccc9bc2d/cpp/model/nn_model_frozen.pb -------------------------------------------------------------------------------- /cpp/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | folder_dir=`pwd` 4 | model_path=${folder_dir}/model/nn_model_frozen.pb 5 | 6 | #cp binary to root folder 7 | cp ./bin/tfcpp_demo ./tfcpp_demo 8 | 9 | ./tfcpp_demo ${model_path} 10 | 11 | -------------------------------------------------------------------------------- /cpp/scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # freeze the graph and the weights 4 | python freeze_graph.py --input_graph=../model/nn_model.pbtxt --input_checkpoint=../ckpt/nn_model.ckpt --output_graph=../model/nn_model_frozen.pb --output_node_names=output_node 5 | 6 | -------------------------------------------------------------------------------- /cpp/scripts/freeze_graph.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | r"""Converts checkpoint variables into Const ops in a standalone GraphDef file. 16 | 17 | This script is designed to take a GraphDef proto, a SaverDef proto, and a set of 18 | variable values stored in a checkpoint file, and output a GraphDef with all of 19 | the variable ops converted into const ops containing the values of the 20 | variables. 21 | 22 | It's useful to do this when we need to load a single file in C++, especially in 23 | environments like mobile or embedded where we may not have access to the 24 | RestoreTensor ops and file loading calls that they rely on. 25 | 26 | An example of command-line usage is: 27 | bazel build tensorflow/python/tools:freeze_graph && \ 28 | bazel-bin/tensorflow/python/tools/freeze_graph \ 29 | --input_graph=some_graph_def.pb \ 30 | --input_checkpoint=model.ckpt-8361242 \ 31 | --output_graph=/tmp/frozen_graph.pb --output_node_names=softmax 32 | 33 | You can also look at freeze_graph_test.py for an example of how to use it. 34 | 35 | """ 36 | from __future__ import absolute_import 37 | from __future__ import division 38 | from __future__ import print_function 39 | 40 | import argparse 41 | import sys 42 | 43 | from google.protobuf import text_format 44 | 45 | from tensorflow.core.framework import graph_pb2 46 | from tensorflow.core.protobuf import saver_pb2 47 | from tensorflow.python import pywrap_tensorflow 48 | from tensorflow.python.client import session 49 | from tensorflow.python.framework import graph_util 50 | from tensorflow.python.framework import importer 51 | from tensorflow.python.platform import app 52 | from tensorflow.python.platform import gfile 53 | from tensorflow.python.training import saver as saver_lib 54 | 55 | FLAGS = None 56 | 57 | 58 | def freeze_graph_with_def_protos( 59 | input_graph_def, 60 | input_saver_def, 61 | input_checkpoint, 62 | output_node_names, 63 | restore_op_name, 64 | filename_tensor_name, 65 | output_graph, 66 | clear_devices, 67 | initializer_nodes, 68 | variable_names_blacklist=""): 69 | """Converts all variables in a graph and checkpoint into constants.""" 70 | del restore_op_name, filename_tensor_name # Unused by updated loading code. 71 | 72 | # 'input_checkpoint' may be a prefix if we're using Saver V2 format 73 | if not saver_lib.checkpoint_exists(input_checkpoint): 74 | print("Input checkpoint '" + input_checkpoint + "' doesn't exist!") 75 | return -1 76 | 77 | if not output_node_names: 78 | print("You need to supply the name of a node to --output_node_names.") 79 | return -1 80 | 81 | # Remove all the explicit device specifications for this node. This helps to 82 | # make the graph more portable. 83 | if clear_devices: 84 | for node in input_graph_def.node: 85 | node.device = "" 86 | 87 | _ = importer.import_graph_def(input_graph_def, name="") 88 | 89 | with session.Session() as sess: 90 | if input_saver_def: 91 | saver = saver_lib.Saver(saver_def=input_saver_def) 92 | saver.restore(sess, input_checkpoint) 93 | else: 94 | var_list = {} 95 | reader = pywrap_tensorflow.NewCheckpointReader(input_checkpoint) 96 | var_to_shape_map = reader.get_variable_to_shape_map() 97 | for key in var_to_shape_map: 98 | try: 99 | tensor = sess.graph.get_tensor_by_name(key + ":0") 100 | except KeyError: 101 | # This tensor doesn't exist in the graph (for example it's 102 | # 'global_step' or a similar housekeeping element) so skip it. 103 | continue 104 | var_list[key] = tensor 105 | saver = saver_lib.Saver(var_list=var_list) 106 | saver.restore(sess, input_checkpoint) 107 | if initializer_nodes: 108 | sess.run(initializer_nodes) 109 | 110 | variable_names_blacklist = (variable_names_blacklist.split(",") if 111 | variable_names_blacklist else None) 112 | output_graph_def = graph_util.convert_variables_to_constants( 113 | sess, 114 | input_graph_def, 115 | output_node_names.split(","), 116 | variable_names_blacklist=variable_names_blacklist) 117 | 118 | with gfile.GFile(output_graph, "wb") as f: 119 | f.write(output_graph_def.SerializeToString()) 120 | print("%d ops in the final graph." % len(output_graph_def.node)) 121 | 122 | 123 | def _parse_input_graph_proto(input_graph, input_binary): 124 | """Parser input tensorflow graph into GraphDef proto.""" 125 | if not gfile.Exists(input_graph): 126 | print("Input graph file '" + input_graph + "' does not exist!") 127 | return -1 128 | input_graph_def = graph_pb2.GraphDef() 129 | mode = "rb" if input_binary else "r" 130 | with gfile.FastGFile(input_graph, mode) as f: 131 | if input_binary: 132 | input_graph_def.ParseFromString(f.read()) 133 | else: 134 | text_format.Merge(f.read(), input_graph_def) 135 | return input_graph_def 136 | 137 | 138 | def _parse_input_saver_proto(input_saver, input_binary): 139 | """Parser input tensorflow Saver into SaverDef proto.""" 140 | if not gfile.Exists(input_saver): 141 | print("Input saver file '" + input_saver + "' does not exist!") 142 | return -1 143 | mode = "rb" if input_binary else "r" 144 | with gfile.FastGFile(input_saver, mode) as f: 145 | saver_def = saver_pb2.SaverDef() 146 | if input_binary: 147 | saver_def.ParseFromString(f.read()) 148 | else: 149 | text_format.Merge(f.read(), saver_def) 150 | return saver_def 151 | 152 | 153 | def freeze_graph(input_graph, 154 | input_saver, 155 | input_binary, 156 | input_checkpoint, 157 | output_node_names, 158 | restore_op_name, 159 | filename_tensor_name, 160 | output_graph, 161 | clear_devices, 162 | initializer_nodes, 163 | variable_names_blacklist=""): 164 | """Converts all variables in a graph and checkpoint into constants.""" 165 | input_graph_def = _parse_input_graph_proto(input_graph, input_binary) 166 | input_saver_def = None 167 | if input_saver: 168 | input_saver_def = _parse_input_saver_proto(input_saver, input_binary) 169 | freeze_graph_with_def_protos( 170 | input_graph_def, 171 | input_saver_def, 172 | input_checkpoint, 173 | output_node_names, 174 | restore_op_name, 175 | filename_tensor_name, 176 | output_graph, 177 | clear_devices, 178 | initializer_nodes, 179 | variable_names_blacklist) 180 | 181 | 182 | def main(unused_args): 183 | freeze_graph(FLAGS.input_graph, FLAGS.input_saver, FLAGS.input_binary, 184 | FLAGS.input_checkpoint, FLAGS.output_node_names, 185 | FLAGS.restore_op_name, FLAGS.filename_tensor_name, 186 | FLAGS.output_graph, FLAGS.clear_devices, FLAGS.initializer_nodes, 187 | FLAGS.variable_names_blacklist) 188 | 189 | 190 | if __name__ == "__main__": 191 | parser = argparse.ArgumentParser() 192 | parser.register("type", "bool", lambda v: v.lower() == "true") 193 | parser.add_argument( 194 | "--input_graph", 195 | type=str, 196 | default="", 197 | help="TensorFlow \'GraphDef\' file to load.") 198 | parser.add_argument( 199 | "--input_saver", 200 | type=str, 201 | default="", 202 | help="TensorFlow saver file to load.") 203 | parser.add_argument( 204 | "--input_checkpoint", 205 | type=str, 206 | default="", 207 | help="TensorFlow variables file to load.") 208 | parser.add_argument( 209 | "--output_graph", 210 | type=str, 211 | default="", 212 | help="Output \'GraphDef\' file name.") 213 | parser.add_argument( 214 | "--input_binary", 215 | nargs="?", 216 | const=True, 217 | type="bool", 218 | default=False, 219 | help="Whether the input files are in binary format.") 220 | parser.add_argument( 221 | "--output_node_names", 222 | type=str, 223 | default="", 224 | help="The name of the output nodes, comma separated.") 225 | parser.add_argument( 226 | "--restore_op_name", 227 | type=str, 228 | default="save/restore_all", 229 | help="The name of the master restore operator.") 230 | parser.add_argument( 231 | "--filename_tensor_name", 232 | type=str, 233 | default="save/Const:0", 234 | help="The name of the tensor holding the save path.") 235 | parser.add_argument( 236 | "--clear_devices", 237 | nargs="?", 238 | const=True, 239 | type="bool", 240 | default=True, 241 | help="Whether to remove device specifications.") 242 | parser.add_argument( 243 | "--initializer_nodes", 244 | type=str, 245 | default="", 246 | help="comma separated list of initializer nodes to run before freezing.") 247 | parser.add_argument( 248 | "--variable_names_blacklist", 249 | type=str, 250 | default="", 251 | help="""\ 252 | comma separated list of variables to skip converting to constants\ 253 | """) 254 | FLAGS, unparsed = parser.parse_known_args() 255 | app.run(main=main, argv=[sys.argv[0]] + unparsed) 256 | -------------------------------------------------------------------------------- /cpp/scripts/nn_model.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | import tensorflow as tf 3 | import numpy as np 4 | from sklearn import datasets 5 | from sklearn.model_selection import train_test_split 6 | 7 | RANDOM_SEED = 42 8 | tf.set_random_seed(RANDOM_SEED) 9 | 10 | parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 11 | data_path = os.path.join(parent_dir, "data") 12 | train_dir = os.path.join(parent_dir, "ckpt") 13 | model_dir = os.path.join(parent_dir, "model") 14 | 15 | flags = tf.flags 16 | flags.DEFINE_string("data_path", data_path, "data_path") 17 | flags.DEFINE_string("train_dir", train_dir, "train_dir") 18 | flags.DEFINE_string("model_dir", model_dir, "model_dir") 19 | 20 | FLAGS = flags.FLAGS 21 | 22 | class TensorNameConfig(object): 23 | input_tensor = "inputs" 24 | target_tensor = "target" 25 | output_tensor = "output_node" 26 | 27 | def init_weights(shape): 28 | """ Weight initialization """ 29 | weights = tf.random_normal(shape, stddev=0.1) 30 | return tf.Variable(weights) 31 | 32 | class NetworkModel(object): 33 | """ Simple Feed Forward Network with node defined in layers 34 | """ 35 | def __init__(self, layers): 36 | if (len(layers) != 3): 37 | print ("Input layer structure doesn't equal 3") 38 | 39 | self.x_size = layers[0] 40 | self.y_size = layers[len(layers) - 1] # iris outcome 3 classes 41 | 42 | # New tensorname config 43 | conf = TensorNameConfig() 44 | 45 | # placeholders 46 | self.X = tf.placeholder("float", shape=[None, self.x_size], name = conf.input_tensor) 47 | self.Y = tf.placeholder("float", shape=[None, self.y_size], name = conf.target_tensor) 48 | 49 | # Weight initializations 50 | w_1 = init_weights((layers[0], layers[1])) 51 | w_2 = init_weights((layers[1], layers[2])) 52 | 53 | # forward propagation 54 | h = tf.nn.sigmoid(tf.matmul(self.X, w_1)) # hidden layer 55 | self.logits = tf.nn.softmax(tf.matmul(h, w_2), name = conf.output_tensor) # softmax logits of this example 56 | 57 | # Get prediction label 58 | self.y_predict = tf.argmax(self.logits, axis=1) 59 | 60 | # Backward propagation 61 | self.cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=self.Y, logits=self.logits)) 62 | self.train_op = tf.train.GradientDescentOptimizer(0.01).minimize(self.cost) 63 | 64 | # Self Saver 65 | self.saver = tf.train.Saver(tf.global_variables()) 66 | 67 | def run_epoch(): 68 | train_X, test_X, train_y, test_y = get_iris_data() 69 | 70 | # Layer's sizes 71 | x_size = train_X.shape[1] # Number of input nodes: 4 features and 1 bias 72 | h_size = 64 # Number of hidden nodes 73 | y_size = train_y.shape[1] # Number of outcomes (3 iris flowers) 74 | layers = [x_size, h_size, y_size] 75 | print ("NN network layer structure") 76 | print (layers) 77 | 78 | with tf.Session() as session: 79 | # New Model 80 | model = NetworkModel(layers) # default network model 81 | #initialization 82 | session.run(tf.global_variables_initializer()) 83 | 84 | for epoch in range(100): 85 | # See all the examples 86 | for x, y in zip(train_X, train_y): 87 | x = np.reshape(x, (1, x.shape[0])) # shape[1, size] 88 | y = np.reshape(y, (1, y.shape[0])) 89 | fetch_list = [model.train_op, model.cost] # [cost, train_op] 90 | session.run(fetch_list, feed_dict={model.X: x, model.Y: y}) 91 | # evaluation 92 | if (epoch % 5 == 0): 93 | train_accuracy = np.mean(np.argmax(train_y, axis=1) == session.run(model.y_predict, feed_dict={model.X: train_X, model.Y: train_y})) 94 | test_accuracy = np.mean(np.argmax(test_y, axis=1) == session.run(model.y_predict, feed_dict={model.X: test_X, model.Y: test_y})) 95 | print ("Epoch %d, training acc %f and test accuracy %f" % (epoch, train_accuracy, test_accuracy)) 96 | 97 | # Saving checkpoint file 98 | if (epoch % 20 == 0): 99 | checkpoint_path = os.path.join(FLAGS.train_dir, "nn_model.ckpt") 100 | model.saver.save(session, checkpoint_path) 101 | print("Model Saved... at epoch" + str(epoch)) 102 | 103 | # write graph 104 | tf.train.write_graph(session.graph_def, FLAGS.model_dir, "nn_model.pbtxt", as_text=True) 105 | session.close() 106 | 107 | def get_iris_data(): 108 | """ Read the iris data set and split them into training and test sets """ 109 | iris = datasets.load_iris() 110 | data = iris["data"] 111 | target = iris["target"] 112 | 113 | # Prepend the column of 1s for bias 114 | N, M = data.shape 115 | all_X = np.ones((N, M + 1)) 116 | all_X[:, 1:] = data 117 | 118 | # Convert into one-hot vectors 119 | num_labels = len(np.unique(target)) 120 | all_Y = np.eye(num_labels)[target] 121 | return train_test_split(all_X, all_Y, test_size=0.33, random_state=RANDOM_SEED) 122 | 123 | def main(): 124 | run_epoch() 125 | 126 | if __name__ == '__main__': 127 | main() 128 | -------------------------------------------------------------------------------- /cpp/src/ann_model_loader.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ann_model_loader.cpp 3 | * 4 | * Created on: 2017年7月7日 5 | * Author: Derek 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include "ann_model_loader.h" 12 | //#include 13 | 14 | using namespace tensorflow; 15 | 16 | namespace tf_model { 17 | 18 | /** 19 | * ANNFeatureAdapter Implementation 20 | * */ 21 | ANNFeatureAdapter::ANNFeatureAdapter() { 22 | 23 | } 24 | 25 | ANNFeatureAdapter::~ANNFeatureAdapter() { 26 | 27 | } 28 | 29 | /* 30 | * @brief: Feature Adapter: convert 1-D double vector to Tensor, shape [1, ndim] 31 | * @param: std::string tname, tensor name; 32 | * @parma: std::vector*, input vector; 33 | * */ 34 | void ANNFeatureAdapter::assign(std::string tname, std::vector* vec) { 35 | //Convert input 1-D double vector to Tensor 36 | int ndim = vec->size(); 37 | if (ndim == 0) { 38 | std::cout << "WARNING: Input Vec size is 0 ..." << std::endl; 39 | return; 40 | } 41 | // Create New tensor and set value 42 | Tensor x(tensorflow::DT_FLOAT, tensorflow::TensorShape({1, ndim})); // New Tensor shape [1, ndim] 43 | auto x_map = x.tensor(); 44 | for (int j = 0; j < ndim; j++) { 45 | x_map(0, j) = (*vec)[j]; 46 | } 47 | // Append to input 48 | input.push_back(std::pair(tname, x)); 49 | } 50 | 51 | /** 52 | * ANN Model Loader Implementation 53 | * */ 54 | ANNModelLoader::ANNModelLoader() { 55 | 56 | } 57 | 58 | ANNModelLoader::~ANNModelLoader() { 59 | 60 | } 61 | 62 | /** 63 | * @brief: load the graph and add to Session 64 | * @param: Session* session, add the graph to the session 65 | * @param: model_path absolute path to exported protobuf file *.pb 66 | * */ 67 | 68 | int ANNModelLoader::load(tensorflow::Session* session, const std::string model_path) { 69 | //Read the pb file into the grapgdef member 70 | tensorflow::Status status_load = ReadBinaryProto(Env::Default(), model_path, &graphdef); 71 | if (!status_load.ok()) { 72 | std::cout << "ERROR: Loading model failed..." << model_path << std::endl; 73 | std::cout << status_load.ToString() << "\n"; 74 | return -1; 75 | } 76 | 77 | // Add the graph to the session 78 | tensorflow::Status status_create = session->Create(graphdef); 79 | if (!status_create.ok()) { 80 | std::cout << "ERROR: Creating graph in session failed..." << status_create.ToString() << std::endl; 81 | return -1; 82 | } 83 | return 0; 84 | } 85 | 86 | /** 87 | * @brief: Making new prediction 88 | * @param: Session* session 89 | * @param: FeatureAdapterBase, common interface of input feature 90 | * @param: std::string, output_node, tensorname of output node 91 | * @param: double, prediction values 92 | * */ 93 | 94 | int ANNModelLoader::predict(tensorflow::Session* session, const FeatureAdapterBase& input_feature, 95 | const std::string output_node, double* prediction) { 96 | // The session will initialize the outputs 97 | std::vector outputs; //shape [batch_size] 98 | 99 | // @input: vector >, feed_dict 100 | // @output_node: std::string, name of the output node op, defined in the protobuf file 101 | tensorflow::Status status = session->Run(input_feature.input, {output_node}, {}, &outputs); 102 | if (!status.ok()) { 103 | std::cout << "ERROR: prediction failed..." << status.ToString() << std::endl; 104 | return -1; 105 | } 106 | 107 | //Fetch output value 108 | std::cout << "Output tensor size:" << outputs.size() << std::endl; 109 | for (std::size_t i = 0; i < outputs.size(); i++) { 110 | std::cout << outputs[i].DebugString(); 111 | } 112 | std::cout << std::endl; 113 | 114 | Tensor t = outputs[0]; // Fetch the first tensor 115 | int ndim = t.shape().dims(); // Get the dimension of the tensor 116 | auto tmap = t.tensor(); // Tensor Shape: [batch_size, target_class_num] 117 | int output_dim = t.shape().dim_size(1); // Get the target_class_num from 1st dimension 118 | std::vector tout; 119 | 120 | // Argmax: Get Final Prediction Label and Probability 121 | int output_class_id = -1; 122 | double output_prob = 0.0; 123 | for (int j = 0; j < output_dim; j++) { 124 | std::cout << "Class " << j << " prob:" << tmap(0, j) << "," << std::endl; 125 | if (tmap(0, j) >= output_prob) { 126 | output_class_id = j; 127 | output_prob = tmap(0, j); 128 | } 129 | } 130 | 131 | // Log 132 | std::cout << "Final class id: " << output_class_id << std::endl; 133 | std::cout << "Final class prob: " << output_prob << std::endl; 134 | 135 | (*prediction) = output_prob; // Assign the probability to prediction 136 | return 0; 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /cpp/src/ann_model_loader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ann_model_loader.h 3 | * 4 | * Created on: 2017年7月7日 5 | * Author: Derek 6 | */ 7 | 8 | #ifndef ANN_MODEL_LOADER_H_ 9 | #define ANN_MODEL_LOADER_H_ 10 | 11 | #include "model_loader_base.h" 12 | #include "tensorflow/core/public/session.h" 13 | #include "tensorflow/core/platform/env.h" 14 | 15 | using namespace tensorflow; 16 | 17 | namespace tf_model { 18 | 19 | /** 20 | * @brief: Model Loader for Feed Forward Neural Network 21 | * */ 22 | class ANNFeatureAdapter: public FeatureAdapterBase { 23 | public: 24 | 25 | ANNFeatureAdapter(); 26 | 27 | ~ANNFeatureAdapter(); 28 | 29 | void assign(std::string tname, std::vector*) override; // (tensor_name, tensor) 30 | 31 | }; 32 | 33 | class ANNModelLoader: public ModelLoaderBase { 34 | public: 35 | ANNModelLoader(); 36 | 37 | ~ANNModelLoader(); 38 | 39 | int load(tensorflow::Session*, const std::string) override; //Load graph file and new session 40 | 41 | int predict(tensorflow::Session*, const FeatureAdapterBase&, const std::string, double*) override; 42 | 43 | }; 44 | 45 | } 46 | 47 | #endif /* ANN_MODEL_LOADER_H_ */ 48 | -------------------------------------------------------------------------------- /cpp/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * main.cpp 3 | * 4 | * Created on: 2017年7月7日 5 | * Author: Derek 6 | */ 7 | 8 | #include 9 | #include "tensorflow/core/public/session.h" 10 | #include "tensorflow/core/platform/env.h" 11 | #include "ann_model_loader.h" 12 | 13 | using namespace tensorflow; 14 | 15 | int main(int argc, char* argv[]) { 16 | if (argc != 2) { 17 | std::cout << "WARNING: Input Args missing" << std::endl; 18 | return 0; 19 | } 20 | std::string model_path = argv[1]; // Model_path *.pb file 21 | 22 | // TensorName pre-defined in python file, Need to extract values from tensors 23 | std::string input_tensor_name = "inputs"; 24 | std::string output_tensor_name = "output_node"; 25 | 26 | // Create New Session 27 | Session* session; 28 | Status status = NewSession(SessionOptions(), &session); 29 | if (!status.ok()) { 30 | std::cout << status.ToString() << "\n"; 31 | return 0; 32 | } 33 | 34 | // Create prediction demo 35 | tf_model::ANNModelLoader model; //Create demo for prediction 36 | if (0 != model.load(session, model_path)) { 37 | std::cout << "Error: Model Loading failed..." << std::endl; 38 | return 0; 39 | } 40 | 41 | // Define Input tensor and Feature Adapter 42 | // Demo example: [1.0, 1.0, 1.0, 1.0, 1.0] for Iris Example, including bias 43 | int ndim = 5; 44 | std::vector input; 45 | for (int i = 0; i < ndim; i++) { 46 | input.push_back(1.0); 47 | } 48 | 49 | // New Feature Adapter to convert vector to tensors dictionary 50 | tf_model::ANNFeatureAdapter input_feat; 51 | input_feat.assign(input_tensor_name, &input); //Assign vec to tensor 52 | 53 | // Make New Prediction 54 | double prediction = 0.0; 55 | if (0 != model.predict(session, input_feat, output_tensor_name, &prediction)) { 56 | std::cout << "WARNING: Prediction failed..." << std::endl; 57 | } 58 | std::cout << "Output Prediction Value:" << prediction << std::endl; 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /cpp/src/model_loader_base.h: -------------------------------------------------------------------------------- 1 | /* 2 | * model_loader_base.h 3 | * 4 | * Created on: 2017年7月7日 5 | * Author: Derek 6 | */ 7 | 8 | #ifndef MODEL_LOADER_BASE_H_ 9 | #define MODEL_LOADER_BASE_H_ 10 | 11 | #include 12 | #include 13 | #include "tensorflow/core/public/session.h" 14 | #include "tensorflow/core/platform/env.h" 15 | 16 | using namespace tensorflow; 17 | 18 | namespace tf_model { 19 | 20 | /** 21 | * Base Class for feature adapter, common interface convert input format to tensors 22 | * */ 23 | class FeatureAdapterBase{ 24 | public: 25 | FeatureAdapterBase() {}; 26 | 27 | virtual ~FeatureAdapterBase() {}; 28 | 29 | virtual void assign(std::string, std::vector*) = 0; // tensor_name, tensor_double_vector 30 | 31 | std::vector > input; 32 | 33 | }; 34 | 35 | class ModelLoaderBase { 36 | public: 37 | 38 | ModelLoaderBase() {}; 39 | 40 | virtual ~ModelLoaderBase() {}; 41 | 42 | virtual int load(tensorflow::Session*, const std::string) = 0; //pure virutal function load method 43 | 44 | virtual int predict(tensorflow::Session*, const FeatureAdapterBase&, const std::string, double*) = 0; 45 | 46 | tensorflow::GraphDef graphdef; //Graph Definition for current model 47 | 48 | }; 49 | 50 | } 51 | #endif /* MODEL_LOADER_BASE_H_ */ 52 | -------------------------------------------------------------------------------- /google270b3db49723c3d4.html: -------------------------------------------------------------------------------- 1 | google-site-verification: google270b3db49723c3d4.html 2 | -------------------------------------------------------------------------------- /mnist/convolutional.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Simple, end-to-end, LeNet-5-like convolutional MNIST model example. 17 | 18 | This should achieve a test error of 0.7%. Please keep this model as simple and 19 | linear as possible, it is meant as a tutorial for simple convolutional models. 20 | Run with --self_test on the command line to execute a short self-test. 21 | """ 22 | from __future__ import absolute_import 23 | from __future__ import division 24 | from __future__ import print_function 25 | 26 | import gzip 27 | import os 28 | import sys 29 | import time 30 | 31 | import numpy 32 | from six.moves import urllib 33 | from six.moves import xrange # pylint: disable=redefined-builtin 34 | import tensorflow as tf 35 | 36 | SOURCE_URL = 'http://yann.lecun.com/exdb/mnist/' 37 | WORK_DIRECTORY = 'data' 38 | IMAGE_SIZE = 28 39 | NUM_CHANNELS = 1 40 | PIXEL_DEPTH = 255 41 | NUM_LABELS = 10 42 | VALIDATION_SIZE = 5000 # Size of the validation set. 43 | SEED = 66478 # Set to None for random seed. 44 | BATCH_SIZE = 64 45 | NUM_EPOCHS = 10 46 | EVAL_BATCH_SIZE = 64 47 | EVAL_FREQUENCY = 100 # Number of steps between evaluations. 48 | 49 | 50 | tf.app.flags.DEFINE_boolean("self_test", False, "True if running a self test.") 51 | tf.app.flags.DEFINE_boolean('use_fp16', False, 52 | "Use half floats instead of full floats if True.") 53 | FLAGS = tf.app.flags.FLAGS 54 | 55 | 56 | def data_type(): 57 | """Return the type of the activations, weights, and placeholder variables.""" 58 | if FLAGS.use_fp16: 59 | return tf.float16 60 | else: 61 | return tf.float32 62 | 63 | 64 | def maybe_download(filename): 65 | """Download the data from Yann's website, unless it's already here.""" 66 | if not tf.gfile.Exists(WORK_DIRECTORY): 67 | tf.gfile.MakeDirs(WORK_DIRECTORY) 68 | filepath = os.path.join(WORK_DIRECTORY, filename) 69 | if not tf.gfile.Exists(filepath): 70 | filepath, _ = urllib.request.urlretrieve(SOURCE_URL + filename, filepath) 71 | with tf.gfile.GFile(filepath) as f: 72 | size = f.Size() 73 | print('Successfully downloaded', filename, size, 'bytes.') 74 | return filepath 75 | 76 | 77 | def extract_data(filename, num_images): 78 | """Extract the images into a 4D tensor [image index, y, x, channels]. 79 | 80 | Values are rescaled from [0, 255] down to [-0.5, 0.5]. 81 | """ 82 | print('Extracting', filename) 83 | with gzip.open(filename) as bytestream: 84 | bytestream.read(16) 85 | buf = bytestream.read(IMAGE_SIZE * IMAGE_SIZE * num_images) 86 | data = numpy.frombuffer(buf, dtype=numpy.uint8).astype(numpy.float32) 87 | data = (data - (PIXEL_DEPTH / 2.0)) / PIXEL_DEPTH 88 | data = data.reshape(num_images, IMAGE_SIZE, IMAGE_SIZE, 1) 89 | return data 90 | 91 | 92 | def extract_labels(filename, num_images): 93 | """Extract the labels into a vector of int64 label IDs.""" 94 | print('Extracting', filename) 95 | with gzip.open(filename) as bytestream: 96 | bytestream.read(8) 97 | buf = bytestream.read(1 * num_images) 98 | labels = numpy.frombuffer(buf, dtype=numpy.uint8).astype(numpy.int64) 99 | return labels 100 | 101 | 102 | def fake_data(num_images): 103 | """Generate a fake dataset that matches the dimensions of MNIST.""" 104 | data = numpy.ndarray( 105 | shape=(num_images, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS), 106 | dtype=numpy.float32) 107 | labels = numpy.zeros(shape=(num_images,), dtype=numpy.int64) 108 | for image in xrange(num_images): 109 | label = image % 2 110 | data[image, :, :, 0] = label - 0.5 111 | labels[image] = label 112 | return data, labels 113 | 114 | 115 | def error_rate(predictions, labels): 116 | """Return the error rate based on dense predictions and sparse labels.""" 117 | return 100.0 - ( 118 | 100.0 * 119 | numpy.sum(numpy.argmax(predictions, 1) == labels) / 120 | predictions.shape[0]) 121 | 122 | 123 | def main(argv=None): # pylint: disable=unused-argument 124 | if FLAGS.self_test: 125 | print('Running self-test.') 126 | train_data, train_labels = fake_data(256) 127 | validation_data, validation_labels = fake_data(EVAL_BATCH_SIZE) 128 | test_data, test_labels = fake_data(EVAL_BATCH_SIZE) 129 | num_epochs = 1 130 | else: 131 | # Get the data. 132 | train_data_filename = maybe_download('train-images-idx3-ubyte.gz') 133 | train_labels_filename = maybe_download('train-labels-idx1-ubyte.gz') 134 | test_data_filename = maybe_download('t10k-images-idx3-ubyte.gz') 135 | test_labels_filename = maybe_download('t10k-labels-idx1-ubyte.gz') 136 | 137 | # Extract it into numpy arrays. 138 | train_data = extract_data(train_data_filename, 60000) 139 | train_labels = extract_labels(train_labels_filename, 60000) 140 | test_data = extract_data(test_data_filename, 10000) 141 | test_labels = extract_labels(test_labels_filename, 10000) 142 | 143 | # Generate a validation set. 144 | validation_data = train_data[:VALIDATION_SIZE, ...] 145 | validation_labels = train_labels[:VALIDATION_SIZE] 146 | train_data = train_data[VALIDATION_SIZE:, ...] 147 | train_labels = train_labels[VALIDATION_SIZE:] 148 | num_epochs = NUM_EPOCHS 149 | train_size = train_labels.shape[0] 150 | 151 | # This is where training samples and labels are fed to the graph. 152 | # These placeholder nodes will be fed a batch of training data at each 153 | # training step using the {feed_dict} argument to the Run() call below. 154 | train_data_node = tf.placeholder( 155 | data_type(), 156 | shape=(BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS)) 157 | train_labels_node = tf.placeholder(tf.int64, shape=(BATCH_SIZE,)) 158 | eval_data = tf.placeholder( 159 | data_type(), 160 | shape=(EVAL_BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS)) 161 | 162 | # The variables below hold all the trainable weights. They are passed an 163 | # initial value which will be assigned when we call: 164 | # {tf.initialize_all_variables().run()} 165 | conv1_weights = tf.Variable( 166 | tf.truncated_normal([5, 5, NUM_CHANNELS, 32], # 5x5 filter, depth 32. 167 | stddev=0.1, 168 | seed=SEED, dtype=data_type())) 169 | conv1_biases = tf.Variable(tf.zeros([32], dtype=data_type())) 170 | conv2_weights = tf.Variable(tf.truncated_normal( 171 | [5, 5, 32, 64], stddev=0.1, 172 | seed=SEED, dtype=data_type())) 173 | conv2_biases = tf.Variable(tf.constant(0.1, shape=[64], dtype=data_type())) 174 | fc1_weights = tf.Variable( # fully connected, depth 512. 175 | tf.truncated_normal([IMAGE_SIZE // 4 * IMAGE_SIZE // 4 * 64, 512], 176 | stddev=0.1, 177 | seed=SEED, 178 | dtype=data_type())) 179 | fc1_biases = tf.Variable(tf.constant(0.1, shape=[512], dtype=data_type())) 180 | fc2_weights = tf.Variable(tf.truncated_normal([512, NUM_LABELS], 181 | stddev=0.1, 182 | seed=SEED, 183 | dtype=data_type())) 184 | fc2_biases = tf.Variable(tf.constant( 185 | 0.1, shape=[NUM_LABELS], dtype=data_type())) 186 | 187 | # We will replicate the model structure for the training subgraph, as well 188 | # as the evaluation subgraphs, while sharing the trainable parameters. 189 | def model(data, train=False): 190 | """The Model definition.""" 191 | # 2D convolution, with 'SAME' padding (i.e. the output feature map has 192 | # the same size as the input). Note that {strides} is a 4D array whose 193 | # shape matches the data layout: [image index, y, x, depth]. 194 | conv = tf.nn.conv2d(data, 195 | conv1_weights, 196 | strides=[1, 1, 1, 1], 197 | padding='SAME') 198 | # Bias and rectified linear non-linearity. 199 | relu = tf.nn.relu(tf.nn.bias_add(conv, conv1_biases)) 200 | # Max pooling. The kernel size spec {ksize} also follows the layout of 201 | # the data. Here we have a pooling window of 2, and a stride of 2. 202 | pool = tf.nn.max_pool(relu, 203 | ksize=[1, 2, 2, 1], 204 | strides=[1, 2, 2, 1], 205 | padding='SAME') 206 | conv = tf.nn.conv2d(pool, 207 | conv2_weights, 208 | strides=[1, 1, 1, 1], 209 | padding='SAME') 210 | relu = tf.nn.relu(tf.nn.bias_add(conv, conv2_biases)) 211 | pool = tf.nn.max_pool(relu, 212 | ksize=[1, 2, 2, 1], 213 | strides=[1, 2, 2, 1], 214 | padding='SAME') 215 | # Reshape the feature map cuboid into a 2D matrix to feed it to the 216 | # fully connected layers. 217 | pool_shape = pool.get_shape().as_list() 218 | reshape = tf.reshape( 219 | pool, 220 | [pool_shape[0], pool_shape[1] * pool_shape[2] * pool_shape[3]]) 221 | # Fully connected layer. Note that the '+' operation automatically 222 | # broadcasts the biases. 223 | hidden = tf.nn.relu(tf.matmul(reshape, fc1_weights) + fc1_biases) 224 | # Add a 50% dropout during training only. Dropout also scales 225 | # activations such that no rescaling is needed at evaluation time. 226 | if train: 227 | hidden = tf.nn.dropout(hidden, 0.5, seed=SEED) 228 | return tf.matmul(hidden, fc2_weights) + fc2_biases 229 | 230 | # Training computation: logits + cross-entropy loss. 231 | logits = model(train_data_node, True) 232 | loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits( 233 | logits, train_labels_node)) 234 | 235 | # L2 regularization for the fully connected parameters. 236 | regularizers = (tf.nn.l2_loss(fc1_weights) + tf.nn.l2_loss(fc1_biases) + 237 | tf.nn.l2_loss(fc2_weights) + tf.nn.l2_loss(fc2_biases)) 238 | # Add the regularization term to the loss. 239 | loss += 5e-4 * regularizers 240 | 241 | # Optimizer: set up a variable that's incremented once per batch and 242 | # controls the learning rate decay. 243 | batch = tf.Variable(0, dtype=data_type()) 244 | # Decay once per epoch, using an exponential schedule starting at 0.01. 245 | learning_rate = tf.train.exponential_decay( 246 | 0.01, # Base learning rate. 247 | batch * BATCH_SIZE, # Current index into the dataset. 248 | train_size, # Decay step. 249 | 0.95, # Decay rate. 250 | staircase=True) 251 | # Use simple momentum for the optimization. 252 | optimizer = tf.train.MomentumOptimizer(learning_rate, 253 | 0.9).minimize(loss, 254 | global_step=batch) 255 | 256 | # Predictions for the current training minibatch. 257 | train_prediction = tf.nn.softmax(logits) 258 | 259 | # Predictions for the test and validation, which we'll compute less often. 260 | eval_prediction = tf.nn.softmax(model(eval_data)) 261 | 262 | # Small utility function to evaluate a dataset by feeding batches of data to 263 | # {eval_data} and pulling the results from {eval_predictions}. 264 | # Saves memory and enables this to run on smaller GPUs. 265 | def eval_in_batches(data, sess): 266 | """Get all predictions for a dataset by running it in small batches.""" 267 | size = data.shape[0] 268 | if size < EVAL_BATCH_SIZE: 269 | raise ValueError("batch size for evals larger than dataset: %d" % size) 270 | predictions = numpy.ndarray(shape=(size, NUM_LABELS), dtype=numpy.float32) 271 | for begin in xrange(0, size, EVAL_BATCH_SIZE): 272 | end = begin + EVAL_BATCH_SIZE 273 | if end <= size: 274 | predictions[begin:end, :] = sess.run( 275 | eval_prediction, 276 | feed_dict={eval_data: data[begin:end, ...]}) 277 | else: 278 | batch_predictions = sess.run( 279 | eval_prediction, 280 | feed_dict={eval_data: data[-EVAL_BATCH_SIZE:, ...]}) 281 | predictions[begin:, :] = batch_predictions[begin - size:, :] 282 | return predictions 283 | 284 | # Create a local session to run the training. 285 | start_time = time.time() 286 | with tf.Session() as sess: 287 | # Run all the initializers to prepare the trainable parameters. 288 | tf.initialize_all_variables().run() 289 | print('Initialized!') 290 | # Loop through training steps. 291 | for step in xrange(int(num_epochs * train_size) // BATCH_SIZE): 292 | # Compute the offset of the current minibatch in the data. 293 | # Note that we could use better randomization across epochs. 294 | offset = (step * BATCH_SIZE) % (train_size - BATCH_SIZE) 295 | batch_data = train_data[offset:(offset + BATCH_SIZE), ...] 296 | batch_labels = train_labels[offset:(offset + BATCH_SIZE)] 297 | # This dictionary maps the batch data (as a numpy array) to the 298 | # node in the graph it should be fed to. 299 | feed_dict = {train_data_node: batch_data, 300 | train_labels_node: batch_labels} 301 | # Run the graph and fetch some of the nodes. 302 | _, l, lr, predictions = sess.run( 303 | [optimizer, loss, learning_rate, train_prediction], 304 | feed_dict=feed_dict) 305 | if step % EVAL_FREQUENCY == 0: 306 | elapsed_time = time.time() - start_time 307 | start_time = time.time() 308 | print('Step %d (epoch %.2f), %.1f ms' % 309 | (step, float(step) * BATCH_SIZE / train_size, 310 | 1000 * elapsed_time / EVAL_FREQUENCY)) 311 | print('Minibatch loss: %.3f, learning rate: %.6f' % (l, lr)) 312 | print('Minibatch error: %.1f%%' % error_rate(predictions, batch_labels)) 313 | print('Validation error: %.1f%%' % error_rate( 314 | eval_in_batches(validation_data, sess), validation_labels)) 315 | sys.stdout.flush() 316 | # Finally print the result! 317 | test_error = error_rate(eval_in_batches(test_data, sess), test_labels) 318 | print('Test error: %.1f%%' % test_error) 319 | if FLAGS.self_test: 320 | print('test_error', test_error) 321 | assert test_error == 0.0, 'expected 0.0 test_error, got %.2f' % ( 322 | test_error,) 323 | 324 | 325 | if __name__ == '__main__': 326 | tf.app.run() 327 | -------------------------------------------------------------------------------- /mnist/convolutional_graph_partitioned.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Simple, end-to-end, LeNet-5-like convolutional MNIST model example. 17 | 18 | This should achieve a test error of 0.7%. Please keep this model as simple and 19 | linear as possible, it is meant as a tutorial for simple convolutional models. 20 | Run with --self_test on the command line to execute a short self-test. 21 | """ 22 | from __future__ import absolute_import 23 | from __future__ import division 24 | from __future__ import print_function 25 | 26 | import gzip 27 | import os 28 | import sys 29 | import time 30 | 31 | import numpy 32 | from six.moves import urllib 33 | from six.moves import xrange # pylint: disable=redefined-builtin 34 | import tensorflow as tf 35 | 36 | SOURCE_URL = 'http://yann.lecun.com/exdb/mnist/' 37 | WORK_DIRECTORY = 'data' 38 | IMAGE_SIZE = 28 39 | NUM_CHANNELS = 1 40 | PIXEL_DEPTH = 255 41 | NUM_LABELS = 10 42 | VALIDATION_SIZE = 5000 # Size of the validation set. 43 | SEED = 66478 # Set to None for random seed. 44 | BATCH_SIZE = 64 45 | NUM_EPOCHS = 10 46 | EVAL_BATCH_SIZE = 64 47 | EVAL_FREQUENCY = 100 # Number of steps between evaluations. 48 | 49 | 50 | tf.app.flags.DEFINE_boolean("self_test", False, "True if running a self test.") 51 | tf.app.flags.DEFINE_boolean('use_fp16', False, 52 | "Use half floats instead of full floats if True.") 53 | FLAGS = tf.app.flags.FLAGS 54 | 55 | # number of device count 56 | tf.app.flags.DEFINE_integer('num_cpu_core', 4, 'Number of CPU cores to use') 57 | tf.app.flags.DEFINE_integer('intra_op_parallelism_threads', 4, 'How many ops can be launched in parallel') 58 | tf.app.flags.DEFINE_integer('num_gpu_core', 0, 'Number of GPU cores to use') 59 | 60 | device_id = -1 # Global Variable Counter for device_id used 61 | 62 | def next_device(use_cpu = True): 63 | ''' See if there is available next device; 64 | Args: use_cpu, global device_id 65 | Return: new device id 66 | ''' 67 | global device_id 68 | if (use_cpu): 69 | if ((device_id + 1) < FLAGS.num_cpu_core): 70 | device_id += 1 71 | device = '/cpu:%d' % device_id 72 | else: 73 | if ((device_id + 1) < FLAGS.num_gpu_core): 74 | device_id += 1 75 | device = '/gpu:%d' % device_id 76 | return device 77 | 78 | def data_type(): 79 | """Return the type of the activations, weights, and placeholder variables.""" 80 | if FLAGS.use_fp16: 81 | return tf.float16 82 | else: 83 | return tf.float32 84 | 85 | 86 | def maybe_download(filename): 87 | """Download the data from Yann's website, unless it's already here.""" 88 | if not tf.gfile.Exists(WORK_DIRECTORY): 89 | tf.gfile.MakeDirs(WORK_DIRECTORY) 90 | filepath = os.path.join(WORK_DIRECTORY, filename) 91 | if not tf.gfile.Exists(filepath): 92 | filepath, _ = urllib.request.urlretrieve(SOURCE_URL + filename, filepath) 93 | with tf.gfile.GFile(filepath) as f: 94 | size = f.Size() 95 | print('Successfully downloaded', filename, size, 'bytes.') 96 | return filepath 97 | 98 | 99 | def extract_data(filename, num_images): 100 | """Extract the images into a 4D tensor [image index, y, x, channels]. 101 | 102 | Values are rescaled from [0, 255] down to [-0.5, 0.5]. 103 | """ 104 | print('Extracting', filename) 105 | with gzip.open(filename) as bytestream: 106 | bytestream.read(16) 107 | buf = bytestream.read(IMAGE_SIZE * IMAGE_SIZE * num_images) 108 | data = numpy.frombuffer(buf, dtype=numpy.uint8).astype(numpy.float32) 109 | data = (data - (PIXEL_DEPTH / 2.0)) / PIXEL_DEPTH 110 | data = data.reshape(num_images, IMAGE_SIZE, IMAGE_SIZE, 1) 111 | return data 112 | 113 | def extract_labels(filename, num_images): 114 | """Extract the labels into a vector of int64 label IDs.""" 115 | print('Extracting', filename) 116 | with gzip.open(filename) as bytestream: 117 | bytestream.read(8) 118 | buf = bytestream.read(1 * num_images) 119 | labels = numpy.frombuffer(buf, dtype=numpy.uint8).astype(numpy.int64) 120 | return labels 121 | 122 | 123 | def fake_data(num_images): 124 | """Generate a fake dataset that matches the dimensions of MNIST.""" 125 | data = numpy.ndarray( 126 | shape=(num_images, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS), 127 | dtype=numpy.float32) 128 | labels = numpy.zeros(shape=(num_images,), dtype=numpy.int64) 129 | for image in xrange(num_images): 130 | label = image % 2 131 | data[image, :, :, 0] = label - 0.5 132 | labels[image] = label 133 | return data, labels 134 | 135 | 136 | def error_rate(predictions, labels): 137 | """Return the error rate based on dense predictions and sparse labels.""" 138 | return 100.0 - ( 139 | 100.0 * 140 | numpy.sum(numpy.argmax(predictions, 1) == labels) / 141 | predictions.shape[0]) 142 | 143 | 144 | def main(argv=None): # pylint: disable=unused-argument 145 | if FLAGS.self_test: 146 | print('Running self-test.') 147 | train_data, train_labels = fake_data(256) 148 | validation_data, validation_labels = fake_data(EVAL_BATCH_SIZE) 149 | test_data, test_labels = fake_data(EVAL_BATCH_SIZE) 150 | num_epochs = 1 151 | else: 152 | # Get the data. 153 | train_data_filename = maybe_download('train-images-idx3-ubyte.gz') 154 | train_labels_filename = maybe_download('train-labels-idx1-ubyte.gz') 155 | test_data_filename = maybe_download('t10k-images-idx3-ubyte.gz') 156 | test_labels_filename = maybe_download('t10k-labels-idx1-ubyte.gz') 157 | 158 | # Extract it into numpy arrays. 159 | train_data = extract_data(train_data_filename, 60000) 160 | train_labels = extract_labels(train_labels_filename, 60000) 161 | test_data = extract_data(test_data_filename, 10000) 162 | test_labels = extract_labels(test_labels_filename, 10000) 163 | 164 | # Generate a validation set. 165 | validation_data = train_data[:VALIDATION_SIZE, ...] 166 | validation_labels = train_labels[:VALIDATION_SIZE] 167 | train_data = train_data[VALIDATION_SIZE:, ...] 168 | train_labels = train_labels[VALIDATION_SIZE:] 169 | num_epochs = NUM_EPOCHS 170 | train_size = train_labels.shape[0] 171 | 172 | # This is where training samples and labels are fed to the graph. 173 | # These placeholder nodes will be fed a batch of training data at each 174 | # training step using the {feed_dict} argument to the Run() call below. 175 | train_data_node = tf.placeholder( 176 | data_type(), 177 | shape=(BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS)) 178 | train_labels_node = tf.placeholder(tf.int64, shape=(BATCH_SIZE,)) 179 | eval_data = tf.placeholder( 180 | data_type(), 181 | shape=(EVAL_BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS)) 182 | 183 | # The variables below hold all the trainable weights. They are passed an 184 | # initial value which will be assigned when we call: 185 | # {tf.initialize_all_variables().run()} 186 | 187 | 188 | 189 | 190 | conv1_weights = tf.Variable( 191 | tf.truncated_normal([5, 5, NUM_CHANNELS, 32], # 5x5 filter, depth 32. 192 | stddev=0.1, 193 | seed=SEED, dtype=data_type())) 194 | conv1_biases = tf.Variable(tf.zeros([32], dtype=data_type())) 195 | conv2_weights = tf.Variable(tf.truncated_normal( 196 | [5, 5, 32, 64], stddev=0.1, 197 | seed=SEED, dtype=data_type())) 198 | conv2_biases = tf.Variable(tf.constant(0.1, shape=[64], dtype=data_type())) 199 | fc1_weights = tf.Variable( # fully connected, depth 512. 200 | tf.truncated_normal([IMAGE_SIZE // 4 * IMAGE_SIZE // 4 * 64, 512], 201 | stddev=0.1, 202 | seed=SEED, 203 | dtype=data_type())) 204 | fc1_biases = tf.Variable(tf.constant(0.1, shape=[512], dtype=data_type())) 205 | fc2_weights = tf.Variable(tf.truncated_normal([512, NUM_LABELS], 206 | stddev=0.1, 207 | seed=SEED, 208 | dtype=data_type())) 209 | fc2_biases = tf.Variable(tf.constant( 210 | 0.1, shape=[NUM_LABELS], dtype=data_type())) 211 | 212 | # We will replicate the model structure for the training subgraph, as well 213 | # as the evaluation subgraphs, while sharing the trainable parameters. 214 | 215 | 216 | def model(data, train=False): 217 | """The Model definition.""" 218 | # 2D convolution, with 'SAME' padding (i.e. the output feature map has 219 | # the same size as the input). Note that {strides} is a 4D array whose 220 | # shape matches the data layout: [image index, y, x, depth]. 221 | 222 | with tf.device(next_device()): 223 | conv = tf.nn.conv2d(data, 224 | conv1_weights, 225 | strides=[1, 1, 1, 1], 226 | padding='SAME') 227 | # Bias and rectified linear non-linearity. 228 | relu = tf.nn.relu(tf.nn.bias_add(conv, conv1_biases)) 229 | # Max pooling. The kernel size spec {ksize} also follows the layout of 230 | # the data. Here we have a pooling window of 2, and a stride of 2. 231 | pool = tf.nn.max_pool(relu, 232 | ksize=[1, 2, 2, 1], 233 | strides=[1, 2, 2, 1], 234 | padding='SAME') 235 | 236 | 237 | with tf.device(next_device()): 238 | conv = tf.nn.conv2d(pool, 239 | conv2_weights, 240 | strides=[1, 1, 1, 1], 241 | padding='SAME') 242 | relu = tf.nn.relu(tf.nn.bias_add(conv, conv2_biases)) 243 | pool = tf.nn.max_pool(relu, 244 | ksize=[1, 2, 2, 1], 245 | strides=[1, 2, 2, 1], 246 | padding='SAME') 247 | # Reshape the feature map cuboid into a 2D matrix to feed it to the 248 | # fully connected layers. 249 | pool_shape = pool.get_shape().as_list() 250 | reshape = tf.reshape( 251 | pool, 252 | [pool_shape[0], pool_shape[1] * pool_shape[2] * pool_shape[3]]) 253 | 254 | 255 | # Fully connected layer. Note that the '+' operation automatically 256 | # broadcasts the biases. 257 | 258 | with tf.device(next_device()): 259 | hidden = tf.nn.relu(tf.matmul(reshape, fc1_weights) + fc1_biases) 260 | # Add a 50% dropout during training only. Dropout also scales 261 | # activations such that no rescaling is needed at evaluation time. 262 | if train: 263 | hidden = tf.nn.dropout(hidden, 0.5, seed=SEED) 264 | output = tf.matmul(hidden, fc2_weights) + fc2_biases 265 | return output 266 | 267 | # Training computation: logits + cross-entropy loss. 268 | logits = model(train_data_node, True) 269 | loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits( 270 | logits, train_labels_node)) 271 | 272 | # L2 regularization for the fully connected parameters. 273 | regularizers = (tf.nn.l2_loss(fc1_weights) + tf.nn.l2_loss(fc1_biases) + 274 | tf.nn.l2_loss(fc2_weights) + tf.nn.l2_loss(fc2_biases)) 275 | # Add the regularization term to the loss. 276 | loss += 5e-4 * regularizers 277 | 278 | # Optimizer: set up a variable that's incremented once per batch and 279 | # controls the learning rate decay. 280 | batch = tf.Variable(0, dtype=data_type()) 281 | # Decay once per epoch, using an exponential schedule starting at 0.01. 282 | learning_rate = tf.train.exponential_decay( 283 | 0.01, # Base learning rate. 284 | batch * BATCH_SIZE, # Current index into the dataset. 285 | train_size, # Decay step. 286 | 0.95, # Decay rate. 287 | staircase=True) 288 | # Use simple momentum for the optimization. 289 | optimizer = tf.train.MomentumOptimizer(learning_rate, 290 | 0.9).minimize(loss, 291 | global_step=batch) 292 | 293 | # Predictions for the current training minibatch. 294 | train_prediction = tf.nn.softmax(logits) 295 | 296 | # Predictions for the test and validation, which we'll compute less often. 297 | eval_prediction = tf.nn.softmax(model(eval_data)) 298 | 299 | # Small utility function to evaluate a dataset by feeding batches of data to 300 | # {eval_data} and pulling the results from {eval_predictions}. 301 | # Saves memory and enables this to run on smaller GPUs. 302 | def eval_in_batches(data, sess): 303 | """Get all predictions for a dataset by running it in small batches.""" 304 | size = data.shape[0] 305 | if size < EVAL_BATCH_SIZE: 306 | raise ValueError("batch size for evals larger than dataset: %d" % size) 307 | predictions = numpy.ndarray(shape=(size, NUM_LABELS), dtype=numpy.float32) 308 | for begin in xrange(0, size, EVAL_BATCH_SIZE): 309 | end = begin + EVAL_BATCH_SIZE 310 | if end <= size: 311 | predictions[begin:end, :] = sess.run( 312 | eval_prediction, 313 | feed_dict={eval_data: data[begin:end, ...]}) 314 | else: 315 | batch_predictions = sess.run( 316 | eval_prediction, 317 | feed_dict={eval_data: data[-EVAL_BATCH_SIZE:, ...]}) 318 | predictions[begin:, :] = batch_predictions[begin - size:, :] 319 | return predictions 320 | 321 | # Create a local session to run the training. 322 | start_time = time.time() 323 | 324 | config = tf.ConfigProto( 325 | device_count={"CPU": FLAGS.num_cpu_core}, # limit to num_cpu_core CPU usage 326 | inter_op_parallelism_threads = 1, 327 | intra_op_parallelism_threads = FLAGS.intra_op_parallelism_threads, 328 | log_device_placement=True 329 | ) 330 | 331 | with tf.Session(config = config) as sess: 332 | # Run all the initializers to prepare the trainable parameters. 333 | tf.initialize_all_variables().run() 334 | print('Initialized!') 335 | # Loop through training steps. 336 | for step in xrange(int(num_epochs * train_size) // BATCH_SIZE): 337 | # Compute the offset of the current minibatch in the data. 338 | # Note that we could use better randomization across epochs. 339 | offset = (step * BATCH_SIZE) % (train_size - BATCH_SIZE) 340 | batch_data = train_data[offset:(offset + BATCH_SIZE), ...] 341 | batch_labels = train_labels[offset:(offset + BATCH_SIZE)] 342 | # This dictionary maps the batch data (as a numpy array) to the 343 | # node in the graph it should be fed to. 344 | feed_dict = {train_data_node: batch_data, 345 | train_labels_node: batch_labels} 346 | # Run the graph and fetch some of the nodes. 347 | _, l, lr, predictions = sess.run( 348 | [optimizer, loss, learning_rate, train_prediction], 349 | feed_dict=feed_dict) 350 | if step % EVAL_FREQUENCY == 0: 351 | elapsed_time = time.time() - start_time 352 | start_time = time.time() 353 | print('Step %d (epoch %.2f), %.1f ms' % 354 | (step, float(step) * BATCH_SIZE / train_size, 355 | 1000 * elapsed_time / EVAL_FREQUENCY)) 356 | print('Minibatch loss: %.3f, learning rate: %.6f' % (l, lr)) 357 | print('Minibatch error: %.1f%%' % error_rate(predictions, batch_labels)) 358 | print('Validation error: %.1f%%' % error_rate( 359 | eval_in_batches(validation_data, sess), validation_labels)) 360 | sys.stdout.flush() 361 | # Finally print the result! 362 | test_error = error_rate(eval_in_batches(test_data, sess), test_labels) 363 | print('Test error: %.1f%%' % test_error) 364 | if FLAGS.self_test: 365 | print('test_error', test_error) 366 | assert test_error == 0.0, 'expected 0.0 test_error, got %.2f' % ( 367 | test_error,) 368 | 369 | 370 | if __name__ == '__main__': 371 | tf.app.run() 372 | -------------------------------------------------------------------------------- /mnist/convolutional_multithread.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Simple, end-to-end, LeNet-5-like convolutional MNIST model example. 17 | 18 | This should achieve a test error of 0.7%. Please keep this model as simple and 19 | linear as possible, it is meant as a tutorial for simple convolutional models. 20 | Run with --self_test on the command line to execute a short self-test. 21 | """ 22 | from __future__ import absolute_import 23 | from __future__ import division 24 | from __future__ import print_function 25 | 26 | import gzip 27 | import os 28 | import sys 29 | import time 30 | 31 | import numpy 32 | from six.moves import urllib 33 | from six.moves import xrange # pylint: disable=redefined-builtin 34 | import tensorflow as tf 35 | 36 | SOURCE_URL = 'http://yann.lecun.com/exdb/mnist/' 37 | WORK_DIRECTORY = 'data' 38 | IMAGE_SIZE = 28 39 | NUM_CHANNELS = 1 40 | PIXEL_DEPTH = 255 41 | NUM_LABELS = 10 42 | VALIDATION_SIZE = 5000 # Size of the validation set. 43 | SEED = 66478 # Set to None for random seed. 44 | BATCH_SIZE = 64 45 | NUM_EPOCHS = 10 46 | EVAL_BATCH_SIZE = 64 47 | EVAL_FREQUENCY = 100 # Number of steps between evaluations. 48 | 49 | 50 | tf.app.flags.DEFINE_boolean("self_test", False, "True if running a self test.") 51 | tf.app.flags.DEFINE_boolean('use_fp16', False, 52 | "Use half floats instead of full floats if True.") 53 | FLAGS = tf.app.flags.FLAGS 54 | 55 | # number of device count 56 | tf.app.flags.DEFINE_integer('num_cpu_core', 4, 'Number of CPU cores to use') 57 | tf.app.flags.DEFINE_integer('intra_op_parallelism_threads', 1, 'How many ops can be launched in parallel') 58 | tf.app.flags.DEFINE_integer('num_gpu_core', 0, 'Number of GPU cores to use') 59 | 60 | def data_type(): 61 | """Return the type of the activations, weights, and placeholder variables.""" 62 | if FLAGS.use_fp16: 63 | return tf.float16 64 | else: 65 | return tf.float32 66 | 67 | 68 | def maybe_download(filename): 69 | """Download the data from Yann's website, unless it's already here.""" 70 | if not tf.gfile.Exists(WORK_DIRECTORY): 71 | tf.gfile.MakeDirs(WORK_DIRECTORY) 72 | filepath = os.path.join(WORK_DIRECTORY, filename) 73 | if not tf.gfile.Exists(filepath): 74 | filepath, _ = urllib.request.urlretrieve(SOURCE_URL + filename, filepath) 75 | with tf.gfile.GFile(filepath) as f: 76 | size = f.Size() 77 | print('Successfully downloaded', filename, size, 'bytes.') 78 | return filepath 79 | 80 | 81 | def extract_data(filename, num_images): 82 | """Extract the images into a 4D tensor [image index, y, x, channels]. 83 | 84 | Values are rescaled from [0, 255] down to [-0.5, 0.5]. 85 | """ 86 | print('Extracting', filename) 87 | with gzip.open(filename) as bytestream: 88 | bytestream.read(16) 89 | buf = bytestream.read(IMAGE_SIZE * IMAGE_SIZE * num_images) 90 | data = numpy.frombuffer(buf, dtype=numpy.uint8).astype(numpy.float32) 91 | data = (data - (PIXEL_DEPTH / 2.0)) / PIXEL_DEPTH 92 | data = data.reshape(num_images, IMAGE_SIZE, IMAGE_SIZE, 1) 93 | return data 94 | 95 | 96 | def extract_labels(filename, num_images): 97 | """Extract the labels into a vector of int64 label IDs.""" 98 | print('Extracting', filename) 99 | with gzip.open(filename) as bytestream: 100 | bytestream.read(8) 101 | buf = bytestream.read(1 * num_images) 102 | labels = numpy.frombuffer(buf, dtype=numpy.uint8).astype(numpy.int64) 103 | return labels 104 | 105 | 106 | def fake_data(num_images): 107 | """Generate a fake dataset that matches the dimensions of MNIST.""" 108 | data = numpy.ndarray( 109 | shape=(num_images, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS), 110 | dtype=numpy.float32) 111 | labels = numpy.zeros(shape=(num_images,), dtype=numpy.int64) 112 | for image in xrange(num_images): 113 | label = image % 2 114 | data[image, :, :, 0] = label - 0.5 115 | labels[image] = label 116 | return data, labels 117 | 118 | 119 | def error_rate(predictions, labels): 120 | """Return the error rate based on dense predictions and sparse labels.""" 121 | return 100.0 - ( 122 | 100.0 * 123 | numpy.sum(numpy.argmax(predictions, 1) == labels) / 124 | predictions.shape[0]) 125 | 126 | 127 | def main(argv=None): # pylint: disable=unused-argument 128 | if FLAGS.self_test: 129 | print('Running self-test.') 130 | train_data, train_labels = fake_data(256) 131 | validation_data, validation_labels = fake_data(EVAL_BATCH_SIZE) 132 | test_data, test_labels = fake_data(EVAL_BATCH_SIZE) 133 | num_epochs = 1 134 | else: 135 | # Get the data. 136 | train_data_filename = maybe_download('train-images-idx3-ubyte.gz') 137 | train_labels_filename = maybe_download('train-labels-idx1-ubyte.gz') 138 | test_data_filename = maybe_download('t10k-images-idx3-ubyte.gz') 139 | test_labels_filename = maybe_download('t10k-labels-idx1-ubyte.gz') 140 | 141 | # Extract it into numpy arrays. 142 | train_data = extract_data(train_data_filename, 60000) 143 | train_labels = extract_labels(train_labels_filename, 60000) 144 | test_data = extract_data(test_data_filename, 10000) 145 | test_labels = extract_labels(test_labels_filename, 10000) 146 | 147 | # Generate a validation set. 148 | validation_data = train_data[:VALIDATION_SIZE, ...] 149 | validation_labels = train_labels[:VALIDATION_SIZE] 150 | train_data = train_data[VALIDATION_SIZE:, ...] 151 | train_labels = train_labels[VALIDATION_SIZE:] 152 | num_epochs = NUM_EPOCHS 153 | train_size = train_labels.shape[0] 154 | 155 | # This is where training samples and labels are fed to the graph. 156 | # These placeholder nodes will be fed a batch of training data at each 157 | # training step using the {feed_dict} argument to the Run() call below. 158 | train_data_node = tf.placeholder( 159 | data_type(), 160 | shape=(BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS)) 161 | train_labels_node = tf.placeholder(tf.int64, shape=(BATCH_SIZE,)) 162 | eval_data = tf.placeholder( 163 | data_type(), 164 | shape=(EVAL_BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, NUM_CHANNELS)) 165 | 166 | # The variables below hold all the trainable weights. They are passed an 167 | # initial value which will be assigned when we call: 168 | # {tf.initialize_all_variables().run()} 169 | conv1_weights = tf.Variable( 170 | tf.truncated_normal([5, 5, NUM_CHANNELS, 32], # 5x5 filter, depth 32. 171 | stddev=0.1, 172 | seed=SEED, dtype=data_type())) 173 | conv1_biases = tf.Variable(tf.zeros([32], dtype=data_type())) 174 | conv2_weights = tf.Variable(tf.truncated_normal( 175 | [5, 5, 32, 64], stddev=0.1, 176 | seed=SEED, dtype=data_type())) 177 | conv2_biases = tf.Variable(tf.constant(0.1, shape=[64], dtype=data_type())) 178 | fc1_weights = tf.Variable( # fully connected, depth 512. 179 | tf.truncated_normal([IMAGE_SIZE // 4 * IMAGE_SIZE // 4 * 64, 512], 180 | stddev=0.1, 181 | seed=SEED, 182 | dtype=data_type())) 183 | fc1_biases = tf.Variable(tf.constant(0.1, shape=[512], dtype=data_type())) 184 | fc2_weights = tf.Variable(tf.truncated_normal([512, NUM_LABELS], 185 | stddev=0.1, 186 | seed=SEED, 187 | dtype=data_type())) 188 | fc2_biases = tf.Variable(tf.constant( 189 | 0.1, shape=[NUM_LABELS], dtype=data_type())) 190 | 191 | # We will replicate the model structure for the training subgraph, as well 192 | # as the evaluation subgraphs, while sharing the trainable parameters. 193 | def model(data, train=False): 194 | """The Model definition.""" 195 | # 2D convolution, with 'SAME' padding (i.e. the output feature map has 196 | # the same size as the input). Note that {strides} is a 4D array whose 197 | # shape matches the data layout: [image index, y, x, depth]. 198 | conv = tf.nn.conv2d(data, 199 | conv1_weights, 200 | strides=[1, 1, 1, 1], 201 | padding='SAME') 202 | # Bias and rectified linear non-linearity. 203 | relu = tf.nn.relu(tf.nn.bias_add(conv, conv1_biases)) 204 | # Max pooling. The kernel size spec {ksize} also follows the layout of 205 | # the data. Here we have a pooling window of 2, and a stride of 2. 206 | pool = tf.nn.max_pool(relu, 207 | ksize=[1, 2, 2, 1], 208 | strides=[1, 2, 2, 1], 209 | padding='SAME') 210 | conv = tf.nn.conv2d(pool, 211 | conv2_weights, 212 | strides=[1, 1, 1, 1], 213 | padding='SAME') 214 | relu = tf.nn.relu(tf.nn.bias_add(conv, conv2_biases)) 215 | pool = tf.nn.max_pool(relu, 216 | ksize=[1, 2, 2, 1], 217 | strides=[1, 2, 2, 1], 218 | padding='SAME') 219 | # Reshape the feature map cuboid into a 2D matrix to feed it to the 220 | # fully connected layers. 221 | pool_shape = pool.get_shape().as_list() 222 | reshape = tf.reshape( 223 | pool, 224 | [pool_shape[0], pool_shape[1] * pool_shape[2] * pool_shape[3]]) 225 | # Fully connected layer. Note that the '+' operation automatically 226 | # broadcasts the biases. 227 | hidden = tf.nn.relu(tf.matmul(reshape, fc1_weights) + fc1_biases) 228 | # Add a 50% dropout during training only. Dropout also scales 229 | # activations such that no rescaling is needed at evaluation time. 230 | if train: 231 | hidden = tf.nn.dropout(hidden, 0.5, seed=SEED) 232 | return tf.matmul(hidden, fc2_weights) + fc2_biases 233 | 234 | # Training computation: logits + cross-entropy loss. 235 | logits = model(train_data_node, True) 236 | loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits( 237 | logits, train_labels_node)) 238 | 239 | # L2 regularization for the fully connected parameters. 240 | regularizers = (tf.nn.l2_loss(fc1_weights) + tf.nn.l2_loss(fc1_biases) + 241 | tf.nn.l2_loss(fc2_weights) + tf.nn.l2_loss(fc2_biases)) 242 | # Add the regularization term to the loss. 243 | loss += 5e-4 * regularizers 244 | 245 | # Optimizer: set up a variable that's incremented once per batch and 246 | # controls the learning rate decay. 247 | batch = tf.Variable(0, dtype=data_type()) 248 | # Decay once per epoch, using an exponential schedule starting at 0.01. 249 | learning_rate = tf.train.exponential_decay( 250 | 0.01, # Base learning rate. 251 | batch * BATCH_SIZE, # Current index into the dataset. 252 | train_size, # Decay step. 253 | 0.95, # Decay rate. 254 | staircase=True) 255 | # Use simple momentum for the optimization. 256 | optimizer = tf.train.MomentumOptimizer(learning_rate, 257 | 0.9).minimize(loss, 258 | global_step=batch) 259 | 260 | # Predictions for the current training minibatch. 261 | train_prediction = tf.nn.softmax(logits) 262 | 263 | # Predictions for the test and validation, which we'll compute less often. 264 | eval_prediction = tf.nn.softmax(model(eval_data)) 265 | 266 | # Small utility function to evaluate a dataset by feeding batches of data to 267 | # {eval_data} and pulling the results from {eval_predictions}. 268 | # Saves memory and enables this to run on smaller GPUs. 269 | def eval_in_batches(data, sess): 270 | """Get all predictions for a dataset by running it in small batches.""" 271 | size = data.shape[0] 272 | if size < EVAL_BATCH_SIZE: 273 | raise ValueError("batch size for evals larger than dataset: %d" % size) 274 | predictions = numpy.ndarray(shape=(size, NUM_LABELS), dtype=numpy.float32) 275 | for begin in xrange(0, size, EVAL_BATCH_SIZE): 276 | end = begin + EVAL_BATCH_SIZE 277 | if end <= size: 278 | predictions[begin:end, :] = sess.run( 279 | eval_prediction, 280 | feed_dict={eval_data: data[begin:end, ...]}) 281 | else: 282 | batch_predictions = sess.run( 283 | eval_prediction, 284 | feed_dict={eval_data: data[-EVAL_BATCH_SIZE:, ...]}) 285 | predictions[begin:, :] = batch_predictions[begin - size:, :] 286 | return predictions 287 | 288 | # Create a local session to run the training. 289 | start_time = time.time() 290 | 291 | config = tf.ConfigProto( 292 | device_count={"CPU": FLAGS.num_cpu_core}, # limit to num_cpu_core CPU usage 293 | inter_op_parallelism_threads = 1, 294 | intra_op_parallelism_threads = FLAGS.intra_op_parallelism_threads, 295 | log_device_placement=True 296 | ) 297 | 298 | with tf.Session(config = config) as sess: 299 | # Run all the initializers to prepare the trainable parameters. 300 | tf.initialize_all_variables().run() 301 | print('Initialized!') 302 | # Loop through training steps. 303 | for step in xrange(int(num_epochs * train_size) // BATCH_SIZE): 304 | # Compute the offset of the current minibatch in the data. 305 | # Note that we could use better randomization across epochs. 306 | offset = (step * BATCH_SIZE) % (train_size - BATCH_SIZE) 307 | batch_data = train_data[offset:(offset + BATCH_SIZE), ...] 308 | batch_labels = train_labels[offset:(offset + BATCH_SIZE)] 309 | # This dictionary maps the batch data (as a numpy array) to the 310 | # node in the graph it should be fed to. 311 | feed_dict = {train_data_node: batch_data, 312 | train_labels_node: batch_labels} 313 | # Run the graph and fetch some of the nodes. 314 | _, l, lr, predictions = sess.run( 315 | [optimizer, loss, learning_rate, train_prediction], 316 | feed_dict=feed_dict) 317 | if step % EVAL_FREQUENCY == 0: 318 | elapsed_time = time.time() - start_time 319 | start_time = time.time() 320 | print('Step %d (epoch %.2f), %.1f ms' % 321 | (step, float(step) * BATCH_SIZE / train_size, 322 | 1000 * elapsed_time / EVAL_FREQUENCY)) 323 | print('Minibatch loss: %.3f, learning rate: %.6f' % (l, lr)) 324 | print('Minibatch error: %.1f%%' % error_rate(predictions, batch_labels)) 325 | print('Validation error: %.1f%%' % error_rate( 326 | eval_in_batches(validation_data, sess), validation_labels)) 327 | sys.stdout.flush() 328 | # Finally print the result! 329 | test_error = error_rate(eval_in_batches(test_data, sess), test_labels) 330 | print('Test error: %.1f%%' % test_error) 331 | if FLAGS.self_test: 332 | print('test_error', test_error) 333 | assert test_error == 0.0, 'expected 0.0 test_error, got %.2f' % ( 334 | test_error,) 335 | 336 | 337 | if __name__ == '__main__': 338 | tf.app.run() 339 | --------------------------------------------------------------------------------