├── .gitignore
├── .ipynb_checkpoints
├── Tutorial_10 - [transfer learning] Add new variables to graph and save the new model-checkpoint.ipynb
├── Tutorial_8 - A very simple example for tensorboard-checkpoint.ipynb
└── Tutorial_9 - How to save the model-checkpoint.ipynb
├── README.md
├── ckpt
├── bi-lstm.ckpt-12.data-00000-of-00001
├── bi-lstm.ckpt-12.index
├── bi-lstm.ckpt-12.meta
└── checkpoint
├── data
└── msr_train.txt
├── doc
└── problem-solution.md
├── example-notebook
├── .ipynb_checkpoints
│ ├── Tutorial_01 Basic Usage-checkpoint.ipynb
│ ├── Tutorial_02 A simple feedforward network for MNIST-checkpoint.ipynb
│ ├── Tutorial_03_1 The usage of name_scope and variable_scope-checkpoint.ipynb
│ ├── Tutorial_03_2 The usage of Collection-checkpoint.ipynb
│ ├── Tutorial_04_1 Convolutional network for MNIST(1)-checkpoint.ipynb
│ ├── Tutorial_04_2 Convolutional network for MNIST(2)-checkpoint.ipynb
│ ├── Tutorial_04_3 Convolutional network for MNIST(3)-checkpoint.ipynb
│ ├── Tutorial_04_3 Convolutional network for MNIST(4)-BN-checkpoint.ipynb
│ ├── Tutorial_05_1 An understandable example to implement Multi-LSTM for MNIST(1)-Copy1-checkpoint.ipynb
│ ├── Tutorial_05_1 An understandable example to implement Multi-LSTM for MNIST-checkpoint.ipynb
│ ├── Tutorial_05_2 An understandable example to implement Multi-GRU for MNIST-checkpoint.ipynb
│ ├── Tutorial_05_3 Bi-GRU for MNIST-checkpoint.ipynb
│ ├── Tutorial_06 A very simple example for tensorboard-checkpoint.ipynb
│ ├── Tutorial_07 How to save the model-checkpoint.ipynb
│ ├── Tutorial_08 [transfer learning] Add new variables to graph and save the new model-checkpoint.ipynb
│ ├── Tutorial_09 [tfrecord] use tfrecord to store sequences of different length-checkpoint.ipynb
│ ├── Tutorial_10 [Dataset] numpy data-checkpoint.ipynb
│ ├── Tutorial_10_3 [Dataset] sequence data-checkpoint.ipynb
│ ├── Tutorial_11 [Dataset] image data-checkpoint.ipynb
│ ├── Tutorial_12 [tf.layer]high layer API-checkpoint.ipynb
│ └── Untitled-checkpoint.ipynb
├── MNIST_data
│ ├── t10k-images-idx3-ubyte.gz
│ ├── t10k-labels-idx1-ubyte.gz
│ ├── train-images-idx3-ubyte.gz
│ └── train-labels-idx1-ubyte.gz
├── Tutorial_01 Basic Usage.ipynb
├── Tutorial_02 A simple feedforward network for MNIST.ipynb
├── Tutorial_03_1 The usage of name_scope and variable_scope.ipynb
├── Tutorial_03_2 The usage of Collection.ipynb
├── Tutorial_04_1 Convolutional network for MNIST(1).ipynb
├── Tutorial_04_2 Convolutional network for MNIST(2).ipynb
├── Tutorial_04_3 Convolutional network for MNIST(3).ipynb
├── Tutorial_05_1 An understandable example to implement Multi-LSTM for MNIST.ipynb
├── Tutorial_05_2 An understandable example to implement Multi-GRU for MNIST.ipynb
├── Tutorial_05_3 Bi-GRU for MNIST.ipynb
├── Tutorial_06 A very simple example for tensorboard.ipynb
├── Tutorial_07 How to save the model.ipynb
├── Tutorial_08 [transfer learning] Add new variables to graph and save the new model.ipynb
├── Tutorial_09 [tfrecord] use tfrecord to store sequences of different length.ipynb
├── Tutorial_10 [Dataset] numpy data.ipynb
├── Tutorial_11 [Dataset] image data.ipynb
└── Tutorial_12 [tf.layer]high layer API.ipynb
├── example-python
├── .ipynb_checkpoints
│ └── tfrecord_sequence_example-checkpoint.ipynb
├── Tutorial-graph.py
├── Tutorial_10_1_numpy_data_1.py
├── Tutorial_10_1_numpy_data_2.py
├── Tutorial_10_2_image_data_1.py
└── Tutorial_10_2_image_data_2.py
├── figs
├── conv_mnist.png
├── graph2.png
├── lstm_8.png
└── lstm_mnist.png
├── models
├── README.md
├── Tutorial_13 - Basic Seq2seq example.ipynb
├── Tutorial_6 - Bi-directional LSTM for sequence labeling (Chinese segmentation).ipynb
├── m01_batch_normalization
│ ├── README.md
│ ├── __init__.py
│ ├── mnist_cnn.py
│ ├── predict.py
│ └── train.py
├── m02_dcgan
│ ├── README.md
│ ├── __init__.py
│ ├── dcgan 生成二次元头像.ipynb
│ └── dcgan.py
├── m03_wgan
│ ├── README.md
│ ├── wgan.py
│ └── wgan_gp.py
└── m04_pix2pix
│ ├── README.md
│ ├── __init__.py
│ ├── model.py
│ ├── pix2pix.py
│ ├── test.py
│ ├── test.sh
│ ├── train.py
│ ├── train.sh
│ └── utils.py
└── utils
├── u01_logging
├── logging1.py
└── training.log
├── u02_tfrecord
├── README.md
├── __init__.py
├── reader_without_shuffle.ipynb
├── sequence_example_lib.py
├── tfrecord_1_numpy_reader.py
├── tfrecord_1_numpy_reader_without_shuffle.py
├── tfrecord_1_numpy_writer.py
├── tfrecord_2_seqence_reader.py
├── tfrecord_2_seqence_writer.py
├── tfrecord_3_image_reader.py
└── tfrecord_3_image_writer.py
└── u03_flags.py
/.gitignore:
--------------------------------------------------------------------------------
1 | ckpt/*
2 | summary/*
3 | data/*
4 | *.pyc
5 | **/.ipynb_checkpoints/
6 | mnist_png/*
7 | *.tfrecord
8 | **/generated_img/
9 | **/generated_img2/
10 | **/generated_img_gp/
11 | **/MNIST_data/
12 | **/ckpt/
13 | **/ckpt*/
14 | **/summary/
15 | **/data/
16 | events*
17 | **/facades_train/
18 | **/facades_test/
19 |
20 |
21 |
--------------------------------------------------------------------------------
/.ipynb_checkpoints/Tutorial_10 - [transfer learning] Add new variables to graph and save the new model-checkpoint.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## 【迁移学习】往一个已经保存好的 模型添加新的变量\n",
8 | "在迁移学习中,通常我们已经训练好一个模型,现在需要修改模型的部分结构,用于我们的新任务。\n",
9 | "\n",
10 | "比如:\n",
11 | "\n",
12 | "在一个图片分类任务中,我们使用别人训练好的网络来提取特征,但是我们的分类数目和原模型不同,这样我们只能取到 fc 层,后面的分类层需要重新写。这样我们就需要添加新的变量。那么这些新加入的变量必须得初始化才能使用。可是我们又不能使用 'tf.global_variables_initializer()' 来初始化,否则原本训练好的模型就没用了。\n",
13 | "\n",
14 | "关于怎么样单独初始化新增的变量,可以参考下面两个链接:\n",
15 | "- [1]https://stackoverflow.com/questions/35164529/in-tensorflow-is-there-any-way-to-just-initialize-uninitialised-variables\n",
16 | "- [2]https://stackoverflow.com/questions/35013080/tensorflow-how-to-get-all-variables-from-rnn-cell-basiclstm-rnn-cell-multirnn\n",
17 | "\n",
18 | "简单的例子可以直接看下面我的实现方式。"
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "### 初始模型定义与保存\n",
26 | "首先定义一个模型,里边有 v1, v2 两个变量,我们把这个模型保存起来。"
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": 1,
32 | "metadata": {
33 | "collapsed": false
34 | },
35 | "outputs": [
36 | {
37 | "name": "stdout",
38 | "output_type": "stream",
39 | "text": [
40 | "Model saved in file: ./ckpt/test-model.ckpt-1\n"
41 | ]
42 | }
43 | ],
44 | "source": [
45 | "import tensorflow as tf\n",
46 | "config = tf.ConfigProto()\n",
47 | "config.gpu_options.allow_growth = True\n",
48 | "sess = tf.Session(config=config)\n",
49 | "\n",
50 | "# Create some variables.\n",
51 | "v1 = tf.Variable([1.0, 2.3], name=\"v1\")\n",
52 | "v2 = tf.Variable(55.5, name=\"v2\")\n",
53 | "\n",
54 | "\n",
55 | "init_op = tf.global_variables_initializer()\n",
56 | "saver = tf.train.Saver()\n",
57 | "ckpt_path = './ckpt/test-model.ckpt'\n",
58 | "sess.run(init_op)\n",
59 | "save_path = saver.save(sess, ckpt_path, global_step=1)\n",
60 | "print(\"Model saved in file: %s\" % save_path)"
61 | ]
62 | },
63 | {
64 | "cell_type": "markdown",
65 | "metadata": {},
66 | "source": [
67 | "**restart(重启kernel然后执行下面cell的代码)**\n",
68 | "### 导入已经保存好的模型,并添加新的变量\n",
69 | "现在把之前保存好的模型,我只需要其中的 v1 变量。同时我还要添加新的变量 v3。"
70 | ]
71 | },
72 | {
73 | "cell_type": "code",
74 | "execution_count": 1,
75 | "metadata": {
76 | "collapsed": false,
77 | "scrolled": false
78 | },
79 | "outputs": [
80 | {
81 | "name": "stdout",
82 | "output_type": "stream",
83 | "text": [
84 | "INFO:tensorflow:Restoring parameters from ./ckpt/test-model.ckpt-1\n",
85 | "[ 1. 2.29999995]\n",
86 | "[ 1. 2.29999995]\n",
87 | "666\n"
88 | ]
89 | },
90 | {
91 | "data": {
92 | "text/plain": [
93 | "'./ckpt/test-model.ckpt-2'"
94 | ]
95 | },
96 | "execution_count": 1,
97 | "metadata": {},
98 | "output_type": "execute_result"
99 | }
100 | ],
101 | "source": [
102 | "import tensorflow as tf\n",
103 | "config = tf.ConfigProto()\n",
104 | "config.gpu_options.allow_growth = True\n",
105 | "sess = tf.Session(config=config)\n",
106 | "\n",
107 | "# Create some variables.\n",
108 | "v1 = tf.Variable([11.0, 16.3], name=\"v1\")\n",
109 | "\n",
110 | "# ** 导入训练好的模型\n",
111 | "saver = tf.train.Saver()\n",
112 | "ckpt_path = './ckpt/test-model.ckpt'\n",
113 | "saver.restore(sess, ckpt_path + '-'+ str(1))\n",
114 | "print(sess.run(v1))\n",
115 | "\n",
116 | "# ** 定义新的变量并单独初始化新定义的变量\n",
117 | "v3 = tf.Variable(666, name='v3', dtype=tf.int32)\n",
118 | "init_new = tf.variables_initializer([v3])\n",
119 | "sess.run(init_new)\n",
120 | "# 。。。这里就可以进行 fine-tune 了\n",
121 | "print(sess.run(v1))\n",
122 | "print(sess.run(v3))\n",
123 | "\n",
124 | "# ** 保存新的模型。 \n",
125 | "# 注意!注意!注意! 一定一定一定要重新定义 saver, 这样才能把 v3 添加到 checkpoint 中\n",
126 | "saver = tf.train.Saver()\n",
127 | "saver.save(sess, ckpt_path, global_step=2)"
128 | ]
129 | },
130 | {
131 | "cell_type": "markdown",
132 | "metadata": {},
133 | "source": [
134 | "**restart(重启kernel然后执行下面cell的代码)**\n",
135 | "### 这样就完成了 fine-tune, 得到了新的模型"
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": 1,
141 | "metadata": {
142 | "collapsed": false
143 | },
144 | "outputs": [
145 | {
146 | "name": "stdout",
147 | "output_type": "stream",
148 | "text": [
149 | "INFO:tensorflow:Restoring parameters from ./ckpt/test-model.ckpt-2\n",
150 | "Model restored.\n",
151 | "[ 1. 2.29999995]\n",
152 | "666\n"
153 | ]
154 | }
155 | ],
156 | "source": [
157 | "import tensorflow as tf\n",
158 | "config = tf.ConfigProto()\n",
159 | "config.gpu_options.allow_growth = True\n",
160 | "sess = tf.Session(config=config)\n",
161 | "\n",
162 | "# Create some variables.\n",
163 | "v1 = tf.Variable([11.0, 16.3], name=\"v1\")\n",
164 | "v3 = tf.Variable(666, name='v3', dtype=tf.int32)\n",
165 | "# Add ops to save and restore all the variables.\n",
166 | "saver = tf.train.Saver()\n",
167 | "\n",
168 | "# Later, launch the model, use the saver to restore variables from disk, and\n",
169 | "# do some work with the model.\n",
170 | "# Restore variables from disk.\n",
171 | "ckpt_path = './ckpt/test-model.ckpt'\n",
172 | "saver.restore(sess, ckpt_path + '-'+ str(2))\n",
173 | "print(\"Model restored.\")\n",
174 | "\n",
175 | "print(sess.run(v1))\n",
176 | "print(sess.run(v3))"
177 | ]
178 | },
179 | {
180 | "cell_type": "code",
181 | "execution_count": null,
182 | "metadata": {
183 | "collapsed": true
184 | },
185 | "outputs": [],
186 | "source": []
187 | }
188 | ],
189 | "metadata": {
190 | "anaconda-cloud": {},
191 | "kernelspec": {
192 | "display_name": "Python [conda root]",
193 | "language": "python",
194 | "name": "conda-root-py"
195 | },
196 | "language_info": {
197 | "codemirror_mode": {
198 | "name": "ipython",
199 | "version": 2
200 | },
201 | "file_extension": ".py",
202 | "mimetype": "text/x-python",
203 | "name": "python",
204 | "nbconvert_exporter": "python",
205 | "pygments_lexer": "ipython2",
206 | "version": "2.7.12"
207 | }
208 | },
209 | "nbformat": 4,
210 | "nbformat_minor": 1
211 | }
212 |
--------------------------------------------------------------------------------
/.ipynb_checkpoints/Tutorial_9 - How to save the model-checkpoint.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## 如何使用 tf.train.Saver() 来保存模型\n",
8 | "之前一直出错,主要是因为坑爹的编码问题。所以要注意文件的路径绝对不不要出现什么中文呀。"
9 | ]
10 | },
11 | {
12 | "cell_type": "code",
13 | "execution_count": 1,
14 | "metadata": {
15 | "collapsed": false
16 | },
17 | "outputs": [
18 | {
19 | "name": "stdout",
20 | "output_type": "stream",
21 | "text": [
22 | "Model saved in file: ./ckpt/test-model.ckpt-1\n"
23 | ]
24 | }
25 | ],
26 | "source": [
27 | "import tensorflow as tf\n",
28 | "config = tf.ConfigProto()\n",
29 | "config.gpu_options.allow_growth = True\n",
30 | "sess = tf.Session(config=config)\n",
31 | "\n",
32 | "# Create some variables.\n",
33 | "v1 = tf.Variable([1.0, 2.3], name=\"v1\")\n",
34 | "v2 = tf.Variable(55.5, name=\"v2\")\n",
35 | "\n",
36 | "# Add an op to initialize the variables.\n",
37 | "init_op = tf.global_variables_initializer()\n",
38 | "\n",
39 | "# Add ops to save and restore all the variables.\n",
40 | "saver = tf.train.Saver()\n",
41 | "\n",
42 | "ckpt_path = './ckpt/test-model.ckpt'\n",
43 | "# Later, launch the model, initialize the variables, do some work, save the\n",
44 | "# variables to disk.\n",
45 | "sess.run(init_op)\n",
46 | "save_path = saver.save(sess, ckpt_path, global_step=1)\n",
47 | "print(\"Model saved in file: %s\" % save_path)"
48 | ]
49 | },
50 | {
51 | "cell_type": "markdown",
52 | "metadata": {},
53 | "source": [
54 | "注意,在上面保存完了模型之后。**Restart kernel** 之后才能使用下面的模型导入。否则会因为两次命名 \"v1\" 而导致名字错误。"
55 | ]
56 | },
57 | {
58 | "cell_type": "code",
59 | "execution_count": 1,
60 | "metadata": {
61 | "collapsed": false
62 | },
63 | "outputs": [
64 | {
65 | "name": "stdout",
66 | "output_type": "stream",
67 | "text": [
68 | "INFO:tensorflow:Restoring parameters from ./ckpt/test-model.ckpt-1\n",
69 | "Model restored.\n",
70 | "[ 1. 2.29999995]\n",
71 | "55.5\n"
72 | ]
73 | }
74 | ],
75 | "source": [
76 | "import tensorflow as tf\n",
77 | "config = tf.ConfigProto()\n",
78 | "config.gpu_options.allow_growth = True\n",
79 | "sess = tf.Session(config=config)\n",
80 | "\n",
81 | "# Create some variables.\n",
82 | "v1 = tf.Variable([11.0, 16.3], name=\"v1\")\n",
83 | "v2 = tf.Variable(33.5, name=\"v2\")\n",
84 | "\n",
85 | "# Add ops to save and restore all the variables.\n",
86 | "saver = tf.train.Saver()\n",
87 | "\n",
88 | "# Later, launch the model, use the saver to restore variables from disk, and\n",
89 | "# do some work with the model.\n",
90 | "# Restore variables from disk.\n",
91 | "ckpt_path = './ckpt/test-model.ckpt'\n",
92 | "saver.restore(sess, ckpt_path + '-'+ str(1))\n",
93 | "print(\"Model restored.\")\n",
94 | "\n",
95 | "print sess.run(v1)\n",
96 | "print sess.run(v2)"
97 | ]
98 | },
99 | {
100 | "cell_type": "markdown",
101 | "metadata": {},
102 | "source": [
103 | "导入模型之前,必须重新再定义一遍变量。\n",
104 | "\n",
105 | "但是并不需要全部变量都重新进行定义,只定义我们需要的变量就行了。\n",
106 | "\n",
107 | "也就是说,**你所定义的变量一定要在 checkpoint 中存在;但不是所有在checkpoint中的变量,你都要重新定义。**"
108 | ]
109 | },
110 | {
111 | "cell_type": "code",
112 | "execution_count": 1,
113 | "metadata": {
114 | "collapsed": false
115 | },
116 | "outputs": [
117 | {
118 | "name": "stdout",
119 | "output_type": "stream",
120 | "text": [
121 | "INFO:tensorflow:Restoring parameters from ./ckpt/test-model.ckpt-1\n",
122 | "Model restored.\n",
123 | "[ 1. 2.29999995]\n"
124 | ]
125 | }
126 | ],
127 | "source": [
128 | "import tensorflow as tf\n",
129 | "config = tf.ConfigProto()\n",
130 | "config.gpu_options.allow_growth = True\n",
131 | "sess = tf.Session(config=config)\n",
132 | "\n",
133 | "# Create some variables.\n",
134 | "v1 = tf.Variable([11.0, 16.3], name=\"v1\")\n",
135 | "\n",
136 | "# Add ops to save and restore all the variables.\n",
137 | "saver = tf.train.Saver()\n",
138 | "\n",
139 | "# Later, launch the model, use the saver to restore variables from disk, and\n",
140 | "# do some work with the model.\n",
141 | "# Restore variables from disk.\n",
142 | "ckpt_path = './ckpt/test-model.ckpt'\n",
143 | "saver.restore(sess, ckpt_path + '-'+ str(1))\n",
144 | "print(\"Model restored.\")\n",
145 | "\n",
146 | "print sess.run(v1)"
147 | ]
148 | },
149 | {
150 | "cell_type": "markdown",
151 | "metadata": {},
152 | "source": [
153 | "## 关于模型保存的一点心得\n",
154 | "\n",
155 | "```\n",
156 | "saver = tf.train.Saver(max_to_keep=3)\n",
157 | "```\n",
158 | "在定义 saver 的时候一般会定义最多保存模型的数量,一般来说,我都不会保存太多模型,模型多了浪费空间,很多时候其实保存最好的模型就够了。方法就是每次迭代到一定步数就在验证集上计算一次 accuracy 或者 f1 值,如果本次结果比上次好才保存新的模型,否则没必要保存。\n",
159 | "\n",
160 | "如果你想用不同 epoch 保存下来的模型进行融合的话,3到5 个模型已经足够了,假设这各融合的模型成为 M,而最好的一个单模型称为 m_best, 这样融合的话对于M 确实可以比 m_best 更好。但是如果拿这个模型和其他结构的模型再做融合的话,M 的效果并没有 m_best 好,因为M 相当于做了平均操作,减少了该模型的“特性”。"
161 | ]
162 | }
163 | ],
164 | "metadata": {
165 | "anaconda-cloud": {},
166 | "kernelspec": {
167 | "display_name": "Python [conda root]",
168 | "language": "python",
169 | "name": "conda-root-py"
170 | },
171 | "language_info": {
172 | "codemirror_mode": {
173 | "name": "ipython",
174 | "version": 2
175 | },
176 | "file_extension": ".py",
177 | "mimetype": "text/x-python",
178 | "name": "python",
179 | "nbconvert_exporter": "python",
180 | "pygments_lexer": "ipython2",
181 | "version": "2.7.12"
182 | }
183 | },
184 | "nbformat": 4,
185 | "nbformat_minor": 1
186 | }
187 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Tensorflow-Tutorial
2 |
3 | 2018-04 更新说明
4 |
5 | 时间过去一年,TensorFlow 已经从 1.0 版本更新到了 1.8 版本,而且最近更新的非常频繁。最烦的就是每次更新很多 API 都改了,一些老版本的代码就跑不通了。因为本项目关注的人越来越多了,所以自己也感觉到非常有必要更新并更正一些之前的错误,否则误人子弟就不好了。这里不少内容可以直接在官方的教程中找到,官方文档也在不断完善中,我也是把里边的例子跑一下,加深理解而已,更多的还是要自己在具体任务中去搭模型,训模型才能很好地掌握。
6 |
7 | 这一次更新主要内容如下:
8 |
9 | - 使用较新版本的 tfmaster
10 | - 所有的代码改成 python3.5
11 | - 重新整理了基础用例
12 | - 添加实战例子
13 |
14 | 因为工作和学习比较忙,所以这些内容也没办法一下子完成。和之前的版本不同,之前我是作为一个入门菜鸟一遍学一边做笔记。虽然现在依然还是理解得不够,但是比之前掌握的知识应该多了不少,希望能够整理成一个更好的教程。
15 |
16 | 之前的代码我放在了另外一个分支上: https://github.com/yongyehuang/Tensorflow-Tutorial/tree/1.2.1
17 |
18 | 如果有什么问题或者建议,欢迎开issue或者邮件与我联系:yongye@bupt.edu.cn
19 |
20 |
21 | ## 运行环境
22 | - python 3.5
23 | - tensorflow master (gpu version)
24 |
25 |
26 | ## 文件结构
27 | ```
28 | |- Tensorflow-Tutorial
29 | | |- example-notebook # 入门教程 notebook 版
30 | | |- example-python # 入门教程 .py 版
31 | | |- utils # 一些工具函数(logging, tf.flags)
32 | | |- models # 一些实战的例子(BN, GAN, 序列标注,seq2seq 等,持续更新)
33 | | |- data # 数据
34 | | |- doc # 相关文档
35 | ```
36 |
37 | ## 1.入门例子
38 | #### T_01.TensorFlow 的基本用法
39 | - [notebook](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_01%20Basic%20Usage.ipynb)
40 |
41 | 介绍 TensorFlow 的变量、常量和基本操作,最后介绍了一个非常简单的回归拟合例子。
42 |
43 |
44 |
45 | #### T_02.实现一个两层的全连接网络对 MNIST 进行分类
46 | - [notebook](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_02%20A%20simple%20feedforward%20network%20for%20MNIST.ipynb)
47 |
48 |
49 |
50 | #### T_03.TensorFlow 变量命名管理机制
51 | - [notebook1](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_03_1%20The%20usage%20of%20%20name_scope%20and%20variable_scope.ipynb)
52 | 介绍 tf.Variable() 和 tf.get_variable() 创建变量的区别;介绍如何使用 tf.name_scope() 和 tf.variable_scope() 管理命名空间。
53 |
54 | - [notebook2](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_03_2%20The%20usage%20of%20%20Collection.ipynb)
55 | 除了使用变量命名来管理变量之外,还经常用到 collection 的方式来聚合一些变量或者操作。
56 |
57 |
58 |
59 | #### T_04.实现一个两层的卷积神经网络(CNN)对 MNIST 进行分类
60 | - [notebook1-使用原生API构建CNN](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_04_1%20Convolutional%20network%20for%20MNIST(1).ipynb)
61 |
62 | 构建一个非常简单的 CNN 网络,同时输出中间各个核的可视化来理解 CNN 的原理。
63 |
64 | 第一层卷积核可视化
65 |
66 | - [notebook2-自定义函数构建CNN](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_04_2%20Convolutional%20network%20for%20MNIST(2).ipynb)
67 |
68 | - [notebook3-使用tf.layers高级API构建CNN](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_04_3%20Convolutional%20network%20for%20MNIST(3).ipynb)
69 |
70 | - [code-加入 BN 层的 CNN](https://github.com/yongyehuang/Tensorflow-Tutorial/tree/master/utils_and_models/m01_batch_normalization)
71 |
72 | 在上一个例子的基础上,加入 BN 层。在 CNN 中,使用 BN 层可以加速收敛速度,同时也能够减小初始化方式的影响。在使用 BN 层的时候要注意训练时用的是 mini-batch 的均值方差,测试时用的是指数平均的均值方差。所以在训练的过程中,一定要记得更新并保存均值方差。
73 |
74 | 在这个小网络中:迭代 10000 步,batch_size=100,大概耗时 45s;添加了 BN 层之后,迭代同样的次数,大概耗时 90s.
75 |
76 |
77 | #### T_05.实现多层的 LSTM 和 GRU 网络对 MNIST 进行分类
78 | - [LSTM-notebook](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_05_1%20An%20understandable%20example%20to%20implement%20Multi-LSTM%20for%20MNIST.ipynb)
79 | - [GRU-notebook](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_05_2%20An%20understandable%20example%20to%20implement%20Multi-GRU%20for%20MNIST.ipynb)
80 | - [Bi-GRU-notebook](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_05_3%20Bi-GRU%20for%20MNIST.ipynb)
81 |
82 |
83 | 字符 8
84 |
85 |
86 | lstm 对字符 8 的识别过程
87 |
88 |
89 |
90 | #### T_06.tensorboard 的简单用法
91 | - [notebook](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_06%20A%20very%20simple%20example%20for%20tensorboard.ipynb)
92 |
93 |
94 | 简单的 tensorboard 可视化
95 |
96 |
97 |
98 | #### T_07.使用 tf.train.Saver() 来保存模型
99 | - [notebook](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_07%20How%20to%20save%20the%20model.ipynb)
100 |
101 |
102 |
103 | #### T_08.【迁移学习】往一个已经保存好的 模型添加新的变量
104 | - [notebook](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_08%20%20%5Btransfer%20learning%5D%20Add%20new%20variables%20to%20graph%20and%20save%20the%20new%20model.ipynb)
105 |
106 |
107 |
108 | #### T_09.使用 tfrecord 打包不定长的序列数据
109 | - [notebook](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_09%20%5Btfrecord%5D%20use%20tfrecord%20to%20store%20sequences%20of%20different%20length.ipynb)
110 | - [reader-code](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/utils_and_models/u02_tfrecord/tfrecord_2_seqence_reader.py)
111 | - [writer-code](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/utils_and_models/u02_tfrecord/tfrecord_2_seqence_writer.py)
112 |
113 |
114 |
115 | #### T_10.使用 tf.data.Dataset 和 tfrecord 给 numpy 数据构建数据集
116 | - [dataset-notebook](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_10%20%5BDataset%5D%20numpy%20data.ipynb)
117 | - [tfrecord-reader-code](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/utils_and_models/u02_tfrecord/tfrecord_1_numpy_reader.py)
118 | - [tfrecord-writer-code](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/utils_and_models/u02_tfrecord/tfrecord_1_numpy_writer.py)
119 |
120 |
121 | 下面是对 MNIST 数据训练集 55000 个样本 读取的一个速度比较,统一 `batch_size=128`,主要比较 `one-shot` 和 `initializable` 两种迭代方式:
122 |
123 | |iter_mode|buffer_size|100 batch(s)|
124 | |:----:|:---:|:---:|
125 | |one-shot|2000|125|
126 | |one-shot|5000|149|
127 | |initializable|2000|0.7|
128 | |initializable|5000|0.7|
129 |
130 | 可以看到,使用 `initializable` 方式的速度明显要快很多。因为使用 `one-shot` 方式会把整个矩阵放在图中,计算非常非常慢。
131 |
132 |
133 |
134 | #### T_11.使用 tf.data.Dataset 和 tfrecord 给 图片数据 构建数据集
135 | - [dataset-notebook](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_11%20%5BDataset%5D%20image%20data.ipynb)
136 | - [tfrecord-writer-code](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/utils_and_models/u02_tfrecord/tfrecord_3_image_writer.py)
137 | - [tfrecord-reader-code](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/utils_and_models/u02_tfrecord/tfrecord_3_image_reader.py)
138 |
139 | 对于 png 数据的读取,我尝试了 3 组不同的方式: one-shot 方式, tf 的队列方式(queue), tfrecord 方式. 同样是在机械硬盘上操作, 结果是 tfrecord 方式明显要快一些。(batch_size=128,图片大小为256*256,机械硬盘)
140 |
141 | |iter_mode|buffer_size|100 batch(s)|
142 | |:----:|:---:|:---:|
143 | |one-shot|2000|75|
144 | |one-shot|5000|86|
145 | |tf.queue|2000|11|
146 | |tf.queue|5000|11|
147 | |tfrecord|2000|5.3|
148 | |tfrecord|5000|5.3|
149 |
150 | 如果是在 SSD 上面的话,tf 的队列方式应该也是比较快的.打包成 tfrecord 格式只是减少了小文件的读取,其实现也是使用队列的。
151 |
152 |
153 | #### T_12.TensorFlow 高级API tf.layers 的使用
154 | - [notebook](https://github.com/yongyehuang/Tensorflow-Tutorial/blob/master/example-notebook/Tutorial_12%20%5Btf.layer%5Dhigh%20layer%20API.ipynb)
155 |
156 | 使用 TensorFlow 原生的 API 能够帮助自己很好的理解网络的细节,但是往往比较低效。 tf.layers 和 tf.keras 一样,是一个封装得比较好的一个高级库,接口用着挺方便的。所以在开发的时候,可以使用高级的接口能够有效的提高工作效率。
157 |
158 |
159 | # 2.TensorFlow 实战(持续更新)
160 | 下面的每个例子都是相互独立的,每个文件夹下面的代码都是可以单独运行的,不依赖于其他文件夹。
161 |
162 | ## [m01_batch_normalization: Batch Normalization 的使用](https://github.com/yongyehuang/Tensorflow-Tutorial/tree/master/models/m01_batch_normalization)
163 | 参考:[tensorflow中batch normalization的用法](https://www.cnblogs.com/hrlnw/p/7227447.html)
164 |
165 | ## [m02_dcgan: 使用 DCGAN 生成二次元头像](https://github.com/yongyehuang/Tensorflow-Tutorial/tree/master/models/m02_dcgan)
166 | 参考:
167 | - [原论文:Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks](https://link.zhihu.com/?target=https%3A//arxiv.org/abs/1511.06434)
168 | - [GAN学习指南:从原理入门到制作生成Demo](https://zhuanlan.zhihu.com/p/24767059)
169 | - [代码:carpedm20/DCGAN-tensorflow](https://github.com/carpedm20/DCGAN-tensorflow)
170 | - [代码:aymericdamien/TensorFlow-Examples](https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/3_NeuralNetworks/dcgan.py)
171 |
172 | 这里的 notebook 和 .py 文件的内容是一样的。本例子和下面的 GAN 模型用的数据集也是用了[GAN学习指南:从原理入门到制作生成Demo](https://zhuanlan.zhihu.com/p/24767059) 的二次元头像,感觉这里例子比较有意思。如果想使用其他数据集的话,只需要把数据集换一下就行了。
173 |
174 | 下载链接: https://pan.baidu.com/s/1HBJpfkIFaGh0s2nfNXJsrA 密码: x39r
175 |
176 | 下载后把所有的图片解压到一个文件夹中,比如本例中是: `data_path = '../../data/anime/'`
177 |
178 | 运行: `python dcgan.py `
179 |
180 | ## [m03_wgan: 使用 WGAN 生成二次元头像](https://github.com/yongyehuang/Tensorflow-Tutorial/tree/master/models/m03_wgan)
181 | 这里的生成器和判别器我只实现了 DCGAN,没有实现 MLP. 如果想实现的话可以参考下面的两个例子。
182 | 参考:
183 | - [原论文:Wasserstein GAN](https://arxiv.org/pdf/1701.07875.pdf)
184 | - [代码:jiamings/wgan](https://github.com/jiamings/wgan)
185 | - [代码:Zardinality/WGAN-tensorflow](https://github.com/Zardinality/WGAN-tensorflow)
186 |
187 | 原版的 wgan: `python wgan.py `
188 |
189 | 改进的 wgan-gp: `python wgan_gp.py`
190 |
191 |
192 | ## [m04_pix2pix: image-to-image](https://github.com/yongyehuang/Tensorflow-Tutorial/tree/master/models/m04_pix2pix)
193 | 代码来自:[affinelayer/pix2pix-tensorflow](https://github.com/affinelayer/pix2pix-tensorflow)
194 |
195 |
--------------------------------------------------------------------------------
/ckpt/bi-lstm.ckpt-12.data-00000-of-00001:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yongyehuang/Tensorflow-Tutorial/88b5cdbdf402a8ae7f65a540e5f81f3da8f45e7d/ckpt/bi-lstm.ckpt-12.data-00000-of-00001
--------------------------------------------------------------------------------
/ckpt/bi-lstm.ckpt-12.index:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yongyehuang/Tensorflow-Tutorial/88b5cdbdf402a8ae7f65a540e5f81f3da8f45e7d/ckpt/bi-lstm.ckpt-12.index
--------------------------------------------------------------------------------
/ckpt/bi-lstm.ckpt-12.meta:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yongyehuang/Tensorflow-Tutorial/88b5cdbdf402a8ae7f65a540e5f81f3da8f45e7d/ckpt/bi-lstm.ckpt-12.meta
--------------------------------------------------------------------------------
/ckpt/checkpoint:
--------------------------------------------------------------------------------
1 | model_checkpoint_path: "test-model.ckpt-2"
2 | all_model_checkpoint_paths: "test-model.ckpt-2"
3 |
--------------------------------------------------------------------------------
/data/msr_train.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yongyehuang/Tensorflow-Tutorial/88b5cdbdf402a8ae7f65a540e5f81f3da8f45e7d/data/msr_train.txt
--------------------------------------------------------------------------------
/doc/problem-solution.md:
--------------------------------------------------------------------------------
1 | ## 1.为什么 relu 激活函数会有失活现象?
2 | > [一个非常大的梯度流过一个 ReLU 神经元,更新过参数之后,这个神经元再也不会对任何数据有激活现象了。](http://blog.csdn.net/cyh_24/article/details/50593400)
3 | > [Must Know Tips/Tricks in Deep Neural Networks (by Xiu-Shen Wei)](http://lamda.nju.edu.cn/weixs/project/CNNTricks/CNNTricks.html)
4 | > [深度学习系列(8):激活函数](https://plushunter.github.io/2017/05/12/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E7%B3%BB%E5%88%97%EF%BC%888%EF%BC%89%EF%BC%9A%E6%BF%80%E6%B4%BB%E5%87%BD%E6%95%B0/)
5 |
6 | A: 在某次反向传播中神经元 C 传过一个很大的梯度,和 C 相连的所有权重系数 w 都变成了很大的负数。假设前一层输出也是 relu 激活函数,那么前一层的输出(C 的输入)一定是非负数。那么神经元 C 一定会处于0梯度状态,没有任何数据(输入)能够拯救他。也就是失活了。
7 |
8 | 那么,**我觉得,在初始化的时候,如果本层(L)使用 relu 激活函数,那么 biases 最好使用较小的正数初始化,如0.01,0.005等。这样可以在一定程度上使得输出偏向于正数,从而避免梯度消失。** 但是也有一点好处,由于部分神经元失活了,这和做了 dropout 一样,能够有助于防止过拟合。
9 |
10 | **除了上面的失活现象以外,relu 激活函数还有偏移现象:输出均值恒大于零。** 失活现象和偏移现象会共同影响网络的收敛性。#8.数据偏移怎么影响网络的收敛?#
11 |
12 |
13 |
14 | ## 2.[code]AlexNet(等 CNN model) 调参过程中要注意什么?
15 | > 在 github 上面有很多不同版本的 AlexNet,网络结构基本都是一样的,在官方的 tensorflow slim 框架中也提供了 alexnet-v2 版本。在我的任务中,发现 slim 版本的 alexnet 效果要比其他版本的好很多(2~4个百分点)。明明结构一样,为什么差别这么大。
16 |
17 | A:虽然我觉得 slim 框架很不友好,但是里边的参数应该都是经过测试得到的较好的结果。很多小的细节都会影响最后的结果,具体要注意的有下面这些点:
18 | - 初始化方式。在我的任务中,初始化方式影响很大。slim 中的每一层的初始化方式和 caffe 的版本中基本一致。包括 conv 层, fc 层的 weights, biases。我就是最后一个 fc 层改了一下初始化,loss 嗖嗖地就降了。
19 | - 优化器。在原版中用的是 RMSProp 优化器,但坑的是用的不是默认参数,最好设置成跟 slim 一致。
20 | - 数据预处理。我用 caffe 算出了整个数据集的均值,然后把原始图片[0.~255.]减去均值,效果还不错。
21 | - lrn。在 slim 的 alexnet-v2 版本中去掉了局部响应层。结果没有变差,速度快了大概一倍吧。
22 |
23 |
24 |
25 | ## 3.[code]tensorflow 训练模型,报无法分配 memory,但是程序继续运行,这时运行的结果有问题吗?
26 | >**ran out of memory trying to allocate 3.27GiB. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory is available.** 这时候,使用 watch nvidia-smi 看显卡使用情况,就会发现使用率非常低。
27 |
28 | A:这种情况下就应该把batch_size减小了!!!虽然程序还在运行,但是你会发现,结果根本不对,loss 根本就没降。这不是因为你的模型不好,学习率不对。把 batch_size 调小看看结果再下定论。
29 |
30 |
31 |
32 | ## 4.什么情况下用 sigmoid 会比 relu 好呢?
33 | > sigmoid 函数有陷入饱和区(造成梯度消失),非零中心和计算效率低的缺点。那么有什么情况下用 sigmoid 会好呢?
34 |
35 | A: 如果只是作为一个普通隐含层的激活函数的话,还是用 relu 就好了。但是如果你后继需要对某层特征进行量化处理的话,sigmoid 就起作用了。relu 层的输出范围太大,不适合做量化。这时候就体现出 0 和 1 的优越性了。同样,使用 tanh 层也是可以的。
36 |
37 |
38 |
39 | ## 5.sigmoid 非 zero-center 会有什么影响,relu 有这样的影响吗?怎么理解因此导致梯度下降权重更新时出现 z 字型的下降?
40 | > [Sigmoid函数的输出不是零中心的。这个性质并不是我们想要的,因为在神经网络后面层中神经元得到的数据不是零中心的。这一情况将影响梯度下降的运作,因为如果输入神经元的数据总是正数(比如在 f=wx+b 中每个元素都是 x>0),那么关于 w 的梯度在反向传播中,将会要么全部是正数,或者全部是负数(比如f=-wx+b).这将会导致梯度下降权重更新时出现z字型的下降(如下图所示)。](https://plushunter.github.io/2017/05/12/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E7%B3%BB%E5%88%97%EF%BC%888%EF%BC%89%EF%BC%9A%E6%BF%80%E6%B4%BB%E5%87%BD%E6%95%B0/)
41 |
42 |
43 |
44 |
45 | ## 6.在 relu 层前面的 BN 层中,为什么不用对 scale 做处理
46 | > [mnist_4.1_batchnorm_five_layers_relu.py](https://github.com/martin-gorner/tensorflow-mnist-tutorial/blob/master/mnist_4.1_batchnorm_five_layers_relu.py)
47 |
48 | A:没想明白.
49 |
50 |
51 |
52 | ## 7.在问题 1 中,relu 激活函数的偏移现象就是数据的输入分布(zero-center)和输出分布变了(no-zero-center).在 BN 中也提到过,这种数据分布的变化为什么会影响网络的收敛性?
53 | > [对于神经网络的各层输出,由于它们经过了层内操作作用,其分布显然与各层对应的输入信号分布不同,而且差异会随着网络深度增大而增大,可是它们所能“指示”的样本标记(label)仍然是不变的,这便符合了covariate shift的定义。](https://www.zhihu.com/question/38102762) 这样源空间 -> 目标空间 的变化怎么影响网络的收敛?
54 |
55 |
56 |
57 | ## 8.在BN中,为什么通过将activation规范为均值和方差一致的手段使得原本会减小的activation的scale变大,防止梯度消失?
58 | [在BN中,是通过将activation规范为均值和方差一致的手段使得原本会减小的activation的scale变大。可以说是一种更有效的local response normalization方法(见4.2.1节)。](https://www.zhihu.com/question/38102762) 在 BN 中,通过mini-batch来规范化某些层/所有层的输入,从而可以固定每层输入信号的均值与方差。对于 mini-batch,首先减去均值,方差归一;接着进行 scale and shift 操作,也就是用学习到的全局均值和方差替换掉了 mini-batch 的均值和方差。 然后送入激活函数如(sigmoid)中,**这时候并没有把sigmoid的输入约束到 0 附近呀,为什么就能够避免梯度消失?**
59 |
60 | A:首先,对于 sigmoid 和 tanh 来说,当输入的绝对值很大时就会陷入饱和区。这个激活函数的输入一般指的是 z(=wx)。
61 | z 很大 -> 陷入饱和区
62 | z 很大 -> wx 这两个向量的点积很大 -> 如果 w 或者 x 的元素值很大,较容易使得 wx 很大? -> w,x 的值很大
63 | BN 避免了梯度消失 -> BN 处理使得 x 向 0 靠近了。但是没有呀??
64 |
65 | [BN使得输入分布大致稳定,从而缩短了参数适应分布的过程,进而缩短训练时间](https://zhuanlan.zhihu.com/p/26532249)
66 |
67 |
68 |
69 | ## 9.center loss 训练有什么需要注意的?center loss 会使类间的相对距离增大吗?
70 | > center loss 最小化类内距离,但是并没有显式地去最大化类间距离。在我的实验中,对加了center loss 的高层特征进行统计分析,发现类内特征的方差明显要比原来更小了,但是特征均值也比原来更小了。这样类间的绝对距离也会比原来小,假设类间中心距离为 L-inter,类内的距离为 L-intra, 类间的相对距离为 L-relative = (L-inter / L-intra)。那么,加上 center loss 后, L-relative 怎么变化?
71 |
72 | A:1.在模型训练的时候记得把每个类的中心特征向量留出接口,以便后继分析。
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/example-notebook/.ipynb_checkpoints/Tutorial_02 A simple feedforward network for MNIST-checkpoint.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# 两层FC层做分类:MNIST\n",
8 | "\n",
9 | "在本教程中,我们来实现一个非常简单的两层全连接层来完成MNIST数据的分类问题。\n",
10 | "\n",
11 | "输入[-1,28*28], FC1 有 1024 个neurons, FC2 有 10 个neurons。这么简单的一个全连接网络,结果测试准确率达到了 0.98。还是非常棒的!!!"
12 | ]
13 | },
14 | {
15 | "cell_type": "code",
16 | "execution_count": 1,
17 | "metadata": {},
18 | "outputs": [],
19 | "source": [
20 | "from __future__ import print_function\n",
21 | "from __future__ import division\n",
22 | "from __future__ import absolute_import\n",
23 | "\n",
24 | "import warnings\n",
25 | "warnings.filterwarnings('ignore') # 不打印 warning \n",
26 | "\n",
27 | "import numpy as np\n",
28 | "import tensorflow as tf\n",
29 | "\n",
30 | "# 设置按需使用GPU\n",
31 | "config = tf.ConfigProto()\n",
32 | "config.gpu_options.allow_growth = True\n",
33 | "sess = tf.Session(config=config)"
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "### 1.导入数据\n",
41 | "下面导入数据这部分的警告可以不用管先,TensorFlow 非常恶心的地方就是不停地改 API,改到发麻。"
42 | ]
43 | },
44 | {
45 | "cell_type": "code",
46 | "execution_count": 2,
47 | "metadata": {},
48 | "outputs": [
49 | {
50 | "name": "stdout",
51 | "output_type": "stream",
52 | "text": [
53 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/base.py:198: retry (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
54 | "Instructions for updating:\n",
55 | "Use the retry module or similar alternatives.\n",
56 | "WARNING:tensorflow:From :3: read_data_sets (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
57 | "Instructions for updating:\n",
58 | "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
59 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:260: maybe_download (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
60 | "Instructions for updating:\n",
61 | "Please write your own downloading logic.\n",
62 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:262: extract_images (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
63 | "Instructions for updating:\n",
64 | "Please use tf.data to implement this functionality.\n",
65 | "Extracting ../data/MNIST_data/train-images-idx3-ubyte.gz\n",
66 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:267: extract_labels (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
67 | "Instructions for updating:\n",
68 | "Please use tf.data to implement this functionality.\n",
69 | "Extracting ../data/MNIST_data/train-labels-idx1-ubyte.gz\n",
70 | "Extracting ../data/MNIST_data/t10k-images-idx3-ubyte.gz\n",
71 | "Extracting ../data/MNIST_data/t10k-labels-idx1-ubyte.gz\n",
72 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:290: DataSet.__init__ (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
73 | "Instructions for updating:\n",
74 | "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n"
75 | ]
76 | }
77 | ],
78 | "source": [
79 | "# 用tensorflow 导入数据\n",
80 | "from tensorflow.examples.tutorials.mnist import input_data\n",
81 | "mnist = input_data.read_data_sets('../data/MNIST_data', one_hot=False, source_url='http://yann.lecun.com/exdb/mnist/')"
82 | ]
83 | },
84 | {
85 | "cell_type": "code",
86 | "execution_count": 3,
87 | "metadata": {},
88 | "outputs": [
89 | {
90 | "name": "stdout",
91 | "output_type": "stream",
92 | "text": [
93 | "training data shape (55000, 784)\n",
94 | "training label shape (55000,)\n"
95 | ]
96 | }
97 | ],
98 | "source": [
99 | "print('training data shape ', mnist.train.images.shape)\n",
100 | "print('training label shape ', mnist.train.labels.shape)"
101 | ]
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "metadata": {},
106 | "source": [
107 | "### 2. 构建网络"
108 | ]
109 | },
110 | {
111 | "cell_type": "code",
112 | "execution_count": 4,
113 | "metadata": {},
114 | "outputs": [
115 | {
116 | "name": "stdout",
117 | "output_type": "stream",
118 | "text": [
119 | "Tensor(\"add_1:0\", shape=(?, 10), dtype=float32)\n"
120 | ]
121 | }
122 | ],
123 | "source": [
124 | "# 权值初始化\n",
125 | "def weight_variable(shape):\n",
126 | " # 用正态分布来初始化权值\n",
127 | " initial = tf.truncated_normal(shape, stddev=0.1)\n",
128 | " return tf.Variable(initial)\n",
129 | "\n",
130 | "def bias_variable(shape):\n",
131 | " # 本例中用relu激活函数,所以用一个很小的正偏置较好\n",
132 | " initial = tf.constant(0.1, shape=shape)\n",
133 | " return tf.Variable(initial)\n",
134 | "\n",
135 | "\n",
136 | "# input_layer\n",
137 | "X_input = tf.placeholder(tf.float32, [None, 784])\n",
138 | "y_input = tf.placeholder(tf.int64, [None]) # 不使用 one-hot \n",
139 | "\n",
140 | "# FC1\n",
141 | "W_fc1 = weight_variable([784, 1024])\n",
142 | "b_fc1 = bias_variable([1024])\n",
143 | "h_fc1 = tf.nn.relu(tf.matmul(X_input, W_fc1) + b_fc1)\n",
144 | "\n",
145 | "# FC2\n",
146 | "W_fc2 = weight_variable([1024, 10])\n",
147 | "b_fc2 = bias_variable([10])\n",
148 | "# y_pre = tf.nn.softmax(tf.matmul(h_fc1, W_fc2) + b_fc2)\n",
149 | "logits = tf.matmul(h_fc1, W_fc2) + b_fc2\n",
150 | "\n",
151 | "print(logits)"
152 | ]
153 | },
154 | {
155 | "cell_type": "markdown",
156 | "metadata": {},
157 | "source": [
158 | "### 3.训练和评估\n",
159 | "下面我们将输入 mnist 的数据来进行训练。在下面有个 mnist.train.next_batch(batch_size=100) 的操作,每次从数据集中取出100个样本。如果想了解怎么实现的话建议看一下源码,其实挺简单的,很多时候需要我们自己去实现读取数据的这个函数。"
160 | ]
161 | },
162 | {
163 | "cell_type": "code",
164 | "execution_count": 5,
165 | "metadata": {},
166 | "outputs": [
167 | {
168 | "name": "stdout",
169 | "output_type": "stream",
170 | "text": [
171 | "step 500, train cost=0.153510, acc=0.950000; test cost=0.123346, acc=0.962500\n",
172 | "step 1000, train cost=0.087353, acc=0.960000; test cost=0.104876, acc=0.967400\n",
173 | "step 1500, train cost=0.033138, acc=0.990000; test cost=0.080937, acc=0.975200\n",
174 | "step 2000, train cost=0.028831, acc=0.990000; test cost=0.077214, acc=0.977800\n",
175 | "step 2500, train cost=0.004817, acc=1.000000; test cost=0.066441, acc=0.980000\n",
176 | "step 3000, train cost=0.015692, acc=1.000000; test cost=0.067741, acc=0.979400\n",
177 | "step 3500, train cost=0.011569, acc=1.000000; test cost=0.075138, acc=0.979400\n",
178 | "step 4000, train cost=0.006310, acc=1.000000; test cost=0.074501, acc=0.978300\n",
179 | "step 4500, train cost=0.008795, acc=1.000000; test cost=0.076483, acc=0.979100\n",
180 | "step 5000, train cost=0.027700, acc=0.980000; test cost=0.073973, acc=0.980000\n"
181 | ]
182 | }
183 | ],
184 | "source": [
185 | "# 1.损失函数:cross_entropy\n",
186 | "# 如果label是 one-hot 的话要换一下损失函数,参考:https://blog.csdn.net/tz_zs/article/details/76086457\n",
187 | "cross_entropy = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y_input, logits=logits)) \n",
188 | "# 2.优化函数:AdamOptimizer, 优化速度要比 GradientOptimizer 快很多\n",
189 | "train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)\n",
190 | "\n",
191 | "# 3.预测结果评估\n",
192 | "# 预测值中最大值(1)即分类结果,是否等于原始标签中的(1)的位置。argmax()取最大值所在的下标\n",
193 | "correct_prediction = tf.equal(tf.argmax(logits, 1), y_input) \n",
194 | "accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))\n",
195 | "\n",
196 | "# 开始运行\n",
197 | "sess.run(tf.global_variables_initializer())\n",
198 | "# 这大概迭代了不到 10 个 epoch, 训练准确率已经达到了0.98\n",
199 | "for i in range(5000):\n",
200 | " X_batch, y_batch = mnist.train.next_batch(batch_size=100)\n",
201 | " cost, acc, _ = sess.run([cross_entropy, accuracy, train_step], feed_dict={X_input: X_batch, y_input: y_batch})\n",
202 | " if (i+1) % 500 == 0:\n",
203 | " test_cost, test_acc = sess.run([cross_entropy, accuracy], feed_dict={X_input: mnist.test.images, y_input: mnist.test.labels})\n",
204 | " print(\"step {}, train cost={:.6f}, acc={:.6f}; test cost={:.6f}, acc={:.6f}\".format(i+1, cost, acc, test_cost, test_acc))\n",
205 | " "
206 | ]
207 | }
208 | ],
209 | "metadata": {
210 | "anaconda-cloud": {},
211 | "kernelspec": {
212 | "display_name": "Python 3",
213 | "language": "python",
214 | "name": "python3"
215 | },
216 | "language_info": {
217 | "codemirror_mode": {
218 | "name": "ipython",
219 | "version": 3
220 | },
221 | "file_extension": ".py",
222 | "mimetype": "text/x-python",
223 | "name": "python",
224 | "nbconvert_exporter": "python",
225 | "pygments_lexer": "ipython3",
226 | "version": "3.5.2"
227 | }
228 | },
229 | "nbformat": 4,
230 | "nbformat_minor": 1
231 | }
232 |
--------------------------------------------------------------------------------
/example-notebook/.ipynb_checkpoints/Tutorial_03_2 The usage of Collection-checkpoint.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# TensorFlow 变量命名管理机制(二)\n",
8 | "\n",
9 | "\n",
10 | "### 1. 用 collection 来聚合变量\n",
11 | "前面介绍了 tensorflow 的变量命名机制,这里要补充一下 `tf.add_to_collection` 和 `tf.get_collection`的用法。\n",
12 | "\n",
13 | "因为神经网络中的参数非常多,有时候我们 只想对某些参数进行操作。除了前面通过变量名称的方法来获取参数之外, TensorFlow 中还有 collection 这么一种操作。\n",
14 | "\n",
15 | "collection 可以聚合多个**变量**或者**操作**。"
16 | ]
17 | },
18 | {
19 | "cell_type": "code",
20 | "execution_count": 1,
21 | "metadata": {},
22 | "outputs": [],
23 | "source": [
24 | "import warnings\n",
25 | "warnings.filterwarnings('ignore') # 不打印 warning \n",
26 | "\n",
27 | "import tensorflow as tf\n",
28 | "\n",
29 | "# 设置GPU按需增长\n",
30 | "config = tf.ConfigProto()\n",
31 | "config.gpu_options.allow_growth = True\n",
32 | "sess = tf.Session(config=config)"
33 | ]
34 | },
35 | {
36 | "cell_type": "markdown",
37 | "metadata": {},
38 | "source": [
39 | "参考:[如何利用tf.add_to_collection、tf.get_collection以及tf.add_n来简化正则项的计算](https://blog.csdn.net/weixin_39980291/article/details/78352125)"
40 | ]
41 | },
42 | {
43 | "cell_type": "code",
44 | "execution_count": 2,
45 | "metadata": {},
46 | "outputs": [
47 | {
48 | "name": "stdout",
49 | "output_type": "stream",
50 | "text": [
51 | "vars in col1: [, ]\n"
52 | ]
53 | }
54 | ],
55 | "source": [
56 | "# 把变量添加到一个 collection 中\n",
57 | "v1 = tf.Variable([1,2,3], name='v1')\n",
58 | "v2 = tf.Variable([2], name='v2')\n",
59 | "v3 = tf.get_variable(name='v3', shape=(2,3))\n",
60 | "\n",
61 | "tf.add_to_collection('col1', v1) # 把 v1 添加到 col1 中\n",
62 | "tf.add_to_collection('col1', v3)\n",
63 | "\n",
64 | "col1s = tf.get_collection(key='col1') # 获取 col1 的变量\n",
65 | "print('vars in col1:', col1s)"
66 | ]
67 | },
68 | {
69 | "cell_type": "markdown",
70 | "metadata": {},
71 | "source": [
72 | "除了把变量添加到集合中,还可以把操作添加到集合中。"
73 | ]
74 | },
75 | {
76 | "cell_type": "code",
77 | "execution_count": 3,
78 | "metadata": {},
79 | "outputs": [
80 | {
81 | "name": "stdout",
82 | "output_type": "stream",
83 | "text": [
84 | "vars in col1: [, , ]\n"
85 | ]
86 | }
87 | ],
88 | "source": [
89 | "op1 = tf.add(v1, 2, name='add_op')\n",
90 | "tf.add_to_collection('col1', op1)\n",
91 | "col1s = tf.get_collection(key='col1') # 获取 col1 的变量\n",
92 | "print('vars in col1:', col1s)"
93 | ]
94 | },
95 | {
96 | "cell_type": "markdown",
97 | "metadata": {},
98 | "source": [
99 | "此外,还可以加上 scope 的约束。"
100 | ]
101 | },
102 | {
103 | "cell_type": "code",
104 | "execution_count": 3,
105 | "metadata": {},
106 | "outputs": [
107 | {
108 | "name": "stdout",
109 | "output_type": "stream",
110 | "text": [
111 | "vars in col1 with scope=model: []\n"
112 | ]
113 | }
114 | ],
115 | "source": [
116 | "with tf.variable_scope('model'):\n",
117 | " v4 = tf.get_variable('v4', shape=[3,4])\n",
118 | " v5 = tf.Variable([1,2,3], name='v5')\n",
119 | "\n",
120 | "tf.add_to_collection('col1', v5)\n",
121 | "col1_vars = tf.get_collection(key='col1', scope='model') # 获取 col1 的变量\n",
122 | "print('vars in col1 with scope=model: ', col1_vars)"
123 | ]
124 | },
125 | {
126 | "cell_type": "markdown",
127 | "metadata": {},
128 | "source": [
129 | "### 2. tf.GraphKeys \n",
130 | "\n",
131 | "参考:[tf.GraphKeys 函数](https://www.w3cschool.cn/tensorflow_python/tensorflow_python-ne7t2ezd.html)\n",
132 | "\n",
133 | "用于图形集合的标准名称。\n",
134 | "\n",
135 | "\n",
136 | "标准库使用各种已知的名称来收集和检索与图形相关联的值。例如,如果没有指定,则 tf.Optimizer 子类默认优化收集的变量tf.GraphKeys.TRAINABLE_VARIABLES,但也可以传递显式的变量列表。\n",
137 | "\n",
138 | "定义了以下标准键:\n",
139 | "\n",
140 | "- GLOBAL_VARIABLES:默认的 Variable 对象集合,在分布式环境共享(模型变量是其中的子集)。参考:tf.global_variables。通常,所有TRAINABLE_VARIABLES 变量都将在 MODEL_VARIABLES,所有 MODEL_VARIABLES 变量都将在 GLOBAL_VARIABLES。\n",
141 | "- LOCAL_VARIABLES:每台计算机的局部变量对象的子集。通常用于临时变量,如计数器。注意:使用 tf.contrib.framework.local_variable 添加到此集合。\n",
142 | "- MODEL_VARIABLES:在模型中用于推理(前馈)的变量对象的子集。注意:使用 tf.contrib.framework.model_variable 添加到此集合。\n",
143 | "- TRAINABLE_VARIABLES:将由优化器训练的变量对象的子集。\n",
144 | "- SUMMARIES:在关系图中创建的汇总张量对象。\n",
145 | "- QUEUE_RUNNERS:用于为计算生成输入的 QueueRunner 对象。\n",
146 | "- MOVING_AVERAGE_VARIABLES:变量对象的子集,它也将保持移动平均值。\n",
147 | "- REGULARIZATION_LOSSES:在图形构造期间收集的正规化损失。\n",
148 | "\n",
149 | "这个知道就好了,要用的时候知道是怎么回事就行了。比如在 BN 层中就有这东西。"
150 | ]
151 | },
152 | {
153 | "cell_type": "code",
154 | "execution_count": null,
155 | "metadata": {},
156 | "outputs": [],
157 | "source": []
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": null,
162 | "metadata": {},
163 | "outputs": [],
164 | "source": []
165 | }
166 | ],
167 | "metadata": {
168 | "anaconda-cloud": {},
169 | "kernelspec": {
170 | "display_name": "Python 3",
171 | "language": "python",
172 | "name": "python3"
173 | },
174 | "language_info": {
175 | "codemirror_mode": {
176 | "name": "ipython",
177 | "version": 3
178 | },
179 | "file_extension": ".py",
180 | "mimetype": "text/x-python",
181 | "name": "python",
182 | "nbconvert_exporter": "python",
183 | "pygments_lexer": "ipython3",
184 | "version": "3.5.2"
185 | }
186 | },
187 | "nbformat": 4,
188 | "nbformat_minor": 1
189 | }
190 |
--------------------------------------------------------------------------------
/example-notebook/.ipynb_checkpoints/Tutorial_04_3 Convolutional network for MNIST(3)-checkpoint.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## CNN做MNIST分类\n",
8 | "\n",
9 | "使用 tf.layers 高级 API 构建 CNN "
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": 1,
15 | "metadata": {},
16 | "outputs": [
17 | {
18 | "name": "stderr",
19 | "output_type": "stream",
20 | "text": [
21 | "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
22 | " from ._conv import register_converters as _register_converters\n"
23 | ]
24 | }
25 | ],
26 | "source": [
27 | "import numpy as np\n",
28 | "import tensorflow as tf\n",
29 | "\n",
30 | "# 设置按需使用GPU\n",
31 | "config = tf.ConfigProto()\n",
32 | "config.gpu_options.allow_growth = True\n",
33 | "sess = tf.InteractiveSession(config=config)\n",
34 | "\n",
35 | "import time"
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {},
41 | "source": [
42 | "## 1.导入数据,用 tensorflow 导入"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": 2,
48 | "metadata": {},
49 | "outputs": [
50 | {
51 | "name": "stdout",
52 | "output_type": "stream",
53 | "text": [
54 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/base.py:198: retry (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
55 | "Instructions for updating:\n",
56 | "Use the retry module or similar alternatives.\n",
57 | "WARNING:tensorflow:From :3: read_data_sets (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
58 | "Instructions for updating:\n",
59 | "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
60 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:260: maybe_download (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
61 | "Instructions for updating:\n",
62 | "Please write your own downloading logic.\n",
63 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:262: extract_images (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
64 | "Instructions for updating:\n",
65 | "Please use tf.data to implement this functionality.\n",
66 | "Extracting MNIST_data/train-images-idx3-ubyte.gz\n",
67 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:267: extract_labels (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
68 | "Instructions for updating:\n",
69 | "Please use tf.data to implement this functionality.\n",
70 | "Extracting MNIST_data/train-labels-idx1-ubyte.gz\n",
71 | "Extracting MNIST_data/t10k-images-idx3-ubyte.gz\n",
72 | "Extracting MNIST_data/t10k-labels-idx1-ubyte.gz\n",
73 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:290: DataSet.__init__ (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
74 | "Instructions for updating:\n",
75 | "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
76 | "(10000,)\n",
77 | "(55000,)\n"
78 | ]
79 | }
80 | ],
81 | "source": [
82 | "# 用tensorflow 导入数据\n",
83 | "from tensorflow.examples.tutorials.mnist import input_data\n",
84 | "mnist = input_data.read_data_sets('MNIST_data', one_hot=False)\n",
85 | "# 看看咱们样本的数量\n",
86 | "print(mnist.test.labels.shape)\n",
87 | "print(mnist.train.labels.shape)"
88 | ]
89 | },
90 | {
91 | "cell_type": "markdown",
92 | "metadata": {},
93 | "source": [
94 | "## 2. 构建网络"
95 | ]
96 | },
97 | {
98 | "cell_type": "code",
99 | "execution_count": 3,
100 | "metadata": {},
101 | "outputs": [
102 | {
103 | "name": "stdout",
104 | "output_type": "stream",
105 | "text": [
106 | "Finished building network.\n"
107 | ]
108 | }
109 | ],
110 | "source": [
111 | "with tf.name_scope('inputs'):\n",
112 | " X_ = tf.placeholder(tf.float32, [None, 784])\n",
113 | " y_ = tf.placeholder(tf.int64, [None])\n",
114 | "\n",
115 | "# 把X转为卷积所需要的形式\n",
116 | "X = tf.reshape(X_, [-1, 28, 28, 1])\n",
117 | "h_conv1 = tf.layers.conv2d(X, filters=32, kernel_size=5, strides=1, padding='same', activation=tf.nn.relu, name='conv1')\n",
118 | "h_pool1 = tf.layers.max_pooling2d(h_conv1, pool_size=2, strides=2, padding='same', name='pool1')\n",
119 | "\n",
120 | "h_conv2 = tf.layers.conv2d(h_pool1, filters=64, kernel_size=5, strides=1, padding='same',activation=tf.nn.relu, name='conv2')\n",
121 | "h_pool2 = tf.layers.max_pooling2d(h_conv2, pool_size=2, strides=2, padding='same', name='pool2')\n",
122 | "\n",
123 | "# flatten\n",
124 | "h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])\n",
125 | "h_fc1 = tf.layers.dense(h_pool2_flat, 1024, name='fc1', activation=tf.nn.relu)\n",
126 | "\n",
127 | "# dropout: 输出的维度和h_fc1一样,只是随机部分值被值为零\n",
128 | "keep_prob = tf.placeholder(tf.float32)\n",
129 | "h_fc1_drop = tf.nn.dropout(h_fc1, 0.5) # 实际测试的时候这里不应该使用 0.5,这里为了方便演示都这样写而已\n",
130 | "h_fc2 = tf.layers.dense(h_fc1_drop, units=10, name='fc2')\n",
131 | "# y_conv = tf.nn.softmax(h_fc2)\n",
132 | "y_conv = h_fc2\n",
133 | "print('Finished building network.')"
134 | ]
135 | },
136 | {
137 | "cell_type": "code",
138 | "execution_count": 4,
139 | "metadata": {},
140 | "outputs": [
141 | {
142 | "name": "stdout",
143 | "output_type": "stream",
144 | "text": [
145 | "Tensor(\"conv1/Relu:0\", shape=(?, 28, 28, 32), dtype=float32)\n",
146 | "Tensor(\"pool1/MaxPool:0\", shape=(?, 14, 14, 32), dtype=float32)\n",
147 | "Tensor(\"conv2/Relu:0\", shape=(?, 14, 14, 64), dtype=float32)\n",
148 | "Tensor(\"pool2/MaxPool:0\", shape=(?, 7, 7, 64), dtype=float32)\n",
149 | "Tensor(\"Reshape_1:0\", shape=(?, 3136), dtype=float32)\n",
150 | "Tensor(\"fc1/Relu:0\", shape=(?, 1024), dtype=float32)\n",
151 | "Tensor(\"fc2/BiasAdd:0\", shape=(?, 10), dtype=float32)\n"
152 | ]
153 | }
154 | ],
155 | "source": [
156 | "print(h_conv1)\n",
157 | "print(h_pool1)\n",
158 | "print(h_conv2)\n",
159 | "print(h_pool2)\n",
160 | "\n",
161 | "print(h_pool2_flat)\n",
162 | "print(h_fc1)\n",
163 | "print(h_fc2)"
164 | ]
165 | },
166 | {
167 | "cell_type": "markdown",
168 | "metadata": {},
169 | "source": [
170 | "## 3.训练和评估"
171 | ]
172 | },
173 | {
174 | "cell_type": "markdown",
175 | "metadata": {},
176 | "source": [
177 | " 在测试的时候不使用 mini_batch, 那么测试的时候会占用较多的GPU(4497M),这在 notebook 交互式编程中是不推荐的。"
178 | ]
179 | },
180 | {
181 | "cell_type": "code",
182 | "execution_count": null,
183 | "metadata": {
184 | "scrolled": false
185 | },
186 | "outputs": [
187 | {
188 | "name": "stdout",
189 | "output_type": "stream",
190 | "text": [
191 | "step 0, training accuracy = 0.1100, pass 1.18s \n",
192 | "step 1000, training accuracy = 0.9800, pass 6.01s \n",
193 | "step 2000, training accuracy = 0.9800, pass 10.82s \n"
194 | ]
195 | }
196 | ],
197 | "source": [
198 | "# cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))\n",
199 | "cross_entropy = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(\n",
200 | " labels=tf.cast(y_, dtype=tf.int32), logits=y_conv))\n",
201 | "\n",
202 | "train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)\n",
203 | "\n",
204 | "correct_prediction = tf.equal(tf.argmax(y_conv,1), y_)\n",
205 | "accuracy = tf.reduce_mean(tf.cast(correct_prediction, \"float\"))\n",
206 | "sess.run(tf.global_variables_initializer())\n",
207 | "\n",
208 | "tic = time.time()\n",
209 | "for i in range(10000):\n",
210 | " batch = mnist.train.next_batch(100)\n",
211 | " if i%1000 == 0:\n",
212 | " train_accuracy = accuracy.eval(feed_dict={\n",
213 | " X_:batch[0], y_: batch[1], keep_prob: 1.0})\n",
214 | " print(\"step {}, training accuracy = {:.4f}, pass {:.2f}s \".format(i, train_accuracy, time.time() - tic))\n",
215 | " train_step.run(feed_dict={X_: batch[0], y_: batch[1]})\n",
216 | "\n",
217 | "print(\"test accuracy %g\"%accuracy.eval(feed_dict={\n",
218 | " X_: mnist.test.images, y_: mnist.test.labels}))"
219 | ]
220 | }
221 | ],
222 | "metadata": {
223 | "anaconda-cloud": {},
224 | "kernelspec": {
225 | "display_name": "Python 3",
226 | "language": "python",
227 | "name": "python3"
228 | },
229 | "language_info": {
230 | "codemirror_mode": {
231 | "name": "ipython",
232 | "version": 3
233 | },
234 | "file_extension": ".py",
235 | "mimetype": "text/x-python",
236 | "name": "python",
237 | "nbconvert_exporter": "python",
238 | "pygments_lexer": "ipython3",
239 | "version": "3.5.2"
240 | }
241 | },
242 | "nbformat": 4,
243 | "nbformat_minor": 1
244 | }
245 |
--------------------------------------------------------------------------------
/example-notebook/.ipynb_checkpoints/Tutorial_04_3 Convolutional network for MNIST(4)-BN-checkpoint.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## CNN做MNIST分类(四)\n",
8 | "\n",
9 | "使用 tf.layers 高级 API 构建 CNN,添加 BN 层。"
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": 1,
15 | "metadata": {},
16 | "outputs": [
17 | {
18 | "name": "stderr",
19 | "output_type": "stream",
20 | "text": [
21 | "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
22 | " from ._conv import register_converters as _register_converters\n"
23 | ]
24 | }
25 | ],
26 | "source": [
27 | "import numpy as np\n",
28 | "import tensorflow as tf\n",
29 | "\n",
30 | "# 设置按需使用GPU\n",
31 | "config = tf.ConfigProto()\n",
32 | "config.gpu_options.allow_growth = True\n",
33 | "sess = tf.InteractiveSession(config=config)\n",
34 | "\n",
35 | "import time"
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {},
41 | "source": [
42 | "## 1.导入数据,用 tensorflow 导入"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": 2,
48 | "metadata": {},
49 | "outputs": [
50 | {
51 | "name": "stdout",
52 | "output_type": "stream",
53 | "text": [
54 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/base.py:198: retry (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
55 | "Instructions for updating:\n",
56 | "Use the retry module or similar alternatives.\n",
57 | "WARNING:tensorflow:From :3: read_data_sets (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
58 | "Instructions for updating:\n",
59 | "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
60 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:260: maybe_download (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
61 | "Instructions for updating:\n",
62 | "Please write your own downloading logic.\n",
63 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/base.py:219: retry..wrap..wrapped_fn (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
64 | "Instructions for updating:\n",
65 | "Please use urllib or similar directly.\n",
66 | "Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes.\n",
67 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:262: extract_images (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
68 | "Instructions for updating:\n",
69 | "Please use tf.data to implement this functionality.\n",
70 | "Extracting MNIST_data/train-images-idx3-ubyte.gz\n",
71 | "Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes.\n",
72 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:267: extract_labels (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
73 | "Instructions for updating:\n",
74 | "Please use tf.data to implement this functionality.\n",
75 | "Extracting MNIST_data/train-labels-idx1-ubyte.gz\n",
76 | "Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes.\n",
77 | "Extracting MNIST_data/t10k-images-idx3-ubyte.gz\n",
78 | "Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes.\n",
79 | "Extracting MNIST_data/t10k-labels-idx1-ubyte.gz\n",
80 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:290: DataSet.__init__ (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
81 | "Instructions for updating:\n",
82 | "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
83 | "(10000,)\n",
84 | "(55000,)\n"
85 | ]
86 | }
87 | ],
88 | "source": [
89 | "# 用tensorflow 导入数据\n",
90 | "from tensorflow.examples.tutorials.mnist import input_data\n",
91 | "mnist = input_data.read_data_sets('MNIST_data', one_hot=False)\n",
92 | "# 看看咱们样本的数量\n",
93 | "print(mnist.test.labels.shape)\n",
94 | "print(mnist.train.labels.shape)"
95 | ]
96 | },
97 | {
98 | "cell_type": "markdown",
99 | "metadata": {},
100 | "source": [
101 | "## 2. 构建网络"
102 | ]
103 | },
104 | {
105 | "cell_type": "code",
106 | "execution_count": 3,
107 | "metadata": {},
108 | "outputs": [
109 | {
110 | "name": "stdout",
111 | "output_type": "stream",
112 | "text": [
113 | "Finished building network.\n"
114 | ]
115 | }
116 | ],
117 | "source": [
118 | "with tf.name_scope('inputs'):\n",
119 | " X_ = tf.placeholder(tf.float32, [None, 784])\n",
120 | " y_ = tf.placeholder(tf.int64, [None])\n",
121 | "\n",
122 | "# 把X转为卷积所需要的形式\n",
123 | "X = tf.reshape(X_, [-1, 28, 28, 1])\n",
124 | "h_conv1 = tf.layers.conv2d(X, filters=32, kernel_size=5, strides=1, padding='same', name='conv1')\n",
125 | "h_bn1 = tf.layers.batch_normalization(h_conv1, )\n",
126 | "h_pool1 = tf.layers.max_pooling2d(h_conv1, pool_size=2, strides=2, padding='same', name='pool1')\n",
127 | "\n",
128 | "h_conv2 = tf.layers.conv2d(h_pool1, filters=64, kernel_size=5, strides=1, padding='same',activation=tf.nn.relu, name='conv2')\n",
129 | "h_pool2 = tf.layers.max_pooling2d(h_conv2, pool_size=2, strides=2, padding='same', name='pool2')\n",
130 | "\n",
131 | "# flatten\n",
132 | "h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])\n",
133 | "h_fc1 = tf.layers.dense(h_pool2_flat, 1024, name='fc1', activation=tf.nn.relu)\n",
134 | "\n",
135 | "# dropout: 输出的维度和h_fc1一样,只是随机部分值被值为零\n",
136 | "keep_prob = tf.placeholder(tf.float32)\n",
137 | "h_fc1_drop = tf.nn.dropout(h_fc1, 0.5) # 实际测试的时候这里不应该使用 0.5,这里为了方便演示都这样写而已\n",
138 | "h_fc2 = tf.layers.dense(h_fc1_drop, units=10, name='fc2')\n",
139 | "# y_conv = tf.nn.softmax(h_fc2)\n",
140 | "y_conv = h_fc2\n",
141 | "print('Finished building network.')"
142 | ]
143 | },
144 | {
145 | "cell_type": "code",
146 | "execution_count": 4,
147 | "metadata": {},
148 | "outputs": [
149 | {
150 | "name": "stdout",
151 | "output_type": "stream",
152 | "text": [
153 | "Tensor(\"conv1/Relu:0\", shape=(?, 28, 28, 32), dtype=float32)\n",
154 | "Tensor(\"pool1/MaxPool:0\", shape=(?, 14, 14, 32), dtype=float32)\n",
155 | "Tensor(\"conv2/Relu:0\", shape=(?, 14, 14, 64), dtype=float32)\n",
156 | "Tensor(\"pool2/MaxPool:0\", shape=(?, 7, 7, 64), dtype=float32)\n",
157 | "Tensor(\"Reshape_1:0\", shape=(?, 3136), dtype=float32)\n",
158 | "Tensor(\"fc1/Relu:0\", shape=(?, 1024), dtype=float32)\n",
159 | "Tensor(\"fc2/BiasAdd:0\", shape=(?, 10), dtype=float32)\n"
160 | ]
161 | }
162 | ],
163 | "source": [
164 | "print(h_conv1)\n",
165 | "print(h_pool1)\n",
166 | "print(h_conv2)\n",
167 | "print(h_pool2)\n",
168 | "\n",
169 | "print(h_pool2_flat)\n",
170 | "print(h_fc1)\n",
171 | "print(h_fc2)"
172 | ]
173 | },
174 | {
175 | "cell_type": "markdown",
176 | "metadata": {},
177 | "source": [
178 | "## 3.训练和评估"
179 | ]
180 | },
181 | {
182 | "cell_type": "markdown",
183 | "metadata": {},
184 | "source": [
185 | " 在测试的时候不使用 mini_batch, 那么测试的时候会占用较多的GPU(4497M),这在 notebook 交互式编程中是不推荐的。"
186 | ]
187 | },
188 | {
189 | "cell_type": "code",
190 | "execution_count": 5,
191 | "metadata": {
192 | "scrolled": false
193 | },
194 | "outputs": [
195 | {
196 | "name": "stdout",
197 | "output_type": "stream",
198 | "text": [
199 | "step 0, training accuracy = 0.1100, pass 1.18s \n",
200 | "step 1000, training accuracy = 0.9800, pass 6.01s \n",
201 | "step 2000, training accuracy = 0.9800, pass 10.82s \n",
202 | "step 3000, training accuracy = 0.9700, pass 15.65s \n",
203 | "step 4000, training accuracy = 1.0000, pass 20.40s \n",
204 | "step 5000, training accuracy = 0.9800, pass 25.26s \n",
205 | "step 6000, training accuracy = 1.0000, pass 30.00s \n",
206 | "step 7000, training accuracy = 0.9900, pass 34.84s \n",
207 | "step 8000, training accuracy = 1.0000, pass 39.66s \n",
208 | "step 9000, training accuracy = 1.0000, pass 44.55s \n",
209 | "test accuracy 0.9924\n"
210 | ]
211 | }
212 | ],
213 | "source": [
214 | "# cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))\n",
215 | "cross_entropy = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(\n",
216 | " labels=tf.cast(y_, dtype=tf.int32), logits=y_conv))\n",
217 | "\n",
218 | "train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)\n",
219 | "\n",
220 | "correct_prediction = tf.equal(tf.argmax(y_conv,1), y_)\n",
221 | "accuracy = tf.reduce_mean(tf.cast(correct_prediction, \"float\"))\n",
222 | "sess.run(tf.global_variables_initializer())\n",
223 | "\n",
224 | "tic = time.time()\n",
225 | "for i in range(10000):\n",
226 | " batch = mnist.train.next_batch(100)\n",
227 | " if i%1000 == 0:\n",
228 | " train_accuracy = accuracy.eval(feed_dict={\n",
229 | " X_:batch[0], y_: batch[1], keep_prob: 1.0})\n",
230 | " print(\"step {}, training accuracy = {:.4f}, pass {:.2f}s \".format(i, train_accuracy, time.time() - tic))\n",
231 | " train_step.run(feed_dict={X_: batch[0], y_: batch[1]})\n",
232 | "\n",
233 | "print(\"test accuracy %g\"%accuracy.eval(feed_dict={\n",
234 | " X_: mnist.test.images, y_: mnist.test.labels}))"
235 | ]
236 | }
237 | ],
238 | "metadata": {
239 | "anaconda-cloud": {},
240 | "kernelspec": {
241 | "display_name": "Python 3",
242 | "language": "python",
243 | "name": "python3"
244 | },
245 | "language_info": {
246 | "codemirror_mode": {
247 | "name": "ipython",
248 | "version": 3
249 | },
250 | "file_extension": ".py",
251 | "mimetype": "text/x-python",
252 | "name": "python",
253 | "nbconvert_exporter": "python",
254 | "pygments_lexer": "ipython3",
255 | "version": "3.5.2"
256 | }
257 | },
258 | "nbformat": 4,
259 | "nbformat_minor": 1
260 | }
261 |
--------------------------------------------------------------------------------
/example-notebook/.ipynb_checkpoints/Tutorial_07 How to save the model-checkpoint.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## 如何使用 tf.train.Saver() 来保存模型\n",
8 | "之前一直出错,主要是因为坑爹的编码问题。所以要注意文件的路径绝对不不要出现什么中文呀。"
9 | ]
10 | },
11 | {
12 | "cell_type": "code",
13 | "execution_count": 1,
14 | "metadata": {},
15 | "outputs": [
16 | {
17 | "name": "stderr",
18 | "output_type": "stream",
19 | "text": [
20 | "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
21 | " from ._conv import register_converters as _register_converters\n"
22 | ]
23 | },
24 | {
25 | "name": "stdout",
26 | "output_type": "stream",
27 | "text": [
28 | "Model saved in file: ../ckpt/test-model.ckpt-1\n"
29 | ]
30 | }
31 | ],
32 | "source": [
33 | "import tensorflow as tf\n",
34 | "config = tf.ConfigProto()\n",
35 | "config.gpu_options.allow_growth = True\n",
36 | "sess = tf.Session(config=config)\n",
37 | "\n",
38 | "# Create some variables.\n",
39 | "v1 = tf.Variable([1.0, 2.3], name=\"v1\")\n",
40 | "v2 = tf.Variable(55.5, name=\"v2\")\n",
41 | "\n",
42 | "# Add an op to initialize the variables.\n",
43 | "init_op = tf.global_variables_initializer()\n",
44 | "\n",
45 | "# Add ops to save and restore all the variables.\n",
46 | "saver = tf.train.Saver()\n",
47 | "\n",
48 | "ckpt_path = '../ckpt/test-model.ckpt'\n",
49 | "# Later, launch the model, initialize the variables, do some work, save the\n",
50 | "# variables to disk.\n",
51 | "sess.run(init_op)\n",
52 | "save_path = saver.save(sess, ckpt_path, global_step=1)\n",
53 | "print(\"Model saved in file: %s\" % save_path)"
54 | ]
55 | },
56 | {
57 | "cell_type": "markdown",
58 | "metadata": {},
59 | "source": [
60 | "注意,在上面保存完了模型之后。**Restart kernel** 之后才能使用下面的模型导入。否则会因为两次命名 \"v1\" 而导致名字错误。"
61 | ]
62 | },
63 | {
64 | "cell_type": "code",
65 | "execution_count": 1,
66 | "metadata": {},
67 | "outputs": [
68 | {
69 | "name": "stderr",
70 | "output_type": "stream",
71 | "text": [
72 | "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
73 | " from ._conv import register_converters as _register_converters\n"
74 | ]
75 | },
76 | {
77 | "name": "stdout",
78 | "output_type": "stream",
79 | "text": [
80 | "INFO:tensorflow:Restoring parameters from ../ckpt/test-model.ckpt-1\n",
81 | "Model restored.\n",
82 | "[1. 2.3]\n",
83 | "55.5\n"
84 | ]
85 | }
86 | ],
87 | "source": [
88 | "import tensorflow as tf\n",
89 | "config = tf.ConfigProto()\n",
90 | "config.gpu_options.allow_growth = True\n",
91 | "sess = tf.Session(config=config)\n",
92 | "\n",
93 | "# Create some variables.\n",
94 | "v1 = tf.Variable([11.0, 16.3], name=\"v1\")\n",
95 | "v2 = tf.Variable(33.5, name=\"v2\")\n",
96 | "\n",
97 | "# Add ops to save and restore all the variables.\n",
98 | "saver = tf.train.Saver()\n",
99 | "\n",
100 | "# Later, launch the model, use the saver to restore variables from disk, and\n",
101 | "# do some work with the model.\n",
102 | "# Restore variables from disk.\n",
103 | "ckpt_path = '../ckpt/test-model.ckpt'\n",
104 | "saver.restore(sess, ckpt_path + '-'+ str(1))\n",
105 | "print(\"Model restored.\")\n",
106 | "\n",
107 | "print(sess.run(v1))\n",
108 | "print(sess.run(v2))"
109 | ]
110 | },
111 | {
112 | "cell_type": "markdown",
113 | "metadata": {},
114 | "source": [
115 | "导入模型之前,必须重新再定义一遍变量。\n",
116 | "\n",
117 | "但是并不需要全部变量都重新进行定义,只定义我们需要的变量就行了。\n",
118 | "\n",
119 | "也就是说,**你所定义的变量一定要在 checkpoint 中存在;但不是所有在checkpoint中的变量,你都要重新定义。**"
120 | ]
121 | },
122 | {
123 | "cell_type": "code",
124 | "execution_count": 1,
125 | "metadata": {},
126 | "outputs": [
127 | {
128 | "name": "stderr",
129 | "output_type": "stream",
130 | "text": [
131 | "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
132 | " from ._conv import register_converters as _register_converters\n"
133 | ]
134 | },
135 | {
136 | "name": "stdout",
137 | "output_type": "stream",
138 | "text": [
139 | "INFO:tensorflow:Restoring parameters from ../ckpt/test-model.ckpt-1\n",
140 | "Model restored.\n",
141 | "[1. 2.3]\n"
142 | ]
143 | }
144 | ],
145 | "source": [
146 | "import tensorflow as tf\n",
147 | "config = tf.ConfigProto()\n",
148 | "config.gpu_options.allow_growth = True\n",
149 | "sess = tf.Session(config=config)\n",
150 | "\n",
151 | "# Create some variables.\n",
152 | "v1 = tf.Variable([11.0, 16.3], name=\"v1\")\n",
153 | "\n",
154 | "# Add ops to save and restore all the variables.\n",
155 | "saver = tf.train.Saver()\n",
156 | "\n",
157 | "# Later, launch the model, use the saver to restore variables from disk, and\n",
158 | "# do some work with the model.\n",
159 | "# Restore variables from disk.\n",
160 | "ckpt_path = '../ckpt/test-model.ckpt'\n",
161 | "saver.restore(sess, ckpt_path + '-'+ str(1))\n",
162 | "print(\"Model restored.\")\n",
163 | "\n",
164 | "print(sess.run(v1))"
165 | ]
166 | },
167 | {
168 | "cell_type": "markdown",
169 | "metadata": {},
170 | "source": [
171 | "## 关于模型保存的一点心得\n",
172 | "\n",
173 | "```\n",
174 | "saver = tf.train.Saver(max_to_keep=3)\n",
175 | "```\n",
176 | "在定义 saver 的时候一般会定义最多保存模型的数量,一般来说,我都不会保存太多模型,模型多了浪费空间,很多时候其实保存最好的模型就够了。方法就是每次迭代到一定步数就在验证集上计算一次 accuracy 或者 f1 值,如果本次结果比上次好才保存新的模型,否则没必要保存。\n",
177 | "\n",
178 | "如果你想用不同 epoch 保存下来的模型进行融合的话,3到5 个模型已经足够了,假设这各融合的模型成为 M,而最好的一个单模型称为 m_best, 这样融合的话对于M 确实可以比 m_best 更好。但是如果拿这个模型和其他结构的模型再做融合的话,M 的效果并没有 m_best 好,因为M 相当于做了平均操作,减少了该模型的“特性”。"
179 | ]
180 | }
181 | ],
182 | "metadata": {
183 | "anaconda-cloud": {},
184 | "kernelspec": {
185 | "display_name": "Python 3",
186 | "language": "python",
187 | "name": "python3"
188 | },
189 | "language_info": {
190 | "codemirror_mode": {
191 | "name": "ipython",
192 | "version": 3
193 | },
194 | "file_extension": ".py",
195 | "mimetype": "text/x-python",
196 | "name": "python",
197 | "nbconvert_exporter": "python",
198 | "pygments_lexer": "ipython3",
199 | "version": "3.5.2"
200 | }
201 | },
202 | "nbformat": 4,
203 | "nbformat_minor": 1
204 | }
205 |
--------------------------------------------------------------------------------
/example-notebook/.ipynb_checkpoints/Tutorial_08 [transfer learning] Add new variables to graph and save the new model-checkpoint.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## 【迁移学习】往一个已经保存好的 模型添加新的变量\n",
8 | "在迁移学习中,通常我们已经训练好一个模型,现在需要修改模型的部分结构,用于我们的新任务。\n",
9 | "\n",
10 | "比如:\n",
11 | "\n",
12 | "在一个图片分类任务中,我们使用别人训练好的网络来提取特征,但是我们的分类数目和原模型不同,这样我们只能取到 fc 层,后面的分类层需要重新写。这样我们就需要添加新的变量。那么这些新加入的变量必须得初始化才能使用。可是我们又不能使用 'tf.global_variables_initializer()' 来初始化,否则原本训练好的模型就没用了。\n",
13 | "\n",
14 | "关于怎么样单独初始化新增的变量,可以参考下面两个链接:\n",
15 | "- [1]https://stackoverflow.com/questions/35164529/in-tensorflow-is-there-any-way-to-just-initialize-uninitialised-variables\n",
16 | "- [2]https://stackoverflow.com/questions/35013080/tensorflow-how-to-get-all-variables-from-rnn-cell-basiclstm-rnn-cell-multirnn\n",
17 | "\n",
18 | "简单的例子可以直接看下面我的实现方式。"
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "### 初始模型定义与保存\n",
26 | "首先定义一个模型,里边有 v1, v2 两个变量,我们把这个模型保存起来。"
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": 1,
32 | "metadata": {},
33 | "outputs": [
34 | {
35 | "name": "stderr",
36 | "output_type": "stream",
37 | "text": [
38 | "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
39 | " from ._conv import register_converters as _register_converters\n"
40 | ]
41 | },
42 | {
43 | "name": "stdout",
44 | "output_type": "stream",
45 | "text": [
46 | "Model saved in file: ../ckpt/test-model.ckpt-1\n"
47 | ]
48 | }
49 | ],
50 | "source": [
51 | "import tensorflow as tf\n",
52 | "config = tf.ConfigProto()\n",
53 | "config.gpu_options.allow_growth = True\n",
54 | "sess = tf.Session(config=config)\n",
55 | "\n",
56 | "# Create some variables.\n",
57 | "v1 = tf.Variable([1.0, 2.3], name=\"v1\")\n",
58 | "v2 = tf.Variable(55.5, name=\"v2\")\n",
59 | "\n",
60 | "\n",
61 | "init_op = tf.global_variables_initializer()\n",
62 | "saver = tf.train.Saver()\n",
63 | "ckpt_path = '../ckpt/test-model.ckpt'\n",
64 | "sess.run(init_op)\n",
65 | "save_path = saver.save(sess, ckpt_path, global_step=1)\n",
66 | "print(\"Model saved in file: %s\" % save_path)"
67 | ]
68 | },
69 | {
70 | "cell_type": "markdown",
71 | "metadata": {},
72 | "source": [
73 | "**restart(重启kernel然后执行下面cell的代码)**\n",
74 | "### 导入已经保存好的模型,并添加新的变量\n",
75 | "现在把之前保存好的模型,我只需要其中的 v1 变量。同时我还要添加新的变量 v3。"
76 | ]
77 | },
78 | {
79 | "cell_type": "code",
80 | "execution_count": 1,
81 | "metadata": {
82 | "scrolled": false
83 | },
84 | "outputs": [
85 | {
86 | "name": "stderr",
87 | "output_type": "stream",
88 | "text": [
89 | "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
90 | " from ._conv import register_converters as _register_converters\n"
91 | ]
92 | },
93 | {
94 | "name": "stdout",
95 | "output_type": "stream",
96 | "text": [
97 | "INFO:tensorflow:Restoring parameters from ../ckpt/test-model.ckpt-1\n",
98 | "[1. 2.3]\n",
99 | "[1. 2.3]\n",
100 | "666\n"
101 | ]
102 | },
103 | {
104 | "data": {
105 | "text/plain": [
106 | "'../ckpt/test-model.ckpt-2'"
107 | ]
108 | },
109 | "execution_count": 1,
110 | "metadata": {},
111 | "output_type": "execute_result"
112 | }
113 | ],
114 | "source": [
115 | "import tensorflow as tf\n",
116 | "config = tf.ConfigProto()\n",
117 | "config.gpu_options.allow_growth = True\n",
118 | "sess = tf.Session(config=config)\n",
119 | "\n",
120 | "# Create some variables.\n",
121 | "v1 = tf.Variable([11.0, 16.3], name=\"v1\")\n",
122 | "\n",
123 | "# ** 导入训练好的模型\n",
124 | "saver = tf.train.Saver()\n",
125 | "ckpt_path = '../ckpt/test-model.ckpt'\n",
126 | "saver.restore(sess, ckpt_path + '-'+ str(1))\n",
127 | "print(sess.run(v1))\n",
128 | "\n",
129 | "# ** 定义新的变量并单独初始化新定义的变量\n",
130 | "v3 = tf.Variable(666, name='v3', dtype=tf.int32)\n",
131 | "init_new = tf.variables_initializer([v3])\n",
132 | "sess.run(init_new)\n",
133 | "# 。。。这里就可以进行 fine-tune 了\n",
134 | "print(sess.run(v1))\n",
135 | "print(sess.run(v3))\n",
136 | "\n",
137 | "# ** 保存新的模型。 \n",
138 | "# 注意!注意!注意! 一定一定一定要重新定义 saver, 这样才能把 v3 添加到 checkpoint 中\n",
139 | "saver = tf.train.Saver()\n",
140 | "saver.save(sess, ckpt_path, global_step=2)"
141 | ]
142 | },
143 | {
144 | "cell_type": "markdown",
145 | "metadata": {},
146 | "source": [
147 | "**restart(重启kernel然后执行下面cell的代码)**\n",
148 | "### 这样就完成了 fine-tune, 得到了新的模型"
149 | ]
150 | },
151 | {
152 | "cell_type": "code",
153 | "execution_count": 1,
154 | "metadata": {
155 | "scrolled": false
156 | },
157 | "outputs": [
158 | {
159 | "name": "stderr",
160 | "output_type": "stream",
161 | "text": [
162 | "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
163 | " from ._conv import register_converters as _register_converters\n"
164 | ]
165 | },
166 | {
167 | "name": "stdout",
168 | "output_type": "stream",
169 | "text": [
170 | "INFO:tensorflow:Restoring parameters from ../ckpt/test-model.ckpt-2\n",
171 | "Model restored.\n",
172 | "[1. 2.3]\n",
173 | "666\n"
174 | ]
175 | }
176 | ],
177 | "source": [
178 | "import tensorflow as tf\n",
179 | "config = tf.ConfigProto()\n",
180 | "config.gpu_options.allow_growth = True\n",
181 | "sess = tf.Session(config=config)\n",
182 | "\n",
183 | "# Create some variables.\n",
184 | "v1 = tf.Variable([11.0, 16.3], name=\"v1\")\n",
185 | "v3 = tf.Variable(666, name='v3', dtype=tf.int32)\n",
186 | "# Add ops to save and restore all the variables.\n",
187 | "saver = tf.train.Saver()\n",
188 | "\n",
189 | "# Later, launch the model, use the saver to restore variables from disk, and\n",
190 | "# do some work with the model.\n",
191 | "# Restore variables from disk.\n",
192 | "ckpt_path = '../ckpt/test-model.ckpt'\n",
193 | "saver.restore(sess, ckpt_path + '-'+ str(2))\n",
194 | "print(\"Model restored.\")\n",
195 | "\n",
196 | "print(sess.run(v1))\n",
197 | "print(sess.run(v3))"
198 | ]
199 | },
200 | {
201 | "cell_type": "code",
202 | "execution_count": null,
203 | "metadata": {
204 | "collapsed": true
205 | },
206 | "outputs": [],
207 | "source": []
208 | }
209 | ],
210 | "metadata": {
211 | "anaconda-cloud": {},
212 | "kernelspec": {
213 | "display_name": "Python 3",
214 | "language": "python",
215 | "name": "python3"
216 | },
217 | "language_info": {
218 | "codemirror_mode": {
219 | "name": "ipython",
220 | "version": 3
221 | },
222 | "file_extension": ".py",
223 | "mimetype": "text/x-python",
224 | "name": "python",
225 | "nbconvert_exporter": "python",
226 | "pygments_lexer": "ipython3",
227 | "version": "3.5.2"
228 | }
229 | },
230 | "nbformat": 4,
231 | "nbformat_minor": 1
232 | }
233 |
--------------------------------------------------------------------------------
/example-notebook/.ipynb_checkpoints/Untitled-checkpoint.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "import warnings\n",
10 | "warnings.filterwarnings('ignore') # 不打印 warning \n",
11 | "\n",
12 | "import tensorflow as tf\n",
13 | "\n",
14 | "# 设置GPU按需增长\n",
15 | "config = tf.ConfigProto()\n",
16 | "config.gpu_options.allow_growth = True\n",
17 | "sess = tf.Session(config=config)\n",
18 | "\n",
19 | "import numpy as np"
20 | ]
21 | },
22 | {
23 | "cell_type": "code",
24 | "execution_count": 4,
25 | "metadata": {},
26 | "outputs": [
27 | {
28 | "name": "stdout",
29 | "output_type": "stream",
30 | "text": [
31 | "Tensor(\"inputs_2:0\", shape=(?, 256, 256, 3), dtype=float32)\n",
32 | "conv1 Tensor(\"conv1/Relu:0\", shape=(?, 62, 62, 96), dtype=float32)\n",
33 | "pool1 Tensor(\"pool1/MaxPool:0\", shape=(?, 30, 30, 96), dtype=float32)\n",
34 | "conv2 \n",
35 | "pool2 Tensor(\"pool2/MaxPool:0\", shape=(?, 14, 14, 256), dtype=float32)\n",
36 | "conv3 Tensor(\"conv3/Relu:0\", shape=(?, 14, 14, 384), dtype=float32)\n",
37 | "conv4 Tensor(\"conv4/Relu:0\", shape=(?, 14, 14, 384), dtype=float32)\n",
38 | "conv5 Tensor(\"conv5/Relu:0\", shape=(?, 14, 14, 256), dtype=float32)\n",
39 | "pool5 Tensor(\"pool5/MaxPool:0\", shape=(?, 6, 6, 256), dtype=float32)\n"
40 | ]
41 | }
42 | ],
43 | "source": [
44 | "def conv2d(scope, x, filter_shape, strides_x, strides_y, padding, std=0.01, biases=0.1):\n",
45 | " \"\"\" 高斯初始化: std=0.01, biases=0.1\n",
46 | " Args:\n",
47 | " scope: scope name of this layer.\n",
48 | " x: 4-D inputs. [batch_size, in_height, in_width, in_channels]\n",
49 | " filter_shape: A list of ints.[filter_height, filter_width, in_channels, out_channels]\n",
50 | " strides: A list of ints. 1-D tensor of length 4. The stride of the sliding window for each dimension of input.\n",
51 | " padding: A string from: \"SAME\", \"VALID\". The type of padding algorithm to use.\n",
52 | " Returns:\n",
53 | " h_conv: A 4-D tensor. [batch_size, out_height, out_width, out_channels].\n",
54 | " if padding is 'SAME', then out_height==in_height.\n",
55 | " else, out_height = in_height - filter_height + 1.\n",
56 | " the same for out_width.\n",
57 | " \"\"\"\n",
58 | " assert padding in ['SAME', 'VALID']\n",
59 | " strides = [1, strides_x, strides_y, 1]\n",
60 | " with tf.variable_scope(scope):\n",
61 | " W_conv = tf.Variable(tf.truncated_normal(filter_shape, dtype=tf.float32, stddev=std), name='weights')\n",
62 | " b_conv = tf.Variable(tf.constant(biases, shape=[filter_shape[-1]], dtype=tf.float32), name='biases')\n",
63 | " h_conv = tf.nn.conv2d(x, W_conv, strides=strides, padding=padding)\n",
64 | " h_conv_relu = tf.nn.relu(h_conv + b_conv)\n",
65 | " return h_conv_relu\n",
66 | "\n",
67 | "def max_pooling(scope, x, k_height, k_width, strides_x, strides_y, padding='SAME'):\n",
68 | " \"\"\"max pooling layer.\"\"\"\n",
69 | " with tf.variable_scope(scope):\n",
70 | " ksize = [1, k_height, k_width, 1]\n",
71 | " strides = [1, strides_x, strides_y, 1]\n",
72 | " h_pool = tf.nn.max_pool(x, ksize, strides, padding)\n",
73 | " return h_pool\n",
74 | "\n",
75 | "\n",
76 | "\n",
77 | "inputs = tf.placeholder(dtype=tf.float32, shape=[None, 256, 256, 3], name='inputs')\n",
78 | "print(inputs)\n",
79 | "\n",
80 | "# 1st Layer: Conv (w ReLu) -> Lrn -> Pool\n",
81 | "conv1 = conv2d('conv1', inputs, [11, 11, 3, 96], 4, 4, 'VALID', biases=0.0)\n",
82 | "pool1 = max_pooling('pool1', conv1, 3, 3, 2, 2, 'VALID')\n",
83 | "print('conv1', conv1)\n",
84 | "print('pool1', pool1)\n",
85 | "\n",
86 | "# 2nd Layer: Conv (w ReLu) -> Lrn -> Pool with 2 groups\n",
87 | "conv2 = conv2d('conv2', pool1, [5, 5, 96, 256], 1, 1, 'SAME')\n",
88 | "pool2 = max_pooling('pool2', conv2, 3, 3, 2, 2, 'VALID')\n",
89 | "print('conv2', conv2d)\n",
90 | "print('pool2', pool2)\n",
91 | "\n",
92 | "# 3rd Layer: Conv (w ReLu)\n",
93 | "conv3 = conv2d('conv3', pool2, [3, 3, 256, 384], 1, 1, 'SAME')\n",
94 | "print('conv3', conv3)\n",
95 | "\n",
96 | "# 4th Layer: Conv (w ReLu)\n",
97 | "conv4 = conv2d('conv4', conv3, [3, 3, 384, 384], 1, 1, 'SAME')\n",
98 | "print('conv4', conv4)\n",
99 | "\n",
100 | "# 5th Layer: Conv (w ReLu) -> Pool splitted into two groups\n",
101 | "conv5 = conv2d('conv5', conv4, [3, 3, 384, 256], 1, 1, 'SAME')\n",
102 | "pool5 = max_pooling('pool5', conv5, 3, 3, 2, 2, 'VALID')\n",
103 | "print('conv5', conv5)\n",
104 | "print('pool5', pool5)\n",
105 | "\n",
106 | "\n",
107 | "# # 6th Layer: Flatten -> FC (w ReLu) -> Dropout\n",
108 | "# flattened = tf.reshape(pool5, [-1, 6 * 6 * 256])\n",
109 | "# fc6 = fc('fc6', flattened, 6 * 6 * 256, 4096, std=0.005, biases=0.1, use_relu=True)\n",
110 | "# dropout6 = dropout(fc6, keep_prob)\n",
111 | "\n",
112 | "# # 7th Layer: FC (w ReLu) -> Dropout\n",
113 | "# fc7 = fc('fc7', dropout6, 4096, 4096, std=0.005, biases=0.1, use_relu=True)\n",
114 | "# dropout7 = dropout(fc7, keep_prob)\n",
115 | "\n",
116 | "# # 8th Layer: FC and return unscaled activations\n",
117 | "# fc8 = fc('fc8', dropout7, 4096, n_class, std=0.01, biases=0.0, use_relu=False)"
118 | ]
119 | },
120 | {
121 | "cell_type": "code",
122 | "execution_count": null,
123 | "metadata": {},
124 | "outputs": [],
125 | "source": []
126 | }
127 | ],
128 | "metadata": {
129 | "kernelspec": {
130 | "display_name": "Python 3",
131 | "language": "python",
132 | "name": "python3"
133 | },
134 | "language_info": {
135 | "codemirror_mode": {
136 | "name": "ipython",
137 | "version": 3
138 | },
139 | "file_extension": ".py",
140 | "mimetype": "text/x-python",
141 | "name": "python",
142 | "nbconvert_exporter": "python",
143 | "pygments_lexer": "ipython3",
144 | "version": "3.5.2"
145 | }
146 | },
147 | "nbformat": 4,
148 | "nbformat_minor": 2
149 | }
150 |
--------------------------------------------------------------------------------
/example-notebook/MNIST_data/t10k-images-idx3-ubyte.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yongyehuang/Tensorflow-Tutorial/88b5cdbdf402a8ae7f65a540e5f81f3da8f45e7d/example-notebook/MNIST_data/t10k-images-idx3-ubyte.gz
--------------------------------------------------------------------------------
/example-notebook/MNIST_data/t10k-labels-idx1-ubyte.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yongyehuang/Tensorflow-Tutorial/88b5cdbdf402a8ae7f65a540e5f81f3da8f45e7d/example-notebook/MNIST_data/t10k-labels-idx1-ubyte.gz
--------------------------------------------------------------------------------
/example-notebook/MNIST_data/train-images-idx3-ubyte.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yongyehuang/Tensorflow-Tutorial/88b5cdbdf402a8ae7f65a540e5f81f3da8f45e7d/example-notebook/MNIST_data/train-images-idx3-ubyte.gz
--------------------------------------------------------------------------------
/example-notebook/MNIST_data/train-labels-idx1-ubyte.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yongyehuang/Tensorflow-Tutorial/88b5cdbdf402a8ae7f65a540e5f81f3da8f45e7d/example-notebook/MNIST_data/train-labels-idx1-ubyte.gz
--------------------------------------------------------------------------------
/example-notebook/Tutorial_02 A simple feedforward network for MNIST.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# 两层FC层做分类:MNIST\n",
8 | "\n",
9 | "在本教程中,我们来实现一个非常简单的两层全连接层来完成MNIST数据的分类问题。\n",
10 | "\n",
11 | "输入[-1,28*28], FC1 有 1024 个neurons, FC2 有 10 个neurons。这么简单的一个全连接网络,结果测试准确率达到了 0.98。还是非常棒的!!!"
12 | ]
13 | },
14 | {
15 | "cell_type": "code",
16 | "execution_count": 1,
17 | "metadata": {},
18 | "outputs": [],
19 | "source": [
20 | "from __future__ import print_function\n",
21 | "from __future__ import division\n",
22 | "from __future__ import absolute_import\n",
23 | "\n",
24 | "import warnings\n",
25 | "warnings.filterwarnings('ignore') # 不打印 warning \n",
26 | "\n",
27 | "import numpy as np\n",
28 | "import tensorflow as tf\n",
29 | "\n",
30 | "# 设置按需使用GPU\n",
31 | "config = tf.ConfigProto()\n",
32 | "config.gpu_options.allow_growth = True\n",
33 | "sess = tf.Session(config=config)"
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "### 1.导入数据\n",
41 | "下面导入数据这部分的警告可以不用管先,TensorFlow 非常恶心的地方就是不停地改 API,改到发麻。"
42 | ]
43 | },
44 | {
45 | "cell_type": "code",
46 | "execution_count": 2,
47 | "metadata": {},
48 | "outputs": [
49 | {
50 | "name": "stdout",
51 | "output_type": "stream",
52 | "text": [
53 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/base.py:198: retry (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
54 | "Instructions for updating:\n",
55 | "Use the retry module or similar alternatives.\n",
56 | "WARNING:tensorflow:From :3: read_data_sets (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
57 | "Instructions for updating:\n",
58 | "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
59 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:260: maybe_download (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
60 | "Instructions for updating:\n",
61 | "Please write your own downloading logic.\n",
62 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:262: extract_images (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
63 | "Instructions for updating:\n",
64 | "Please use tf.data to implement this functionality.\n",
65 | "Extracting ../data/MNIST_data/train-images-idx3-ubyte.gz\n",
66 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:267: extract_labels (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
67 | "Instructions for updating:\n",
68 | "Please use tf.data to implement this functionality.\n",
69 | "Extracting ../data/MNIST_data/train-labels-idx1-ubyte.gz\n",
70 | "Extracting ../data/MNIST_data/t10k-images-idx3-ubyte.gz\n",
71 | "Extracting ../data/MNIST_data/t10k-labels-idx1-ubyte.gz\n",
72 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:290: DataSet.__init__ (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
73 | "Instructions for updating:\n",
74 | "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n"
75 | ]
76 | }
77 | ],
78 | "source": [
79 | "# 用tensorflow 导入数据\n",
80 | "from tensorflow.examples.tutorials.mnist import input_data\n",
81 | "mnist = input_data.read_data_sets('../data/MNIST_data', one_hot=False, source_url='http://yann.lecun.com/exdb/mnist/')"
82 | ]
83 | },
84 | {
85 | "cell_type": "code",
86 | "execution_count": 3,
87 | "metadata": {},
88 | "outputs": [
89 | {
90 | "name": "stdout",
91 | "output_type": "stream",
92 | "text": [
93 | "training data shape (55000, 784)\n",
94 | "training label shape (55000,)\n"
95 | ]
96 | }
97 | ],
98 | "source": [
99 | "print('training data shape ', mnist.train.images.shape)\n",
100 | "print('training label shape ', mnist.train.labels.shape)"
101 | ]
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "metadata": {},
106 | "source": [
107 | "### 2. 构建网络"
108 | ]
109 | },
110 | {
111 | "cell_type": "code",
112 | "execution_count": 4,
113 | "metadata": {},
114 | "outputs": [
115 | {
116 | "name": "stdout",
117 | "output_type": "stream",
118 | "text": [
119 | "Tensor(\"add_1:0\", shape=(?, 10), dtype=float32)\n"
120 | ]
121 | }
122 | ],
123 | "source": [
124 | "# 权值初始化\n",
125 | "def weight_variable(shape):\n",
126 | " # 用正态分布来初始化权值\n",
127 | " initial = tf.truncated_normal(shape, stddev=0.1)\n",
128 | " return tf.Variable(initial)\n",
129 | "\n",
130 | "def bias_variable(shape):\n",
131 | " # 本例中用relu激活函数,所以用一个很小的正偏置较好\n",
132 | " initial = tf.constant(0.1, shape=shape)\n",
133 | " return tf.Variable(initial)\n",
134 | "\n",
135 | "\n",
136 | "# input_layer\n",
137 | "X_input = tf.placeholder(tf.float32, [None, 784])\n",
138 | "y_input = tf.placeholder(tf.int64, [None]) # 不使用 one-hot \n",
139 | "\n",
140 | "# FC1\n",
141 | "W_fc1 = weight_variable([784, 1024])\n",
142 | "b_fc1 = bias_variable([1024])\n",
143 | "h_fc1 = tf.nn.relu(tf.matmul(X_input, W_fc1) + b_fc1)\n",
144 | "\n",
145 | "# FC2\n",
146 | "W_fc2 = weight_variable([1024, 10])\n",
147 | "b_fc2 = bias_variable([10])\n",
148 | "# y_pre = tf.nn.softmax(tf.matmul(h_fc1, W_fc2) + b_fc2)\n",
149 | "logits = tf.matmul(h_fc1, W_fc2) + b_fc2\n",
150 | "\n",
151 | "print(logits)"
152 | ]
153 | },
154 | {
155 | "cell_type": "markdown",
156 | "metadata": {},
157 | "source": [
158 | "### 3.训练和评估\n",
159 | "下面我们将输入 mnist 的数据来进行训练。在下面有个 mnist.train.next_batch(batch_size=100) 的操作,每次从数据集中取出100个样本。如果想了解怎么实现的话建议看一下源码,其实挺简单的,很多时候需要我们自己去实现读取数据的这个函数。"
160 | ]
161 | },
162 | {
163 | "cell_type": "code",
164 | "execution_count": 5,
165 | "metadata": {},
166 | "outputs": [
167 | {
168 | "name": "stdout",
169 | "output_type": "stream",
170 | "text": [
171 | "step 500, train cost=0.153510, acc=0.950000; test cost=0.123346, acc=0.962500\n",
172 | "step 1000, train cost=0.087353, acc=0.960000; test cost=0.104876, acc=0.967400\n",
173 | "step 1500, train cost=0.033138, acc=0.990000; test cost=0.080937, acc=0.975200\n",
174 | "step 2000, train cost=0.028831, acc=0.990000; test cost=0.077214, acc=0.977800\n",
175 | "step 2500, train cost=0.004817, acc=1.000000; test cost=0.066441, acc=0.980000\n",
176 | "step 3000, train cost=0.015692, acc=1.000000; test cost=0.067741, acc=0.979400\n",
177 | "step 3500, train cost=0.011569, acc=1.000000; test cost=0.075138, acc=0.979400\n",
178 | "step 4000, train cost=0.006310, acc=1.000000; test cost=0.074501, acc=0.978300\n",
179 | "step 4500, train cost=0.008795, acc=1.000000; test cost=0.076483, acc=0.979100\n",
180 | "step 5000, train cost=0.027700, acc=0.980000; test cost=0.073973, acc=0.980000\n"
181 | ]
182 | }
183 | ],
184 | "source": [
185 | "# 1.损失函数:cross_entropy\n",
186 | "# 如果label是 one-hot 的话要换一下损失函数,参考:https://blog.csdn.net/tz_zs/article/details/76086457\n",
187 | "cross_entropy = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y_input, logits=logits)) \n",
188 | "# 2.优化函数:AdamOptimizer, 优化速度要比 GradientOptimizer 快很多\n",
189 | "train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)\n",
190 | "\n",
191 | "# 3.预测结果评估\n",
192 | "# 预测值中最大值(1)即分类结果,是否等于原始标签中的(1)的位置。argmax()取最大值所在的下标\n",
193 | "correct_prediction = tf.equal(tf.argmax(logits, 1), y_input) \n",
194 | "accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))\n",
195 | "\n",
196 | "# 开始运行\n",
197 | "sess.run(tf.global_variables_initializer())\n",
198 | "# 这大概迭代了不到 10 个 epoch, 训练准确率已经达到了0.98\n",
199 | "for i in range(5000):\n",
200 | " X_batch, y_batch = mnist.train.next_batch(batch_size=100)\n",
201 | " cost, acc, _ = sess.run([cross_entropy, accuracy, train_step], feed_dict={X_input: X_batch, y_input: y_batch})\n",
202 | " if (i+1) % 500 == 0:\n",
203 | " test_cost, test_acc = sess.run([cross_entropy, accuracy], feed_dict={X_input: mnist.test.images, y_input: mnist.test.labels})\n",
204 | " print(\"step {}, train cost={:.6f}, acc={:.6f}; test cost={:.6f}, acc={:.6f}\".format(i+1, cost, acc, test_cost, test_acc))\n",
205 | " "
206 | ]
207 | }
208 | ],
209 | "metadata": {
210 | "anaconda-cloud": {},
211 | "kernelspec": {
212 | "display_name": "Python 3",
213 | "language": "python",
214 | "name": "python3"
215 | },
216 | "language_info": {
217 | "codemirror_mode": {
218 | "name": "ipython",
219 | "version": 3
220 | },
221 | "file_extension": ".py",
222 | "mimetype": "text/x-python",
223 | "name": "python",
224 | "nbconvert_exporter": "python",
225 | "pygments_lexer": "ipython3",
226 | "version": "3.5.2"
227 | }
228 | },
229 | "nbformat": 4,
230 | "nbformat_minor": 1
231 | }
232 |
--------------------------------------------------------------------------------
/example-notebook/Tutorial_03_2 The usage of Collection.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# TensorFlow 变量命名管理机制(二)\n",
8 | "\n",
9 | "\n",
10 | "### 1. 用 collection 来聚合变量\n",
11 | "前面介绍了 tensorflow 的变量命名机制,这里要补充一下 `tf.add_to_collection` 和 `tf.get_collection`的用法。\n",
12 | "\n",
13 | "因为神经网络中的参数非常多,有时候我们 只想对某些参数进行操作。除了前面通过变量名称的方法来获取参数之外, TensorFlow 中还有 collection 这么一种操作。\n",
14 | "\n",
15 | "collection 可以聚合多个**变量**或者**操作**。"
16 | ]
17 | },
18 | {
19 | "cell_type": "code",
20 | "execution_count": 1,
21 | "metadata": {},
22 | "outputs": [],
23 | "source": [
24 | "import warnings\n",
25 | "warnings.filterwarnings('ignore') # 不打印 warning \n",
26 | "\n",
27 | "import tensorflow as tf\n",
28 | "\n",
29 | "# 设置GPU按需增长\n",
30 | "config = tf.ConfigProto()\n",
31 | "config.gpu_options.allow_growth = True\n",
32 | "sess = tf.Session(config=config)"
33 | ]
34 | },
35 | {
36 | "cell_type": "markdown",
37 | "metadata": {},
38 | "source": [
39 | "参考:[如何利用tf.add_to_collection、tf.get_collection以及tf.add_n来简化正则项的计算](https://blog.csdn.net/weixin_39980291/article/details/78352125)"
40 | ]
41 | },
42 | {
43 | "cell_type": "code",
44 | "execution_count": 2,
45 | "metadata": {},
46 | "outputs": [
47 | {
48 | "name": "stdout",
49 | "output_type": "stream",
50 | "text": [
51 | "vars in col1: [, ]\n"
52 | ]
53 | }
54 | ],
55 | "source": [
56 | "# 把变量添加到一个 collection 中\n",
57 | "v1 = tf.Variable([1,2,3], name='v1')\n",
58 | "v2 = tf.Variable([2], name='v2')\n",
59 | "v3 = tf.get_variable(name='v3', shape=(2,3))\n",
60 | "\n",
61 | "tf.add_to_collection('col1', v1) # 把 v1 添加到 col1 中\n",
62 | "tf.add_to_collection('col1', v3)\n",
63 | "\n",
64 | "col1s = tf.get_collection(key='col1') # 获取 col1 的变量\n",
65 | "print('vars in col1:', col1s)"
66 | ]
67 | },
68 | {
69 | "cell_type": "markdown",
70 | "metadata": {},
71 | "source": [
72 | "除了把变量添加到集合中,还可以把操作添加到集合中。"
73 | ]
74 | },
75 | {
76 | "cell_type": "code",
77 | "execution_count": 3,
78 | "metadata": {},
79 | "outputs": [
80 | {
81 | "name": "stdout",
82 | "output_type": "stream",
83 | "text": [
84 | "vars in col1: [, , ]\n"
85 | ]
86 | }
87 | ],
88 | "source": [
89 | "op1 = tf.add(v1, 2, name='add_op')\n",
90 | "tf.add_to_collection('col1', op1)\n",
91 | "col1s = tf.get_collection(key='col1') # 获取 col1 的变量\n",
92 | "print('vars in col1:', col1s)"
93 | ]
94 | },
95 | {
96 | "cell_type": "markdown",
97 | "metadata": {},
98 | "source": [
99 | "此外,还可以加上 scope 的约束。"
100 | ]
101 | },
102 | {
103 | "cell_type": "code",
104 | "execution_count": 3,
105 | "metadata": {},
106 | "outputs": [
107 | {
108 | "name": "stdout",
109 | "output_type": "stream",
110 | "text": [
111 | "vars in col1 with scope=model: []\n"
112 | ]
113 | }
114 | ],
115 | "source": [
116 | "with tf.variable_scope('model'):\n",
117 | " v4 = tf.get_variable('v4', shape=[3,4])\n",
118 | " v5 = tf.Variable([1,2,3], name='v5')\n",
119 | "\n",
120 | "tf.add_to_collection('col1', v5)\n",
121 | "col1_vars = tf.get_collection(key='col1', scope='model') # 获取 col1 的变量\n",
122 | "print('vars in col1 with scope=model: ', col1_vars)"
123 | ]
124 | },
125 | {
126 | "cell_type": "markdown",
127 | "metadata": {},
128 | "source": [
129 | "### 2. tf.GraphKeys \n",
130 | "\n",
131 | "参考:[tf.GraphKeys 函数](https://www.w3cschool.cn/tensorflow_python/tensorflow_python-ne7t2ezd.html)\n",
132 | "\n",
133 | "用于图形集合的标准名称。\n",
134 | "\n",
135 | "\n",
136 | "标准库使用各种已知的名称来收集和检索与图形相关联的值。例如,如果没有指定,则 tf.Optimizer 子类默认优化收集的变量tf.GraphKeys.TRAINABLE_VARIABLES,但也可以传递显式的变量列表。\n",
137 | "\n",
138 | "定义了以下标准键:\n",
139 | "\n",
140 | "- GLOBAL_VARIABLES:默认的 Variable 对象集合,在分布式环境共享(模型变量是其中的子集)。参考:tf.global_variables。通常,所有TRAINABLE_VARIABLES 变量都将在 MODEL_VARIABLES,所有 MODEL_VARIABLES 变量都将在 GLOBAL_VARIABLES。\n",
141 | "- LOCAL_VARIABLES:每台计算机的局部变量对象的子集。通常用于临时变量,如计数器。注意:使用 tf.contrib.framework.local_variable 添加到此集合。\n",
142 | "- MODEL_VARIABLES:在模型中用于推理(前馈)的变量对象的子集。注意:使用 tf.contrib.framework.model_variable 添加到此集合。\n",
143 | "- TRAINABLE_VARIABLES:将由优化器训练的变量对象的子集。\n",
144 | "- SUMMARIES:在关系图中创建的汇总张量对象。\n",
145 | "- QUEUE_RUNNERS:用于为计算生成输入的 QueueRunner 对象。\n",
146 | "- MOVING_AVERAGE_VARIABLES:变量对象的子集,它也将保持移动平均值。\n",
147 | "- REGULARIZATION_LOSSES:在图形构造期间收集的正规化损失。\n",
148 | "\n",
149 | "这个知道就好了,要用的时候知道是怎么回事就行了。比如在 BN 层中就有这东西。"
150 | ]
151 | },
152 | {
153 | "cell_type": "code",
154 | "execution_count": null,
155 | "metadata": {},
156 | "outputs": [],
157 | "source": []
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": null,
162 | "metadata": {},
163 | "outputs": [],
164 | "source": []
165 | }
166 | ],
167 | "metadata": {
168 | "anaconda-cloud": {},
169 | "kernelspec": {
170 | "display_name": "Python 3",
171 | "language": "python",
172 | "name": "python3"
173 | },
174 | "language_info": {
175 | "codemirror_mode": {
176 | "name": "ipython",
177 | "version": 3
178 | },
179 | "file_extension": ".py",
180 | "mimetype": "text/x-python",
181 | "name": "python",
182 | "nbconvert_exporter": "python",
183 | "pygments_lexer": "ipython3",
184 | "version": "3.5.2"
185 | }
186 | },
187 | "nbformat": 4,
188 | "nbformat_minor": 1
189 | }
190 |
--------------------------------------------------------------------------------
/example-notebook/Tutorial_04_3 Convolutional network for MNIST(3).ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## CNN做MNIST分类\n",
8 | "\n",
9 | "使用 tf.layers 高级 API 构建 CNN "
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": 1,
15 | "metadata": {},
16 | "outputs": [
17 | {
18 | "name": "stderr",
19 | "output_type": "stream",
20 | "text": [
21 | "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
22 | " from ._conv import register_converters as _register_converters\n"
23 | ]
24 | }
25 | ],
26 | "source": [
27 | "import numpy as np\n",
28 | "import tensorflow as tf\n",
29 | "\n",
30 | "# 设置按需使用GPU\n",
31 | "config = tf.ConfigProto()\n",
32 | "config.gpu_options.allow_growth = True\n",
33 | "sess = tf.InteractiveSession(config=config)\n",
34 | "\n",
35 | "import time"
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {},
41 | "source": [
42 | "## 1.导入数据,用 tensorflow 导入"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": 2,
48 | "metadata": {},
49 | "outputs": [
50 | {
51 | "name": "stdout",
52 | "output_type": "stream",
53 | "text": [
54 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/base.py:198: retry (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
55 | "Instructions for updating:\n",
56 | "Use the retry module or similar alternatives.\n",
57 | "WARNING:tensorflow:From :3: read_data_sets (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
58 | "Instructions for updating:\n",
59 | "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
60 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:260: maybe_download (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
61 | "Instructions for updating:\n",
62 | "Please write your own downloading logic.\n",
63 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:262: extract_images (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
64 | "Instructions for updating:\n",
65 | "Please use tf.data to implement this functionality.\n",
66 | "Extracting MNIST_data/train-images-idx3-ubyte.gz\n",
67 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:267: extract_labels (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
68 | "Instructions for updating:\n",
69 | "Please use tf.data to implement this functionality.\n",
70 | "Extracting MNIST_data/train-labels-idx1-ubyte.gz\n",
71 | "Extracting MNIST_data/t10k-images-idx3-ubyte.gz\n",
72 | "Extracting MNIST_data/t10k-labels-idx1-ubyte.gz\n",
73 | "WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:290: DataSet.__init__ (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
74 | "Instructions for updating:\n",
75 | "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
76 | "(10000,)\n",
77 | "(55000,)\n"
78 | ]
79 | }
80 | ],
81 | "source": [
82 | "# 用tensorflow 导入数据\n",
83 | "from tensorflow.examples.tutorials.mnist import input_data\n",
84 | "mnist = input_data.read_data_sets('MNIST_data', one_hot=False)\n",
85 | "# 看看咱们样本的数量\n",
86 | "print(mnist.test.labels.shape)\n",
87 | "print(mnist.train.labels.shape)"
88 | ]
89 | },
90 | {
91 | "cell_type": "markdown",
92 | "metadata": {},
93 | "source": [
94 | "## 2. 构建网络"
95 | ]
96 | },
97 | {
98 | "cell_type": "code",
99 | "execution_count": 3,
100 | "metadata": {},
101 | "outputs": [
102 | {
103 | "name": "stdout",
104 | "output_type": "stream",
105 | "text": [
106 | "Finished building network.\n"
107 | ]
108 | }
109 | ],
110 | "source": [
111 | "with tf.name_scope('inputs'):\n",
112 | " X_ = tf.placeholder(tf.float32, [None, 784])\n",
113 | " y_ = tf.placeholder(tf.int64, [None])\n",
114 | "\n",
115 | "# 把X转为卷积所需要的形式\n",
116 | "X = tf.reshape(X_, [-1, 28, 28, 1])\n",
117 | "h_conv1 = tf.layers.conv2d(X, filters=32, kernel_size=5, strides=1, padding='same', activation=tf.nn.relu, name='conv1')\n",
118 | "h_pool1 = tf.layers.max_pooling2d(h_conv1, pool_size=2, strides=2, padding='same', name='pool1')\n",
119 | "\n",
120 | "h_conv2 = tf.layers.conv2d(h_pool1, filters=64, kernel_size=5, strides=1, padding='same',activation=tf.nn.relu, name='conv2')\n",
121 | "h_pool2 = tf.layers.max_pooling2d(h_conv2, pool_size=2, strides=2, padding='same', name='pool2')\n",
122 | "\n",
123 | "# flatten\n",
124 | "h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])\n",
125 | "h_fc1 = tf.layers.dense(h_pool2_flat, 1024, name='fc1', activation=tf.nn.relu)\n",
126 | "\n",
127 | "# dropout: 输出的维度和h_fc1一样,只是随机部分值被值为零\n",
128 | "keep_prob = tf.placeholder(tf.float32)\n",
129 | "h_fc1_drop = tf.nn.dropout(h_fc1, 0.5) # 实际测试的时候这里不应该使用 0.5,这里为了方便演示都这样写而已\n",
130 | "h_fc2 = tf.layers.dense(h_fc1_drop, units=10, name='fc2')\n",
131 | "# y_conv = tf.nn.softmax(h_fc2)\n",
132 | "y_conv = h_fc2\n",
133 | "print('Finished building network.')"
134 | ]
135 | },
136 | {
137 | "cell_type": "code",
138 | "execution_count": 4,
139 | "metadata": {},
140 | "outputs": [
141 | {
142 | "name": "stdout",
143 | "output_type": "stream",
144 | "text": [
145 | "Tensor(\"conv1/Relu:0\", shape=(?, 28, 28, 32), dtype=float32)\n",
146 | "Tensor(\"pool1/MaxPool:0\", shape=(?, 14, 14, 32), dtype=float32)\n",
147 | "Tensor(\"conv2/Relu:0\", shape=(?, 14, 14, 64), dtype=float32)\n",
148 | "Tensor(\"pool2/MaxPool:0\", shape=(?, 7, 7, 64), dtype=float32)\n",
149 | "Tensor(\"Reshape_1:0\", shape=(?, 3136), dtype=float32)\n",
150 | "Tensor(\"fc1/Relu:0\", shape=(?, 1024), dtype=float32)\n",
151 | "Tensor(\"fc2/BiasAdd:0\", shape=(?, 10), dtype=float32)\n"
152 | ]
153 | }
154 | ],
155 | "source": [
156 | "print(h_conv1)\n",
157 | "print(h_pool1)\n",
158 | "print(h_conv2)\n",
159 | "print(h_pool2)\n",
160 | "\n",
161 | "print(h_pool2_flat)\n",
162 | "print(h_fc1)\n",
163 | "print(h_fc2)"
164 | ]
165 | },
166 | {
167 | "cell_type": "markdown",
168 | "metadata": {},
169 | "source": [
170 | "## 3.训练和评估"
171 | ]
172 | },
173 | {
174 | "cell_type": "markdown",
175 | "metadata": {},
176 | "source": [
177 | " 在测试的时候不使用 mini_batch, 那么测试的时候会占用较多的GPU(4497M),这在 notebook 交互式编程中是不推荐的。"
178 | ]
179 | },
180 | {
181 | "cell_type": "code",
182 | "execution_count": 5,
183 | "metadata": {
184 | "scrolled": false
185 | },
186 | "outputs": [
187 | {
188 | "name": "stdout",
189 | "output_type": "stream",
190 | "text": [
191 | "step 0, training accuracy = 0.1100, pass 1.18s \n",
192 | "step 1000, training accuracy = 0.9800, pass 6.01s \n",
193 | "step 2000, training accuracy = 0.9800, pass 10.82s \n",
194 | "step 3000, training accuracy = 0.9700, pass 15.65s \n",
195 | "step 4000, training accuracy = 1.0000, pass 20.40s \n",
196 | "step 5000, training accuracy = 0.9800, pass 25.26s \n",
197 | "step 6000, training accuracy = 1.0000, pass 30.00s \n",
198 | "step 7000, training accuracy = 0.9900, pass 34.84s \n",
199 | "step 8000, training accuracy = 1.0000, pass 39.66s \n",
200 | "step 9000, training accuracy = 1.0000, pass 44.55s \n",
201 | "test accuracy 0.9924\n"
202 | ]
203 | }
204 | ],
205 | "source": [
206 | "# cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))\n",
207 | "cross_entropy = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(\n",
208 | " labels=tf.cast(y_, dtype=tf.int32), logits=y_conv))\n",
209 | "\n",
210 | "train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)\n",
211 | "\n",
212 | "correct_prediction = tf.equal(tf.argmax(y_conv,1), y_)\n",
213 | "accuracy = tf.reduce_mean(tf.cast(correct_prediction, \"float\"))\n",
214 | "sess.run(tf.global_variables_initializer())\n",
215 | "\n",
216 | "tic = time.time()\n",
217 | "for i in range(10000):\n",
218 | " batch = mnist.train.next_batch(100)\n",
219 | " if i%1000 == 0:\n",
220 | " train_accuracy = accuracy.eval(feed_dict={\n",
221 | " X_:batch[0], y_: batch[1], keep_prob: 1.0})\n",
222 | " print(\"step {}, training accuracy = {:.4f}, pass {:.2f}s \".format(i, train_accuracy, time.time() - tic))\n",
223 | " train_step.run(feed_dict={X_: batch[0], y_: batch[1]})\n",
224 | "\n",
225 | "print(\"test accuracy %g\"%accuracy.eval(feed_dict={\n",
226 | " X_: mnist.test.images, y_: mnist.test.labels}))"
227 | ]
228 | }
229 | ],
230 | "metadata": {
231 | "anaconda-cloud": {},
232 | "kernelspec": {
233 | "display_name": "Python 3",
234 | "language": "python",
235 | "name": "python3"
236 | },
237 | "language_info": {
238 | "codemirror_mode": {
239 | "name": "ipython",
240 | "version": 3
241 | },
242 | "file_extension": ".py",
243 | "mimetype": "text/x-python",
244 | "name": "python",
245 | "nbconvert_exporter": "python",
246 | "pygments_lexer": "ipython3",
247 | "version": "3.5.2"
248 | }
249 | },
250 | "nbformat": 4,
251 | "nbformat_minor": 1
252 | }
253 |
--------------------------------------------------------------------------------
/example-notebook/Tutorial_07 How to save the model.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## 如何使用 tf.train.Saver() 来保存模型\n",
8 | "之前一直出错,主要是因为坑爹的编码问题。所以要注意文件的路径绝对不不要出现什么中文呀。"
9 | ]
10 | },
11 | {
12 | "cell_type": "code",
13 | "execution_count": 1,
14 | "metadata": {},
15 | "outputs": [
16 | {
17 | "name": "stderr",
18 | "output_type": "stream",
19 | "text": [
20 | "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
21 | " from ._conv import register_converters as _register_converters\n"
22 | ]
23 | },
24 | {
25 | "name": "stdout",
26 | "output_type": "stream",
27 | "text": [
28 | "Model saved in file: ../ckpt/test-model.ckpt-1\n"
29 | ]
30 | }
31 | ],
32 | "source": [
33 | "import tensorflow as tf\n",
34 | "config = tf.ConfigProto()\n",
35 | "config.gpu_options.allow_growth = True\n",
36 | "sess = tf.Session(config=config)\n",
37 | "\n",
38 | "# Create some variables.\n",
39 | "v1 = tf.Variable([1.0, 2.3], name=\"v1\")\n",
40 | "v2 = tf.Variable(55.5, name=\"v2\")\n",
41 | "\n",
42 | "# Add an op to initialize the variables.\n",
43 | "init_op = tf.global_variables_initializer()\n",
44 | "\n",
45 | "# Add ops to save and restore all the variables.\n",
46 | "saver = tf.train.Saver()\n",
47 | "\n",
48 | "ckpt_path = '../ckpt/test-model.ckpt'\n",
49 | "# Later, launch the model, initialize the variables, do some work, save the\n",
50 | "# variables to disk.\n",
51 | "sess.run(init_op)\n",
52 | "save_path = saver.save(sess, ckpt_path, global_step=1)\n",
53 | "print(\"Model saved in file: %s\" % save_path)"
54 | ]
55 | },
56 | {
57 | "cell_type": "markdown",
58 | "metadata": {},
59 | "source": [
60 | "注意,在上面保存完了模型之后。**Restart kernel** 之后才能使用下面的模型导入。否则会因为两次命名 \"v1\" 而导致名字错误。"
61 | ]
62 | },
63 | {
64 | "cell_type": "code",
65 | "execution_count": 1,
66 | "metadata": {},
67 | "outputs": [
68 | {
69 | "name": "stderr",
70 | "output_type": "stream",
71 | "text": [
72 | "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
73 | " from ._conv import register_converters as _register_converters\n"
74 | ]
75 | },
76 | {
77 | "name": "stdout",
78 | "output_type": "stream",
79 | "text": [
80 | "INFO:tensorflow:Restoring parameters from ../ckpt/test-model.ckpt-1\n",
81 | "Model restored.\n",
82 | "[1. 2.3]\n",
83 | "55.5\n"
84 | ]
85 | }
86 | ],
87 | "source": [
88 | "import tensorflow as tf\n",
89 | "config = tf.ConfigProto()\n",
90 | "config.gpu_options.allow_growth = True\n",
91 | "sess = tf.Session(config=config)\n",
92 | "\n",
93 | "# Create some variables.\n",
94 | "v1 = tf.Variable([11.0, 16.3], name=\"v1\")\n",
95 | "v2 = tf.Variable(33.5, name=\"v2\")\n",
96 | "\n",
97 | "# Add ops to save and restore all the variables.\n",
98 | "saver = tf.train.Saver()\n",
99 | "\n",
100 | "# Later, launch the model, use the saver to restore variables from disk, and\n",
101 | "# do some work with the model.\n",
102 | "# Restore variables from disk.\n",
103 | "ckpt_path = '../ckpt/test-model.ckpt'\n",
104 | "saver.restore(sess, ckpt_path + '-'+ str(1))\n",
105 | "print(\"Model restored.\")\n",
106 | "\n",
107 | "print(sess.run(v1))\n",
108 | "print(sess.run(v2))"
109 | ]
110 | },
111 | {
112 | "cell_type": "markdown",
113 | "metadata": {},
114 | "source": [
115 | "导入模型之前,必须重新再定义一遍变量。\n",
116 | "\n",
117 | "但是并不需要全部变量都重新进行定义,只定义我们需要的变量就行了。\n",
118 | "\n",
119 | "也就是说,**你所定义的变量一定要在 checkpoint 中存在;但不是所有在checkpoint中的变量,你都要重新定义。**"
120 | ]
121 | },
122 | {
123 | "cell_type": "code",
124 | "execution_count": 1,
125 | "metadata": {},
126 | "outputs": [
127 | {
128 | "name": "stderr",
129 | "output_type": "stream",
130 | "text": [
131 | "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
132 | " from ._conv import register_converters as _register_converters\n"
133 | ]
134 | },
135 | {
136 | "name": "stdout",
137 | "output_type": "stream",
138 | "text": [
139 | "INFO:tensorflow:Restoring parameters from ../ckpt/test-model.ckpt-1\n",
140 | "Model restored.\n",
141 | "[1. 2.3]\n"
142 | ]
143 | }
144 | ],
145 | "source": [
146 | "import tensorflow as tf\n",
147 | "config = tf.ConfigProto()\n",
148 | "config.gpu_options.allow_growth = True\n",
149 | "sess = tf.Session(config=config)\n",
150 | "\n",
151 | "# Create some variables.\n",
152 | "v1 = tf.Variable([11.0, 16.3], name=\"v1\")\n",
153 | "\n",
154 | "# Add ops to save and restore all the variables.\n",
155 | "saver = tf.train.Saver()\n",
156 | "\n",
157 | "# Later, launch the model, use the saver to restore variables from disk, and\n",
158 | "# do some work with the model.\n",
159 | "# Restore variables from disk.\n",
160 | "ckpt_path = '../ckpt/test-model.ckpt'\n",
161 | "saver.restore(sess, ckpt_path + '-'+ str(1))\n",
162 | "print(\"Model restored.\")\n",
163 | "\n",
164 | "print(sess.run(v1))"
165 | ]
166 | },
167 | {
168 | "cell_type": "markdown",
169 | "metadata": {},
170 | "source": [
171 | "## 关于模型保存的一点心得\n",
172 | "\n",
173 | "```\n",
174 | "saver = tf.train.Saver(max_to_keep=3)\n",
175 | "```\n",
176 | "在定义 saver 的时候一般会定义最多保存模型的数量,一般来说,我都不会保存太多模型,模型多了浪费空间,很多时候其实保存最好的模型就够了。方法就是每次迭代到一定步数就在验证集上计算一次 accuracy 或者 f1 值,如果本次结果比上次好才保存新的模型,否则没必要保存。\n",
177 | "\n",
178 | "如果你想用不同 epoch 保存下来的模型进行融合的话,3到5 个模型已经足够了,假设这各融合的模型成为 M,而最好的一个单模型称为 m_best, 这样融合的话对于M 确实可以比 m_best 更好。但是如果拿这个模型和其他结构的模型再做融合的话,M 的效果并没有 m_best 好,因为M 相当于做了平均操作,减少了该模型的“特性”。"
179 | ]
180 | }
181 | ],
182 | "metadata": {
183 | "anaconda-cloud": {},
184 | "kernelspec": {
185 | "display_name": "Python 3",
186 | "language": "python",
187 | "name": "python3"
188 | },
189 | "language_info": {
190 | "codemirror_mode": {
191 | "name": "ipython",
192 | "version": 3
193 | },
194 | "file_extension": ".py",
195 | "mimetype": "text/x-python",
196 | "name": "python",
197 | "nbconvert_exporter": "python",
198 | "pygments_lexer": "ipython3",
199 | "version": "3.5.2"
200 | }
201 | },
202 | "nbformat": 4,
203 | "nbformat_minor": 1
204 | }
205 |
--------------------------------------------------------------------------------
/example-notebook/Tutorial_08 [transfer learning] Add new variables to graph and save the new model.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## 【迁移学习】往一个已经保存好的 模型添加新的变量\n",
8 | "在迁移学习中,通常我们已经训练好一个模型,现在需要修改模型的部分结构,用于我们的新任务。\n",
9 | "\n",
10 | "比如:\n",
11 | "\n",
12 | "在一个图片分类任务中,我们使用别人训练好的网络来提取特征,但是我们的分类数目和原模型不同,这样我们只能取到 fc 层,后面的分类层需要重新写。这样我们就需要添加新的变量。那么这些新加入的变量必须得初始化才能使用。可是我们又不能使用 'tf.global_variables_initializer()' 来初始化,否则原本训练好的模型就没用了。\n",
13 | "\n",
14 | "关于怎么样单独初始化新增的变量,可以参考下面两个链接:\n",
15 | "- [1]https://stackoverflow.com/questions/35164529/in-tensorflow-is-there-any-way-to-just-initialize-uninitialised-variables\n",
16 | "- [2]https://stackoverflow.com/questions/35013080/tensorflow-how-to-get-all-variables-from-rnn-cell-basiclstm-rnn-cell-multirnn\n",
17 | "\n",
18 | "简单的例子可以直接看下面我的实现方式。"
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "### 初始模型定义与保存\n",
26 | "首先定义一个模型,里边有 v1, v2 两个变量,我们把这个模型保存起来。"
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": 1,
32 | "metadata": {},
33 | "outputs": [
34 | {
35 | "name": "stderr",
36 | "output_type": "stream",
37 | "text": [
38 | "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
39 | " from ._conv import register_converters as _register_converters\n"
40 | ]
41 | },
42 | {
43 | "name": "stdout",
44 | "output_type": "stream",
45 | "text": [
46 | "Model saved in file: ../ckpt/test-model.ckpt-1\n"
47 | ]
48 | }
49 | ],
50 | "source": [
51 | "import tensorflow as tf\n",
52 | "config = tf.ConfigProto()\n",
53 | "config.gpu_options.allow_growth = True\n",
54 | "sess = tf.Session(config=config)\n",
55 | "\n",
56 | "# Create some variables.\n",
57 | "v1 = tf.Variable([1.0, 2.3], name=\"v1\")\n",
58 | "v2 = tf.Variable(55.5, name=\"v2\")\n",
59 | "\n",
60 | "\n",
61 | "init_op = tf.global_variables_initializer()\n",
62 | "saver = tf.train.Saver()\n",
63 | "ckpt_path = '../ckpt/test-model.ckpt'\n",
64 | "sess.run(init_op)\n",
65 | "save_path = saver.save(sess, ckpt_path, global_step=1)\n",
66 | "print(\"Model saved in file: %s\" % save_path)"
67 | ]
68 | },
69 | {
70 | "cell_type": "markdown",
71 | "metadata": {},
72 | "source": [
73 | "**restart(重启kernel然后执行下面cell的代码)**\n",
74 | "### 导入已经保存好的模型,并添加新的变量\n",
75 | "现在把之前保存好的模型,我只需要其中的 v1 变量。同时我还要添加新的变量 v3。"
76 | ]
77 | },
78 | {
79 | "cell_type": "code",
80 | "execution_count": 1,
81 | "metadata": {
82 | "scrolled": false
83 | },
84 | "outputs": [
85 | {
86 | "name": "stderr",
87 | "output_type": "stream",
88 | "text": [
89 | "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
90 | " from ._conv import register_converters as _register_converters\n"
91 | ]
92 | },
93 | {
94 | "name": "stdout",
95 | "output_type": "stream",
96 | "text": [
97 | "INFO:tensorflow:Restoring parameters from ../ckpt/test-model.ckpt-1\n",
98 | "[1. 2.3]\n",
99 | "[1. 2.3]\n",
100 | "666\n"
101 | ]
102 | },
103 | {
104 | "data": {
105 | "text/plain": [
106 | "'../ckpt/test-model.ckpt-2'"
107 | ]
108 | },
109 | "execution_count": 1,
110 | "metadata": {},
111 | "output_type": "execute_result"
112 | }
113 | ],
114 | "source": [
115 | "import tensorflow as tf\n",
116 | "config = tf.ConfigProto()\n",
117 | "config.gpu_options.allow_growth = True\n",
118 | "sess = tf.Session(config=config)\n",
119 | "\n",
120 | "# Create some variables.\n",
121 | "v1 = tf.Variable([11.0, 16.3], name=\"v1\")\n",
122 | "\n",
123 | "# ** 导入训练好的模型\n",
124 | "saver = tf.train.Saver()\n",
125 | "ckpt_path = '../ckpt/test-model.ckpt'\n",
126 | "saver.restore(sess, ckpt_path + '-'+ str(1))\n",
127 | "print(sess.run(v1))\n",
128 | "\n",
129 | "# ** 定义新的变量并单独初始化新定义的变量\n",
130 | "v3 = tf.Variable(666, name='v3', dtype=tf.int32)\n",
131 | "init_new = tf.variables_initializer([v3])\n",
132 | "sess.run(init_new)\n",
133 | "# 。。。这里就可以进行 fine-tune 了\n",
134 | "print(sess.run(v1))\n",
135 | "print(sess.run(v3))\n",
136 | "\n",
137 | "# ** 保存新的模型。 \n",
138 | "# 注意!注意!注意! 一定一定一定要重新定义 saver, 这样才能把 v3 添加到 checkpoint 中\n",
139 | "saver = tf.train.Saver()\n",
140 | "saver.save(sess, ckpt_path, global_step=2)"
141 | ]
142 | },
143 | {
144 | "cell_type": "markdown",
145 | "metadata": {},
146 | "source": [
147 | "**restart(重启kernel然后执行下面cell的代码)**\n",
148 | "### 这样就完成了 fine-tune, 得到了新的模型"
149 | ]
150 | },
151 | {
152 | "cell_type": "code",
153 | "execution_count": 1,
154 | "metadata": {
155 | "scrolled": false
156 | },
157 | "outputs": [
158 | {
159 | "name": "stderr",
160 | "output_type": "stream",
161 | "text": [
162 | "/usr/local/lib/python3.5/dist-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
163 | " from ._conv import register_converters as _register_converters\n"
164 | ]
165 | },
166 | {
167 | "name": "stdout",
168 | "output_type": "stream",
169 | "text": [
170 | "INFO:tensorflow:Restoring parameters from ../ckpt/test-model.ckpt-2\n",
171 | "Model restored.\n",
172 | "[1. 2.3]\n",
173 | "666\n"
174 | ]
175 | }
176 | ],
177 | "source": [
178 | "import tensorflow as tf\n",
179 | "config = tf.ConfigProto()\n",
180 | "config.gpu_options.allow_growth = True\n",
181 | "sess = tf.Session(config=config)\n",
182 | "\n",
183 | "# Create some variables.\n",
184 | "v1 = tf.Variable([11.0, 16.3], name=\"v1\")\n",
185 | "v3 = tf.Variable(666, name='v3', dtype=tf.int32)\n",
186 | "# Add ops to save and restore all the variables.\n",
187 | "saver = tf.train.Saver()\n",
188 | "\n",
189 | "# Later, launch the model, use the saver to restore variables from disk, and\n",
190 | "# do some work with the model.\n",
191 | "# Restore variables from disk.\n",
192 | "ckpt_path = '../ckpt/test-model.ckpt'\n",
193 | "saver.restore(sess, ckpt_path + '-'+ str(2))\n",
194 | "print(\"Model restored.\")\n",
195 | "\n",
196 | "print(sess.run(v1))\n",
197 | "print(sess.run(v3))"
198 | ]
199 | },
200 | {
201 | "cell_type": "code",
202 | "execution_count": null,
203 | "metadata": {
204 | "collapsed": true
205 | },
206 | "outputs": [],
207 | "source": []
208 | }
209 | ],
210 | "metadata": {
211 | "anaconda-cloud": {},
212 | "kernelspec": {
213 | "display_name": "Python 3",
214 | "language": "python",
215 | "name": "python3"
216 | },
217 | "language_info": {
218 | "codemirror_mode": {
219 | "name": "ipython",
220 | "version": 3
221 | },
222 | "file_extension": ".py",
223 | "mimetype": "text/x-python",
224 | "name": "python",
225 | "nbconvert_exporter": "python",
226 | "pygments_lexer": "ipython3",
227 | "version": "3.5.2"
228 | }
229 | },
230 | "nbformat": 4,
231 | "nbformat_minor": 1
232 | }
233 |
--------------------------------------------------------------------------------
/example-python/Tutorial-graph.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | import tensorflow as tf
4 | import os
5 |
6 | config = tf.ConfigProto()
7 | config.gpu_options.allow_growth = True
8 | sess = tf.Session(config=config)
9 |
10 | """TensorBoard 简单例子。
11 | tf.summary.scalar('var_name', var) # 记录标量的变化
12 | tf.summary.histogram('vec_name', vec) # 记录向量或者矩阵,tensor的数值分布变化。
13 |
14 | merged = tf.summary.merge_all() # 把所有的记录并把他们写到 log_dir 中
15 | train_writer = tf.summary.FileWriter(FLAGS.log_dir + '/train', sess.graph) # 保存位置
16 |
17 | 运行完后,在命令行中输入 tensorboard --logdir=log_dir_path
18 | """
19 |
20 | tf.app.flags.DEFINE_string('log_dir', 'summary/graph/', 'log saving path')
21 | FLAGS = tf.app.flags.FLAGS
22 | if os.path.exists(FLAGS.log_dir):
23 | os.rmdir(FLAGS.log_dir)
24 | os.makedirs(FLAGS.log_dir)
25 | print 'created log_dir path'
26 |
27 | with tf.name_scope('add_example'):
28 | a = tf.Variable(tf.truncated_normal([100, 1], mean=0.5, stddev=0.5), name='var_a')
29 | tf.summary.histogram('a_hist', a)
30 | b = tf.Variable(tf.truncated_normal([100, 1], mean=-0.5, stddev=1.0), name='var_b')
31 | tf.summary.histogram('b_hist', b)
32 | increase_b = tf.assign(b, b + 0.05)
33 | c = tf.add(a, b)
34 | tf.summary.histogram('c_hist', c)
35 | c_mean = tf.reduce_mean(c)
36 | tf.summary.scalar('c_mean', c_mean)
37 | merged = tf.summary.merge_all()
38 | writer = tf.summary.FileWriter(FLAGS.log_dir + 'add_example', sess.graph)
39 |
40 |
41 | def main(_):
42 | sess.run(tf.global_variables_initializer())
43 | for step in xrange(500):
44 | sess.run([merged, increase_b]) # 每步改变一次 b 的值
45 | summary = sess.run(merged)
46 | writer.add_summary(summary, step)
47 | writer.close()
48 |
49 |
50 | if __name__ == '__main__':
51 | tf.app.run()
52 |
--------------------------------------------------------------------------------
/example-python/Tutorial_10_1_numpy_data_1.py:
--------------------------------------------------------------------------------
1 | """Use tf.data.Dataset to create dataset for numpy data.
2 | With dataset.make_one_shot_iterator(), it is easy but very slow.
3 | """
4 |
5 | from __future__ import print_function
6 | from __future__ import division
7 | from __future__ import absolute_import
8 |
9 | import warnings
10 |
11 | warnings.filterwarnings('ignore') # 不打印 warning
12 | import tensorflow as tf
13 |
14 | # 设置GPU按需增长
15 | config = tf.ConfigProto()
16 | config.gpu_options.allow_growth = True
17 | sess = tf.Session(config=config)
18 |
19 | import numpy as np
20 | import time
21 | import sys
22 |
23 | from tensorflow.examples.tutorials.mnist import input_data
24 |
25 | mnist = input_data.read_data_sets('../data/MNIST_data', one_hot=True)
26 |
27 | X = mnist.train.images
28 | y = mnist.train.labels
29 |
30 | batch_size = 128
31 | # 创建 dataset
32 | dataset = tf.data.Dataset.from_tensor_slices((X, y))
33 | print('dataset is', dataset)
34 |
35 | # 对数据进行操作
36 | # def pre_func(X, y):
37 | # X = tf.multiply(X, 2)
38 | # return X, y
39 | # dataset = dataset.map(pre_func)
40 |
41 | dataset = dataset.shuffle(buffer_size=5000) # 设置 buffle_size 越大,shuffle 越均匀
42 | dataset = dataset.repeat().batch(batch_size)
43 | print('after get batch', dataset)
44 |
45 | # 生成迭代器
46 | iterator = dataset.make_one_shot_iterator()
47 | print(iterator)
48 |
49 | # 迭代取值
50 | time0 = time.time()
51 | for count in range(100): # 100batch 125 seconds
52 | X_batch, y_batch = sess.run(iterator.get_next())
53 | sys.stdout.write("\rloop {}, pass {:.2f}s".format(count, time.time() - time0))
54 | sys.stdout.flush()
55 | # print('count = {} : y = {}'.format(count, y_batch.reshape([-1])))
56 |
57 |
--------------------------------------------------------------------------------
/example-python/Tutorial_10_1_numpy_data_2.py:
--------------------------------------------------------------------------------
1 | """Use tf.data.Dataset to create dataset for numpy data.
2 | With dataset.make_initializable_iterator(), it is more faster then dataset.make_one_shot_iterator().
3 | """
4 |
5 | from __future__ import print_function
6 | from __future__ import division
7 | from __future__ import absolute_import
8 |
9 | import warnings
10 |
11 | warnings.filterwarnings('ignore') # 不打印 warning
12 | import tensorflow as tf
13 |
14 | # 设置GPU按需增长
15 | config = tf.ConfigProto()
16 | config.gpu_options.allow_growth = True
17 | sess = tf.Session(config=config)
18 |
19 | import numpy as np
20 | import time
21 | import sys
22 |
23 | from tensorflow.examples.tutorials.mnist import input_data
24 |
25 | mnist = input_data.read_data_sets('../data/MNIST_data', one_hot=True)
26 |
27 | X = mnist.train.images
28 | y = mnist.train.labels
29 |
30 | # 使用 placeholder 来取代 array,并使用 initiable iterator, 在需要的时候再将 array 传进去
31 | # 这样能够避免把大数组保存在图中
32 | X_placeholder = tf.placeholder(dtype=X.dtype, shape=X.shape)
33 | y_placeholder = tf.placeholder(dtype=y.dtype, shape=y.shape)
34 |
35 | batch_size = 128
36 | # 创建 dataset
37 | dataset = tf.data.Dataset.from_tensor_slices((X_placeholder, y_placeholder))
38 | print('dataset is', dataset)
39 |
40 | # 对数据进行操作
41 | # def pre_func(X, y):
42 | # X = tf.multiply(X, 2)
43 | # return X, y
44 | # dataset = dataset.map(pre_func)
45 |
46 | dataset = dataset.shuffle(buffer_size=5000) # 设置 buffle_size 越大,shuffle 越均匀
47 | dataset = dataset.repeat().batch(batch_size)
48 | print('after get batch', dataset)
49 |
50 | # 生成迭代器
51 | iterator = dataset.make_initializable_iterator()
52 | print(iterator)
53 | sess.run(iterator.initializer, feed_dict={X_placeholder: X, y_placeholder: y})
54 |
55 | # 迭代取值
56 | time0 = time.time()
57 | for count in range(100): # 100batch 1.95 seconds
58 | X_batch, y_batch = sess.run(iterator.get_next())
59 | sys.stdout.write("\rloop {}, pass {:.2f}s".format(count, time.time() - time0))
60 | sys.stdout.flush()
61 | # print('count = {} : y = {}'.format(count, y_batch.reshape([-1])))
62 |
63 |
--------------------------------------------------------------------------------
/example-python/Tutorial_10_2_image_data_1.py:
--------------------------------------------------------------------------------
1 | """Use tf.data.Dataset to create dataset for image(png) data.
2 | With one-shot
3 | """
4 |
5 | from __future__ import print_function
6 | from __future__ import division
7 | from __future__ import absolute_import
8 |
9 | import warnings
10 |
11 | warnings.filterwarnings('ignore') # 不打印 warning
12 | import tensorflow as tf
13 |
14 |
15 | # 设置GPU按需增长
16 | config = tf.ConfigProto()
17 | config.gpu_options.allow_growth = True
18 | sess = tf.Session(config=config)
19 |
20 | import numpy as np
21 | import sys
22 | import os
23 | import time
24 |
25 |
26 | def get_file_path(data_path='../data/sketchy_000000000000/'):
27 | """解析文件夹,获取每个文件的路径和标签。"""
28 | img_paths = list()
29 | labels = list()
30 | class_dirs = sorted(os.listdir(data_path))
31 | dict_class2id = dict()
32 | for i in range(len(class_dirs)):
33 | label = i
34 | class_dir = class_dirs[i]
35 | dict_class2id[class_dir] = label
36 | class_path = os.path.join(data_path, class_dir) # 每类的路径
37 | file_names = sorted(os.listdir(class_path))
38 | for file_name in file_names:
39 | file_path = os.path.join(class_path, file_name)
40 | img_paths.append(file_path)
41 | labels.append(label)
42 | return img_paths, labels
43 |
44 |
45 | def parse_png(img_path, label, height=256, width=256, channel=3):
46 | """根据 img_path 读入图片并做相应处理"""
47 | # 从硬盘上读取图片
48 | img = tf.read_file(img_path)
49 | img_decoded = tf.image.decode_png(img, channels=channel)
50 | # resize
51 | img_resized = tf.image.resize_images(img_decoded, [height, width])
52 | # normalize
53 | img_norm = img_resized * 1.0 / 127.5 - 1.0
54 | return img_norm, label
55 |
56 |
57 | img_paths, labels = get_file_path()
58 | batch_size = 128
59 | dataset = tf.data.Dataset.from_tensor_slices((img_paths, labels))
60 | dataset = dataset.map(parse_png)
61 | print('parsing image', dataset)
62 | dataset = dataset.shuffle(buffer_size=5000).repeat().batch(batch_size)
63 | print('batch', dataset)
64 |
65 | # 生成迭代器
66 | iterator = dataset.make_one_shot_iterator()
67 | print(iterator)
68 |
69 | time0 = time.time()
70 | for count in range(100):
71 | X_batch, y_batch = sess.run(iterator.get_next())
72 | sys.stdout.write("\rloop {}, pass {:.2f}s".format(count, time.time() - time0))
73 | sys.stdout.flush()
74 |
--------------------------------------------------------------------------------
/example-python/Tutorial_10_2_image_data_2.py:
--------------------------------------------------------------------------------
1 | """Use tf.data.Dataset to create dataset for image(png) data.
2 | With TF Queue, shuffle data
3 |
4 | refer: https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/5_DataManagement/build_an_image_dataset.py
5 | """
6 |
7 | from __future__ import print_function
8 | from __future__ import division
9 | from __future__ import absolute_import
10 |
11 | import warnings
12 |
13 | warnings.filterwarnings('ignore') # 不打印 warning
14 | import tensorflow as tf
15 |
16 | # 设置GPU按需增长
17 | config = tf.ConfigProto()
18 | config.gpu_options.allow_growth = True
19 | sess = tf.Session(config=config)
20 |
21 | import numpy as np
22 | import sys
23 | import os
24 | import time
25 |
26 |
27 | def get_file_path(data_path='../data/sketchy_000000000000/'):
28 | """解析文件夹,获取每个文件的路径和标签。"""
29 | img_paths = list()
30 | labels = list()
31 | class_dirs = sorted(os.listdir(data_path))
32 | dict_class2id = dict()
33 | for i in range(len(class_dirs)):
34 | label = i
35 | class_dir = class_dirs[i]
36 | dict_class2id[class_dir] = label
37 | class_path = os.path.join(data_path, class_dir) # 每类的路径
38 | file_names = sorted(os.listdir(class_path))
39 | for file_name in file_names:
40 | file_path = os.path.join(class_path, file_name)
41 | img_paths.append(file_path)
42 | labels.append(label)
43 | return img_paths, labels
44 |
45 |
46 | def get_batch(img_paths, labels, batch_size=128, height=256, width=256, channel=3):
47 | """根据 img_path 读入图片并做相应处理"""
48 | # 从硬盘上读取图片
49 | img_paths = np.asarray(img_paths)
50 | labels = np.asarray(labels)
51 |
52 | img_paths = tf.convert_to_tensor(img_paths, dtype=tf.string)
53 | labels = tf.convert_to_tensor(labels, dtype=tf.int32)
54 | # Build a TF Queue, shuffle data
55 | image, label = tf.train.slice_input_producer([img_paths, labels], shuffle=True)
56 | # Read images from disk
57 | image = tf.read_file(image)
58 | image = tf.image.decode_jpeg(image, channels=channel)
59 | # Resize images to a common size
60 | image = tf.image.resize_images(image, [height, width])
61 | # Normalize
62 | image = image * 1.0 / 127.5 - 1.0
63 | # Create batches
64 | X_batch, y_batch = tf.train.batch([image, label], batch_size=batch_size,
65 | capacity=batch_size * 8,
66 | num_threads=4)
67 | return X_batch, y_batch
68 |
69 |
70 | img_paths, labels = get_file_path()
71 | X_batch, y_batch = get_batch(img_paths, labels)
72 |
73 | sess.run(tf.global_variables_initializer())
74 | tf.train.start_queue_runners(sess=sess)
75 |
76 | time0 = time.time()
77 | for count in range(100): # 11s for 100batch
78 | _X_batch, _y_batch = sess.run([X_batch, y_batch])
79 | sys.stdout.write("\rloop {}, pass {:.2f}s".format(count, time.time() - time0))
80 | sys.stdout.flush()
81 |
--------------------------------------------------------------------------------
/figs/conv_mnist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yongyehuang/Tensorflow-Tutorial/88b5cdbdf402a8ae7f65a540e5f81f3da8f45e7d/figs/conv_mnist.png
--------------------------------------------------------------------------------
/figs/graph2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yongyehuang/Tensorflow-Tutorial/88b5cdbdf402a8ae7f65a540e5f81f3da8f45e7d/figs/graph2.png
--------------------------------------------------------------------------------
/figs/lstm_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yongyehuang/Tensorflow-Tutorial/88b5cdbdf402a8ae7f65a540e5f81f3da8f45e7d/figs/lstm_8.png
--------------------------------------------------------------------------------
/figs/lstm_mnist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yongyehuang/Tensorflow-Tutorial/88b5cdbdf402a8ae7f65a540e5f81f3da8f45e7d/figs/lstm_mnist.png
--------------------------------------------------------------------------------
/models/README.md:
--------------------------------------------------------------------------------
1 | # TensorFlow 实战
2 | 下面的每个例子都是相互独立的,每个文件夹下面的代码都是可以单独运行的,不依赖于其他文件夹。
3 |
4 | ## m01_batch_normalization: Batch Normalization 的使用。
5 | 参考:[tensorflow中batch normalization的用法](https://www.cnblogs.com/hrlnw/p/7227447.html)
6 |
7 | ## m02_dcgan: 使用 DCGAN 生成二次元头像
8 | 参考:
9 | - [原论文:Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks](https://link.zhihu.com/?target=https%3A//arxiv.org/abs/1511.06434)
10 | - [GAN学习指南:从原理入门到制作生成Demo](https://zhuanlan.zhihu.com/p/24767059)
11 | - [代码:carpedm20/DCGAN-tensorflow](https://github.com/carpedm20/DCGAN-tensorflow)
12 | - [代码:aymericdamien/TensorFlow-Examples](https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/3_NeuralNetworks/dcgan.py)
13 |
14 | 这里的 notebook 和 .py 文件的内容是一样的。本例子和下面的 GAN 模型用的数据集也是用了[GAN学习指南:从原理入门到制作生成Demo](https://zhuanlan.zhihu.com/p/24767059) 的二次元头像,感觉这里例子比较有意思。如果想使用其他数据集的话,只需要把数据集换一下就行了。
15 |
16 | 下载链接: https://pan.baidu.com/s/1HBJpfkIFaGh0s2nfNXJsrA 密码: x39r
17 |
18 | 下载后把所有的图片解压到一个文件夹中,比如本例中是: `data_path = '../../data/anime/'`
19 |
20 | 运行: `python dcgan.py `
21 |
22 | ## m03_wgan: 使用 WGAN 生成二次元头像
23 | 这里的生成器和判别器我只实现了 DCGAN,没有实现 MLP. 如果想实现的话可以参考下面的两个例子。
24 | 参考:
25 | - [原论文:Wasserstein GAN](https://arxiv.org/pdf/1701.07875.pdf)
26 | - [代码:jiamings/wgan](https://github.com/jiamings/wgan)
27 | - [代码:Zardinality/WGAN-tensorflow](https://github.com/Zardinality/WGAN-tensorflow)
28 |
29 | 原版的 wgan: `python wgan.py `
30 |
31 | 改进的 wgan-gp: `python wgan_gp.py`
32 |
33 |
34 | ## m04_pix2pix: image-to-image GAN
35 |
36 |
37 |
--------------------------------------------------------------------------------
/models/m01_batch_normalization/README.md:
--------------------------------------------------------------------------------
1 | Batch Normalization 的使用。
2 |
3 | 参考:[tensorflow中batch normalization的用法](https://www.cnblogs.com/hrlnw/p/7227447.html)
4 |
5 |
--------------------------------------------------------------------------------
/models/m01_batch_normalization/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 |
--------------------------------------------------------------------------------
/models/m01_batch_normalization/mnist_cnn.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | """网络结构定义。
4 | 关于 tf.layers.batch_normalization() 的理解参考: [tensorflow中batch normalization的用法](https://www.cnblogs.com/hrlnw/p/7227447.html)
5 | """
6 |
7 | from __future__ import print_function, division, absolute_import
8 |
9 | import tensorflow as tf
10 |
11 |
12 | class Model(object):
13 | def __init__(self, settings):
14 | self.model_name = settings.model_name
15 | self.img_size = settings.img_size
16 | self.n_channel = settings.n_channel
17 | self.n_class = settings.n_class
18 | self.drop_rate = settings.drop_rate
19 | self.global_step = tf.Variable(0, trainable=False, name='Global_Step')
20 | self.learning_rate = tf.train.exponential_decay(settings.learning_rate,
21 | self.global_step, settings.decay_step,
22 | settings.decay_rate, staircase=True)
23 |
24 | self.conv_weight_initializer = tf.contrib.layers.xavier_initializer(uniform=True)
25 | self.conv_biases_initializer = tf.zeros_initializer()
26 | # 最后一个全连接层的初始化
27 | self.fc_weight_initializer = tf.truncated_normal_initializer(0.0, 0.005)
28 | self.fc_biases_initializer = tf.constant_initializer(0.1)
29 |
30 | # placeholders
31 | with tf.name_scope('Inputs'):
32 | self.X_inputs = tf.placeholder(tf.float32, [None, self.img_size, self.img_size, self.n_channel],
33 | name='X_inputs')
34 | self.y_inputs = tf.placeholder(tf.int64, [None], name='y_input')
35 |
36 | self.logits_train = self.inference(is_training=True, reuse=False)
37 | self.logits_test = self.inference(is_training=False, reuse=True)
38 |
39 | # 预测结果
40 | self.pred_lables = tf.argmax(self.logits_test, axis=1)
41 | self.pred_probas = tf.nn.softmax(self.logits_test)
42 | self.test_loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(
43 | labels=tf.cast(self.y_inputs, dtype=tf.int32), logits=self.logits_test))
44 | self.test_acc = tf.reduce_mean(tf.cast(tf.equal(self.pred_lables, self.y_inputs), tf.float32))
45 |
46 | # 训练结果
47 | self.train_lables = tf.argmax(self.logits_train, axis=1)
48 | self.train_loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(
49 | labels=tf.cast(self.y_inputs, dtype=tf.int32), logits=self.logits_train))
50 | self.train_acc = tf.reduce_mean(tf.cast(tf.equal(self.train_lables, self.y_inputs), tf.float32))
51 |
52 | self.optimizer = tf.train.AdamOptimizer(learning_rate=self.learning_rate)
53 | update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
54 | """
55 | **注意:** 下面一定要使用这样的方式来写。
56 | with tf.control_dependencies(update_ops) 这句话的意思是当运行下面的内容(train_op) 时,一定先执行 update_ops 的所有操作。
57 | 这里的 update_ops 在这里主要是更新 BN 层的滑动平均值和滑动方差。
58 |
59 | 除了 BN 层外,还有 center loss 中也采用这样的方式,在 center loss 中,update_ops 操作主要更新类中心向量。
60 | 因为之前在 center loss 犯过没更新 center 的错误,所以印象非常深刻。
61 | """
62 | with tf.control_dependencies(update_ops): # 这句话的意思是当运行下面的内容(train_op) 时,一定先执行 update_ops 的所有操作
63 | self.train_op = self.optimizer.minimize(self.train_loss, global_step=self.global_step)
64 |
65 | def inference(self, is_training, reuse=False):
66 | """带 BN 层的CNN """
67 | with tf.variable_scope('cnn', reuse=reuse):
68 | # 第一个卷积层 + BN + max_pooling
69 | conv1 = tf.layers.conv2d(self.X_inputs, filters=32, kernel_size=5, strides=1, padding='same',
70 | kernel_initializer=self.conv_weight_initializer, name='conv1')
71 | bn1 = tf.layers.batch_normalization(conv1, training=is_training, name='bn1')
72 | bn1 = tf.nn.relu(bn1) # 一般都是先经过 BN 层再加激活函数的
73 | pool1 = tf.layers.max_pooling2d(bn1, pool_size=2, strides=2, padding='same', name='pool1')
74 |
75 | # 第二个卷积层 + BN + max_pooling
76 | conv2 = tf.layers.conv2d(pool1, filters=64, kernel_size=5, strides=1, padding='same',
77 | kernel_initializer=self.conv_weight_initializer, name='conv2')
78 | bn2 = tf.layers.batch_normalization(conv2, training=is_training, name='bn2')
79 | bn2 = tf.nn.relu(bn2) # 一般都是先经过 BN 层再加激活函数的
80 | pool2 = tf.layers.max_pooling2d(bn2, pool_size=2, strides=2, padding='same', name='pool2')
81 |
82 | # 全连接,使用卷积来实现
83 | _, k_height, k_width, k_depth = pool2.get_shape().as_list()
84 | fc1 = tf.layers.conv2d(pool2, filters=1024, kernel_size=k_height, name='fc1')
85 | bn3 = tf.layers.batch_normalization(fc1, training=is_training, name='bn3')
86 | bn3 = tf.nn.relu(bn3)
87 |
88 | # dropout, 如果 is_training = False 就不会执行 dropout
89 | fc1_drop = tf.layers.dropout(bn3, rate=self.drop_rate, training=is_training)
90 |
91 | # 最后的输出层
92 | flatten_layer = tf.layers.flatten(fc1_drop)
93 | out = tf.layers.dense(flatten_layer, units=self.n_class)
94 | return out
95 |
96 | def inference2(self, is_training, reuse=False):
97 | """不带 BN 层的 CNN。"""
98 | with tf.variable_scope('cnn', reuse=reuse):
99 | # 第一个卷积层 + BN + max_pooling
100 | conv1 = tf.layers.conv2d(self.X_inputs, filters=32, kernel_size=5, strides=1, padding='same',
101 | activation=tf.nn.relu,
102 | kernel_initializer=self.conv_weight_initializer, name='conv1')
103 | pool1 = tf.layers.max_pooling2d(conv1, pool_size=2, strides=2, padding='same', name='pool1')
104 |
105 | # 第二个卷积层 + BN + max_pooling
106 | conv2 = tf.layers.conv2d(pool1, filters=64, kernel_size=5, strides=1, padding='same',
107 | activation=tf.nn.relu,
108 | kernel_initializer=self.conv_weight_initializer, name='conv2')
109 | pool2 = tf.layers.max_pooling2d(conv2, pool_size=2, strides=2, padding='same', name='pool2')
110 |
111 | # 全连接,使用卷积来实现
112 | _, k_height, k_width, k_depth = pool2.get_shape().as_list()
113 | fc1 = tf.layers.conv2d(pool2, filters=1024, kernel_size=k_height, activation=tf.nn.relu, name='fc1')
114 |
115 | # dropout, 如果 is_training = False 就不会执行 dropout
116 | fc1_drop = tf.layers.dropout(fc1, rate=self.drop_rate, training=is_training)
117 |
118 | # 最后的输出层
119 | flatten_layer = tf.layers.flatten(fc1_drop)
120 | out = tf.layers.dense(flatten_layer, units=self.n_class)
121 | return out
122 |
--------------------------------------------------------------------------------
/models/m01_batch_normalization/predict.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | from __future__ import print_function, division, absolute_import
4 |
5 | import tensorflow as tf
6 | import numpy as np
7 | import os
8 | import time
9 |
10 | from mnist_cnn import Model
11 |
12 |
13 | class Settings(object):
14 | def __init__(self):
15 | self.model_name = 'mnist_cnn'
16 | self.img_size = 28
17 | self.n_channel = 1
18 | self.n_class = 10
19 | self.drop_rate = 0.5
20 | self.learning_rate = 0.001
21 | self.decay_step = 2000
22 | self.decay_rate = 0.5
23 | self.training_steps = 10000
24 | self.batch_size = 100
25 |
26 | self.summary_path = 'summary/' + self.model_name + '/'
27 | self.ckpt_path = 'ckpt/' + self.model_name + '/'
28 |
29 | if not os.path.exists(self.summary_path):
30 | os.makedirs(self.summary_path)
31 | if not os.path.exists(self.ckpt_path):
32 | os.makedirs(self.ckpt_path)
33 |
34 |
35 | def main():
36 | """模型训练。"""
37 | from tensorflow.examples.tutorials.mnist import input_data
38 |
39 | mnist = input_data.read_data_sets("../../data/MNIST_data", one_hot=False)
40 | print(mnist.test.labels.shape)
41 | print(mnist.train.labels.shape)
42 |
43 | my_setting = Settings()
44 | with tf.variable_scope(my_setting.model_name):
45 | model = Model(my_setting)
46 |
47 | # 模型要保存的变量
48 | var_list = tf.trainable_variables()
49 | if model.global_step not in var_list:
50 | var_list.append(model.global_step)
51 | # 添加 BN 层的均值和方差
52 | global_vars = tf.global_variables()
53 | bn_moving_vars = [v for v in global_vars if 'moving_mean' in v.name]
54 | bn_moving_vars += [v for v in global_vars if 'moving_variance' in v.name]
55 | var_list += bn_moving_vars
56 | # 创建Saver
57 | saver = tf.train.Saver(var_list=var_list)
58 |
59 | config = tf.ConfigProto()
60 | config.gpu_options.allow_growth = True
61 | with tf.Session(config=config) as sess:
62 | if not os.path.exists(my_setting.ckpt_path + 'checkpoint'):
63 | print("There is no checkpoit, please check out.")
64 | exit()
65 | saver.restore(sess, tf.train.latest_checkpoint(my_setting.ckpt_path))
66 | tic = time.time()
67 | n_batch = len(mnist.test.labels) // my_setting.batch_size
68 | predict_labels = list()
69 | true_labels = list()
70 | for step in range(n_batch):
71 | X_batch, y_batch = mnist.test.next_batch(my_setting.batch_size, shuffle=False)
72 | X_batch = X_batch.reshape([-1, 28, 28, 1])
73 | pred_label, test_loss, test_acc = sess.run([model.pred_lables, model.test_loss, model.test_acc],
74 | feed_dict={model.X_inputs: X_batch, model.y_inputs: y_batch})
75 | predict_labels.append(pred_label)
76 | true_labels.append(y_batch)
77 | predict_labels = np.hstack(predict_labels)
78 | true_labels = np.hstack(true_labels)
79 | acc = np.sum(predict_labels == true_labels) / len(true_labels)
80 | print("Test sample number = {}, acc = {:.4f}, pass {:.2f}s".format(len(true_labels), acc, time.time() - tic))
81 |
82 |
83 | if __name__ == '__main__':
84 | main()
85 |
--------------------------------------------------------------------------------
/models/m01_batch_normalization/train.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | from __future__ import print_function, division, absolute_import
4 |
5 | import tensorflow as tf
6 | import os
7 | import time
8 |
9 | from mnist_cnn import Model
10 |
11 |
12 | class Settings(object):
13 | def __init__(self):
14 | self.model_name = 'mnist_cnn'
15 | self.img_size = 28
16 | self.n_channel = 1
17 | self.n_class = 10
18 | self.drop_rate = 0.5
19 | self.learning_rate = 0.001
20 | self.decay_step = 2000
21 | self.decay_rate = 0.5
22 | self.training_steps = 10000 # 耗时 90s
23 | self.batch_size = 100
24 |
25 | self.summary_path = 'summary/' + self.model_name + '/'
26 | self.ckpt_path = 'ckpt/' + self.model_name + '/'
27 |
28 | if not os.path.exists(self.summary_path):
29 | os.makedirs(self.summary_path)
30 | if not os.path.exists(self.ckpt_path):
31 | os.makedirs(self.ckpt_path)
32 |
33 |
34 | def main():
35 | """模型训练。"""
36 | from tensorflow.examples.tutorials.mnist import input_data
37 |
38 | mnist = input_data.read_data_sets("../../data/MNIST_data", one_hot=False)
39 | print(mnist.test.labels.shape)
40 | print(mnist.train.labels.shape)
41 |
42 | my_setting = Settings()
43 | with tf.variable_scope(my_setting.model_name):
44 | model = Model(my_setting)
45 |
46 | # 模型要保存的变量
47 | var_list = tf.trainable_variables()
48 | if model.global_step not in var_list:
49 | var_list.append(model.global_step)
50 | # 添加 BN 层的均值和方差
51 | global_vars = tf.global_variables()
52 | bn_moving_vars = [v for v in global_vars if 'moving_mean' in v.name]
53 | bn_moving_vars += [v for v in global_vars if 'moving_variance' in v.name]
54 | var_list += bn_moving_vars
55 | # 创建Saver
56 | saver = tf.train.Saver(var_list=var_list)
57 |
58 | config = tf.ConfigProto()
59 | config.gpu_options.allow_growth = True
60 | with tf.Session(config=config) as sess:
61 | print("initializing variables.")
62 | sess.run(tf.global_variables_initializer())
63 | sess.run(tf.local_variables_initializer())
64 | if os.path.exists(my_setting.ckpt_path + 'checkpoint'):
65 | print("restore checkpoint.")
66 | saver.restore(sess, tf.train.latest_checkpoint(my_setting.ckpt_path))
67 | tic = time.time()
68 | for step in range(my_setting.training_steps):
69 | if 0 == step % 100:
70 | X_batch, y_batch = mnist.train.next_batch(my_setting.batch_size, shuffle=True)
71 | X_batch = X_batch.reshape([-1, 28, 28, 1])
72 | _, g_step, train_loss, train_acc = sess.run(
73 | [model.train_op, model.global_step, model.train_loss, model.train_acc],
74 | feed_dict={model.X_inputs: X_batch, model.y_inputs: y_batch})
75 | X_batch, y_batch = mnist.test.next_batch(my_setting.batch_size, shuffle=True)
76 | X_batch = X_batch.reshape([-1, 28, 28, 1])
77 | test_loss, test_acc = sess.run([model.test_loss, model.test_acc],
78 | feed_dict={model.X_inputs: X_batch, model.y_inputs: y_batch})
79 | print(
80 | "Global_step={:.2f}, train_loss={:.2f}, train_acc={:.2f}; test_loss={:.2f}, test_acc={:.2f}; pass {:.2f}s".format(
81 | g_step, train_loss, train_acc, test_loss, test_acc, time.time() - tic
82 | ))
83 | else:
84 | X_batch, y_batch = mnist.train.next_batch(my_setting.batch_size, shuffle=True)
85 | X_batch = X_batch.reshape([-1, 28, 28, 1])
86 | sess.run([model.train_op], feed_dict={model.X_inputs: X_batch, model.y_inputs: y_batch})
87 | if 0 == (step + 1) % 1000:
88 | path = saver.save(sess, os.path.join(my_setting.ckpt_path, 'model.ckpt'),
89 | global_step=sess.run(model.global_step))
90 | print("Save model to {} ".format(path))
91 |
92 |
93 | if __name__ == '__main__':
94 | main()
95 |
--------------------------------------------------------------------------------
/models/m02_dcgan/README.md:
--------------------------------------------------------------------------------
1 | ## 使用 DCGAN 生成二次元头像
2 | 参考:
3 | - [原论文:Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks](https://link.zhihu.com/?target=https%3A//arxiv.org/abs/1511.06434)
4 | - [GAN学习指南:从原理入门到制作生成Demo](https://zhuanlan.zhihu.com/p/24767059)
5 | - [代码:carpedm20/DCGAN-tensorflow](https://github.com/carpedm20/DCGAN-tensorflow)
6 | - [代码:aymericdamien/TensorFlow-Examples](https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/3_NeuralNetworks/dcgan.py)
7 |
8 |
9 | 这里的 notebook 和 .py 文件的内容是一样的。
10 |
11 | 运行: `python dcgan.py ` 即可
--------------------------------------------------------------------------------
/models/m02_dcgan/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 |
--------------------------------------------------------------------------------
/models/m03_wgan/README.md:
--------------------------------------------------------------------------------
1 | ## 使用 WGAN 生成二次元头像
2 | 参考:
3 | - [原论文:Wasserstein GAN](https://arxiv.org/pdf/1701.07875.pdf)
4 | - [代码:jiamings/wgan](https://github.com/jiamings/wgan)
5 | - [代码:Zardinality/WGAN-tensorflow](https://github.com/Zardinality/WGAN-tensorflow)
6 |
7 |
8 | 运行: `python wgan.py ` 即可
9 |
10 | (wgan-gp.py 仍有bug...)
11 |
--------------------------------------------------------------------------------
/models/m03_wgan/wgan.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | from __future__ import print_function, division, absolute_import
4 |
5 | import warnings
6 |
7 | warnings.filterwarnings('ignore') # 不打印 warning
8 |
9 | import matplotlib
10 |
11 | matplotlib.use('Agg')
12 |
13 | import numpy as np
14 | import tensorflow as tf
15 | import matplotlib.pyplot as plt
16 |
17 | import time
18 | import os
19 | import sys
20 |
21 |
22 | # Generator Network
23 | # Input: Noise, Output: Image
24 | def generator(z, reuse=False):
25 | """输入噪声,输出图片。
26 | G网络中使用ReLU作为激活函数,最后一层使用tanh.
27 | 每一层都加 BN
28 | """
29 | with tf.variable_scope('Generator', reuse=reuse) as scope:
30 | # 按照论文的网络结构,第一层用一个全连接层
31 | x = tf.layers.dense(z, units=4 * 4 * 1024)
32 | x = tf.nn.relu(tf.layers.batch_normalization(x, training=True, name='bn1'))
33 | # Reshape to a 4-D array of images: (batch, height, width, channels)
34 | # 然后把全链接层的输出 reshape 成 4D 的 tensor
35 | x = tf.reshape(x, shape=[-1, 4, 4, 1024])
36 | print('tr_conv4:', x)
37 | # Deconvolution, image shape: (batch, 8, 8, 512)
38 | x = tf.layers.conv2d_transpose(x, 512, 5, strides=2, padding='same')
39 | x = tf.nn.relu(tf.layers.batch_normalization(x, training=True, name='bn2'))
40 | print('tr_conv3:', x)
41 | # Deconvolution, image shape: (batch, 16, 16, 256)
42 | x = tf.layers.conv2d_transpose(x, 256, 5, strides=2, padding='same')
43 | x = tf.nn.relu(tf.layers.batch_normalization(x, training=True, name='bn3'))
44 | print('tr_conv2:', x)
45 | # Deconvolution, image shape: (batch, 32, 32, 128)
46 | x = tf.layers.conv2d_transpose(x, 128, 5, strides=2, padding='same')
47 | x = tf.nn.relu(tf.layers.batch_normalization(x, training=True, name='bn4'))
48 | print('tr_conv1:', x)
49 | # Deconvolution, image shape: (batch, 64, 64, 3)
50 | x = tf.layers.conv2d_transpose(x, 3, 5, strides=2, padding='same')
51 | x = tf.nn.tanh(tf.layers.batch_normalization(x, training=True, name='bn5'))
52 | print('output_image:', x)
53 | return x
54 |
55 |
56 | def discriminator(x, reuse=False):
57 | """判别器。
58 | D网络中使用LeakyReLU作为激活函数。
59 | """
60 | with tf.variable_scope('Discriminator', reuse=reuse):
61 | # Typical convolutional neural network to classify images.
62 | print('input_image:', x)
63 | x = tf.layers.conv2d(x, 128, 5, strides=2, padding='same')
64 | x = tf.nn.leaky_relu(tf.layers.batch_normalization(x, training=True, name='bn1'))
65 | print('conv1:', x)
66 | x = tf.layers.conv2d(x, 256, 5, strides=2, padding='same')
67 | x = tf.nn.leaky_relu(tf.layers.batch_normalization(x, training=True, name='bn2'))
68 | print('conv2:', x)
69 | x = tf.layers.conv2d(x, 512, 5, strides=2, padding='same')
70 | x = tf.nn.leaky_relu(tf.layers.batch_normalization(x, training=True, name='bn3'))
71 | print('conv3:', x)
72 | x = tf.layers.conv2d(x, 1024, 5, strides=2, padding='same')
73 | x = tf.nn.leaky_relu(tf.layers.batch_normalization(x, training=True, name='bn4'))
74 | print('conv4:', x)
75 | x = tf.layers.flatten(x)
76 | x = tf.layers.dense(x, 1)
77 | print('output:', x)
78 | return x
79 |
80 |
81 | def get_file_path(data_path='../../data/anime/'):
82 | """解析文件夹,获取每个文件的路径和标签(在这个例子中所有的真实图片的标签都是1)。"""
83 | files = os.listdir(data_path)
84 | img_paths = [file for file in files if file.endswith('.jpg')]
85 | img_paths = list(map(lambda s: os.path.join(data_path, s), img_paths))
86 | labels = [1] * len(img_paths)
87 | return img_paths, labels
88 |
89 |
90 | def get_batch(img_paths, labels, batch_size=50, height=64, width=64, channel=3):
91 | """根据 img_path 读入图片并做相应处理"""
92 | # 从硬盘上读取图片
93 | img_paths = np.asarray(img_paths)
94 | labels = np.asarray(labels)
95 |
96 | img_paths = tf.convert_to_tensor(img_paths, dtype=tf.string)
97 | labels = tf.convert_to_tensor(labels, dtype=tf.int32)
98 | # Build a TF Queue, shuffle data
99 | image, label = tf.train.slice_input_producer([img_paths, labels], shuffle=True)
100 | # Read images from disk
101 | image = tf.read_file(image)
102 | image = tf.image.decode_jpeg(image, channels=channel)
103 | # Resize images to a common size
104 | image = tf.image.resize_images(image, [height, width])
105 | # Normalize
106 | image = image * 1.0 / 127.5 - 1.0
107 | # Create batches
108 | X_batch, y_batch = tf.train.batch([image, label], batch_size=batch_size,
109 | capacity=batch_size * 8,
110 | num_threads=4)
111 | return X_batch, y_batch
112 |
113 |
114 | def generate_img(sess, seed=3, show=False, save_path='generated_img'):
115 | """利用随机噪声生成图片, 并保存图片。"""
116 | if not os.path.exists(save_path):
117 | os.makedirs(save_path)
118 | step = sess.run(global_step)
119 | n_row, n_col = 5, 10
120 | f, a = plt.subplots(n_row, n_col, figsize=(n_col, n_row))
121 | np.random.seed(seed) # 每次都用相同的随机数便于对比结果
122 | z_batch = np.random.uniform(-1., 1., size=[n_row * n_col, noise_dim])
123 | fake_imgs = sess.run(gen_image, feed_dict={noise_input: z_batch})
124 | for i in range(n_row):
125 | # Noise input.
126 | for j in range(n_col):
127 | # Generate image from noise. Extend to 3 channels for matplot figure.
128 | img = (fake_imgs[n_col * i + j] + 1) / 2
129 | a[i][j].imshow(img)
130 | a[i][j].axis('off')
131 | f.savefig(os.path.join(save_path, '{}.png'.format(step)), dpi=100)
132 | if show:
133 | f.show()
134 |
135 |
136 | # 构建网络
137 | # Network Params
138 | image_dim = 64 # 头像的尺度
139 | n_channel = 3
140 | noise_dim = 100 # 输入噪声 z 的维度
141 |
142 | noise_input = tf.placeholder(tf.float32, shape=[None, noise_dim])
143 | real_img_input = tf.placeholder(tf.float32, shape=[None, image_dim, image_dim, n_channel])
144 |
145 | # 构造网络:生成器
146 | gen_image = generator(noise_input)
147 |
148 | # 判别器有两种输入,一种真实图像,一种生成器生成的假图像
149 | disc_real = discriminator(real_img_input) # 真图像输出的结果
150 | disc_fake = discriminator(gen_image, reuse=True)
151 |
152 | # 损失函数 (与DCGAN第1个改变)
153 | disc_loss = tf.reduce_mean(disc_fake - disc_real)
154 | gen_loss = tf.reduce_mean(-disc_fake)
155 |
156 | # 两个优化器
157 | # Build Optimizers (第2个改变)
158 | global_step = tf.Variable(0, trainable=False, name='Global_Step')
159 | optimizer_gen = tf.train.RMSPropOptimizer(learning_rate=5e-5)
160 | optimizer_disc = tf.train.RMSPropOptimizer(learning_rate=5e-5)
161 |
162 | # G 和 D 的参数
163 | gen_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope='Generator')
164 | # Discriminator Network Variables
165 | disc_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope='Discriminator')
166 |
167 | # 对于 D 的参数进行裁剪 (第3个改变,注意每次更新完 D 后都要执行裁剪)
168 | clipped_disc = [tf.assign(v, tf.clip_by_value(v, -0.01, 0.01)) for v in disc_vars]
169 |
170 | # Create training operations
171 | update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
172 | with tf.control_dependencies(update_ops): # 这句话的意思是当运行下面的内容(train_op) 时,一定先执行 update_ops 的所有操作
173 | train_gen = optimizer_gen.minimize(gen_loss, var_list=gen_vars, global_step=global_step)
174 | train_disc = optimizer_disc.minimize(disc_loss, var_list=disc_vars)
175 |
176 | # 模型要保存的变量
177 | # var_list = tf.global_variables() + tf.local_variables() # 这样保存所有变量不会出错,但是很多没必要的变量也保存了。414M 每个 ckpt
178 | var_list = tf.trainable_variables()
179 | if global_step not in var_list:
180 | var_list.append(global_step)
181 | # 添加 BN 层的均值和方差
182 | global_vars = tf.global_variables()
183 | bn_moving_vars = [v for v in global_vars if 'moving_mean' in v.name]
184 | bn_moving_vars += [v for v in global_vars if 'moving_variance' in v.name]
185 | var_list += bn_moving_vars
186 | # 创建Saver
187 |
188 | saver = tf.train.Saver(var_list=var_list)
189 |
190 | # 模型保存路径
191 | ckpt_path = 'ckpt/'
192 | if not os.path.exists(ckpt_path):
193 | os.makedirs(ckpt_path)
194 |
195 | # Training Params
196 | num_steps = 500000
197 | batch_size = 64
198 | d_iters = 5 # 更新 d_iters 次 D, 更新 1 次 G
199 |
200 | # 构建数据读取函数
201 | img_paths, labels = get_file_path()
202 | print("n_sample={}".format(len(img_paths)))
203 | get_X_batch, get_y_batch = get_batch(img_paths, labels, batch_size=batch_size)
204 |
205 | # Start training
206 | config = tf.ConfigProto()
207 | config.gpu_options.allow_growth = True
208 | with tf.Session(config=config) as sess:
209 | print("initializing variables.")
210 | sess.run(tf.global_variables_initializer())
211 | sess.run(tf.local_variables_initializer())
212 |
213 | if os.path.exists(ckpt_path + 'checkpoint'):
214 | print("restore checkpoint.")
215 | saver.restore(sess, tf.train.latest_checkpoint(ckpt_path))
216 |
217 | # 启动数据读取队列
218 | coord = tf.train.Coordinator()
219 | threads = tf.train.start_queue_runners(sess=sess, coord=coord)
220 |
221 |
222 | def get_batch():
223 | # 准备输入数据:真实图片
224 | X_batch, _ = sess.run([get_X_batch, get_y_batch]) # 本例中不管 _y_batch 的label
225 | # 准备噪声输入
226 | z_batch = np.random.uniform(-1., 1., size=[batch_size, noise_dim])
227 | # Training 这里的输入不需要 target
228 | feed_dict = {real_img_input: X_batch, noise_input: z_batch}
229 | return feed_dict
230 |
231 |
232 | try:
233 | tic = time.time()
234 | for i in range(1, num_steps + 1):
235 | # update 5 次 D,update 1 次 G
236 | dl = 0.0
237 | for _ in range(d_iters):
238 | _, _, dl = sess.run([train_disc, clipped_disc, disc_loss], feed_dict=get_batch())
239 | _, gl = sess.run([train_gen, gen_loss], feed_dict=get_batch())
240 |
241 | if i % 5 == 0:
242 | print(
243 | 'Step {}: Generator Loss: {:.2f}, Discriminator Loss: {:.2f}. Time passed {:.2f}s'.format(i, gl, dl,
244 | time.time() - tic))
245 | if i % 200 == 0: # 每训练 1000 step,生成一次图片
246 | generate_img(sess)
247 | path = saver.save(sess, os.path.join(ckpt_path, 'model.ckpt'), global_step=sess.run(global_step))
248 | print("Save model to {} ".format(path))
249 |
250 | generate_img(sess) # 最后一次生成图像
251 | except Exception as e:
252 | print(e)
253 | finally:
254 | coord.request_stop()
255 | coord.join(threads)
256 |
--------------------------------------------------------------------------------
/models/m04_pix2pix/README.md:
--------------------------------------------------------------------------------
1 | # pix2pix
2 |
3 | 代码来自:[affinelayer/pix2pix-tensorflow](https://github.com/affinelayer/pix2pix-tensorflow)
4 |
5 | pix2pix.py 是原代码。
6 |
7 | 原始的代码比较长,包括数据读取,模型结构,模型训练和测试都是放在一个文件中。
8 |
9 | 根据原始代码,整理成了四个文件:
10 | - utils.py: 数据读取和数据处理函数。
11 | - model.py: pix2pix GAN 模型代码。
12 | - train.py: 模型训练的代码。
13 | - test.py: 模型测试的代码。
14 |
15 | 运行:
16 | - 训练: `sh train.sh`
17 | - 测试:`sh test.sh`
18 |
--------------------------------------------------------------------------------
/models/m04_pix2pix/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 |
--------------------------------------------------------------------------------
/models/m04_pix2pix/test.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | """模型训练代码"""
4 | from __future__ import print_function, division, absolute_import
5 |
6 | import tensorflow as tf
7 | import numpy as np
8 | import argparse
9 | import os
10 | import json
11 | import glob
12 | import random
13 | import collections
14 | import math
15 | import time
16 | import sys
17 |
18 | sys.path.append('.')
19 | from utils import *
20 | from model import *
21 |
22 | parser = argparse.ArgumentParser()
23 | parser.add_argument("--input_dir", help="path to folder containing images")
24 | parser.add_argument("--mode", type=str, default="test", choices=["train", "test", "export"])
25 | parser.add_argument("--output_dir", required=True, help="where to put output files")
26 | parser.add_argument("--seed", type=int)
27 | parser.add_argument("--checkpoint", default=None,
28 | help="directory with checkpoint to resume training from or use for testing")
29 |
30 | parser.add_argument("--max_steps", type=int, help="number of training steps (0 to disable)")
31 | parser.add_argument("--max_epochs", type=int, help="number of training epochs")
32 | parser.add_argument("--summary_freq", type=int, default=100, help="update summaries every summary_freq steps")
33 | parser.add_argument("--progress_freq", type=int, default=50, help="display progress every progress_freq steps")
34 | parser.add_argument("--trace_freq", type=int, default=0, help="trace execution every trace_freq steps")
35 | parser.add_argument("--display_freq", type=int, default=0,
36 | help="write current training images every display_freq steps")
37 | parser.add_argument("--save_freq", type=int, default=5000, help="save model every save_freq steps, 0 to disable")
38 |
39 | parser.add_argument("--separable_conv", action="store_true", help="use separable convolutions in the generator")
40 | parser.add_argument("--aspect_ratio", type=float, default=1.0, help="aspect ratio of output images (width/height)")
41 | parser.add_argument("--lab_colorization", action="store_true",
42 | help="split input image into brightness (A) and color (B)")
43 | parser.add_argument("--batch_size", type=int, default=1, help="number of images in batch")
44 | parser.add_argument("--which_direction", type=str, default="AtoB", choices=["AtoB", "BtoA"])
45 | parser.add_argument("--ngf", type=int, default=64, help="number of generator filters in first conv layer")
46 | parser.add_argument("--ndf", type=int, default=64, help="number of discriminator filters in first conv layer")
47 | parser.add_argument("--scale_size", type=int, default=286, help="scale images to this size before cropping to 256x256")
48 | parser.add_argument("--flip", dest="flip", action="store_true", help="flip images horizontally")
49 | parser.add_argument("--no_flip", dest="flip", action="store_false", help="don't flip images horizontally")
50 | parser.set_defaults(flip=True)
51 | parser.add_argument("--lr", type=float, default=0.0002, help="initial learning rate for adam")
52 | parser.add_argument("--beta1", type=float, default=0.5, help="momentum term of adam")
53 | parser.add_argument("--l1_weight", type=float, default=100.0, help="weight on L1 term for generator gradient")
54 | parser.add_argument("--gan_weight", type=float, default=1.0, help="weight on GAN term for generator gradient")
55 |
56 | # export options
57 | parser.add_argument("--output_filetype", default="png", choices=["png", "jpeg"])
58 | a = parser.parse_args()
59 |
60 |
61 | def main():
62 | if a.seed is None:
63 | a.seed = random.randint(0, 2 ** 31 - 1)
64 |
65 | tf.set_random_seed(a.seed)
66 | np.random.seed(a.seed)
67 | random.seed(a.seed)
68 |
69 | if not os.path.exists(a.output_dir):
70 | os.makedirs(a.output_dir)
71 |
72 | if a.checkpoint is None:
73 | raise Exception("checkpoint required for test mode")
74 |
75 | # load some options from the checkpoint
76 | options = {"which_direction", "ngf", "ndf", "lab_colorization"}
77 | with open(os.path.join(a.checkpoint, "options.json")) as f:
78 | for key, val in json.loads(f.read()).items():
79 | if key in options:
80 | print("loaded", key, "=", val)
81 | setattr(a, key, val)
82 | # disable these features in test mode
83 | a.scale_size = CROP_SIZE
84 | a.flip = False
85 |
86 | # 打印参数
87 | for k, v in a._get_kwargs():
88 | print(k, "=", v)
89 |
90 | # 写入参数
91 | with open(os.path.join(a.output_dir, "options.json"), "w") as f:
92 | f.write(json.dumps(vars(a), sort_keys=True, indent=4))
93 |
94 | # 准备数据读入
95 | examples = load_examples(input_dir=a.input_dir, batch_size=a.batch_size, mode=a.mode,
96 | which_direction=a.which_direction)
97 | print("examples count = %d" % examples.count)
98 |
99 | # 创建模型
100 | # inputs and targets are [batch_size, height, width, channels]
101 | model = create_model(examples.inputs, examples.targets)
102 |
103 | # undo colorization splitting on images that we use for display/output
104 | if a.lab_colorization:
105 | if a.which_direction == "AtoB":
106 | # inputs is brightness, this will be handled fine as a grayscale image
107 | # need to augment targets and outputs with brightness
108 | targets = augment(examples.targets, examples.inputs)
109 | outputs = augment(model.outputs, examples.inputs)
110 | # inputs can be deprocessed normally and handled as if they are single channel
111 | # grayscale images
112 | inputs = deprocess(examples.inputs)
113 | elif a.which_direction == "BtoA":
114 | # inputs will be color channels only, get brightness from targets
115 | inputs = augment(examples.inputs, examples.targets)
116 | targets = deprocess(examples.targets)
117 | outputs = deprocess(model.outputs)
118 | else:
119 | raise Exception("invalid direction")
120 | else: # 把数据映射回到 (0, 1) 之间便于最后保存图片
121 | inputs = deprocess(examples.inputs)
122 | targets = deprocess(examples.targets)
123 | outputs = deprocess(model.outputs)
124 |
125 | def convert(image):
126 | """把原始的img改成整形的类型,自动的映射到 [0,255]间"""
127 | if a.aspect_ratio != 1.0: # 如果 aspect_ratio 不是 1 (不是方形)的话需要resize恢复大小
128 | # upscale to correct aspect ratio
129 | size = [CROP_SIZE, int(round(CROP_SIZE * a.aspect_ratio))]
130 | image = tf.image.resize_images(image, size=size, method=tf.image.ResizeMethod.BICUBIC)
131 |
132 | return tf.image.convert_image_dtype(image, dtype=tf.uint8, saturate=True)
133 |
134 | # reverse any processing on images so they can be written to disk or displayed to user
135 | with tf.name_scope("convert_inputs"):
136 | converted_inputs = convert(inputs)
137 |
138 | with tf.name_scope("convert_targets"):
139 | converted_targets = convert(targets)
140 |
141 | with tf.name_scope("convert_outputs"):
142 | converted_outputs = convert(outputs)
143 |
144 | with tf.name_scope("encode_images"):
145 | display_fetches = {
146 | "paths": examples.paths,
147 | "inputs": tf.map_fn(tf.image.encode_png, converted_inputs, dtype=tf.string, name="input_pngs"),
148 | "targets": tf.map_fn(tf.image.encode_png, converted_targets, dtype=tf.string, name="target_pngs"),
149 | "outputs": tf.map_fn(tf.image.encode_png, converted_outputs, dtype=tf.string, name="output_pngs"),
150 | }
151 |
152 | # summaries
153 | with tf.name_scope("inputs_summary"):
154 | tf.summary.image("inputs", converted_inputs)
155 |
156 | with tf.name_scope("targets_summary"):
157 | tf.summary.image("targets", converted_targets)
158 |
159 | with tf.name_scope("outputs_summary"):
160 | tf.summary.image("outputs", converted_outputs)
161 |
162 | with tf.name_scope("predict_real_summary"):
163 | tf.summary.image("predict_real", tf.image.convert_image_dtype(model.predict_real, dtype=tf.uint8))
164 |
165 | with tf.name_scope("predict_fake_summary"):
166 | tf.summary.image("predict_fake", tf.image.convert_image_dtype(model.predict_fake, dtype=tf.uint8))
167 |
168 | tf.summary.scalar("discriminator_loss", model.discrim_loss)
169 | tf.summary.scalar("generator_loss_GAN", model.gen_loss_GAN)
170 | tf.summary.scalar("generator_loss_L1", model.gen_loss_L1)
171 |
172 | for var in tf.trainable_variables():
173 | tf.summary.histogram(var.op.name + "/values", var)
174 |
175 | for grad, var in model.discrim_grads_and_vars + model.gen_grads_and_vars:
176 | tf.summary.histogram(var.op.name + "/gradients", grad)
177 |
178 | with tf.name_scope("parameter_count"):
179 | parameter_count = tf.reduce_sum([tf.reduce_prod(tf.shape(v)) for v in tf.trainable_variables()])
180 |
181 | saver = tf.train.Saver(max_to_keep=1)
182 |
183 | logdir = a.output_dir if (a.trace_freq > 0 or a.summary_freq > 0) else None
184 | sv = tf.train.Supervisor(logdir=logdir, save_summaries_secs=0, saver=None)
185 | with sv.managed_session() as sess:
186 | print("parameter_count =", sess.run(parameter_count))
187 |
188 | if a.checkpoint is not None:
189 | print("loading model from checkpoint")
190 | checkpoint = tf.train.latest_checkpoint(a.checkpoint)
191 | saver.restore(sess, checkpoint)
192 |
193 | max_steps = 2 ** 32
194 | if a.max_epochs is not None:
195 | max_steps = examples.steps_per_epoch * a.max_epochs
196 | if a.max_steps is not None:
197 | max_steps = a.max_steps
198 |
199 | # testing
200 | # at most, process the test data once
201 | start = time.time()
202 | max_steps = min(examples.steps_per_epoch, max_steps)
203 | for step in range(max_steps):
204 | results = sess.run(display_fetches)
205 | filesets = save_images(results, output_dir=a.output_dir)
206 | for i, f in enumerate(filesets):
207 | print("evaluated image", f["name"])
208 | index_path = append_index(filesets, output_dir=a.output_dir)
209 | print("wrote index at", index_path)
210 | print("rate", (time.time() - start) / max_steps)
211 |
212 |
213 |
214 | if __name__ == '__main__':
215 | main()
--------------------------------------------------------------------------------
/models/m04_pix2pix/test.sh:
--------------------------------------------------------------------------------
1 | python3 test.py \
2 | --mode test \
3 | --output_dir "facades_test" \
4 | --input_dir "../../data/facades/test" \
5 | --checkpoint "facades_train" \
6 | --which_direction BtoA
7 |
--------------------------------------------------------------------------------
/models/m04_pix2pix/train.sh:
--------------------------------------------------------------------------------
1 | python3 train.py \
2 | --mode train \
3 | --output_dir "facades_train" \
4 | --max_epochs 200 \
5 | --input_dir "../../data/facades/train" \
6 | --which_direction BtoA
7 |
--------------------------------------------------------------------------------
/utils/u01_logging/logging1.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | import logging
4 | import logging.handlers
5 |
6 | """the use of logging.
7 | refer: http://blog.csdn.net/chosen0ne/article/details/7319306
8 |
9 | - handler:将日志记录(log record)发送到合适的目的地(destination),比如文件,socket等。
10 | 一个logger对象可以通过addHandler方法添加0到多个handler,每个handler又可以定义不同日志级别,以实现日志分级过滤显示。
11 | - formatter:指定日志记录输出的具体格式。formatter的构造方法需要两个参数:消息的格式字符串和日期字符串,这两个参数都是可选的。
12 | """
13 |
14 | # 1.保存至日志文件
15 | LOG_FILE = 'training.log'
16 | # 2.设置日志,maxBytes设置文件大小,backpuCount设置文件数量
17 | handler = logging.handlers.RotatingFileHandler(LOG_FILE, maxBytes=1024 * 1024, backupCount=5) # 实例化handler
18 | # 3.设置消息输出格式
19 | fmt = '%(asctime)s - %(filename)s:%(lineno)s - %(name)s - %(message)s'
20 |
21 | formatter = logging.Formatter(fmt) # 实例化formatter
22 | handler.setFormatter(formatter) # 为handler添加formatter
23 |
24 | logger = logging.getLogger('train') # 获取名为tst的logger
25 | logger.addHandler(handler) # 为logger添加handler
26 | logger.setLevel(logging.DEBUG)
27 |
28 | for i in range(10):
29 | logger.info('first info message %d' % i)
30 | logger.debug('first debug message %d' % i)
31 |
--------------------------------------------------------------------------------
/utils/u01_logging/training.log:
--------------------------------------------------------------------------------
1 | 2017-09-10 22:21:16,411 - logging1.py:28 - train - first info message 0
2 | 2017-09-10 22:21:16,411 - logging1.py:29 - train - first debug message 0
3 | 2017-09-10 22:21:16,412 - logging1.py:28 - train - first info message 1
4 | 2017-09-10 22:21:16,412 - logging1.py:29 - train - first debug message 1
5 | 2017-09-10 22:21:16,412 - logging1.py:28 - train - first info message 2
6 | 2017-09-10 22:21:16,412 - logging1.py:29 - train - first debug message 2
7 | 2017-09-10 22:21:16,412 - logging1.py:28 - train - first info message 3
8 | 2017-09-10 22:21:16,412 - logging1.py:29 - train - first debug message 3
9 | 2017-09-10 22:21:16,412 - logging1.py:28 - train - first info message 4
10 | 2017-09-10 22:21:16,412 - logging1.py:29 - train - first debug message 4
11 | 2017-09-10 22:21:16,412 - logging1.py:28 - train - first info message 5
12 | 2017-09-10 22:21:16,412 - logging1.py:29 - train - first debug message 5
13 | 2017-09-10 22:21:16,413 - logging1.py:28 - train - first info message 6
14 | 2017-09-10 22:21:16,413 - logging1.py:29 - train - first debug message 6
15 | 2017-09-10 22:21:16,413 - logging1.py:28 - train - first info message 7
16 | 2017-09-10 22:21:16,413 - logging1.py:29 - train - first debug message 7
17 | 2017-09-10 22:21:16,413 - logging1.py:28 - train - first info message 8
18 | 2017-09-10 22:21:16,413 - logging1.py:29 - train - first debug message 8
19 | 2017-09-10 22:21:16,413 - logging1.py:28 - train - first info message 9
20 | 2017-09-10 22:21:16,413 - logging1.py:29 - train - first debug message 9
21 |
--------------------------------------------------------------------------------
/utils/u02_tfrecord/README.md:
--------------------------------------------------------------------------------
1 | ### 使用 tfrecord 打包数据
2 | 这里主要针对的是 tf1.2 及以前的版本,tf1.3和tf1.4 提供了新的 data API。等这个月把手头的实验做完更新后再尝试新的接口。
3 |
4 | #### 数据维度相同
5 | 比如固定大小的矩阵,数组,图片等,比较简单,可以使用 tf.train.Example() 进行打包。参考:
6 | - tfrecord-1-numpy-writer.py
7 | - tfrecord-1-numpy-reader.py
8 | - tfrecord-1-numpy-reader_without_shuffle.py
9 |
10 | #### 数据维度不同(变长序列)
11 | 比如文本数据,每个序列的长度都是不固定的。可以使用 tf.train.SequenceExample() 进行打包。参考:
12 | - tfrecord-2-seqence-writer.py
13 | - tfrecord-2-seqence-reader.py
14 |
15 | [sequence_example_lib.py](https://github.com/tensorflow/magenta/blob/master/magenta/common/sequence_example_lib.py)是官方提供一个例子,但是在官方文档中并没有提到这个例子,我也是费了好大力气才找到这个例子。tf1.3增加了 Dataset API,但是在 tf1.2 中的文档中,却没有一点说明,巨坑。
16 |
17 | 在 tf.train.Example() 中,通过 tf.train.Features() 把数据写入 tfrecord 文件。这些数据必须是具有相同的长度的**数组**,如果我们需要写入的是矩阵的话,我一般都是先reshape成 1D 的数组再进行写入。在读取数据的时候可以使用 tf.train.shuffle_batch() 直接读取数据。在读取数据的时候一定要明确指定数组的维度。
18 |
19 | 在 tf.train.SequenceExample(),包括 context 和 feature_lists 两部分。context 和 tf.train.Example() 作用类似,用于保存维度固定的数据。feature_lists 用于保存任意长度的序列数据。具体的写法参照 Tutorial-tfrecord-seqence-writer.py
20 |
21 | 在数据读取的时候,不能简单的通过 tf.train.shuffle_batch() 进行 batch 读取,因为我们没法给定数据的维度。解决方法是使用 tf.train.batch() 来进行读取,而且 **dynamic_pad 参数必须为 True,自动把batch中的数据填充0至一样的长度。** (所以在定义词典的时候,一定要把 '' 的 id 对应为 0.)由于 batch() 函数不能进行 shuffle,所以我们只能借助 tf.RandomShuffleQueue() 函数维护一个队列来实现 shuffle。
22 |
23 |
24 | #### 图片数据
25 | - tfrecord-3-image-writer.py
26 | - tfrecord-3-image-reader.py
27 |
--------------------------------------------------------------------------------
/utils/u02_tfrecord/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 |
--------------------------------------------------------------------------------
/utils/u02_tfrecord/reader_without_shuffle.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {
7 | "collapsed": false,
8 | "scrolled": false
9 | },
10 | "outputs": [
11 | {
12 | "name": "stdout",
13 | "output_type": "stream",
14 | "text": [
15 | "Tensor(\"tfrecord_data/ParseSingleExample/Squeeze_X:0\", shape=(2,), dtype=float32)\n",
16 | "Tensor(\"tfrecord_data/ParseSingleExample/Squeeze_y:0\", shape=(), dtype=int64)\n",
17 | "** batch 0\n",
18 | "('_y_batch:', array([0, 1, 2, 3]))\n",
19 | "** batch 1\n",
20 | "('_y_batch:', array([4, 5, 6, 7]))\n",
21 | "** batch 2\n",
22 | "('_y_batch:', array([ 8, 9, 10, 11]))\n",
23 | "** batch 3\n",
24 | "('_y_batch:', array([12, 13, 15, 14]))\n",
25 | "** batch 4\n",
26 | "('_y_batch:', array([17, 16, 19, 18]))\n",
27 | "** batch 5\n",
28 | "('_y_batch:', array([20, 21, 22, 23]))\n",
29 | "** batch 6\n",
30 | "('_y_batch:', array([24, 25, 26, 27]))\n",
31 | "** batch 7\n",
32 | "('_y_batch:', array([29, 28, 30, 31]))\n",
33 | "** batch 8\n",
34 | "('_y_batch:', array([33, 32, 34, 35]))\n",
35 | "** batch 9\n",
36 | "('_y_batch:', array([36, 37, 38, 39]))\n",
37 | "** batch 10\n",
38 | "('_y_batch:', array([40, 42, 41, 44]))\n",
39 | "** batch 11\n",
40 | "('_y_batch:', array([43, 46, 45, 47]))\n",
41 | "** batch 12\n",
42 | "('_y_batch:', array([48, 0, 49, 2]))\n",
43 | "** batch 13\n",
44 | "('_y_batch:', array([1, 3, 4, 6]))\n",
45 | "** batch 14\n",
46 | "('_y_batch:', array([5, 8, 7, 9]))\n",
47 | "** batch 15\n",
48 | "('_y_batch:', array([10, 12, 11, 13]))\n",
49 | "** batch 16\n",
50 | "('_y_batch:', array([14, 16, 15, 17]))\n",
51 | "** batch 17\n",
52 | "('_y_batch:', array([18, 20, 19, 21]))\n",
53 | "** batch 18\n",
54 | "('_y_batch:', array([22, 23, 24, 26]))\n",
55 | "** batch 19\n",
56 | "('_y_batch:', array([25, 27, 28, 29]))\n",
57 | "** batch 20\n",
58 | "('_y_batch:', array([30, 31, 32, 33]))\n",
59 | "** batch 21\n",
60 | "('_y_batch:', array([35, 34, 37, 36]))\n",
61 | "** batch 22\n",
62 | "('_y_batch:', array([39, 38, 41, 40]))\n",
63 | "** batch 23\n",
64 | "('_y_batch:', array([43, 42, 44, 45]))\n",
65 | "** batch 24\n",
66 | "('_y_batch:', array([46, 47, 49, 48]))\n",
67 | "** batch 25\n",
68 | "('_y_batch:', array([1, 0, 2, 3]))\n",
69 | "** batch 26\n",
70 | "('_y_batch:', array([4, 5, 6, 7]))\n",
71 | "** batch 27\n",
72 | "('_y_batch:', array([ 8, 9, 10, 11]))\n",
73 | "** batch 28\n",
74 | "('_y_batch:', array([12, 13, 15, 14]))\n",
75 | "** batch 29\n",
76 | "('_y_batch:', array([17, 16, 19, 18]))\n",
77 | "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 14, 17, 16, 19, 18, 20, 21, 22, 23, 24, 25, 26, 27, 29, 28, 30, 31, 33, 32, 34, 35, 36, 37, 38, 39, 40, 42, 41, 44, 43, 46, 45, 47, 48, 0, 49, 2, 1, 3, 4, 6, 5, 8, 7, 9, 10, 12, 11, 13, 14, 16, 15, 17, 18, 20, 19, 21, 22, 23, 24, 26, 25, 27, 28, 29, 30, 31, 32, 33, 35, 34, 37, 36, 39, 38, 41, 40, 43, 42, 44, 45, 46, 47, 49, 48, 1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 14, 17, 16, 19, 18]\n"
78 | ]
79 | }
80 | ],
81 | "source": [
82 | "# -*- coding:utf-8 -*- \n",
83 | "\n",
84 | "import tensorflow as tf\n",
85 | "\n",
86 | "'''read data.\n",
87 | "without shuffle, for validation or test data.\n",
88 | "'''\n",
89 | "\n",
90 | "# output file name string to a queue\n",
91 | "with tf.variable_scope('tfrecord_data'):\n",
92 | " filename_queue = tf.train.string_input_producer(['../data/test1.tfrecord', '../data/test2.tfrecord'], num_epochs=None,\n",
93 | " shuffle=False)\n",
94 | " # create a reader from file queue\n",
95 | " reader = tf.TFRecordReader()\n",
96 | " _, serialized_example = reader.read(filename_queue)\n",
97 | " # get feature from serialized example\n",
98 | " features = tf.parse_single_example(serialized_example,\n",
99 | " features={\n",
100 | " 'X': tf.FixedLenFeature([2], tf.float32),\n",
101 | " 'y': tf.FixedLenFeature([], tf.int64)}\n",
102 | " )\n",
103 | " X_out = features['X']\n",
104 | " y_out = features['y']\n",
105 | "\n",
106 | " print(X_out)\n",
107 | " print(y_out)\n",
108 | " X_batch, y_batch = tf.train.batch([X_out, y_out],\n",
109 | " batch_size=4,\n",
110 | " capacity=10,\n",
111 | " num_threads=2,\n",
112 | " allow_smaller_final_batch=True)\n",
113 | " new_ops = [v for v in tf.global_variables() if v.name.startswith(vs.name + '/')]\n",
114 | " \n",
115 | "sess = tf.Session()\n",
116 | "# init = tf.global_variables_initializer()\n",
117 | "init = tf.group(tf.global_variables_initializer(),\n",
118 | " tf.local_variables_initializer())\n",
119 | "sess.run(init)\n",
120 | "\n",
121 | "coord = tf.train.Coordinator()\n",
122 | "threads = tf.train.start_queue_runners(sess=sess, coord=coord)\n",
123 | "y_outputs = list()\n",
124 | "for i in xrange(30):\n",
125 | " try:\n",
126 | " _X_batch, _y_batch = sess.run([X_batch, y_batch])\n",
127 | " print('** batch %d' % i)\n",
128 | " print('_y_batch:', _y_batch)\n",
129 | " y_outputs.extend(_y_batch.tolist())\n",
130 | " except tf.errors.OutOfRangeError, e:\n",
131 | " print(e.message)\n",
132 | " break\n",
133 | "print(y_outputs)\n",
134 | "\n",
135 | "coord.request_stop()\n",
136 | "coord.join(threads)"
137 | ]
138 | },
139 | {
140 | "cell_type": "code",
141 | "execution_count": 7,
142 | "metadata": {
143 | "collapsed": true
144 | },
145 | "outputs": [],
146 | "source": [
147 | "tf.train.Coordinator?"
148 | ]
149 | },
150 | {
151 | "cell_type": "code",
152 | "execution_count": 6,
153 | "metadata": {
154 | "collapsed": false
155 | },
156 | "outputs": [
157 | {
158 | "name": "stdout",
159 | "output_type": "stream",
160 | "text": [
161 | "FIFOQueue '_2_tfrecord_data/batch/fifo_queue' is closed and has insufficient elements (requested 4, current size 0)\n",
162 | "\t [[Node: tfrecord_data/batch = QueueDequeueUpToV2[component_types=[DT_FLOAT, DT_INT64], timeout_ms=-1, _device=\"/job:localhost/replica:0/task:0/cpu:0\"](tfrecord_data/batch/fifo_queue, tfrecord_data/batch/n)]]\n",
163 | "[]\n",
164 | "[]\n"
165 | ]
166 | }
167 | ],
168 | "source": [
169 | "y_outputs = list()\n",
170 | "sess.run(tf.variables_initializer(new_ops))\n",
171 | "coord1 = tf.train.Coordinator()\n",
172 | "threads = tf.train.start_queue_runners(sess=sess, coord=coord1)\n",
173 | "for i in xrange(30):\n",
174 | " try:\n",
175 | " _X_batch, _y_batch = sess.run([X_batch, y_batch])\n",
176 | " print('** batch %d' % i)\n",
177 | " print('_y_batch:', _y_batch)\n",
178 | " y_outputs.extend(_y_batch.tolist())\n",
179 | " except tf.errors.OutOfRangeError, e:\n",
180 | " print(e.message)\n",
181 | " break\n",
182 | "print(y_outputs)\n",
183 | "print(sorted(y_outputs))"
184 | ]
185 | },
186 | {
187 | "cell_type": "code",
188 | "execution_count": null,
189 | "metadata": {
190 | "collapsed": true
191 | },
192 | "outputs": [],
193 | "source": []
194 | }
195 | ],
196 | "metadata": {
197 | "anaconda-cloud": {},
198 | "kernelspec": {
199 | "display_name": "Python [conda root]",
200 | "language": "python",
201 | "name": "conda-root-py"
202 | },
203 | "language_info": {
204 | "codemirror_mode": {
205 | "name": "ipython",
206 | "version": 2
207 | },
208 | "file_extension": ".py",
209 | "mimetype": "text/x-python",
210 | "name": "python",
211 | "nbconvert_exporter": "python",
212 | "pygments_lexer": "ipython2",
213 | "version": "2.7.12"
214 | }
215 | },
216 | "nbformat": 4,
217 | "nbformat_minor": 1
218 | }
219 |
--------------------------------------------------------------------------------
/utils/u02_tfrecord/sequence_example_lib.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | # Copyright 2016 Google Inc. All Rights Reserved.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | """Utility functions for working with tf.train.SequenceExamples.
17 | https://github.com/tensorflow/magenta/blob/master/magenta/common/sequence_example_lib.py
18 | """
19 |
20 | import math
21 | import tensorflow as tf
22 |
23 | QUEUE_CAPACITY = 500
24 | SHUFFLE_MIN_AFTER_DEQUEUE = QUEUE_CAPACITY // 5
25 |
26 |
27 | def make_sequence_example(inputs, labels):
28 | """Returns a SequenceExample for the given inputs and labels.
29 |
30 | Args:
31 | inputs: A list of input vectors. Each input vector is a list of floats.
32 | labels: A list of ints.
33 |
34 | Returns:
35 | A tf.train.SequenceExample containing inputs and labels.
36 | """
37 | input_features = [
38 | tf.train.Feature(float_list=tf.train.FloatList(value=input_))
39 | for input_ in inputs]
40 | label_features = [
41 | tf.train.Feature(int64_list=tf.train.Int64List(value=[label]))
42 | for label in labels]
43 | feature_list = {
44 | 'inputs': tf.train.FeatureList(feature=input_features),
45 | 'labels': tf.train.FeatureList(feature=label_features)
46 | }
47 | feature_lists = tf.train.FeatureLists(feature_list=feature_list)
48 | return tf.train.SequenceExample(feature_lists=feature_lists)
49 |
50 |
51 | def _shuffle_inputs(input_tensors, capacity, min_after_dequeue, num_threads):
52 | """Shuffles tensors in `input_tensors`, maintaining grouping."""
53 | shuffle_queue = tf.RandomShuffleQueue(
54 | capacity, min_after_dequeue, dtypes=[t.dtype for t in input_tensors])
55 | enqueue_op = shuffle_queue.enqueue(input_tensors)
56 | runner = tf.train.QueueRunner(shuffle_queue, [enqueue_op] * num_threads)
57 | tf.train.add_queue_runner(runner)
58 |
59 | output_tensors = shuffle_queue.dequeue()
60 |
61 | for i in range(len(input_tensors)):
62 | output_tensors[i].set_shape(input_tensors[i].shape)
63 |
64 | return output_tensors
65 |
66 |
67 | def get_padded_batch(file_list, batch_size, input_size,
68 | num_enqueuing_threads=4, shuffle=False):
69 | """Reads batches of SequenceExamples from TFRecords and pads them.
70 |
71 | Can deal with variable length SequenceExamples by padding each batch to the
72 | length of the longest sequence with zeros.
73 |
74 | Args:
75 | file_list: A list of paths to TFRecord files containing SequenceExamples.
76 | batch_size: The number of SequenceExamples to include in each batch.
77 | input_size: The size of each input vector. The returned batch of inputs
78 | will have a shape [batch_size, num_steps, input_size].
79 | num_enqueuing_threads: The number of threads to use for enqueuing
80 | SequenceExamples.
81 | shuffle: Whether to shuffle the batches.
82 |
83 | Returns:
84 | inputs: A tensor of shape [batch_size, num_steps, input_size] of floats32s.
85 | labels: A tensor of shape [batch_size, num_steps] of int64s.
86 | lengths: A tensor of shape [batch_size] of int32s. The lengths of each
87 | SequenceExample before padding.
88 | Raises:
89 | ValueError: If `shuffle` is True and `num_enqueuing_threads` is less than 2.
90 | """
91 | file_queue = tf.train.string_input_producer(file_list)
92 | reader = tf.TFRecordReader()
93 | _, serialized_example = reader.read(file_queue)
94 |
95 | sequence_features = {
96 | 'inputs': tf.FixedLenSequenceFeature(shape=[input_size],
97 | dtype=tf.float32),
98 | 'labels': tf.FixedLenSequenceFeature(shape=[],
99 | dtype=tf.int64)}
100 |
101 | _, sequence = tf.parse_single_sequence_example(
102 | serialized_example, sequence_features=sequence_features)
103 |
104 | length = tf.shape(sequence['inputs'])[0] # 序列长度
105 | input_tensors = [sequence['inputs'], sequence['labels'], length]
106 |
107 | if shuffle:
108 | if num_enqueuing_threads < 2:
109 | raise ValueError(
110 | '`num_enqueuing_threads` must be at least 2 when shuffling.')
111 | shuffle_threads = int(math.ceil(num_enqueuing_threads) / 2.)
112 |
113 | # Since there may be fewer records than SHUFFLE_MIN_AFTER_DEQUEUE, take the
114 | # minimum of that number and the number of records.
115 | min_after_dequeue = count_records(
116 | file_list, stop_at=SHUFFLE_MIN_AFTER_DEQUEUE)
117 | input_tensors = _shuffle_inputs(
118 | input_tensors, capacity=QUEUE_CAPACITY,
119 | min_after_dequeue=min_after_dequeue,
120 | num_threads=shuffle_threads)
121 |
122 | num_enqueuing_threads -= shuffle_threads
123 |
124 | tf.logging.info(input_tensors)
125 | return tf.train.batch(
126 | input_tensors,
127 | batch_size=batch_size,
128 | capacity=QUEUE_CAPACITY,
129 | num_threads=num_enqueuing_threads,
130 | dynamic_pad=True,
131 | allow_smaller_final_batch=False)
132 |
133 |
134 | def count_records(file_list, stop_at=None):
135 | """Counts number of records in files from `file_list` up to `stop_at`.
136 |
137 | Args:
138 | file_list: List of TFRecord files to count records in.
139 | stop_at: Optional number of records to stop counting at.
140 |
141 | Returns:
142 | Integer number of records in files from `file_list` up to `stop_at`.
143 | """
144 | num_records = 0
145 | for tfrecord_file in file_list:
146 | tf.logging.info('Counting records in %s.', tfrecord_file)
147 | for _ in tf.python_io.tf_record_iterator(tfrecord_file):
148 | num_records += 1
149 | if stop_at and num_records >= stop_at:
150 | tf.logging.info('Number of records is at least %d.', num_records)
151 | return num_records
152 | tf.logging.info('Total records: %d', num_records)
153 | return num_records
154 |
155 |
156 | def flatten_maybe_padded_sequences(maybe_padded_sequences, lengths=None):
157 | """Flattens the batch of sequences, removing padding (if applicable).
158 |
159 | Args:
160 | maybe_padded_sequences: A tensor of possibly padded sequences to flatten,
161 | sized `[N, M, ...]` where M = max(lengths).
162 | lengths: Optional length of each sequence, sized `[N]`. If None, assumes no
163 | padding.
164 |
165 | Returns:
166 | flatten_maybe_padded_sequences: The flattened sequence tensor, sized
167 | `[sum(lengths), ...]`.
168 | """
169 |
170 | def flatten_unpadded_sequences():
171 | # The sequences are equal length, so we should just flatten over the first
172 | # two dimensions.
173 | return tf.reshape(maybe_padded_sequences,
174 | [-1] + maybe_padded_sequences.shape.as_list()[2:])
175 |
176 | if lengths is None:
177 | return flatten_unpadded_sequences()
178 |
179 | def flatten_padded_sequences():
180 | indices = tf.where(tf.sequence_mask(lengths))
181 | return tf.gather_nd(maybe_padded_sequences, indices)
182 |
183 | return tf.cond(
184 | tf.equal(tf.reduce_min(lengths), tf.shape(maybe_padded_sequences)[1]),
185 | flatten_unpadded_sequences,
186 | flatten_padded_sequences)
187 |
--------------------------------------------------------------------------------
/utils/u02_tfrecord/tfrecord_1_numpy_reader.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | import tensorflow as tf
4 | import os
5 | import sys
6 | import time
7 |
8 | '''read data
9 | 从 tfrecord 文件中读取数据,对应数据的格式为固定shape的数据。
10 | '''
11 |
12 | # **1.把所有的 tfrecord 文件名列表写入队列中
13 | tfrecord_dir = 'tfrecord/numpy/'
14 | tfrecord_files = os.listdir(tfrecord_dir)
15 | tfrecord_files = list(map(lambda s: os.path.join(tfrecord_dir, s), tfrecord_files))
16 |
17 | filename_queue = tf.train.string_input_producer(tfrecord_files, num_epochs=None, shuffle=True)
18 |
19 | # **2.创建一个读取器
20 | reader = tf.TFRecordReader()
21 | _, serialized_example = reader.read(filename_queue)
22 | # **3.根据你写入的格式对应说明读取的格式
23 | features = tf.parse_single_example(serialized_example,
24 | features={
25 | 'X': tf.FixedLenFeature([784], tf.float32), # 注意如果不是标量,需要说明数组长度
26 | 'y': tf.FixedLenFeature([], tf.int64)} # 而标量就不用说明
27 | )
28 | X_out = features['X']
29 | y_out = features['y']
30 |
31 | print(X_out)
32 | print(y_out)
33 | # **4.通过 tf.train.shuffle_batch 或者 tf.train.batch 函数读取数据
34 | """
35 | 在shuffle_batch 函数中,有几个参数的作用如下:
36 | capacity: 队列的容量,容量越大的话,shuffle 得就更加均匀,但是占用内存也会更多
37 | num_threads: 读取进程数,进程越多,读取速度相对会快些,根据个人配置决定
38 | min_after_dequeue: 保证队列中最少的数据量。
39 | 假设我们设定了队列的容量C,在我们取走部分数据m以后,队列中只剩下了 (C-m) 个数据。然后队列会不断补充数据进来,
40 | 如果后勤供应(CPU性能,线程数量)补充速度慢的话,那么下一次取数据的时候,可能才补充了一点点,如果补充完后的数据个数少于
41 | min_after_dequeue 的话,不能取走数据,得继续等它补充超过 min_after_dequeue 个样本以后才让取走数据。
42 | 这样做保证了队列中混着足够多的数据,从而才能保证 shuffle 取值更加随机。
43 | 但是,min_after_dequeue 不能设置太大,否则补充时间很长,读取速度会很慢。
44 | """
45 | X_batch, y_batch = tf.train.shuffle_batch([X_out, y_out], batch_size=128,
46 | capacity=2000, min_after_dequeue=100, num_threads=4)
47 | sess = tf.Session()
48 | init = tf.global_variables_initializer()
49 | sess.run(init)
50 |
51 | # **5.启动队列进行数据读取
52 | # 下面的 coord 是个线程协调器,把启动队列的时候加上线程协调器。
53 | # 这样,在数据读取完毕以后,调用协调器把线程全部都关了。
54 | coord = tf.train.Coordinator()
55 | threads = tf.train.start_queue_runners(sess=sess, coord=coord)
56 | # y_outputs = list()
57 | # for i in range(5):
58 | # _X_batch, _y_batch = sess.run([X_batch, y_batch])
59 | # print('** batch %d' % i)
60 | # print('_X_batch:\n', _X_batch)
61 | # print('_y_batch:\n', _y_batch)
62 | # y_outputs.extend(_y_batch.tolist())
63 | # print('All y_outputs: \n', y_outputs)
64 |
65 | # 迭代取值
66 | time0 = time.time()
67 | for count in range(100): # 100batch 125 seconds
68 | _X_batch, _y_batch = sess.run([X_batch, y_batch])
69 | sys.stdout.write("\rloop {}, pass {:.2f}s".format(count, time.time() - time0))
70 | sys.stdout.flush()
71 |
72 | # **6.最后记得把队列关掉
73 | coord.request_stop()
74 | coord.join(threads)
75 |
76 |
--------------------------------------------------------------------------------
/utils/u02_tfrecord/tfrecord_1_numpy_reader_without_shuffle.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | import tensorflow as tf
4 | import os
5 | import time
6 |
7 | '''read data.
8 | without shuffle, for validation or test data.
9 | 遍历一次数据集,针对验证集或者训练集,我们不需要使用 shuffle 的方式读取 batch,而是需要保证完整的遍历一次数据集。
10 | 和 tf.train.shuffle_batch 的读取方式类似,只是有几个地方需要注意:
11 | 1.把文件名字写入队列的时候,记得设 shuffle=False
12 | 2.同时设置 num_epochs 参数为 1. 这样当读取完一个epoch以后就会抛出 OutOfRangeError.
13 | 3.tf.train.batch() 函数的 allow_smaller_final_batch 参数一定要设置 True, 才不会漏掉最后不满 batch_size 的一小部分数据
14 | 4.在初始化的时候加上 tf.initialize_local_variables(), 否则会报错。
15 | 5.记得加上 try...except... 来捕获 OutOfRangeError
16 | '''
17 |
18 | # **1.把所有的 tfrecord 文件名列表写入队列中
19 | tfrecord_dir = 'tfrecord/numpy/'
20 | tfrecord_files = os.listdir(tfrecord_dir)
21 | tfrecord_files = list(map(lambda s: os.path.join(tfrecord_dir, s), tfrecord_files))
22 |
23 | filename_queue = tf.train.string_input_producer(tfrecord_files, num_epochs=None, shuffle=True)
24 |
25 | # create a reader from file queue
26 | reader = tf.TFRecordReader()
27 | _, serialized_example = reader.read(filename_queue)
28 | # get feature from serialized example
29 | features = tf.parse_single_example(serialized_example,
30 | features={
31 | 'X': tf.FixedLenFeature([784], tf.float32),
32 | 'y': tf.FixedLenFeature([], tf.int64)}
33 | )
34 | X_out = features['X']
35 | y_out = features['y']
36 |
37 | batch_size = 128
38 | X_batch, y_batch = tf.train.batch([X_out, y_out],
39 | batch_size=2,
40 | capacity=2000,
41 | num_threads=4,
42 | allow_smaller_final_batch=True) # 保证遍历完整个数据集
43 |
44 | # 如果设定了读取轮数(num_epochs)为1,所以就算使用 shuffle_batch, 也会保证只取一个epoch,不重复,也不会漏失
45 | # X_batch, y_batch = tf.train.shuffle_batch([X_out, y_out],
46 | # batch_size=6,
47 | # capacity=20,
48 | # min_after_dequeue=10,
49 | # num_threads=2,
50 | # allow_smaller_final_batch=True)
51 |
52 | sess = tf.Session()
53 | # 注意下面这个,如果设了 num_epoch,需要初始化 local_variables
54 | init = tf.group(tf.global_variables_initializer(),
55 | tf.initialize_local_variables())
56 | sess.run(init)
57 |
58 | coord = tf.train.Coordinator()
59 | threads = tf.train.start_queue_runners(sess=sess, coord=coord)
60 | y_outputs = list()
61 | for i in range(25):
62 | try:
63 | _X_batch, _y_batch = sess.run([X_batch, y_batch])
64 | print('** batch %d' % i)
65 | print('_y_batch:\n', _y_batch)
66 | y_outputs.extend(_y_batch.tolist())
67 | except tf.errors.OutOfRangeError as e:
68 | print(e.message)
69 | break
70 | print('all y_outputs:', y_outputs)
71 | print('sorted y_outputs:', sorted(y_outputs))
72 |
73 | coord.request_stop()
74 | coord.join(threads)
75 |
--------------------------------------------------------------------------------
/utils/u02_tfrecord/tfrecord_1_numpy_writer.py:
--------------------------------------------------------------------------------
1 | """tfrecord 写入数据.
2 | 将固定shape的矩阵写入 tfrecord 文件。这种形式的数据写入 tfrecord 是最简单的。
3 | refer: http://blog.csdn.net/qq_16949707/article/details/53483493
4 | """
5 |
6 | from __future__ import print_function
7 | from __future__ import division
8 | from __future__ import absolute_import
9 |
10 | import tensorflow as tf
11 | import numpy as np
12 | from tqdm import tqdm
13 | import os
14 | import sys
15 | import time
16 |
17 | from tensorflow.examples.tutorials.mnist import input_data
18 |
19 | mnist = input_data.read_data_sets('../../data/MNIST_data', one_hot=False)
20 | X = mnist.train.images
21 | y = mnist.train.labels
22 |
23 | NUM_SHARDS = 64 # tfrecord 文件的数量,稍微大些对 shuffle 会好些
24 | n_sample = len(X)
25 | num_per_shard = n_sample // NUM_SHARDS # 每个 tfrecord 的样本数量
26 | # 在打包之前先手动打乱一次
27 | new_idxs = np.random.permutation(n_sample)
28 | X = X[new_idxs]
29 | y = y[new_idxs]
30 |
31 | tfrecord_dir = 'tfrecord/numpy/'
32 | if not os.path.exists(tfrecord_dir):
33 | os.makedirs(tfrecord_dir)
34 |
35 | time0 = time.time()
36 | for shard_id in range(NUM_SHARDS):
37 | output_filename = '%d-of-%d.tfrecord' % (shard_id, NUM_SHARDS)
38 | output_path = os.path.join(tfrecord_dir, output_filename)
39 | with tf.python_io.TFRecordWriter(output_path) as writer:
40 | start_ndx = shard_id * num_per_shard
41 | end_ndx = min((shard_id + 1) * num_per_shard, n_sample)
42 | for i in range(start_ndx, end_ndx):
43 | sys.stdout.write('\r>> Converting image %d/%d shard %d, %g s' % (
44 | i + 1, n_sample, shard_id, time.time() - time0))
45 | sys.stdout.flush()
46 |
47 | X_sample = X[i].tolist()
48 | y_sample = y[i]
49 | # **3.定义数据类型,按照这里固定的形式写,有float_list(好像只有32位), int64_list, bytes_list.
50 | example = tf.train.Example(
51 | features=tf.train.Features(
52 | feature={'X': tf.train.Feature(float_list=tf.train.FloatList(value=X_sample)),
53 | 'y': tf.train.Feature(int64_list=tf.train.Int64List(value=[y_sample]))}))
54 | # **4.序列化数据并写入文件中
55 | serialized = example.SerializeToString()
56 | writer.write(serialized)
57 |
58 | print('Finished writing training data to tfrecord files.')
59 |
--------------------------------------------------------------------------------
/utils/u02_tfrecord/tfrecord_2_seqence_reader.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | import tensorflow as tf
4 | import math
5 |
6 | QUEUE_CAPACITY = 100
7 | SHUFFLE_MIN_AFTER_DEQUEUE = QUEUE_CAPACITY // 5
8 |
9 | """
10 | 读取变长序列数据。
11 | 和固定shape的数据读取方式不一样,在读取变长序列中,我们无法使用 tf.train.shuffle_batch() 函数,只能使用
12 | tf.train.batch() 函数进行读取,而且,在读取的时候,必须设置 dynamic_pad 参数为 True, 把所有的序列 padding
13 | 到固定长度(该batch中最长的序列长度),padding部分为 0。
14 |
15 | 此外,在训练的时候为了实现 shuffle 功能,我们可以使用 RandomShuffleQueue 队列来完成。详见下面的 _shuffle_inputs 函数。
16 | """
17 |
18 |
19 | def _shuffle_inputs(input_tensors, capacity, min_after_dequeue, num_threads):
20 | """Shuffles tensors in `input_tensors`, maintaining grouping."""
21 | shuffle_queue = tf.RandomShuffleQueue(
22 | capacity, min_after_dequeue, dtypes=[t.dtype for t in input_tensors])
23 | enqueue_op = shuffle_queue.enqueue(input_tensors)
24 | runner = tf.train.QueueRunner(shuffle_queue, [enqueue_op] * num_threads)
25 | tf.train.add_queue_runner(runner)
26 |
27 | output_tensors = shuffle_queue.dequeue()
28 |
29 | for i in range(len(input_tensors)):
30 | output_tensors[i].set_shape(input_tensors[i].shape)
31 |
32 | return output_tensors
33 |
34 |
35 | def get_padded_batch(file_list, batch_size, num_enqueuing_threads=4, shuffle=False):
36 | """Reads batches of SequenceExamples from TFRecords and pads them.
37 |
38 | Can deal with variable length SequenceExamples by padding each batch to the
39 | length of the longest sequence with zeros.
40 |
41 | Args:
42 | file_list: A list of paths to TFRecord files containing SequenceExamples.
43 | batch_size: The number of SequenceExamples to include in each batch.
44 | num_enqueuing_threads: The number of threads to use for enqueuing
45 | SequenceExamples.
46 | shuffle: Whether to shuffle the batches.
47 |
48 | Returns:
49 | labels: A tensor of shape [batch_size] of int64s.
50 | frames: A tensor of shape [batch_size, num_steps] of floats32s. note that
51 | num_steps is the max time_step of all the tensors.
52 | Raises:
53 | ValueError: If `shuffle` is True and `num_enqueuing_threads` is less than 2.
54 | """
55 | file_queue = tf.train.string_input_producer(file_list)
56 | reader = tf.TFRecordReader()
57 | _, serialized_example = reader.read(file_queue)
58 |
59 | context_features = {
60 | "label": tf.FixedLenFeature([], dtype=tf.int64)
61 | }
62 | sequence_features = {
63 | "frame": tf.FixedLenSequenceFeature([], dtype=tf.int64)
64 | }
65 |
66 | context_parsed, sequence_parsed = tf.parse_single_sequence_example(
67 | serialized=serialized_example,
68 | context_features=context_features,
69 | sequence_features=sequence_features
70 | )
71 |
72 | labels = context_parsed['label']
73 | frames = sequence_parsed['frame']
74 | input_tensors = [labels, frames]
75 |
76 | if shuffle:
77 | if num_enqueuing_threads < 2:
78 | raise ValueError(
79 | '`num_enqueuing_threads` must be at least 2 when shuffling.')
80 | shuffle_threads = int(math.ceil(num_enqueuing_threads) / 2.)
81 |
82 | # Since there may be fewer records than SHUFFLE_MIN_AFTER_DEQUEUE, take the
83 | # minimum of that number and the number of records.
84 | min_after_dequeue = count_records(
85 | file_list, stop_at=SHUFFLE_MIN_AFTER_DEQUEUE)
86 | input_tensors = _shuffle_inputs(
87 | input_tensors, capacity=QUEUE_CAPACITY,
88 | min_after_dequeue=min_after_dequeue,
89 | num_threads=shuffle_threads)
90 |
91 | num_enqueuing_threads -= shuffle_threads
92 |
93 | tf.logging.info(input_tensors)
94 | return tf.train.batch(
95 | input_tensors,
96 | batch_size=batch_size,
97 | capacity=QUEUE_CAPACITY,
98 | num_threads=num_enqueuing_threads,
99 | dynamic_pad=True,
100 | allow_smaller_final_batch=False)
101 |
102 |
103 | def count_records(file_list, stop_at=None):
104 | """Counts number of records in files from `file_list` up to `stop_at`.
105 |
106 | Args:
107 | file_list: List of TFRecord files to count records in.
108 | stop_at: Optional number of records to stop counting at.
109 |
110 | Returns:
111 | Integer number of records in files from `file_list` up to `stop_at`.
112 | """
113 | num_records = 0
114 | for tfrecord_file in file_list:
115 | tf.logging.info('Counting records in %s.', tfrecord_file)
116 | for _ in tf.python_io.tf_record_iterator(tfrecord_file):
117 | num_records += 1
118 | if stop_at and num_records >= stop_at:
119 | tf.logging.info('Number of records is at least %d.', num_records)
120 | return num_records
121 | tf.logging.info('Total records: %d', num_records)
122 | return num_records
123 |
124 |
125 | if __name__ == '__main__':
126 | tfrecord_file_names = ['../../data/seq_test1.tfrecord', '../../data/seq_test2.tfrecord']
127 | label_batch, frame_batch = get_padded_batch(tfrecord_file_names, 10, shuffle=True)
128 | config = tf.ConfigProto()
129 | config.gpu_options.allow_growth = True
130 | sess = tf.Session(config=config)
131 | tf.train.start_queue_runners(sess=sess)
132 | for i in xrange(3):
133 | _frames_batch, _label_batch = sess.run([frame_batch, label_batch])
134 | print('** batch %d' % i)
135 | print(_label_batch)
136 | print(_frames_batch)
137 |
--------------------------------------------------------------------------------
/utils/u02_tfrecord/tfrecord_2_seqence_writer.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | import tensorflow as tf
4 | import numpy as np
5 | from tqdm import tqdm
6 |
7 | '''tfrecord 写入序列数据,每个样本的长度不固定。
8 | 和固定 shape 的数据处理方式类似,前者使用 tf.train.Example() 方式,而对于变长序列数据,需要使用
9 | tf.train.SequenceExample()。 在 tf.train.SequenceExample() 中,又包括了两部分:
10 | context 来放置非序列化部分;
11 | feature_lists 放置变长序列。
12 |
13 | refer:
14 | https://github.com/tensorflow/magenta/blob/master/magenta/common/sequence_example_lib.py
15 | https://github.com/dennybritz/tf-rnn
16 | http://leix.me/2017/01/09/tensorflow-practical-guides/
17 | https://github.com/siavash9000/im2txt_demo/blob/master/im2txt/im2txt/ops/inputs.py
18 | '''
19 |
20 | # **1.创建文件
21 | writer1 = tf.python_io.TFRecordWriter('../../data/seq_test1.tfrecord')
22 | writer2 = tf.python_io.TFRecordWriter('../../data/seq_test2.tfrecord')
23 |
24 | # 非序列数据
25 | labels = [1, 2, 3, 4, 5, 1, 2, 3, 4]
26 | # 长度不固定的序列
27 | frames = [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5],
28 | [1], [2, 2], [3, 3, 3], [4, 4, 4, 4]]
29 |
30 |
31 | writer = writer1
32 | for i in tqdm(xrange(len(labels))): # **2.对于每个样本
33 | if i == len(labels) / 2:
34 | writer = writer2
35 | print('\nThere are %d sample writen into writer1' % i)
36 | label = labels[i]
37 | frame = frames[i]
38 | # 非序列化
39 | label_feature = tf.train.Feature(int64_list=tf.train.Int64List(value=[label]))
40 | # 序列化
41 | frame_feature = [
42 | tf.train.Feature(int64_list=tf.train.Int64List(value=[frame_])) for frame_ in frame
43 | ]
44 |
45 | seq_example = tf.train.SequenceExample(
46 | # context 来放置非序列化部分
47 | context=tf.train.Features(feature={
48 | "label": label_feature
49 | }),
50 | # feature_lists 放置变长序列
51 | feature_lists=tf.train.FeatureLists(feature_list={
52 | "frame": tf.train.FeatureList(feature=frame_feature),
53 | })
54 | )
55 |
56 | serialized = seq_example.SerializeToString()
57 | writer.write(serialized) # **4.写入文件中
58 |
59 | print('Finished.')
60 | writer1.close()
61 | writer2.close()
62 |
--------------------------------------------------------------------------------
/utils/u02_tfrecord/tfrecord_3_image_reader.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | import tensorflow as tf
4 |
5 | import os
6 | import time
7 | import sys
8 |
9 | '''read data
10 | 从 tfrecord 文件中读取数据,对应数据的格式为 png 格式。
11 | '''
12 |
13 | # **1.把所有的 tfrecord 文件名列表写入队列中
14 | TFRECORD_DIR = 'tfrecord/sketchy_image/'
15 | tfrecord_files = os.listdir(TFRECORD_DIR)
16 | tfrecord_files = list(map(lambda s: os.path.join(TFRECORD_DIR, s), tfrecord_files))
17 |
18 | filename_queue = tf.train.string_input_producer(tfrecord_files, num_epochs=None, shuffle=True)
19 | # **2.创建一个读取器
20 | reader = tf.TFRecordReader()
21 | _, serialized_example = reader.read(filename_queue)
22 | # **3.根据你写入的格式对应说明读取的格式
23 | features = tf.parse_single_example(serialized_example,
24 | features={
25 | 'image': tf.FixedLenFeature([], tf.string),
26 | 'label': tf.FixedLenFeature([], tf.int64)
27 | }
28 | )
29 | img = features['image']
30 | # 这里需要对图片进行解码
31 | img = tf.image.decode_png(img, channels=3) # 这里,也可以解码为 1 通道
32 | img = tf.image.resize_images(images=img, size=(224, 224))
33 | # img = tf.image.resize_image_with_crop_or_pad(img, 224, 224)
34 | # img = tf.reshape(img, [256, 256, 3]) # 256*256*3
35 |
36 | label = features['label']
37 |
38 | print('img is', img)
39 | print('label is', label)
40 | # **4.通过 tf.train.shuffle_batch 或者 tf.train.batch 函数读取数据
41 | """
42 | 这里,你会发现每次取出来的数据都是一个类别的,除非你把 capacity 和 min_after_dequeue 设得很大,如
43 | X_batch, y_batch = tf.train.shuffle_batch([img, label], batch_size=100,
44 | capacity=20000, min_after_dequeue=10000, num_threads=3)
45 | 这是因为在打包的时候都是一个类别一个类别的顺序打包的,所以每次填数据都是按照那个顺序填充进来。
46 | 只有当我们把队列容量舍得非常大,这样在队列中才会混杂各个类别的数据。但是这样非常不好,因为这样的话,
47 | 读取速度就会非常慢。所以解决方法是:
48 | 1.在写入数据的时候先进行数据 shuffle。
49 | 2.多存几个 tfrecord 文件,比如 64 个。
50 | """
51 |
52 | X_batch, y_batch = tf.train.shuffle_batch([img, label], batch_size=128,
53 | capacity=5000, min_after_dequeue=100, num_threads=2)
54 |
55 | config = tf.ConfigProto()
56 | config.gpu_options.allow_growth = True
57 | sess = tf.Session(config=config)
58 | init = tf.global_variables_initializer()
59 | sess.run(init)
60 |
61 | # **5.启动队列进行数据读取
62 | # 下面的 coord 是个线程协调器,把启动队列的时候加上线程协调器。
63 | # 这样,在数据读取完毕以后,调用协调器把线程全部都关了。
64 | coord = tf.train.Coordinator()
65 | threads = tf.train.start_queue_runners(sess=sess, coord=coord)
66 | # y_outputs = list()
67 | # for i in range(5):
68 | # _X_batch, _y_batch = sess.run([X_batch, y_batch])
69 | # print('** batch %d' % i)
70 | # print('_X_batch.shape:', _X_batch.shape)
71 | # print('_y_batch:', _y_batch)
72 | # y_outputs.extend(_y_batch.tolist())
73 | # print(y_outputs)
74 |
75 | time0 = time.time()
76 | # 只解析图片 200batch 9.6 seconds
77 | # resize_images 200batch 22.8 seconds
78 | # resize_image_with_crop_or_pad 200batch 22.4 seconds
79 | for count in range(500):
80 | _X_batch, _y_batch = sess.run([X_batch, y_batch])
81 | sys.stdout.write("\rloop {}, pass {:.2f}s".format(count, time.time() - time0))
82 | sys.stdout.flush()
83 |
84 | # **6.最后记得把队列关掉
85 | coord.request_stop()
86 | coord.join(threads)
87 |
--------------------------------------------------------------------------------
/utils/u02_tfrecord/tfrecord_3_image_writer.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | import tensorflow as tf
4 | import numpy as np
5 | from tqdm import tqdm
6 | import sys
7 | import os
8 | import time
9 |
10 | '''tfrecord 写入数据.
11 | 将图片数据写入 tfrecord 文件。以 png格式数据集为例。
12 |
13 | 现在网上关于打包图片的例子非常多,实现方式各式各样,效率也相差非常多。
14 | 选择合适的方式能够有效地节省时间和硬盘空间。
15 | 有几点需要注意:
16 | 1.打包 tfrecord 的时候,千万不要使用 Image.open() 或者 matplotlib.image.imread() 等方式读取。
17 | 1张小于10kb的png图片,前者(Image.open) 打开后,生成的对象100+kb, 后者直接生成 numpy 数组,大概是原图片的几百倍大小。
18 | 所以应该直接使用 tf.gfile.FastGFile() 方式读入图片。
19 | 2.从 tfrecord 中取数据的时候,再用 tf.image.decode_png() 对图片进行解码。
20 | 3.不要随便使用 tf.image.resize_image_with_crop_or_pad 等函数,可以直接使用 tf.reshape()。前者速度极慢。
21 | '''
22 |
23 | # png 文件路径
24 | IMG_DIR = '../../data/sketchy_000000000000/'
25 | TFRECORD_DIR = 'tfrecord/sketchy_image/'
26 | NUM_SHARDS = 64 # tfrecord 文件的数量,稍微大些对 shuffle 会好些
27 |
28 |
29 | def get_file_path(data_path='../../data/sketchy_000000000000/'):
30 | """解析文件夹,获取每个文件的路径和标签。"""
31 | img_paths = list()
32 | labels = list()
33 | # 必须保证测试集 和 训练集中类别数相同,如果不同的话应该使用 dict_class2id 来保证类别对应正确。
34 | class_dirs = sorted(os.listdir(data_path))
35 | dict_class2id = dict()
36 | for i in range(len(class_dirs)):
37 | label = i
38 | class_dir = class_dirs[i]
39 | dict_class2id[class_dir] = label
40 | class_path = os.path.join(data_path, class_dir) # 每类的路径
41 | file_names = sorted(os.listdir(class_path))
42 | for file_name in file_names:
43 | file_path = os.path.join(class_path, file_name)
44 | img_paths.append(file_path)
45 | labels.append(label)
46 | img_paths = np.asarray(img_paths)
47 | labels = np.asarray(labels)
48 | return img_paths, labels
49 |
50 |
51 | def bytes_feature(values):
52 | return tf.train.Feature(bytes_list=tf.train.BytesList(value=[values]))
53 |
54 |
55 | def int64_feature(values):
56 | return tf.train.Feature(int64_list=tf.train.Int64List(value=[values]))
57 |
58 |
59 | def convert_tfrecord_dataset(tfrecord_dir, n_shards, img_paths, labels, shuffle=True):
60 | """ convert samples to tfrecord dataset.
61 | Args:
62 | dataset_dir: 数据集的路径。
63 | tfrecord_dir: 保存 tfrecord 文件的路径。
64 | n_shards: tfrecord 文件个数
65 | img_paths: 图片的名字。
66 | labels:图片的标签。
67 | """
68 | if not os.path.exists(tfrecord_dir):
69 | os.makedirs(tfrecord_dir)
70 | n_sample = len(img_paths)
71 | num_per_shard = n_sample // n_shards # 每个 tfrecord 的样本数量
72 |
73 | # 在打包之前先手动打乱一次
74 | if shuffle:
75 | new_idxs = np.random.permutation(n_sample)
76 | img_paths = img_paths[new_idxs]
77 | labels = labels[new_idxs]
78 |
79 | time0 = time.time()
80 | for shard_id in range(n_shards):
81 | output_filename = '%d-of-%d.tfrecord' % (shard_id, n_shards)
82 | output_path = os.path.join(tfrecord_dir, output_filename)
83 | with tf.python_io.TFRecordWriter(output_path) as writer:
84 | start_ndx = shard_id * num_per_shard
85 | end_ndx = min((shard_id + 1) * num_per_shard, n_sample)
86 | for i in range(start_ndx, end_ndx):
87 | sys.stdout.write('\r>> Converting image %d/%d shard %d, %g s' % (
88 | i + 1, n_sample, shard_id, time.time() - time0))
89 | sys.stdout.flush()
90 | png_path = img_paths[i]
91 | label = labels[i]
92 | img = tf.gfile.FastGFile(png_path, 'rb').read() # 读入图片
93 | example = tf.train.Example(
94 | features=tf.train.Features(
95 | feature={
96 | 'image': bytes_feature(img),
97 | 'label': int64_feature(label)
98 | }))
99 | serialized = example.SerializeToString()
100 | writer.write(serialized)
101 | print('\nFinished writing data to tfrecord files.')
102 |
103 |
104 | if __name__ == '__main__':
105 | img_paths, labels = get_file_path()
106 | convert_tfrecord_dataset(TFRECORD_DIR, NUM_SHARDS, img_paths, labels, shuffle=True)
107 |
--------------------------------------------------------------------------------
/utils/u03_flags.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | import tensorflow as tf
4 |
5 | """tf.app.flags 用来实现对命令行参数进行解析。
6 | 一般先使用 tf.app.flags.DEFINE_ ... 来定义参数;
7 | 然后通过 tf.app.flags.FLAGS 对象取各个参数。
8 | """
9 |
10 | flags = tf.flags
11 | logging = tf.logging
12 |
13 | FLAGS = flags.FLAGS
14 | flags.DEFINE_string('name', 'huang', 'str_name')
15 | flags.DEFINE_integer('age', 99, 'people age')
16 | flags.DEFINE_float('weight', 51.1, 'people weight')
17 |
18 | def main(_):
19 | print 'FLAGS.name=', FLAGS.name
20 | print 'FLAGS.age=', FLAGS.age
21 | print 'FLAGS.weight=', FLAGS.weight
22 |
23 | if __name__ == '__main__':
24 | tf.app.run() # 会自动运行 main() 函数
25 |
--------------------------------------------------------------------------------