├── .gitignore ├── README.md ├── mkdocs.yml └── sources ├── activations.md ├── applications.md ├── backend.md ├── callbacks.md ├── constraints.md ├── contributing.md ├── datasets.md ├── examples ├── addition_rnn.md ├── antirectifier.md ├── babi_memnn.md ├── babi_rnn.md ├── cifar10_cnn.md ├── cifar10_resnet.md ├── class_activation_maps.md ├── cnn_seq2seq.md ├── conv_filter_visualization.md ├── conv_lstm.md ├── deep_dream.md ├── image_ocr.md ├── imdb_bidirectional_lstm.md ├── imdb_cnn.md ├── imdb_cnn_lstm.md ├── imdb_fasttext.md ├── imdb_lstm.md ├── lstm_seq2seq.md ├── lstm_seq2seq_restore.md ├── lstm_stateful.md ├── lstm_text_generation.md ├── mnist_acgan.md ├── mnist_cnn.md ├── mnist_denoising_autoencoder.md ├── mnist_hierarchical_rnn.md ├── mnist_irnn.md ├── mnist_mlp.md ├── mnist_net2net.md ├── mnist_siamese.md ├── mnist_sklearn_wrapper.md ├── mnist_swwae.md ├── mnist_transfer_cnn.md ├── neural_doodle.md ├── neural_style_transfer.md ├── pretrained_word_embeddings.md ├── reuters_mlp.md ├── reuters_mlp_relu_vs_selu.md ├── variational_autoencoder.md └── variational_autoencoder_deconv.md ├── getting-started ├── faq.md ├── functional-api-guide.md └── sequential-model-guide.md ├── img ├── aws-logo.png ├── favicon.ico ├── google-logo.png ├── keras-logo-small.jpg ├── microsoft-logo.png ├── multi-input-multi-output-graph.png ├── nvidia-logo.png └── regular_stacked_lstm.png ├── index.md ├── initializers.md ├── layers ├── about-keras-layers.md ├── advanced-activations.md ├── convolutional.md ├── core.md ├── embeddings.md ├── local.md ├── merge.md ├── noise.md ├── normalization.md ├── pooling.md ├── recurrent.md ├── wrappers.md └── writing-your-own-keras-layers.md ├── losses.md ├── metrics.md ├── models ├── about-keras-models.md ├── model.md └── sequential.md ├── optimizers.md ├── preprocessing ├── image.md ├── sequence.md └── text.md ├── regularizers.md ├── scikit-learn-api.md ├── utils.md ├── visualization.md └── why-use-keras.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chinese (zh-cn) translation of the Keras docs 2 | 3 | 有关最新文档,请访问 Read the Docs 备份版本:[keras-zh](https://keras-zh.readthedocs.io/),每月更新。 4 | 5 | 有关官方原始文档,请访问 [Keras官方中文文档](https://keras.io/zh/)。 6 | 7 | Translation has done! 文档已完成,欢迎进一步修订。 8 | 9 | 翻译过程中,请直接将 `sources/` 中 `.md` 文件中的英文替换为中文。 10 | 11 | 12 | ## 排版规范 Typesetting 13 | 14 | 此文档遵循 [中文排版指南](https://github.com/sparanoid/chinese-copywriting-guidelines) 规范,并在此之上遵守以下约定: 15 | 16 | * 英文的左右保持一个空白,避免中英文字黏在一起; 17 | * 使用全角标点符号; 18 | * 严格遵循 Markdown 语法; 19 | * 原文中的双引号(" ")请代换成中文的引号(「」符号怎么打出来见 [这里](http://zhihu.com/question/19755746/answer/27233392)); 20 | * 「`加亮`」和「**加粗**」和「[链接]()」都需要在左右保持一个空格。 21 | 22 | ## 翻译对照列表 Conventions 23 | 24 | - 该翻译用于 `zh-cn` (简体中文,中国大陆地区)。 25 | - 当遇到以下 `专业术语` 的时候,请使用以下列表进行对照翻译。(未完待续) 26 | 27 | 28 | | English | 中文 | 29 | |:-------------------|:--------------------| 30 | | arguments         | 参数                | 31 | | boolean           | 布尔                | 32 | | data augumentation | 数据增强            | 33 | | deep learning     | 深度学习            | 34 | | float             | 浮点数               | 35 | | Functional API     | 函数式 API     | 36 | | Fuzz factor       | 模糊因子             | 37 | | input shape       | 输入尺寸             | 38 | | index             | 索引                 | 39 | | int               | 整数                 | 40 | | layer             | 层                  | 41 | | loss function     | 损失函数             | 42 | | metrics | 评估标准 | 43 | | nD tensor         | nD 张量             | 44 | | Numpy Array | Numpy 矩阵 | 45 | | objective | 目标 | 46 | | optimizer | 优化器 | 47 | | output shape | 输出尺寸 | 48 | | regularizer       | 正则化器             | 49 | | return | 返回 | 50 | | recurrent | 循环 | 51 | | Sequential Model | 顺序模型 | 52 | | shape | 尺寸 | 53 | | target | 目标 | 54 | | testing | 测试 | 55 | | training | 训练 | 56 | | wrapper           | 封装器               | 57 | 58 | 59 | Welcome to contribute!!! 60 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Keras 中文文档 2 | theme: 3 | name: null 4 | custom_dir: theme 5 | static_templates: 6 | - 404.html 7 | include_search_page: true 8 | search_index_only: false 9 | highlightjs: true 10 | hljs_languages: [] 11 | include_homepage_in_sidebar: true 12 | prev_next_buttons_location: bottom 13 | navigation_depth: 4 14 | titles_only: false 15 | sticky_navigation: true 16 | collapse_navigation: true 17 | 18 | docs_dir: sources 19 | repo_url: http://github.com/keras-team/keras-docs-zh 20 | site_url: http://keras.io/zh/ 21 | site_description: 'Keras,Python 深度学习库中文文档。' 22 | 23 | dev_addr: '0.0.0.0:8000' 24 | google_analytics: ['UA-61785484-1', 'keras.io'] 25 | 26 | nav: 27 | - 主页: index.md 28 | - 为什么选择 Keras?: why-use-keras.md 29 | - 快速开始: 30 | - Sequential 顺序模型指引: getting-started/sequential-model-guide.md 31 | - 函数式 API 指引: getting-started/functional-api-guide.md 32 | - FAQ 常见问题解答: getting-started/faq.md 33 | - 模型: 34 | - 关于 Keras 模型: models/about-keras-models.md 35 | - Sequential 顺序模型: models/sequential.md 36 | - Model (函数式 API): models/model.md 37 | - 网络层: 38 | - 关于 Keras 网络层: layers/about-keras-layers.md 39 | - 核心网络层: layers/core.md 40 | - 卷积层 Convolutional Layers: layers/convolutional.md 41 | - 池化层 Pooling Layers: layers/pooling.md 42 | - 局部连接层 Locally-connected Layers: layers/local.md 43 | - 循环层 Recurrent Layers: layers/recurrent.md 44 | - 嵌入层 Embedding Layers: layers/embeddings.md 45 | - 融合层 Merge Layers: layers/merge.md 46 | - 高级激活层 Advanced Activations Layers: layers/advanced-activations.md 47 | - 标准化层 Normalization Layers: layers/normalization.md 48 | - 噪声层 Noise layers: layers/noise.md 49 | - 层封装器 Layer wrappers: layers/wrappers.md 50 | - 编写你自己的层: layers/writing-your-own-keras-layers.md 51 | - 数据预处理: 52 | - 序列预处理: preprocessing/sequence.md 53 | - 文本预处理: preprocessing/text.md 54 | - 图像预处理: preprocessing/image.md 55 | - 损失函数 Losses: losses.md 56 | - 评估标准 Metrics: metrics.md 57 | - 优化器 Optimizers: optimizers.md 58 | - 激活函数 Activations: activations.md 59 | - 回调 Callbacks: callbacks.md 60 | - 常用数据集 Datasets: datasets.md 61 | - 应用 Applications: applications.md 62 | - 后端 Backend: backend.md 63 | - 初始化 Initializers: initializers.md 64 | - 正则化 Regularizers: regularizers.md 65 | - 约束项 Constraints: constraints.md 66 | - 可视化 Visualization: visualization.md 67 | - Scikit-learn API: scikit-learn-api.md 68 | - 工具 Utils: utils.md 69 | - 贡献: contributing.md 70 | - 经典样例: 71 | - RNN 加法: examples/addition_rnn.md 72 | - 自定义层 - antirectifier: examples/antirectifier.md 73 | - Baby RNN: examples/babi_rnn.md 74 | - Baby MemNN: examples/babi_memnn.md 75 | - CIFAR-10 CNN: examples/cifar10_cnn.md 76 | - CIFAR-10 ResNet: examples/cifar10_resnet.md 77 | - 卷积滤波器可视化: examples/conv_filter_visualization.md 78 | - 卷积 LSTM: examples/conv_lstm.md 79 | - Deep Dream: examples/deep_dream.md 80 | - 图片 OCR: examples/image_ocr.md 81 | - 双向 LSTM: examples/imdb_bidirectional_lstm.md 82 | - 1D CNN 文本分类: examples/imdb_cnn.md 83 | - CNN-LSTM 情感分类: examples/imdb_cnn_lstm.md 84 | - Fasttext 文本分类: examples/imdb_fasttext.md 85 | - LSTM 情感分类: examples/imdb_lstm.md 86 | - Sequence to sequence - 训练: examples/lstm_seq2seq.md 87 | - Sequence to sequence - 预测: examples/lstm_seq2seq_restore.md 88 | - Stateful LSTM: examples/lstm_stateful.md 89 | - LSTM for 文本生成: examples/lstm_text_generation.md 90 | - GAN 辅助分类器: examples/mnist_acgan.md 91 | -------------------------------------------------------------------------------- /sources/activations.md: -------------------------------------------------------------------------------- 1 | 2 | ## 激活函数的用法 3 | 4 | 激活函数可以通过设置单独的 `Activation` 层实现,也可以在构造层对象时通过传递 `activation` 参数实现: 5 | 6 | ```python 7 | from keras.layers import Activation, Dense 8 | 9 | model.add(Dense(64)) 10 | model.add(Activation('tanh')) 11 | ``` 12 | 13 | 等价于: 14 | 15 | 16 | ```python 17 | model.add(Dense(64, activation='tanh')) 18 | ``` 19 | 20 | 你也可以通过传递一个逐元素运算的 Theano/TensorFlow/CNTK 函数来作为激活函数: 21 | 22 | ```python 23 | from keras import backend as K 24 | 25 | model.add(Dense(64, activation=K.tanh)) 26 | model.add(Activation(K.tanh)) 27 | ``` 28 | 29 | ## 预定义激活函数 30 | 31 | ### elu 32 | 33 | ```python 34 | keras.activations.elu(x, alpha=1.0) 35 | ``` 36 | 37 | 指数线性单元。 38 | 39 | __参数__ 40 | 41 | - __x__:输入张量。 42 | - __alpha__:一个标量,表示负数部分的斜率。 43 | 44 | __返回__ 45 | 46 | 线性指数激活:如果 `x > 0`,返回值为 `x`;如果 `x < 0` 返回值为 `alpha * (exp(x)-1)` 47 | 48 | __参考文献__ 49 | 50 | - [Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs)](https://arxiv.org/abs/1511.07289) 51 | 52 | ---- 53 | 54 | ### softmax 55 | 56 | 57 | ```python 58 | keras.activations.softmax(x, axis=-1) 59 | ``` 60 | 61 | 62 | Softmax 激活函数。 63 | 64 | __参数__ 65 | 66 | - __x__:输入张量。 67 | - __axis__:整数,代表 softmax 所作用的维度。 68 | 69 | __返回__ 70 | 71 | softmax 变换后的张量。 72 | 73 | __异常__ 74 | 75 | - __ValueError__:如果 `dim(x) == 1`。 76 | 77 | ---- 78 | 79 | 80 | ### selu 81 | 82 | 83 | ```python 84 | keras.activations.selu(x) 85 | ``` 86 | 87 | 可伸缩的指数线性单元(SELU)。 88 | 89 | SELU 等同于:`scale * elu(x, alpha)`,其中 alpha 和 scale 是预定义的常量。只要正确初始化权重(参见 `lecun_normal` 初始化方法)并且输入的数量「足够大」(参见参考文献获得更多信息),选择合适的 alpha 和 scale 的值,就可以在两个连续层之间保留输入的均值和方差。 90 | 91 | __参数__ 92 | 93 | - __x__: 一个用来用于计算激活函数的张量或变量。 94 | 95 | __返回__ 96 | 97 | 可伸缩的指数线性激活:`scale * elu(x, alpha)`。 98 | 99 | __注意__ 100 | 101 | - 与「lecun_normal」初始化方法一起使用。 102 | - 与 dropout 的变种「AlphaDropout」一起使用。 103 | 104 | __参考文献__ 105 | 106 | - [Self-Normalizing Neural Networks](https://arxiv.org/abs/1706.02515) 107 | 108 | ---- 109 | 110 | ### softplus 111 | 112 | 113 | ```python 114 | keras.activations.softplus(x) 115 | ``` 116 | 117 | Softplus 激活函数。 118 | 119 | __参数__ 120 | 121 | - __x__: 输入张量。 122 | 123 | __返回__ 124 | 125 | Softplus 激活:`log(exp(x) + 1)`。 126 | 127 | ---- 128 | 129 | ### softsign 130 | 131 | 132 | ```python 133 | keras.activations.softsign(x) 134 | ``` 135 | 136 | Softsign 激活函数。 137 | 138 | __参数__ 139 | 140 | - __x__: 输入张量。 141 | 142 | __返回__ 143 | 144 | Softsign 激活:`x / (abs(x) + 1)`。 145 | 146 | ---- 147 | 148 | ### relu 149 | 150 | 151 | ```python 152 | keras.activations.relu(x, alpha=0.0, max_value=None, threshold=0.0) 153 | ``` 154 | 155 | 整流线性单元。 156 | 157 | 使用默认值时,它返回逐元素的 `max(x, 0)`。 158 | 159 | 否则,它遵循: 160 | 161 | - 如果 `x >= max_value`:`f(x) = max_value`, 162 | - 如果 `threshold <= x < max_value`:`f(x) = x`, 163 | - 否则:`f(x) = alpha * (x - threshold)`。 164 | 165 | __参数__ 166 | 167 | - __x__: 输入张量。 168 | - __alpha__:负数部分的斜率。默认为 0。 169 | - __max_value__:输出的最大值。 170 | - __threshold__: 浮点数。Thresholded activation 的阈值值。 171 | 172 | __返回__ 173 | 174 | 一个张量。 175 | 176 | ---- 177 | 178 | ### tanh 179 | 180 | ```python 181 | keras.activations.tanh(x) 182 | ``` 183 | 184 | 双曲正切激活函数。 185 | 186 | __参数__ 187 | 188 | - __x__: 输入张量。 189 | 190 | __返回__ 191 | 192 | 双曲正切激活函数: 193 | `tanh(x) = (exp(x) - exp(-x)) / (exp(x) + exp(-x))` 194 | 195 | ---- 196 | 197 | ### sigmoid 198 | 199 | 200 | ```python 201 | sigmoid(x) 202 | ``` 203 | 204 | Sigmoid 激活函数。 205 | 206 | __参数__ 207 | 208 | - __x__: 输入张量. 209 | 210 | __返回__ 211 | 212 | Sigmoid激活函数: `1 / (1 + exp(-x))`. 213 | 214 | ---- 215 | 216 | ### hard_sigmoid 217 | 218 | 219 | ```python 220 | hard_sigmoid(x) 221 | ``` 222 | 223 | Hard sigmoid 激活函数。 224 | 225 | 计算速度比 sigmoid 激活函数更快。 226 | 227 | __参数__ 228 | 229 | - __x__: 输入张量。 230 | 231 | __返回__ 232 | 233 | Hard sigmoid 激活函数: 234 | 235 | - 如果 `x < -2.5`,返回 `0`。 236 | - 如果 `x > 2.5`,返回 `1`。 237 | - 如果 `-2.5 <= x <= 2.5`,返回 `0.2 * x + 0.5`。 238 | 239 | ---- 240 | 241 | ### exponential 242 | 243 | 244 | ```python 245 | keras.activations.exponential(x) 246 | ``` 247 | 248 | 自然数指数激活函数。 249 | 250 | ---- 251 | 252 | ### linear 253 | 254 | 255 | ```python 256 | keras.activations.linear(x) 257 | ``` 258 | 259 | 线性激活函数(即不做任何改变) 260 | 261 | __参数__ 262 | 263 | - __x__: 输入张量。 264 | 265 | __返回__ 266 | 267 | 输入张量,不变。 268 | 269 | 270 | ## 高级激活函数 271 | 272 | 对于 Theano/TensorFlow/CNTK 不能表达的复杂激活函数,如含有可学习参数的激活函数,可通过[高级激活函数](layers/advanced-activations.md)实现,可以在 `keras.layers.advanced_activations` 模块中找到。 这些高级激活函数包括 `PReLU` 和 `LeakyReLU`。 273 | -------------------------------------------------------------------------------- /sources/constraints.md: -------------------------------------------------------------------------------- 1 | ## 约束项的使用 2 | 3 | `constraints` 模块的函数允许在优化期间对网络参数设置约束(例如非负性)。 4 | 5 | 约束是以层为对象进行的。具体的 API 因层而异,但 `Dense`,`Conv1D`,`Conv2D` 和 `Conv3D` 这些层具有统一的 API。 6 | 7 | 约束层开放 2 个关键字参数: 8 | 9 | - `kernel_constraint` 用于主权重矩阵。 10 | - `bias_constraint` 用于偏置。 11 | 12 | ```python 13 | from keras.constraints import max_norm 14 | model.add(Dense(64, kernel_constraint=max_norm(2.))) 15 | ``` 16 | 17 | ## 预定义的约束 18 | 19 | 20 | [[source]](https://github.com/keras-team/keras/blob/master/keras/constraints.py#L22) 21 | ### MaxNorm 22 | 23 | ```python 24 | keras.constraints.MaxNorm(max_value=2, axis=0) 25 | ``` 26 | 27 | MaxNorm 最大范数权值约束。 28 | 29 | 映射到每个隐藏单元的权值的约束,使其具有小于或等于期望值的范数。 30 | 31 | __参数__ 32 | 33 | - __max_value__: 输入权值的最大范数。 34 | - __axis__: 整数,需要计算权值范数的轴。 35 | 例如,在 `Dense` 层中权值矩阵的尺寸为 `(input_dim, output_dim)`, 36 | 设置 `axis` 为 `0` 以约束每个长度为 `(input_dim,)` 的权值向量。 37 | 在 `Conv2D` 层(`data_format="channels_last"`)中,权值张量的尺寸为 38 | `(rows, cols, input_depth, output_depth)`,设置 `axis` 为 `[0, 1, 2]` 39 | 以越是每个尺寸为 `(rows, cols, input_depth)` 的滤波器张量的权值。 40 | 41 | __参考文献__ 42 | 43 | - [Dropout: A Simple Way to Prevent Neural Networks from Overfitting](http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf) 44 | 45 | ---- 46 | 47 | [[source]](https://github.com/keras-team/keras/blob/master/keras/constraints.py#L61) 48 | ### NonNeg 49 | 50 | ```python 51 | keras.constraints.NonNeg() 52 | ``` 53 | 54 | 权重非负的约束。 55 | 56 | ---- 57 | 58 | [[source]](https://github.com/keras-team/keras/blob/master/keras/constraints.py#L69) 59 | ### UnitNorm 60 | 61 | ```python 62 | keras.constraints.UnitNorm(axis=0) 63 | ``` 64 | 65 | 映射到每个隐藏单元的权值的约束,使其具有单位范数。 66 | 67 | __参数__ 68 | 69 | - __axis__: 整数,需要计算权值范数的轴。 70 | 例如,在 `Dense` 层中权值矩阵的尺寸为 `(input_dim, output_dim)`, 71 | 设置 `axis` 为 `0` 以约束每个长度为 `(input_dim,)` 的权值向量。 72 | 在 `Conv2D` 层(`data_format="channels_last"`)中,权值张量的尺寸为 73 | `(rows, cols, input_depth, output_depth)`,设置 `axis` 为 `[0, 1, 2]` 74 | 以越是每个尺寸为 `(rows, cols, input_depth)` 的滤波器张量的权值。 75 | 76 | ---- 77 | 78 | [[source]](https://github.com/keras-team/keras/blob/master/keras/constraints.py#L98) 79 | ### MinMaxNorm 80 | 81 | ```python 82 | keras.constraints.MinMaxNorm(min_value=0.0, max_value=1.0, rate=1.0, axis=0) 83 | ``` 84 | 85 | MinMaxNorm 最小/最大范数权值约束。 86 | 87 | 映射到每个隐藏单元的权值的约束,使其范数在上下界之间。 88 | 89 | __参数__ 90 | 91 | - __min_value__: 输入权值的最小范数。 92 | - __max_value__: 输入权值的最大范数。 93 | - __rate__: 强制执行约束的比例:权值将被重新调整为 94 | `(1 - rate) * norm + rate * norm.clip(min_value, max_value)`。 95 | 实际上,这意味着 rate = 1.0 代表严格执行约束,而 rate <1.0 意味着权值 96 | 将在每一步重新调整以缓慢移动到所需间隔内的值。 97 | - __axis__: 整数,需要计算权值范数的轴。 98 | 例如,在 `Dense` 层中权值矩阵的尺寸为 `(input_dim, output_dim)`, 99 | 设置 `axis` 为 `0` 以约束每个长度为 `(input_dim,)` 的权值向量。 100 | 在 `Conv2D` 层(`data_format="channels_last"`)中,权值张量的尺寸为 101 | `(rows, cols, input_depth, output_depth)`,设置 `axis` 为 `[0, 1, 2]` 102 | 以越是每个尺寸为 `(rows, cols, input_depth)` 的滤波器张量的权值。 103 | 104 | 105 | --- 106 | -------------------------------------------------------------------------------- /sources/contributing.md: -------------------------------------------------------------------------------- 1 | # 关于 Github Issues 和 Pull Requests 2 | 3 | 找到一个漏洞?有一个新的功能建议?想要对代码库做出贡献?请务必先阅读这些。 4 | 5 | ## 漏洞报告 6 | 7 | 你的代码不起作用,你确定问题在于Keras?请按照以下步骤报告错误。 8 | 9 | 1. 你的漏洞可能已经被修复了。确保更新到目前的Keras master分支,以及最新的 Theano/TensorFlow/CNTK master 分支。 10 | 轻松更新 Theano 的方法:`pip install git+git://github.com/Theano/Theano.git --upgrade` 11 | 12 | 2. 搜索相似问题。 确保在搜索已经解决的 Issue 时删除 `is:open` 标签。有可能已经有人遇到了这个漏洞。同时记得检查 Keras [FAQ](/faq/)。仍然有问题?在 Github 上开一个 Issue,让我们知道。 13 | 14 | 3. 确保你向我们提供了有关你的配置的有用信息:什么操作系统?什么 Keras 后端?你是否在 GPU 上运行,Cuda 和 cuDNN 的版本是多少?GPU型号是什么? 15 | 16 | 4. 为我们提供一个脚本来重现这个问题。该脚本应该可以按原样运行,并且不应该要求下载外部数据(如果需要在某些测试数据上运行模型,请使用随机生成的数据)。我们建议你使用 Github Gists 来张贴你的代码。任何无法重现的问题都会被关闭。 17 | 18 | 5. 如果可能的话,自己动手修复这个漏洞 - 如果可以的话! 19 | 20 | 你提供的信息越多,我们就越容易验证存在错误,并且我们可以采取更快的行动。如果你想快速解决你的问题,尊许上述步骤操作是至关重要的。 21 | 22 | --- 23 | 24 | ## 请求新功能 25 | 26 | 你也可以使用 [TensorFlow Github issues](https://github.com/tensorflow/tensorflow/issues) 来请求你希望在 Keras 中看到的功能,或者在 Keras API 中的更改。 27 | 28 | 1. 提供你想要的功能的清晰和详细的解释,以及为什么添加它很重要。请记住,我们需要的功能是对于大多数用户而言的,不仅仅是一小部分人。如果你只是针对少数用户,请考虑为 Keras 编写附加库。对 Keras 来说,避免臃肿的 API 和代码库是至关重要的。 29 | 30 | 2. 提供代码片段,演示您所需的 API 并说明您的功能的用例。 当然,在这一点上你不需要写任何真正的代码! 31 | 32 | 3. 讨论完需要在 `tf.keras` 中添加德该功能后,你可以选择尝试提一个 Pull Request。如果你完全可以,开始写一些代码。相比时间上,我们总是有更多的工作要做。如果你可以写一些代码,那么这将加速这个过程。 33 | 34 | 35 | --- 36 | 37 | ## 请求贡献代码 38 | 39 | 在[这个板块](https://github.com/keras-team/keras/projects/1)我们会列出当前需要添加的出色的问题和新功能。如果你想要为 Keras 做贡献,这就是可以开始的地方。 40 | 41 | 42 | --- 43 | 44 | ## Pull Requests 合并请求 45 | 46 | **我应该在哪里提交我的合并请求?** 47 | 48 | #### 注意: 49 | 50 | 我们不再会向多后端 Keras 添加新功能(我们仅仅修复漏洞),因为我们正重新将开发精力投入到 tf.keras 上。如果你仍然像提交新的功能申请,请直接将它提交到 TensorFlow 仓库的 tf.keras 中。 51 | 52 | 1. **Keras 改进与漏洞修复**, 请到 [Keras `master` 分支](https://github.com/keras-team/keras/tree/master)。 53 | 54 | 2. **测试新功能**, 例如网络层和数据集,请到 [keras-contrib](https://github.com/farizrahman4u/keras-contrib)。除非它是一个在 [Requests for Contributions](https://github.com/keras-team/keras/projects/1) 中列出的新功能,它属于 Keras 的核心部分。如果你觉得你的功能属于 Keras 核心,你可以提交一个设计文档,来解释你的功能,并争取它(请看以下解释)。 55 | 56 | 请注意任何有关 **代码风格**(而不是修复修复,改进文档或添加新功能)的 PR 都会被拒绝。 57 | 58 | 以下是提交你的改进的快速指南: 59 | 60 | 1. 如果你的 PR 介绍了功能的改变,确保你从撰写设计文档并将其发给 Keras 邮件列表开始,以讨论是否应该修改,以及如何处理。这将拯救你于 PR 关闭。当然,如果你的 PR 只是一个简单的漏洞修复,那就不需要这样做。撰写与提交设计文档的过程如下所示: 61 | - 从这个 [Google 文档模版](https://docs.google.com/document/d/1ZXNfce77LDW9tFAj6U5ctaJmI5mT7CQXOFMEAZo-mAA/edit#) 开始,将它复制为一个新的 Google 文档。 62 | - 填写内容。注意你需要插入代码样例。要插入代码,请使用 Google 文档插件,例如 [CodePretty] (https://chrome.google.com/webstore/detail/code-pretty/igjbncgfgnfpbnifnnlcmjfbnidkndnh?hl=en) (有许多可用的插件)。 63 | - 将共享设置为 「每个有链接的人都可以发表评论」。 64 | - 将文档发给 `keras-users@googlegroups.com`,主题从 `[API DESIGN REVIEW]` (全大写) 开始,这样我们才会注意到它。 65 | - 等待评论,回复评论。必要时修改提案。 66 | - 该提案最终将被批准或拒绝。一旦获得批准,您可以发出合并请求或要求他人撰写合并请求。 67 | 68 | 69 | 2. 撰写代码(或者让别人写)。这是最难的一部分。 70 | 71 | 3. 确保你引入的任何新功能或类都有适当的文档。确保你触摸的任何代码仍具有最新的文档。**应该严格遵循 Docstring 风格**。尤其是,它们应该在 MarkDown 中格式化,并且应该有 `Arguments`,`Returns`,`Raises` 部分(如果适用)。查看代码示例中的其他文档以做参考。 72 | 73 | 4. 撰写测试。你的代码应该有完整的单元测试覆盖。如果你想看到你的 PR 迅速合并,这是至关重要的。 74 | 75 | 5. 在本地运行测试套件。这很简单:在 Keras 目录下,直接运行: `py.test tests/`。 76 | - 您还需要安装测试包: `pip install -e .[tests]`。 77 | 78 | 6. 确保通过所有测试: 79 | - 使用 Theano 后端,Python 2.7 和 Python 3.5。确保你有 Theano 的开发版本。 80 | - 使用 TensorFlow 后端,Python 2.7 和 Python 3.5。确保你有 TensorFlow 的开发版本。 81 | - 使用 CNTK 后端, Python 2.7 和 Python 3.5。确保你有 CNTK 的开发版本。 82 | 83 | 7. 我们使用 PEP8 语法约定,但是当涉及到行长时,我们不是教条式的。尽管如此,确保你的行保持合理的大小。为了让您的生活更轻松,我们推荐使用 PEP8 linter: 84 | - 安装 PEP8 包:`pip install pep8 pytest-pep8 autopep8` 85 | - 运行独立的 PEP8 检查: `py.test --pep8 -m pep8` 86 | - 你可以通过运行这个命令自动修复一些 PEP8 错误: `autopep8 -i --select `。 87 | 例如: `autopep8 -i --select E128 tests/keras/backend/test_backends.py` 88 | 89 | 8. 提交时,请使用适当的描述性提交消息。 90 | 91 | 9. 更新文档。如果引入新功能,请确保包含演示新功能用法的代码片段。 92 | 93 | 10. 提交你的 PR。如果你的更改已在之前的讨论中获得批准,并且你有完整(并通过)的单元测试以及正确的 docstring/文档,则你的 PR 可能会立即合并。 94 | 95 | --- 96 | 97 | ## 添加新的样例 98 | 99 | 即使你不贡献 Keras 源代码,如果你有一个简洁而强大的 Keras 应用,请考虑将它添加到我们的样例集合中。[现有的例子](https://github.com/keras-team/keras/tree/master/examples)展示惯用的 Keras 代码:确保保持自己的脚本具有相同的风格。 100 | -------------------------------------------------------------------------------- /sources/datasets.md: -------------------------------------------------------------------------------- 1 | # 数据集 2 | 3 | ## CIFAR10 小图像分类数据集 4 | 5 | 50,000 张 32x32 彩色训练图像数据,以及 10,000 张测试图像数据,总共分为 10 个类别。 6 | 7 | ### 用法: 8 | 9 | ```python 10 | from keras.datasets import cifar10 11 | 12 | (x_train, y_train), (x_test, y_test) = cifar10.load_data() 13 | ``` 14 | 15 | - __返回:__ 16 | - 2 个元组: 17 | - __x_train, x_test__: uint8 数组表示的 RGB 图像数据,尺寸为 (num_samples, 3, 32, 32) 或 (num_samples, 32, 32, 3),基于 `image_data_format` 后端设定的 `channels_first` 或 `channels_last`。 18 | - __y_train, y_test__: uint8 数组表示的类别标签(范围在 0-9 之间的整数),尺寸为 (num_samples, 1)。 19 | 20 | 21 | --- 22 | 23 | ## CIFAR100 小图像分类数据集 24 | 25 | 50,000 张 32x32 彩色训练图像数据,以及 10,000 张测试图像数据,总共分为 100 个类别。 26 | 27 | ### 用法: 28 | 29 | ```python 30 | from keras.datasets import cifar100 31 | 32 | (x_train, y_train), (x_test, y_test) = cifar100.load_data(label_mode='fine') 33 | ``` 34 | 35 | - __返回:__ 36 | - 2 个元组: 37 | - __x_train, x_test__: uint8 数组表示的 RGB 图像数据,尺寸为 (num_samples, 3, 32, 32) 或 (num_samples, 32, 32, 3),基于 `image_data_format` 后端设定的 `channels_first` 或 `channels_last`。 38 | - __y_train, y_test__: uint8 数组表示的类别标签,尺寸为 (num_samples, 1)。 39 | 40 | - __参数:__ 41 | - __label_mode__: "fine" 或者 "coarse" 42 | 43 | 44 | --- 45 | 46 | ## IMDB 电影评论情感分类数据集 47 | 48 | 数据集来自 IMDB 的 25,000 条电影评论,以情绪(正面/负面)标记。评论已经过预处理,并编码为词索引(整数)的[序列](preprocessing/sequence.md)表示。为了方便起见,将词按数据集中出现的频率进行索引,例如整数 3 编码数据中第三个最频繁的词。这允许快速筛选操作,例如:「只考虑前 10,000 个最常用的词,但排除前 20 个最常见的词」。 49 | 50 | 作为惯例,0 不代表特定的单词,而是被用于编码任何未知单词。 51 | 52 | ### 用法 53 | 54 | ```python 55 | from keras.datasets import imdb 56 | 57 | (x_train, y_train), (x_test, y_test) = imdb.load_data(path="imdb.npz", 58 | num_words=None, 59 | skip_top=0, 60 | maxlen=None, 61 | seed=113, 62 | start_char=1, 63 | oov_char=2, 64 | index_from=3) 65 | ``` 66 | 67 | - __返回:__ 68 | - 2 个元组: 69 | - __x_train, x_test__: 序列的列表,即词索引的列表。如果指定了 `num_words` 参数,则可能的最大索引值是 `num_words-1`。如果指定了 `maxlen` 参数,则可能的最大序列长度为 `maxlen`。 70 | - __y_train, y_test__: 整数标签列表 (1 或 0)。 71 | 72 | - __参数:__ 73 | - __path__: 如果你本地没有该数据集 (在 `'~/.keras/datasets/' + path`),它将被下载到此目录。 74 | - __num_words__: 整数或 None。要考虑的最常用的词语。任何不太频繁的词将在序列数据中显示为 `oov_char` 值。 75 | - __skip_top__: 整数。要忽略的最常见的单词(它们将在序列数据中显示为 `oov_char` 值)。 76 | - __maxlen__: 整数。最大序列长度。 任何更长的序列都将被截断。 77 | - __seed__: 整数。用于可重现数据混洗的种子。 78 | - __start_char__: 整数。序列的开始将用这个字符标记。设置为 1,因为 0 通常作为填充字符。 79 | - __oov_char__: 整数。由于 `num_words` 或 `skip_top` 限制而被删除的单词将被替换为此字符。 80 | - __index_from__: 整数。使用此数以上更高的索引值实际词汇索引的开始。 81 | 82 | 83 | --- 84 | 85 | ## 路透社新闻主题分类 86 | 87 | 数据集来源于路透社的 11,228 条新闻文本,总共分为 46 个主题。与 IMDB 数据集一样,每条新闻都被编码为一个词索引的序列(相同的约定)。 88 | 89 | ### 用法: 90 | 91 | ```python 92 | from keras.datasets import reuters 93 | 94 | (x_train, y_train), (x_test, y_test) = reuters.load_data(path="reuters.npz", 95 | num_words=None, 96 | skip_top=0, 97 | maxlen=None, 98 | test_split=0.2, 99 | seed=113, 100 | start_char=1, 101 | oov_char=2, 102 | index_from=3) 103 | ``` 104 | 105 | 规格与 IMDB 数据集的规格相同,但增加了: 106 | 107 | - __test_split__: 浮点型。用作测试集的数据比例。 108 | 109 | 该数据集还提供了用于编码序列的词索引: 110 | 111 | ```python 112 | word_index = reuters.get_word_index(path="reuters_word_index.json") 113 | ``` 114 | 115 | - __返回:__ 一个字典,其中键是单词(字符串),值是索引(整数)。 例如,`word_index["giraffe"]` 可能会返回 `1234`。 116 | 117 | - __参数:__ 118 | - __path__: 如果在本地没有索引文件 (at `'~/.keras/datasets/' + path`), 它将被下载到该目录。 119 | 120 | --- 121 | 122 | ## MNIST 手写字符数据集 123 | 124 | 训练集为 60,000 张 28x28 像素灰度图像,测试集为 10,000 同规格图像,总共 10 类数字标签。 125 | 126 | ### 用法: 127 | 128 | ```python 129 | from keras.datasets import mnist 130 | 131 | (x_train, y_train), (x_test, y_test) = mnist.load_data() 132 | ``` 133 | 134 | - __返回:__ 135 | - 2 个元组: 136 | - __x_train, x_test__: uint8 数组表示的灰度图像,尺寸为 (num_samples, 28, 28)。 137 | - __y_train, y_test__: uint8 数组表示的数字标签(范围在 0-9 之间的整数),尺寸为 (num_samples,)。 138 | 139 | - __参数:__ 140 | - __path__: 如果在本地没有索引文件 (at `'~/.keras/datasets/' + path`), 它将被下载到该目录。 141 | 142 | 143 | --- 144 | 145 | ## Fashion-MNIST 时尚物品数据集 146 | 147 | 训练集为 60,000 张 28x28 像素灰度图像,测试集为 10,000 同规格图像,总共 10 类时尚物品标签。该数据集可以用作 MNIST 的直接替代品。类别标签是: 148 | 149 | | 类别 | 描述 | 中文 | 150 | | --- | --- | --- | 151 | | 0 | T-shirt/top | T恤/上衣 | 152 | | 1 | Trouser | 裤子 | 153 | | 2 | Pullover | 套头衫 | 154 | | 3 | Dress | 连衣裙 | 155 | | 4 | Coat | 外套 | 156 | | 5 | Sandal | 凉鞋 | 157 | | 6 | Shirt | 衬衫 | 158 | | 7 | Sneaker | 运动鞋 | 159 | | 8 | Bag | 背包 | 160 | | 9 | Ankle boot | 短靴 | 161 | 162 | ### 用法: 163 | 164 | ```python 165 | from keras.datasets import fashion_mnist 166 | 167 | (x_train, y_train), (x_test, y_test) = fashion_mnist.load_data() 168 | ``` 169 | 170 | - __返回:__ 171 | - 2 个元组: 172 | - __x_train, x_test__: uint8 数组表示的灰度图像,尺寸为 (num_samples, 28, 28)。 173 | - __y_train, y_test__: uint8 数组表示的数字标签(范围在 0-9 之间的整数),尺寸为 (num_samples,)。 174 | 175 | 176 | --- 177 | 178 | ## Boston 房价回归数据集 179 | 180 | 181 | 数据集来自卡内基梅隆大学维护的 StatLib 库。 182 | 183 | 样本包含 1970 年代的在波士顿郊区不同位置的房屋信息,总共有 13 种房屋属性。 184 | 目标值是一个位置的房屋的中值(单位:k$)。 185 | 186 | 187 | ### 用法: 188 | 189 | ```python 190 | from keras.datasets import boston_housing 191 | 192 | (x_train, y_train), (x_test, y_test) = boston_housing.load_data() 193 | ``` 194 | 195 | - __参数:__ 196 | - __path__: 缓存本地数据集的位置 197 | (相对路径 ~/.keras/datasets)。 198 | - __seed__: 在计算测试分割之前对数据进行混洗的随机种子。 199 | - __test_split__: 需要保留作为测试数据的比例。 200 | 201 | - __返回:__ Numpy 数组的元组: `(x_train, y_train), (x_test, y_test)`。 202 | 203 | -------------------------------------------------------------------------------- /sources/examples/addition_rnn.md: -------------------------------------------------------------------------------- 1 | 2 | # 实现一个用来执行加法的序列到序列学习模型 3 | 4 | 输入: "535+61" 5 | 6 | 输出: "596" 7 | 8 | 使用重复的标记字符(空格)处理填充。 9 | 10 | 输入可以选择性地反转,它被认为可以提高许多任务的性能,例如: 11 | [Learning to Execute](http://arxiv.org/abs/1410.4615) 12 | 以及 13 | [Sequence to Sequence Learning with Neural Networks](http://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf)。 14 | 15 | 从理论上讲,它引入了源和目标之间的短期依赖关系。 16 | 17 | 两个反转的数字 + 一个 LSTM 层(128个隐藏单元),在 55 个 epochs 后,5k 的训练样本取得了 99% 的训练/测试准确率。 18 | 19 | 三个反转的数字 + 一个 LSTM 层(128个隐藏单元),在 100 个 epochs 后,50k 的训练样本取得了 99% 的训练/测试准确率。 20 | 21 | 四个反转的数字 + 一个 LSTM 层(128个隐藏单元),在 20 个 epochs 后,400k 的训练样本取得了 99% 的训练/测试准确率。 22 | 23 | 五个反转的数字 + 一个 LSTM 层(128个隐藏单元),在 30 个 epochs 后,550k 的训练样本取得了 99% 的训练/测试准确率。 24 | 25 | 26 | ```python 27 | from __future__ import print_function 28 | from keras.models import Sequential 29 | from keras import layers 30 | import numpy as np 31 | from six.moves import range 32 | 33 | 34 | class CharacterTable(object): 35 | """给定一组字符: 36 | + 将它们编码为 one-hot 整数表示 37 | + 将 one-hot 或整数表示解码为字符输出 38 | + 将一个概率向量解码为字符输出 39 | """ 40 | def __init__(self, chars): 41 | """初始化字符表。 42 | 43 | # 参数: 44 | chars: 可以出现在输入中的字符。 45 | """ 46 | self.chars = sorted(set(chars)) 47 | self.char_indices = dict((c, i) for i, c in enumerate(self.chars)) 48 | self.indices_char = dict((i, c) for i, c in enumerate(self.chars)) 49 | 50 | def encode(self, C, num_rows): 51 | """给定字符串 C 的 one-hot 编码。 52 | 53 | # 参数 54 | C: 需要编码的字符串。 55 | num_rows: 返回的 one-hot 编码的行数。 56 | 这用来保证每个数据的行数相同。 57 | """ 58 | x = np.zeros((num_rows, len(self.chars))) 59 | for i, c in enumerate(C): 60 | x[i, self.char_indices[c]] = 1 61 | return x 62 | 63 | def decode(self, x, calc_argmax=True): 64 | """将给定的向量或 2D array 解码为它们的字符输出。 65 | 66 | # 参数 67 | x: 一个向量或 2D 概率数组或 one-hot 表示, 68 | 或 字符索引的向量(如果 `calc_argmax=False`)。 69 | calc_argmax: 是否根据最大概率来找到字符,默认为 `True`。 70 | """ 71 | if calc_argmax: 72 | x = x.argmax(axis=-1) 73 | return ''.join(self.indices_char[x] for x in x) 74 | 75 | 76 | class colors: 77 | ok = '\033[92m' 78 | fail = '\033[91m' 79 | close = '\033[0m' 80 | 81 | # 模型和数据的参数 82 | TRAINING_SIZE = 50000 83 | DIGITS = 3 84 | REVERSE = True 85 | 86 | # 输入的最大长度是 'int+int' (例如, '345+678'). int 的最大长度为 DIGITS。 87 | MAXLEN = DIGITS + 1 + DIGITS 88 | 89 | # 所有的数字,加上符号,以及用于填充的空格。 90 | chars = '0123456789+ ' 91 | ctable = CharacterTable(chars) 92 | 93 | questions = [] 94 | expected = [] 95 | seen = set() 96 | print('Generating data...') 97 | while len(questions) < TRAINING_SIZE: 98 | f = lambda: int(''.join(np.random.choice(list('0123456789')) 99 | for i in range(np.random.randint(1, DIGITS + 1)))) 100 | a, b = f(), f() 101 | # 跳过任何已有的加法问题 102 | # 同事跳过任何 x+Y == Y+x 的情况(即排序)。 103 | key = tuple(sorted((a, b))) 104 | if key in seen: 105 | continue 106 | seen.add(key) 107 | # 利用空格填充,是的长度始终为 MAXLEN。 108 | q = '{}+{}'.format(a, b) 109 | query = q + ' ' * (MAXLEN - len(q)) 110 | ans = str(a + b) 111 | # 答案可能的最长长度为 DIGITS + 1。 112 | ans += ' ' * (DIGITS + 1 - len(ans)) 113 | if REVERSE: 114 | # 反转查询,例如,'12+345 ' 变成 ' 543+21'. 115 | # (注意用于填充的空格) 116 | query = query[::-1] 117 | questions.append(query) 118 | expected.append(ans) 119 | print('Total addition questions:', len(questions)) 120 | 121 | print('Vectorization...') 122 | x = np.zeros((len(questions), MAXLEN, len(chars)), dtype=np.bool) 123 | y = np.zeros((len(questions), DIGITS + 1, len(chars)), dtype=np.bool) 124 | for i, sentence in enumerate(questions): 125 | x[i] = ctable.encode(sentence, MAXLEN) 126 | for i, sentence in enumerate(expected): 127 | y[i] = ctable.encode(sentence, DIGITS + 1) 128 | 129 | # 混洗 (x, y),因为 x 的后半段几乎都是比较大的数字。 130 | indices = np.arange(len(y)) 131 | np.random.shuffle(indices) 132 | x = x[indices] 133 | y = y[indices] 134 | 135 | # 显式地分离出 10% 的训练数据作为验证集。 136 | split_at = len(x) - len(x) // 10 137 | (x_train, x_val) = x[:split_at], x[split_at:] 138 | (y_train, y_val) = y[:split_at], y[split_at:] 139 | 140 | print('Training Data:') 141 | print(x_train.shape) 142 | print(y_train.shape) 143 | 144 | print('Validation Data:') 145 | print(x_val.shape) 146 | print(y_val.shape) 147 | 148 | # 可以尝试更改为 GRU, 或 SimpleRNN。 149 | RNN = layers.LSTM 150 | HIDDEN_SIZE = 128 151 | BATCH_SIZE = 128 152 | LAYERS = 1 153 | 154 | print('Build model...') 155 | model = Sequential() 156 | # 利用 RNN 将输入序列「编码」为一个 HIDDEN_SIZE 长度的输出向量。 157 | # 注意:在输入序列具有可变长度的情况下, 158 | # 使用 input_shape=(None, num_feature). 159 | model.add(RNN(HIDDEN_SIZE, input_shape=(MAXLEN, len(chars)))) 160 | # 作为解码器 RNN 的输入,为每个时间步重复地提供 RNN 的最后输出。 161 | # 重复 'DIGITS + 1' 次,因为它是最大输出长度。 162 | # 例如,当 DIGITS=3, 最大输出为 999+999=1998。 163 | model.add(layers.RepeatVector(DIGITS + 1)) 164 | # 解码器 RNN 可以是多个堆叠的层,或一个单独的层。 165 | for _ in range(LAYERS): 166 | # 通过设置 return_sequences 为 True, 将不仅返回最后一个输出,而是返回目前的所有输出,形式为(num_samples, timesteps, output_dim)。 167 | # 这是必须的,因为后面的 TimeDistributed 需要第一个维度是时间步。 168 | model.add(RNN(HIDDEN_SIZE, return_sequences=True)) 169 | 170 | # 将全连接层应用于输入的每个时间片。 171 | # 对于输出序列的每一步,决定应选哪个字符。 172 | model.add(layers.TimeDistributed(layers.Dense(len(chars), activation='softmax'))) 173 | model.compile(loss='categorical_crossentropy', 174 | optimizer='adam', 175 | metrics=['accuracy']) 176 | model.summary() 177 | 178 | # 训练模型,并在每一代显示验证数据的预测。 179 | for iteration in range(1, 200): 180 | print() 181 | print('-' * 50) 182 | print('Iteration', iteration) 183 | model.fit(x_train, y_train, 184 | batch_size=BATCH_SIZE, 185 | epochs=1, 186 | validation_data=(x_val, y_val)) 187 | # 从随机验证集中选择 10 个样本,以便我们可以看到错误。 188 | for i in range(10): 189 | ind = np.random.randint(0, len(x_val)) 190 | rowx, rowy = x_val[np.array([ind])], y_val[np.array([ind])] 191 | preds = model.predict_classes(rowx, verbose=0) 192 | q = ctable.decode(rowx[0]) 193 | correct = ctable.decode(rowy[0]) 194 | guess = ctable.decode(preds[0], calc_argmax=False) 195 | print('Q', q[::-1] if REVERSE else q, end=' ') 196 | print('T', correct, end=' ') 197 | if correct == guess: 198 | print(colors.ok + '☑' + colors.close, end=' ') 199 | else: 200 | print(colors.fail + '☒' + colors.close, end=' ') 201 | print(guess) 202 | ``` -------------------------------------------------------------------------------- /sources/examples/antirectifier.md: -------------------------------------------------------------------------------- 1 | # 本示例演示了如何为 Keras 编写自定义网络层。 2 | 3 | 我们构建了一个称为 'Antirectifier' 的自定义激活层,该层可以修改通过它的张量的形状。 4 | 我们需要指定两个方法: `compute_output_shape` 和 `call`。 5 | 6 | 注意,相同的结果也可以通过 Lambda 层取得。 7 | 8 | 我们的自定义层是使用 Keras 后端 (`K`) 中的基元编写的,因而代码可以在 TensorFlow 和 Theano 上运行。 9 | 10 | 11 | ```python 12 | from __future__ import print_function 13 | import keras 14 | from keras.models import Sequential 15 | from keras import layers 16 | from keras.datasets import mnist 17 | from keras import backend as K 18 | 19 | 20 | class Antirectifier(layers.Layer): 21 | '''这是样本级的 L2 标准化与输入的正负部分串联的组合。 22 | 结果是两倍于输入样本的样本张量。 23 | 24 | 它可以用于替代 ReLU。 25 | 26 | # 输入尺寸 27 | 2D 张量,尺寸为 (samples, n) 28 | 29 | # 输出尺寸 30 | 2D 张量,尺寸为 (samples, 2*n) 31 | 32 | # 理论依据 33 | 在应用 ReLU 时,假设先前输出的分布接近于 0 的中心, 34 | 那么将丢弃一半的输入。这是非常低效的。 35 | 36 | Antirectifier 允许像 ReLU 一样返回全正输出,而不会丢弃任何数据。 37 | 38 | 在 MNIST 上进行的测试表明,Antirectifier 可以训练参数少两倍但具 39 | 有与基于 ReLU 的等效网络相当的分类精度的网络。 40 | ''' 41 | 42 | def compute_output_shape(self, input_shape): 43 | shape = list(input_shape) 44 | assert len(shape) == 2 # 仅对 2D 张量有效 45 | shape[-1] *= 2 46 | return tuple(shape) 47 | 48 | def call(self, inputs): 49 | inputs -= K.mean(inputs, axis=1, keepdims=True) 50 | inputs = K.l2_normalize(inputs, axis=1) 51 | pos = K.relu(inputs) 52 | neg = K.relu(-inputs) 53 | return K.concatenate([pos, neg], axis=1) 54 | 55 | # 全局参数 56 | batch_size = 128 57 | num_classes = 10 58 | epochs = 40 59 | 60 | # 切分为训练和测试的数据 61 | (x_train, y_train), (x_test, y_test) = mnist.load_data() 62 | 63 | x_train = x_train.reshape(60000, 784) 64 | x_test = x_test.reshape(10000, 784) 65 | x_train = x_train.astype('float32') 66 | x_test = x_test.astype('float32') 67 | x_train /= 255 68 | x_test /= 255 69 | print(x_train.shape[0], 'train samples') 70 | print(x_test.shape[0], 'test samples') 71 | 72 | # 将类向量转化为二进制类矩阵 73 | y_train = keras.utils.to_categorical(y_train, num_classes) 74 | y_test = keras.utils.to_categorical(y_test, num_classes) 75 | 76 | # 构建模型 77 | model = Sequential() 78 | model.add(layers.Dense(256, input_shape=(784,))) 79 | model.add(Antirectifier()) 80 | model.add(layers.Dropout(0.1)) 81 | model.add(layers.Dense(256)) 82 | model.add(Antirectifier()) 83 | model.add(layers.Dropout(0.1)) 84 | model.add(layers.Dense(num_classes)) 85 | model.add(layers.Activation('softmax')) 86 | 87 | # 编译模型 88 | model.compile(loss='categorical_crossentropy', 89 | optimizer='rmsprop', 90 | metrics=['accuracy']) 91 | 92 | # 训练模型 93 | model.fit(x_train, y_train, 94 | batch_size=batch_size, 95 | epochs=epochs, 96 | verbose=1, 97 | validation_data=(x_test, y_test)) 98 | 99 | # 接下来,与具有 2 倍大的密集层 100 | # 和 ReLU 的等效网络进行比较 101 | ``` 102 | -------------------------------------------------------------------------------- /sources/examples/cifar10_cnn.md: -------------------------------------------------------------------------------- 1 | 2 | # 在 CIFAR10 小型图像数据集上训练一个深度卷积神经网络。 3 | 4 | 在 25 轮迭代后 验证集准确率达到 75%,在 50 轮后达到 79%。 5 | (尽管目前仍然欠拟合)。 6 | 7 | ```python 8 | from __future__ import print_function 9 | import keras 10 | from keras.datasets import cifar10 11 | from keras.preprocessing.image import ImageDataGenerator 12 | from keras.models import Sequential 13 | from keras.layers import Dense, Dropout, Activation, Flatten 14 | from keras.layers import Conv2D, MaxPooling2D 15 | import os 16 | 17 | batch_size = 32 18 | num_classes = 10 19 | epochs = 100 20 | data_augmentation = True 21 | num_predictions = 20 22 | save_dir = os.path.join(os.getcwd(), 'saved_models') 23 | model_name = 'keras_cifar10_trained_model.h5' 24 | 25 | # 数据,切分为训练和测试集。 26 | (x_train, y_train), (x_test, y_test) = cifar10.load_data() 27 | print('x_train shape:', x_train.shape) 28 | print(x_train.shape[0], 'train samples') 29 | print(x_test.shape[0], 'test samples') 30 | 31 | # 将类向量转换为二进制类矩阵。 32 | y_train = keras.utils.to_categorical(y_train, num_classes) 33 | y_test = keras.utils.to_categorical(y_test, num_classes) 34 | 35 | model = Sequential() 36 | model.add(Conv2D(32, (3, 3), padding='same', 37 | input_shape=x_train.shape[1:])) 38 | model.add(Activation('relu')) 39 | model.add(Conv2D(32, (3, 3))) 40 | model.add(Activation('relu')) 41 | model.add(MaxPooling2D(pool_size=(2, 2))) 42 | model.add(Dropout(0.25)) 43 | 44 | model.add(Conv2D(64, (3, 3), padding='same')) 45 | model.add(Activation('relu')) 46 | model.add(Conv2D(64, (3, 3))) 47 | model.add(Activation('relu')) 48 | model.add(MaxPooling2D(pool_size=(2, 2))) 49 | model.add(Dropout(0.25)) 50 | 51 | model.add(Flatten()) 52 | model.add(Dense(512)) 53 | model.add(Activation('relu')) 54 | model.add(Dropout(0.5)) 55 | model.add(Dense(num_classes)) 56 | model.add(Activation('softmax')) 57 | 58 | # 初始化 RMSprop 优化器。 59 | opt = keras.optimizers.RMSprop(learning_rate=0.0001, decay=1e-6) 60 | 61 | # 利用 RMSprop 来训练模型。 62 | model.compile(loss='categorical_crossentropy', 63 | optimizer=opt, 64 | metrics=['accuracy']) 65 | 66 | x_train = x_train.astype('float32') 67 | x_test = x_test.astype('float32') 68 | x_train /= 255 69 | x_test /= 255 70 | 71 | if not data_augmentation: 72 | print('Not using data augmentation.') 73 | model.fit(x_train, y_train, 74 | batch_size=batch_size, 75 | epochs=epochs, 76 | validation_data=(x_test, y_test), 77 | shuffle=True) 78 | else: 79 | print('Using real-time data augmentation.') 80 | # 这一步将进行数据处理和实时数据增益。data augmentation: 81 | datagen = ImageDataGenerator( 82 | featurewise_center=False, # 将整个数据集的均值设为0 83 | samplewise_center=False, # 将每个样本的均值设为0 84 | featurewise_std_normalization=False, # 将输入除以整个数据集的标准差 85 | samplewise_std_normalization=False, # 将输入除以其标准差 86 | zca_whitening=False, # 运用 ZCA 白化 87 | zca_epsilon=1e-06, # ZCA 白化的 epsilon值 88 | rotation_range=0, # 随机旋转图像范围 (角度, 0 to 180) 89 | # 随机水平移动图像 (总宽度的百分比) 90 | width_shift_range=0.1, 91 | # 随机垂直移动图像 (总高度的百分比) 92 | height_shift_range=0.1, 93 | shear_range=0., # 设置随机裁剪范围 94 | zoom_range=0., # 设置随机放大范围 95 | channel_shift_range=0., # 设置随机通道切换的范围 96 | # 设置填充输入边界之外的点的模式 97 | fill_mode='nearest', 98 | cval=0., # 在 fill_mode = "constant" 时使用的值 99 | horizontal_flip=True, # 随机水平翻转图像 100 | vertical_flip=False, # 随机垂直翻转图像 101 | # 设置缩放因子 (在其他转换之前使用) 102 | rescale=None, 103 | # 设置将应用于每一个输入的函数 104 | preprocessing_function=None, 105 | # 图像数据格式,"channels_first" 或 "channels_last" 之一 106 | data_format=None, 107 | # 保留用于验证的图像比例(严格在0和1之间) 108 | validation_split=0.0) 109 | 110 | # 计算特征标准化所需的计算量 111 | # (如果应用 ZCA 白化,则为 std,mean和主成分). 112 | datagen.fit(x_train) 113 | 114 | # 利用由 datagen.flow() 生成的批来训练模型 115 | model.fit_generator(datagen.flow(x_train, y_train, 116 | batch_size=batch_size), 117 | epochs=epochs, 118 | validation_data=(x_test, y_test), 119 | workers=4) 120 | 121 | # 保存模型和权重 122 | if not os.path.isdir(save_dir): 123 | os.makedirs(save_dir) 124 | model_path = os.path.join(save_dir, model_name) 125 | model.save(model_path) 126 | print('Saved trained model at %s ' % model_path) 127 | 128 | # 评估训练模型 129 | scores = model.evaluate(x_test, y_test, verbose=1) 130 | print('Test loss:', scores[0]) 131 | print('Test accuracy:', scores[1]) 132 | ``` 133 | -------------------------------------------------------------------------------- /sources/examples/class_activation_maps.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ```python 4 | import argparse 5 | import cv2 6 | import matplotlib.pyplot as plt 7 | 8 | from keras.models import Model 9 | 10 | import keras.applications.resnet50 as resnet 11 | from keras.layers import UpSampling2D, Conv2D 12 | 13 | # 设置合适的图片文件 14 | parser = argparse.ArgumentParser(description='Class activation maps with Keras.') 15 | parser.add_argument('input_image', metavar='base', type=str, 16 | help='Path to the image to use.') 17 | args = parser.parse_args() 18 | input_image = args.input_image 19 | 20 | 21 | ################################################################ 22 | # 以下参数可以更改为使用全局平均池化的其他模型。 23 | # 例如 InceptionResnetV2 / NASNetLarge 24 | NETWORK_INPUT_SIZE = 224 25 | MODEL_CLASS = resnet.ResNet50 26 | PREPROCESS_FN = resnet.preprocess_input 27 | LAST_CONV_LAYER = 'activation_49' 28 | PRED_LAYER = 'fc1000' 29 | ################################################################ 30 | 31 | # 图像类别数目 32 | N_CLASSES = 1000 33 | 34 | 35 | def load_img(fname, input_size, preprocess_fn): 36 | original_img = cv2.imread(fname)[:, :, ::-1] 37 | original_size = (original_img.shape[1], original_img.shape[0]) 38 | img = cv2.resize(original_img, (input_size, input_size)) 39 | imgs = np.expand_dims(preprocess_fn(img), axis=0) 40 | return imgs, original_img, original_size 41 | 42 | 43 | def get_cam_model(model_class, 44 | input_size=224, 45 | last_conv_layer='activation_49', 46 | pred_layer='fc1000'): 47 | model = model_class(input_shape=(input_size, input_size, 3)) 48 | 49 | final_params = model.get_layer(pred_layer).get_weights() 50 | final_params = (final_params[0].reshape( 51 | 1, 1, -1, N_CLASSES), final_params[1]) 52 | 53 | last_conv_output = model.get_layer(last_conv_layer).output 54 | x = UpSampling2D(size=(32, 32), interpolation='bilinear')( 55 | last_conv_output) 56 | x = Conv2D(filters=N_CLASSES, kernel_size=( 57 | 1, 1), name='predictions_2')(x) 58 | 59 | cam_model = Model(inputs=model.input, 60 | outputs=[model.output, x]) 61 | cam_model.get_layer('predictions_2').set_weights(final_params) 62 | return cam_model 63 | 64 | 65 | def postprocess(preds, cams, top_k=1): 66 | idxes = np.argsort(preds[0])[-top_k:] 67 | class_activation_map = np.zeros_like(cams[0, :, :, 0]) 68 | for i in idxes: 69 | class_activation_map += cams[0, :, :, i] 70 | return class_activation_map 71 | 72 | 73 | # 1. 载入图像 74 | imgs, original_img, original_size = load_img(input_image, 75 | input_size=NETWORK_INPUT_SIZE, 76 | preprocess_fn=resnet.preprocess_input) 77 | 78 | # 2. 预测 79 | model = get_cam_model(resnet.ResNet50, 80 | NETWORK_INPUT_SIZE, 81 | LAST_CONV_LAYER, 82 | PRED_LAYER) 83 | preds, cams = model.predict(imgs) 84 | 85 | # 3. 后期处理 86 | class_activation_map = postprocess(preds, cams) 87 | 88 | # 4. 绘制 image+cam 为原始尺寸 89 | plt.imshow(original_img, alpha=0.5) 90 | plt.imshow(cv2.resize(class_activation_map, 91 | original_size), cmap='jet', alpha=0.5) 92 | plt.show() 93 | ``` 94 | -------------------------------------------------------------------------------- /sources/examples/cnn_seq2seq.md: -------------------------------------------------------------------------------- 1 | # 用 Keras 实现字符级序列到序列模型。 2 | 3 | 该脚本演示了如何实现基本的字符级 CNN 序列到序列模型。 4 | 我们将其用于将英文短句逐个字符翻译成法语短句。 5 | 请注意,进行字符级机器翻译是非比寻常的,因为在此领域中词级模型更为常见。 6 | 本示例仅用于演示目的。 7 | 8 | **算法总结** 9 | 10 | - 我们从一个领域的输入序列(例如英语句子)和另一个领域的对应目标序列(例如法语句子)开始。 11 | - 编码器 CNN 对输入字符序列进行编码。 12 | - 对解码器 CNN 进行训练,以将目标序列转换为相同序列,但以后将偏移一个时间步,在这种情况下,该训练过程称为 "教师强制"。它使用编码器的输出。实际上,解码器会根据输入序列,根据给定的 `targets[...t]` 来学习生成 `target[t+1...]`。 13 | - 在推理模式下,当我们想解码未知的输入序列时,我们: 14 | - 对输入序列进行编码; 15 | - 从大小为1的目标序列开始(仅是序列开始字符); 16 | - 将输入序列和 1 个字符的目标序列馈送到解码器,以生成下一个字符的预测; 17 | - 使用这些预测来采样下一个字符(我们仅使用 argmax); 18 | - 将采样的字符附加到目标序列; 19 | - 重复直到我们达到字符数限制。 20 | 21 | **数据下载** 22 | 23 | [English to French sentence pairs.](http://www.manythings.org/anki/fra-eng.zip) 24 | 25 | [Lots of neat sentence pairs datasets.](http://www.manythings.org/anki/) 26 | 27 | **参考** 28 | 29 | - lstm_seq2seq.py 30 | - https://wanasit.github.io/attention-based-sequence-to-sequence-in-keras.html 31 | 32 | 33 | ```python 34 | from __future__ import print_function 35 | import numpy as np 36 | from keras.layers import Input, Convolution1D, Dot, Dense, Activation, Concatenate 37 | from keras.models import Model 38 | batch_size = 64 # 训练批次大小。 39 | epochs = 100 # 训练迭代轮次。 40 | num_samples = 10000 # 训练样本数。 41 | # 磁盘数据文件路径 42 | data_path = 'fra-eng/fra.txt' 43 | # 向量化数据。 44 | input_texts = [] 45 | target_texts = [] 46 | input_characters = set() 47 | target_characters = set() 48 | with open(data_path, 'r', encoding='utf-8') as f: 49 | lines = f.read().split('\n') 50 | for line in lines[: min(num_samples, len(lines) - 1)]: 51 | input_text, target_text = line.split('\t') 52 | # 我们使用 "tab" 作为 "起始序列" 字符, 53 | # 对于目标,使用 "\n" 作为 "终止序列" 字符。 54 | target_text = '\t' + target_text + '\n' 55 | input_texts.append(input_text) 56 | target_texts.append(target_text) 57 | for char in input_text: 58 | if char not in input_characters: 59 | input_characters.add(char) 60 | for char in target_text: 61 | if char not in target_characters: 62 | target_characters.add(char) 63 | input_characters = sorted(list(input_characters)) 64 | target_characters = sorted(list(target_characters)) 65 | num_encoder_tokens = len(input_characters) 66 | num_decoder_tokens = len(target_characters) 67 | max_encoder_seq_length = max([len(txt) for txt in input_texts]) 68 | max_decoder_seq_length = max([len(txt) for txt in target_texts]) 69 | print('Number of samples:', len(input_texts)) 70 | print('Number of unique input tokens:', num_encoder_tokens) 71 | print('Number of unique output tokens:', num_decoder_tokens) 72 | print('Max sequence length for inputs:', max_encoder_seq_length) 73 | print('Max sequence length for outputs:', max_decoder_seq_length) 74 | input_token_index = dict( 75 | [(char, i) for i, char in enumerate(input_characters)]) 76 | target_token_index = dict( 77 | [(char, i) for i, char in enumerate(target_characters)]) 78 | encoder_input_data = np.zeros( 79 | (len(input_texts), max_encoder_seq_length, num_encoder_tokens), 80 | dtype='float32') 81 | decoder_input_data = np.zeros( 82 | (len(input_texts), max_decoder_seq_length, num_decoder_tokens), 83 | dtype='float32') 84 | decoder_target_data = np.zeros( 85 | (len(input_texts), max_decoder_seq_length, num_decoder_tokens), 86 | dtype='float32') 87 | for i, (input_text, target_text) in enumerate(zip(input_texts, target_texts)): 88 | for t, char in enumerate(input_text): 89 | encoder_input_data[i, t, input_token_index[char]] = 1. 90 | for t, char in enumerate(target_text): 91 | # decoder_target_data is ahead of decoder_input_data by one timestep 92 | decoder_input_data[i, t, target_token_index[char]] = 1. 93 | if t > 0: 94 | # decoder_target_data will be ahead by one timestep 95 | # and will not include the start character. 96 | decoder_target_data[i, t - 1, target_token_index[char]] = 1. 97 | # 定义输入序列并处理它。 98 | encoder_inputs = Input(shape=(None, num_encoder_tokens)) 99 | # Encoder 100 | x_encoder = Convolution1D(256, kernel_size=3, activation='relu', 101 | padding='causal')(encoder_inputs) 102 | x_encoder = Convolution1D(256, kernel_size=3, activation='relu', 103 | padding='causal', dilation_rate=2)(x_encoder) 104 | x_encoder = Convolution1D(256, kernel_size=3, activation='relu', 105 | padding='causal', dilation_rate=4)(x_encoder) 106 | decoder_inputs = Input(shape=(None, num_decoder_tokens)) 107 | # Decoder 108 | x_decoder = Convolution1D(256, kernel_size=3, activation='relu', 109 | padding='causal')(decoder_inputs) 110 | x_decoder = Convolution1D(256, kernel_size=3, activation='relu', 111 | padding='causal', dilation_rate=2)(x_decoder) 112 | x_decoder = Convolution1D(256, kernel_size=3, activation='relu', 113 | padding='causal', dilation_rate=4)(x_decoder) 114 | # Attention 115 | attention = Dot(axes=[2, 2])([x_decoder, x_encoder]) 116 | attention = Activation('softmax')(attention) 117 | context = Dot(axes=[2, 1])([attention, x_encoder]) 118 | decoder_combined_context = Concatenate(axis=-1)([context, x_decoder]) 119 | decoder_outputs = Convolution1D(64, kernel_size=3, activation='relu', 120 | padding='causal')(decoder_combined_context) 121 | decoder_outputs = Convolution1D(64, kernel_size=3, activation='relu', 122 | padding='causal')(decoder_outputs) 123 | # 输出 124 | decoder_dense = Dense(num_decoder_tokens, activation='softmax') 125 | decoder_outputs = decoder_dense(decoder_outputs) 126 | # 定义将 `encoder_input_data` & `decoder_input_data` 127 | # 转化为 `decoder_target_data`的模型。 128 | model = Model([encoder_inputs, decoder_inputs], decoder_outputs) 129 | model.summary() 130 | # 执行训练 131 | model.compile(optimizer='adam', loss='categorical_crossentropy') 132 | model.fit([encoder_input_data, decoder_input_data], decoder_target_data, 133 | batch_size=batch_size, 134 | epochs=epochs, 135 | validation_split=0.2) 136 | # 保存模型 137 | model.save('cnn_s2s.h5') 138 | # 接下来: 推理模式 (采样)。 139 | # 定义采样模型 140 | reverse_input_char_index = dict( 141 | (i, char) for char, i in input_token_index.items()) 142 | reverse_target_char_index = dict( 143 | (i, char) for char, i in target_token_index.items()) 144 | nb_examples = 100 145 | in_encoder = encoder_input_data[:nb_examples] 146 | in_decoder = np.zeros( 147 | (len(input_texts), max_decoder_seq_length, num_decoder_tokens), 148 | dtype='float32') 149 | in_decoder[:, 0, target_token_index["\t"]] = 1 150 | predict = np.zeros( 151 | (len(input_texts), max_decoder_seq_length), 152 | dtype='float32') 153 | for i in range(max_decoder_seq_length - 1): 154 | predict = model.predict([in_encoder, in_decoder]) 155 | predict = predict.argmax(axis=-1) 156 | predict_ = predict[:, i].ravel().tolist() 157 | for j, x in enumerate(predict_): 158 | in_decoder[j, i + 1, x] = 1 159 | for seq_index in range(nb_examples): 160 | # 抽取一个序列(训练集的一部分)进行解码。 161 | output_seq = predict[seq_index, :].ravel().tolist() 162 | decoded = [] 163 | for x in output_seq: 164 | if reverse_target_char_index[x] == "\n": 165 | break 166 | else: 167 | decoded.append(reverse_target_char_index[x]) 168 | decoded_sentence = "".join(decoded) 169 | print('-') 170 | print('Input sentence:', input_texts[seq_index]) 171 | print('Decoded sentence:', decoded_sentence) 172 | ``` 173 | -------------------------------------------------------------------------------- /sources/examples/conv_lstm.md: -------------------------------------------------------------------------------- 1 | # 此脚本演示了卷积LSTM网络的使用。 2 | 3 | 该网络用于预测包含移动方块的人工生成的电影的下一帧。 4 | 5 | 6 | ```python 7 | from keras.models import Sequential 8 | from keras.layers.convolutional import Conv3D 9 | from keras.layers.convolutional_recurrent import ConvLSTM2D 10 | from keras.layers.normalization import BatchNormalization 11 | import numpy as np 12 | import pylab as plt 13 | 14 | # 我们创建一个网络层,以尺寸为 (n_frames,width,height,channels) 的电影作为输入,并返回相同尺寸的电影。 15 | seq = Sequential() 16 | seq.add(ConvLSTM2D(filters=40, kernel_size=(3, 3), 17 | input_shape=(None, 40, 40, 1), 18 | padding='same', return_sequences=True)) 19 | seq.add(BatchNormalization()) 20 | 21 | seq.add(ConvLSTM2D(filters=40, kernel_size=(3, 3), 22 | padding='same', return_sequences=True)) 23 | seq.add(BatchNormalization()) 24 | 25 | seq.add(ConvLSTM2D(filters=40, kernel_size=(3, 3), 26 | padding='same', return_sequences=True)) 27 | seq.add(BatchNormalization()) 28 | 29 | seq.add(ConvLSTM2D(filters=40, kernel_size=(3, 3), 30 | padding='same', return_sequences=True)) 31 | seq.add(BatchNormalization()) 32 | 33 | seq.add(Conv3D(filters=1, kernel_size=(3, 3, 3), 34 | activation='sigmoid', 35 | padding='same', data_format='channels_last')) 36 | seq.compile(loss='binary_crossentropy', optimizer='adadelta') 37 | 38 | 39 | # 人工数据生成: 40 | # 生成内部有3到7个移动方块的电影。 41 | # 方块的尺寸为 1x1 或 2x2 像素, 42 | # 随着时间的推移线性移动。 43 | # 为方便起见,我们首先创建宽度和高度较大的电影(80x80),最后选择 40x40 的窗口。 44 | 45 | def generate_movies(n_samples=1200, n_frames=15): 46 | row = 80 47 | col = 80 48 | noisy_movies = np.zeros((n_samples, n_frames, row, col, 1), dtype=np.float) 49 | shifted_movies = np.zeros((n_samples, n_frames, row, col, 1), 50 | dtype=np.float) 51 | 52 | for i in range(n_samples): 53 | # 添加 3 到 7 个移动方块 54 | n = np.random.randint(3, 8) 55 | 56 | for j in range(n): 57 | # 初始位置 58 | xstart = np.random.randint(20, 60) 59 | ystart = np.random.randint(20, 60) 60 | # 运动方向 61 | directionx = np.random.randint(0, 3) - 1 62 | directiony = np.random.randint(0, 3) - 1 63 | 64 | # 方块尺寸 65 | w = np.random.randint(2, 4) 66 | 67 | for t in range(n_frames): 68 | x_shift = xstart + directionx * t 69 | y_shift = ystart + directiony * t 70 | noisy_movies[i, t, x_shift - w: x_shift + w, 71 | y_shift - w: y_shift + w, 0] += 1 72 | 73 | # 通过添加噪音使其更加健壮。 74 | # 这个想法是,如果在推理期间,像素的值不是一个, 75 | # 我们需要训练更加健壮的网络,并仍然将其视为属于方块的像素。 76 | if np.random.randint(0, 2): 77 | noise_f = (-1)**np.random.randint(0, 2) 78 | noisy_movies[i, t, 79 | x_shift - w - 1: x_shift + w + 1, 80 | y_shift - w - 1: y_shift + w + 1, 81 | 0] += noise_f * 0.1 82 | 83 | # Shift the ground truth by 1 84 | x_shift = xstart + directionx * (t + 1) 85 | y_shift = ystart + directiony * (t + 1) 86 | shifted_movies[i, t, x_shift - w: x_shift + w, 87 | y_shift - w: y_shift + w, 0] += 1 88 | 89 | # 裁剪为 40x40 窗口 90 | noisy_movies = noisy_movies[::, ::, 20:60, 20:60, ::] 91 | shifted_movies = shifted_movies[::, ::, 20:60, 20:60, ::] 92 | noisy_movies[noisy_movies >= 1] = 1 93 | shifted_movies[shifted_movies >= 1] = 1 94 | return noisy_movies, shifted_movies 95 | 96 | # 训练网络 97 | noisy_movies, shifted_movies = generate_movies(n_samples=1200) 98 | seq.fit(noisy_movies[:1000], shifted_movies[:1000], batch_size=10, 99 | epochs=300, validation_split=0.05) 100 | 101 | # 在一部电影上测试网络 102 | # 用前 7 个位置训练它,然后预测新的位置 103 | which = 1004 104 | track = noisy_movies[which][:7, ::, ::, ::] 105 | 106 | for j in range(16): 107 | new_pos = seq.predict(track[np.newaxis, ::, ::, ::, ::]) 108 | new = new_pos[::, -1, ::, ::, ::] 109 | track = np.concatenate((track, new), axis=0) 110 | 111 | 112 | # 然后将预测与实际进行比较 113 | track2 = noisy_movies[which][::, ::, ::, ::] 114 | for i in range(15): 115 | fig = plt.figure(figsize=(10, 5)) 116 | 117 | ax = fig.add_subplot(121) 118 | 119 | if i >= 7: 120 | ax.text(1, 3, 'Predictions !', fontsize=20, color='w') 121 | else: 122 | ax.text(1, 3, 'Initial trajectory', fontsize=20) 123 | 124 | toplot = track[i, ::, ::, 0] 125 | 126 | plt.imshow(toplot) 127 | ax = fig.add_subplot(122) 128 | plt.text(1, 3, 'Ground truth', fontsize=20) 129 | 130 | toplot = track2[i, ::, ::, 0] 131 | if i >= 2: 132 | toplot = shifted_movies[which][i - 1, ::, ::, 0] 133 | 134 | plt.imshow(toplot) 135 | plt.savefig('%i_animate.png' % (i + 1)) 136 | ``` 137 | -------------------------------------------------------------------------------- /sources/examples/deep_dream.md: -------------------------------------------------------------------------------- 1 | # Keras 实现的 Deep Dreaming。 2 | 3 | 按以下命令执行该脚本: 4 | ```python 5 | python deep_dream.py path_to_your_base_image.jpg prefix_for_results 6 | ``` 7 | 8 | 例如: 9 | ```python 10 | python deep_dream.py img/mypic.jpg results/dream 11 | ``` 12 | 13 | 14 | ```python 15 | from __future__ import print_function 16 | 17 | from keras.preprocessing.image import load_img, save_img, img_to_array 18 | import numpy as np 19 | import scipy 20 | import argparse 21 | 22 | from keras.applications import inception_v3 23 | from keras import backend as K 24 | 25 | parser = argparse.ArgumentParser(description='Deep Dreams with Keras.') 26 | parser.add_argument('base_image_path', metavar='base', type=str, 27 | help='Path to the image to transform.') 28 | parser.add_argument('result_prefix', metavar='res_prefix', type=str, 29 | help='Prefix for the saved results.') 30 | 31 | args = parser.parse_args() 32 | base_image_path = args.base_image_path 33 | result_prefix = args.result_prefix 34 | 35 | # 这些是我们尝试最大化激活的层的名称,以及它们们在我们试图最大化的最终损失中的权重。 36 | # 你可以调整这些设置以获得新的视觉效果。 37 | settings = { 38 | 'features': { 39 | 'mixed2': 0.2, 40 | 'mixed3': 0.5, 41 | 'mixed4': 2., 42 | 'mixed5': 1.5, 43 | }, 44 | } 45 | 46 | 47 | def preprocess_image(image_path): 48 | # 用于打开,调整图片大小并将图片格式化为适当的张量的实用函数。 49 | img = load_img(image_path) 50 | img = img_to_array(img) 51 | img = np.expand_dims(img, axis=0) 52 | img = inception_v3.preprocess_input(img) 53 | return img 54 | 55 | 56 | def deprocess_image(x): 57 | # 函数将张量转换为有效图像的实用函数。 58 | if K.image_data_format() == 'channels_first': 59 | x = x.reshape((3, x.shape[2], x.shape[3])) 60 | x = x.transpose((1, 2, 0)) 61 | else: 62 | x = x.reshape((x.shape[1], x.shape[2], 3)) 63 | x /= 2. 64 | x += 0.5 65 | x *= 255. 66 | x = np.clip(x, 0, 255).astype('uint8') 67 | return x 68 | 69 | K.set_learning_phase(0) 70 | 71 | # 使用我们的占位符构建 InceptionV3 网络。 72 | # 该模型将加载预先训练的 ImageNet 权重。 73 | model = inception_v3.InceptionV3(weights='imagenet', 74 | include_top=False) 75 | dream = model.input 76 | print('Model loaded.') 77 | 78 | # 获取每个『关键』层的符号输出(我们为它们指定了唯一的名称)。 79 | layer_dict = dict([(layer.name, layer) for layer in model.layers]) 80 | 81 | # 定义损失。 82 | loss = K.variable(0.) 83 | for layer_name in settings['features']: 84 | # 将层特征的 L2 范数添加到损失中。 85 | if layer_name not in layer_dict: 86 | raise ValueError('Layer ' + layer_name + ' not found in model.') 87 | coeff = settings['features'][layer_name] 88 | x = layer_dict[layer_name].output 89 | # 我们通过仅涉及损失中的非边界像素来避免边界伪影。 90 | scaling = K.prod(K.cast(K.shape(x), 'float32')) 91 | if K.image_data_format() == 'channels_first': 92 | loss = loss + coeff * K.sum(K.square(x[:, :, 2: -2, 2: -2])) / scaling 93 | else: 94 | loss = loss + coeff * K.sum(K.square(x[:, 2: -2, 2: -2, :])) / scaling 95 | 96 | # 计算 dream 即损失的梯度。 97 | grads = K.gradients(loss, dream)[0] 98 | # 标准化梯度。 99 | grads /= K.maximum(K.mean(K.abs(grads)), K.epsilon()) 100 | 101 | # 设置函数,以检索给定输入图像的损失和梯度的值。 102 | outputs = [loss, grads] 103 | fetch_loss_and_grads = K.function([dream], outputs) 104 | 105 | 106 | def eval_loss_and_grads(x): 107 | outs = fetch_loss_and_grads([x]) 108 | loss_value = outs[0] 109 | grad_values = outs[1] 110 | return loss_value, grad_values 111 | 112 | 113 | def resize_img(img, size): 114 | img = np.copy(img) 115 | if K.image_data_format() == 'channels_first': 116 | factors = (1, 1, 117 | float(size[0]) / img.shape[2], 118 | float(size[1]) / img.shape[3]) 119 | else: 120 | factors = (1, 121 | float(size[0]) / img.shape[1], 122 | float(size[1]) / img.shape[2], 123 | 1) 124 | return scipy.ndimage.zoom(img, factors, order=1) 125 | 126 | 127 | def gradient_ascent(x, iterations, step, max_loss=None): 128 | for i in range(iterations): 129 | loss_value, grad_values = eval_loss_and_grads(x) 130 | if max_loss is not None and loss_value > max_loss: 131 | break 132 | print('..Loss value at', i, ':', loss_value) 133 | x += step * grad_values 134 | return x 135 | 136 | 137 | """Process: 138 | 139 | - 载入原始图像。 140 | - 定义一系列预处理规模 (即图像尺寸),从最小到最大。 141 | - 将原始图像调整为最小尺寸。 142 | - 对于每个规模,从最小的(即当前的)开始: 143 | - 执行梯度提升 144 | - 将图像放大到下一个比例 145 | - 重新投射在提升时丢失的细节 146 | - 当我们回到原始大小时停止。 147 | 148 | 为了获得在放大过程中丢失的细节,我们只需将原始图像缩小,放大,然后将结果与(调整大小的)原始图像进行比较即可。 149 | """ 150 | 151 | 152 | # 把玩这些超参数也可以让你获得新的效果 153 | step = 0.01 # 梯度提升步长 154 | num_octave = 3 # 运行梯度提升的规模数 155 | octave_scale = 1.4 # 规模之间的比 156 | iterations = 20 # 每个规模的提升步数 157 | max_loss = 10. 158 | 159 | img = preprocess_image(base_image_path) 160 | if K.image_data_format() == 'channels_first': 161 | original_shape = img.shape[2:] 162 | else: 163 | original_shape = img.shape[1:3] 164 | successive_shapes = [original_shape] 165 | for i in range(1, num_octave): 166 | shape = tuple([int(dim / (octave_scale ** i)) for dim in original_shape]) 167 | successive_shapes.append(shape) 168 | successive_shapes = successive_shapes[::-1] 169 | original_img = np.copy(img) 170 | shrunk_original_img = resize_img(img, successive_shapes[0]) 171 | 172 | for shape in successive_shapes: 173 | print('Processing image shape', shape) 174 | img = resize_img(img, shape) 175 | img = gradient_ascent(img, 176 | iterations=iterations, 177 | step=step, 178 | max_loss=max_loss) 179 | upscaled_shrunk_original_img = resize_img(shrunk_original_img, shape) 180 | same_size_original = resize_img(original_img, shape) 181 | lost_detail = same_size_original - upscaled_shrunk_original_img 182 | 183 | img += lost_detail 184 | shrunk_original_img = resize_img(original_img, shape) 185 | 186 | save_img(result_prefix + '.png', deprocess_image(np.copy(img))) 187 | ``` 188 | -------------------------------------------------------------------------------- /sources/examples/imdb_bidirectional_lstm.md: -------------------------------------------------------------------------------- 1 | 2 | # 在 IMDB 情感分类任务上训练双向 LSTM。 3 | 4 | Output after 4 epochs on CPU: ~0.8146. Time per epoch on CPU (Core i7): ~150s. 5 | 6 | 在 CPU 上经过 4 个轮次后的输出:〜0.8146。 7 | CPU(Core i7)上每个轮次的时间:〜150s。 8 | 9 | ```python 10 | from __future__ import print_function 11 | import numpy as np 12 | 13 | from keras.preprocessing import sequence 14 | from keras.models import Sequential 15 | from keras.layers import Dense, Dropout, Embedding, LSTM, Bidirectional 16 | from keras.datasets import imdb 17 | 18 | 19 | max_features = 20000 20 | # 在此数量的单词之后剪切文本(取最常见的 max_features 个单词) 21 | maxlen = 100 22 | batch_size = 32 23 | 24 | print('Loading data...') 25 | (x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features) 26 | print(len(x_train), 'train sequences') 27 | print(len(x_test), 'test sequences') 28 | 29 | print('Pad sequences (samples x time)') 30 | x_train = sequence.pad_sequences(x_train, maxlen=maxlen) 31 | x_test = sequence.pad_sequences(x_test, maxlen=maxlen) 32 | print('x_train shape:', x_train.shape) 33 | print('x_test shape:', x_test.shape) 34 | y_train = np.array(y_train) 35 | y_test = np.array(y_test) 36 | 37 | model = Sequential() 38 | model.add(Embedding(max_features, 128, input_length=maxlen)) 39 | model.add(Bidirectional(LSTM(64))) 40 | model.add(Dropout(0.5)) 41 | model.add(Dense(1, activation='sigmoid')) 42 | 43 | # 尝试使用不同的优化器和优化器配置 44 | model.compile('adam', 'binary_crossentropy', metrics=['accuracy']) 45 | 46 | print('Train...') 47 | model.fit(x_train, y_train, 48 | batch_size=batch_size, 49 | epochs=4, 50 | validation_data=[x_test, y_test]) 51 | ``` -------------------------------------------------------------------------------- /sources/examples/imdb_cnn.md: -------------------------------------------------------------------------------- 1 | # 本示例演示了将 Convolution1D 用于文本分类。 2 | 3 | 2个轮次后达到 0.89 的测试精度。
4 | 在 Intel i5 2.4Ghz CPU 上每轮次 90秒。
5 | 在 Tesla K40 GPU 上每轮次 10秒。 6 | 7 | 8 | ```python 9 | from __future__ import print_function 10 | 11 | from keras.preprocessing import sequence 12 | from keras.models import Sequential 13 | from keras.layers import Dense, Dropout, Activation 14 | from keras.layers import Embedding 15 | from keras.layers import Conv1D, GlobalMaxPooling1D 16 | from keras.datasets import imdb 17 | 18 | # 设置参数: 19 | max_features = 5000 20 | maxlen = 400 21 | batch_size = 32 22 | embedding_dims = 50 23 | filters = 250 24 | kernel_size = 3 25 | hidden_dims = 250 26 | epochs = 2 27 | 28 | print('Loading data...') 29 | (x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features) 30 | print(len(x_train), 'train sequences') 31 | print(len(x_test), 'test sequences') 32 | 33 | print('Pad sequences (samples x time)') 34 | x_train = sequence.pad_sequences(x_train, maxlen=maxlen) 35 | x_test = sequence.pad_sequences(x_test, maxlen=maxlen) 36 | print('x_train shape:', x_train.shape) 37 | print('x_test shape:', x_test.shape) 38 | 39 | print('Build model...') 40 | model = Sequential() 41 | 42 | # 我们从有效的嵌入层开始,该层将 vocab 索引映射到 embedding_dims 维度 43 | model.add(Embedding(max_features, 44 | embedding_dims, 45 | input_length=maxlen)) 46 | model.add(Dropout(0.2)) 47 | 48 | # 我们添加了一个 Convolution1D,它将学习大小为 filter_length 的过滤器词组过滤器: 49 | model.add(Conv1D(filters, 50 | kernel_size, 51 | padding='valid', 52 | activation='relu', 53 | strides=1)) 54 | # 我们使用最大池化: 55 | model.add(GlobalMaxPooling1D()) 56 | 57 | # We add a vanilla hidden layer: 58 | model.add(Dense(hidden_dims)) 59 | model.add(Dropout(0.2)) 60 | model.add(Activation('relu')) 61 | 62 | # 我们投影到单个单位输出层上,并用 sigmoid 压扁它: 63 | model.add(Dense(1)) 64 | model.add(Activation('sigmoid')) 65 | 66 | model.compile(loss='binary_crossentropy', 67 | optimizer='adam', 68 | metrics=['accuracy']) 69 | model.fit(x_train, y_train, 70 | batch_size=batch_size, 71 | epochs=epochs, 72 | validation_data=(x_test, y_test)) 73 | ``` -------------------------------------------------------------------------------- /sources/examples/imdb_cnn_lstm.md: -------------------------------------------------------------------------------- 1 | # 在 IMDB 情绪分类任务上训练循环卷积网络。 2 | 3 | 2 个轮次后达到 0.8498 的测试精度。K520 GPU 上为 41 秒/轮次。 4 | 5 | 6 | ```python 7 | from __future__ import print_function 8 | 9 | from keras.preprocessing import sequence 10 | from keras.models import Sequential 11 | from keras.layers import Dense, Dropout, Activation 12 | from keras.layers import Embedding 13 | from keras.layers import LSTM 14 | from keras.layers import Conv1D, MaxPooling1D 15 | from keras.datasets import imdb 16 | 17 | # Embedding 18 | max_features = 20000 19 | maxlen = 100 20 | embedding_size = 128 21 | 22 | # Convolution 23 | kernel_size = 5 24 | filters = 64 25 | pool_size = 4 26 | 27 | # LSTM 28 | lstm_output_size = 70 29 | 30 | # Training 31 | batch_size = 30 32 | epochs = 2 33 | 34 | ''' 35 | 注意: 36 | batch_size 是高度敏感的 37 | 由于数据集非常小,因此仅需要 2 个轮次。 38 | ''' 39 | 40 | print('Loading data...') 41 | (x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features) 42 | print(len(x_train), 'train sequences') 43 | print(len(x_test), 'test sequences') 44 | 45 | print('Pad sequences (samples x time)') 46 | x_train = sequence.pad_sequences(x_train, maxlen=maxlen) 47 | x_test = sequence.pad_sequences(x_test, maxlen=maxlen) 48 | print('x_train shape:', x_train.shape) 49 | print('x_test shape:', x_test.shape) 50 | 51 | print('Build model...') 52 | 53 | model = Sequential() 54 | model.add(Embedding(max_features, embedding_size, input_length=maxlen)) 55 | model.add(Dropout(0.25)) 56 | model.add(Conv1D(filters, 57 | kernel_size, 58 | padding='valid', 59 | activation='relu', 60 | strides=1)) 61 | model.add(MaxPooling1D(pool_size=pool_size)) 62 | model.add(LSTM(lstm_output_size)) 63 | model.add(Dense(1)) 64 | model.add(Activation('sigmoid')) 65 | 66 | model.compile(loss='binary_crossentropy', 67 | optimizer='adam', 68 | metrics=['accuracy']) 69 | 70 | print('Train...') 71 | model.fit(x_train, y_train, 72 | batch_size=batch_size, 73 | epochs=epochs, 74 | validation_data=(x_test, y_test)) 75 | score, acc = model.evaluate(x_test, y_test, batch_size=batch_size) 76 | print('Test score:', score) 77 | print('Test accuracy:', acc) 78 | ``` -------------------------------------------------------------------------------- /sources/examples/imdb_fasttext.md: -------------------------------------------------------------------------------- 1 | # 本示例演示了使用 fasttext 进行文本分类 2 | 3 | 根据Joulin等人的论文: 4 | 5 | [Bags of Tricks for Efficient Text Classification](https://arxiv.org/abs/1607.01759) 6 | 7 | 在具有 uni-gram 和 bi-gram 嵌入的 IMDB 数据集上的结果: 8 | 9 | Embedding|Accuracy, 5 epochs|Speed (s/epoch)|Hardware 10 | :--------|-----------------:|----:|:------- 11 | Uni-gram | 0.8813| 8|i7 CPU 12 | Bi-gram | 0.9056| 2|GTx 980M GPU 13 | 14 | 15 | ```python 16 | from __future__ import print_function 17 | import numpy as np 18 | 19 | from keras.preprocessing import sequence 20 | from keras.models import Sequential 21 | from keras.layers import Dense 22 | from keras.layers import Embedding 23 | from keras.layers import GlobalAveragePooling1D 24 | from keras.datasets import imdb 25 | 26 | 27 | def create_ngram_set(input_list, ngram_value=2): 28 | """ 29 | 从整数列表中提取一组 n 元语法。 30 | 31 | >>> create_ngram_set([1, 4, 9, 4, 1, 4], ngram_value=2) 32 | {(4, 9), (4, 1), (1, 4), (9, 4)} 33 | 34 | >>> create_ngram_set([1, 4, 9, 4, 1, 4], ngram_value=3) 35 | [(1, 4, 9), (4, 9, 4), (9, 4, 1), (4, 1, 4)] 36 | """ 37 | return set(zip(*[input_list[i:] for i in range(ngram_value)])) 38 | 39 | 40 | def add_ngram(sequences, token_indice, ngram_range=2): 41 | """ 42 | 通过附加 n-gram 值来增强列表(序列)的输入列表。 43 | 44 | 示例:添加 bi-gram 45 | >>> sequences = [[1, 3, 4, 5], [1, 3, 7, 9, 2]] 46 | >>> token_indice = {(1, 3): 1337, (9, 2): 42, (4, 5): 2017} 47 | >>> add_ngram(sequences, token_indice, ngram_range=2) 48 | [[1, 3, 4, 5, 1337, 2017], [1, 3, 7, 9, 2, 1337, 42]] 49 | 50 | 示例:添加 tri-gram 51 | >>> sequences = [[1, 3, 4, 5], [1, 3, 7, 9, 2]] 52 | >>> token_indice = {(1, 3): 1337, (9, 2): 42, (4, 5): 2017, (7, 9, 2): 2018} 53 | >>> add_ngram(sequences, token_indice, ngram_range=3) 54 | [[1, 3, 4, 5, 1337, 2017], [1, 3, 7, 9, 2, 1337, 42, 2018]] 55 | """ 56 | new_sequences = [] 57 | for input_list in sequences: 58 | new_list = input_list[:] 59 | for ngram_value in range(2, ngram_range + 1): 60 | for i in range(len(new_list) - ngram_value + 1): 61 | ngram = tuple(new_list[i:i + ngram_value]) 62 | if ngram in token_indice: 63 | new_list.append(token_indice[ngram]) 64 | new_sequences.append(new_list) 65 | 66 | return new_sequences 67 | 68 | # 设置参数 69 | # ngram_range = 2 会添加bi-grams 特征 70 | ngram_range = 1 71 | max_features = 20000 72 | maxlen = 400 73 | batch_size = 32 74 | embedding_dims = 50 75 | epochs = 5 76 | 77 | print('Loading data...') 78 | (x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features) 79 | print(len(x_train), 'train sequences') 80 | print(len(x_test), 'test sequences') 81 | print('Average train sequence length: {}'.format( 82 | np.mean(list(map(len, x_train)), dtype=int))) 83 | print('Average test sequence length: {}'.format( 84 | np.mean(list(map(len, x_test)), dtype=int))) 85 | 86 | if ngram_range > 1: 87 | print('Adding {}-gram features'.format(ngram_range)) 88 | # 从训练集中创建一组唯一的 n-gram。 89 | ngram_set = set() 90 | for input_list in x_train: 91 | for i in range(2, ngram_range + 1): 92 | set_of_ngram = create_ngram_set(input_list, ngram_value=i) 93 | ngram_set.update(set_of_ngram) 94 | 95 | # 将 n-gram token 映射到唯一整数的字典。 96 |     # 整数值大于 max_features, 97 | # 以避免与现有功能冲突。 98 | start_index = max_features + 1 99 | token_indice = {v: k + start_index for k, v in enumerate(ngram_set)} 100 | indice_token = {token_indice[k]: k for k in token_indice} 101 | 102 | # max_features 是可以在数据集中找到的最大整数。 103 | max_features = np.max(list(indice_token.keys())) + 1 104 | 105 | # 使用 n-grams 功能增强 x_train 和 x_test 106 | x_train = add_ngram(x_train, token_indice, ngram_range) 107 | x_test = add_ngram(x_test, token_indice, ngram_range) 108 | print('Average train sequence length: {}'.format( 109 | np.mean(list(map(len, x_train)), dtype=int))) 110 | print('Average test sequence length: {}'.format( 111 | np.mean(list(map(len, x_test)), dtype=int))) 112 | 113 | print('Pad sequences (samples x time)') 114 | x_train = sequence.pad_sequences(x_train, maxlen=maxlen) 115 | x_test = sequence.pad_sequences(x_test, maxlen=maxlen) 116 | print('x_train shape:', x_train.shape) 117 | print('x_test shape:', x_test.shape) 118 | 119 | print('Build model...') 120 | model = Sequential() 121 | 122 | # 我们从有效的嵌入层开始,该层将 vocab 索引映射到 embedding_dims 维度 123 | model.add(Embedding(max_features, 124 | embedding_dims, 125 | input_length=maxlen)) 126 | 127 | # 我们添加了 GlobalAveragePooling1D,它将对文档中所有单词执行平均嵌入 128 | model.add(GlobalAveragePooling1D()) 129 | 130 | # 我们投影到单个单位输出层上,并用 sigmoid 压扁它: 131 | model.add(Dense(1, activation='sigmoid')) 132 | 133 | model.compile(loss='binary_crossentropy', 134 | optimizer='adam', 135 | metrics=['accuracy']) 136 | 137 | model.fit(x_train, y_train, 138 | batch_size=batch_size, 139 | epochs=epochs, 140 | validation_data=(x_test, y_test)) 141 | ``` -------------------------------------------------------------------------------- /sources/examples/imdb_lstm.md: -------------------------------------------------------------------------------- 1 | # 在 IMDB 情感分类任务上训练 LSTM 模型。 2 | 3 | 与 TF-IDF + LogReg 之类的简单且快得多的方法相比,LSTM 实际上由于数据集太小而无济于事。 4 | 5 | **注意** 6 | 7 | - RNN 非常棘手。批次大小、损失和优化器的选择很重要,等等。某些配置无法收敛。 8 | - 训练期间的 LSTM 损失减少模式可能与你在 CNN/MLP 等中看到的完全不同。 9 | 10 | ```python 11 | from __future__ import print_function 12 | 13 | from keras.preprocessing import sequence 14 | from keras.models import Sequential 15 | from keras.layers import Dense, Embedding 16 | from keras.layers import LSTM 17 | from keras.datasets import imdb 18 | 19 | max_features = 20000 20 | # 在此数量的单词之后剪切文本(取最常见的 max_features 个单词) 21 | maxlen = 80 22 | batch_size = 32 23 | 24 | print('Loading data...') 25 | (x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features) 26 | print(len(x_train), 'train sequences') 27 | print(len(x_test), 'test sequences') 28 | 29 | print('Pad sequences (samples x time)') 30 | x_train = sequence.pad_sequences(x_train, maxlen=maxlen) 31 | x_test = sequence.pad_sequences(x_test, maxlen=maxlen) 32 | print('x_train shape:', x_train.shape) 33 | print('x_test shape:', x_test.shape) 34 | 35 | print('Build model...') 36 | model = Sequential() 37 | model.add(Embedding(max_features, 128)) 38 | model.add(LSTM(128, dropout=0.2, recurrent_dropout=0.2)) 39 | model.add(Dense(1, activation='sigmoid')) 40 | 41 | # 尝试使用不同的优化器和优化器配置 42 | model.compile(loss='binary_crossentropy', 43 | optimizer='adam', 44 | metrics=['accuracy']) 45 | 46 | print('Train...') 47 | model.fit(x_train, y_train, 48 | batch_size=batch_size, 49 | epochs=15, 50 | validation_data=(x_test, y_test)) 51 | score, acc = model.evaluate(x_test, y_test, 52 | batch_size=batch_size) 53 | print('Test score:', score) 54 | print('Test accuracy:', acc) 55 | ``` -------------------------------------------------------------------------------- /sources/examples/lstm_seq2seq.md: -------------------------------------------------------------------------------- 1 | 2 | # Keras 序列到序列模型示例(字符级)。 3 | 4 | 该脚本演示了如何实现基本的字符级序列到序列模型。 5 | 我们将其用于将英文短句逐个字符翻译成法语短句。 6 | 请注意,进行字符级机器翻译是非常不寻常的,因为在此领域中词级模型更为常见。 7 | 8 | 9 | 10 | **算法总结** 11 | 12 | - 我们从一个领域的输入序列(例如英语句子)和另一个领域的对应目标序列(例如法语句子)开始; 13 | - 编码器 LSTM 将输入序列变换为 2 个状态向量(我们保留最后的 LSTM 状态并丢弃输出); 14 | - 对解码器 LSTM 进行训练,以将目标序列转换为相同序列,但以后将偏移一个时间步,在这种情况下,该训练过程称为 "教师强制"。 15 | 它使用编码器的输出。实际上,解码器会根据输入序列,根据给定的 `targets[...t]` 来学习生成 `target[t+1...]`。 16 | - 在推理模式下,当我们想解码未知的输入序列时,我们: 17 | - 对输入序列进行编码; 18 | - 从大小为1的目标序列开始(仅是序列开始字符); 19 | - 将输入序列和 1 个字符的目标序列馈送到解码器,以生成下一个字符的预测; 20 | - 使用这些预测来采样下一个字符(我们仅使用 argmax); 21 | - 将采样的字符附加到目标序列; 22 | - 重复直到我们达到字符数限制。 23 | 24 | **数据下载** 25 | 26 | [English to French sentence pairs. 27 | ](http://www.manythings.org/anki/fra-eng.zip) 28 | 29 | [Lots of neat sentence pairs datasets. 30 | ](http://www.manythings.org/anki/) 31 | 32 | **参考** 33 | 34 | - [Sequence to Sequence Learning with Neural Networks 35 | ](https://arxiv.org/abs/1409.3215) 36 | - [Learning Phrase Representations using 37 | RNN Encoder-Decoder for Statistical Machine Translation 38 | ](https://arxiv.org/abs/1406.1078) 39 | 40 | 41 | ```python 42 | from __future__ import print_function 43 | 44 | from keras.models import Model 45 | from keras.layers import Input, LSTM, Dense 46 | import numpy as np 47 | 48 | batch_size = 64 # 训练批次大小。 49 | epochs = 100 # 训练迭代轮次。 50 | latent_dim = 256 # 编码空间隐层维度。 51 | num_samples = 10000 # 训练样本数。 52 | # 磁盘数据文件路径。 53 | data_path = 'fra-eng/fra.txt' 54 | 55 | # 向量化数据。 56 | input_texts = [] 57 | target_texts = [] 58 | input_characters = set() 59 | target_characters = set() 60 | with open(data_path, 'r', encoding='utf-8') as f: 61 | lines = f.read().split('\n') 62 | for line in lines[: min(num_samples, len(lines) - 1)]: 63 | input_text, target_text = line.split('\t') 64 | # 我们使用 "tab" 作为 "起始序列" 字符, 65 | # 对于目标,使用 "\n" 作为 "终止序列" 字符。 66 | target_text = '\t' + target_text + '\n' 67 | input_texts.append(input_text) 68 | target_texts.append(target_text) 69 | for char in input_text: 70 | if char not in input_characters: 71 | input_characters.add(char) 72 | for char in target_text: 73 | if char not in target_characters: 74 | target_characters.add(char) 75 | 76 | input_characters = sorted(list(input_characters)) 77 | target_characters = sorted(list(target_characters)) 78 | num_encoder_tokens = len(input_characters) 79 | num_decoder_tokens = len(target_characters) 80 | max_encoder_seq_length = max([len(txt) for txt in input_texts]) 81 | max_decoder_seq_length = max([len(txt) for txt in target_texts]) 82 | 83 | print('Number of samples:', len(input_texts)) 84 | print('Number of unique input tokens:', num_encoder_tokens) 85 | print('Number of unique output tokens:', num_decoder_tokens) 86 | print('Max sequence length for inputs:', max_encoder_seq_length) 87 | print('Max sequence length for outputs:', max_decoder_seq_length) 88 | 89 | input_token_index = dict( 90 | [(char, i) for i, char in enumerate(input_characters)]) 91 | target_token_index = dict( 92 | [(char, i) for i, char in enumerate(target_characters)]) 93 | 94 | encoder_input_data = np.zeros( 95 | (len(input_texts), max_encoder_seq_length, num_encoder_tokens), 96 | dtype='float32') 97 | decoder_input_data = np.zeros( 98 | (len(input_texts), max_decoder_seq_length, num_decoder_tokens), 99 | dtype='float32') 100 | decoder_target_data = np.zeros( 101 | (len(input_texts), max_decoder_seq_length, num_decoder_tokens), 102 | dtype='float32') 103 | 104 | for i, (input_text, target_text) in enumerate(zip(input_texts, target_texts)): 105 | for t, char in enumerate(input_text): 106 | encoder_input_data[i, t, input_token_index[char]] = 1. 107 | encoder_input_data[i, t + 1:, input_token_index[' ']] = 1. 108 | for t, char in enumerate(target_text): 109 | # decoder_target_data 领先 decoder_input_data by 一个时间步。 110 | decoder_input_data[i, t, target_token_index[char]] = 1. 111 | if t > 0: 112 | # decoder_target_data 将提前一个时间步,并且将不包含开始字符。 113 | decoder_target_data[i, t - 1, target_token_index[char]] = 1. 114 | decoder_input_data[i, t + 1:, target_token_index[' ']] = 1. 115 | decoder_target_data[i, t:, target_token_index[' ']] = 1. 116 | # 定义输入序列并处理它。 117 | encoder_inputs = Input(shape=(None, num_encoder_tokens)) 118 | encoder = LSTM(latent_dim, return_state=True) 119 | encoder_outputs, state_h, state_c = encoder(encoder_inputs) 120 | # 我们抛弃 `encoder_outputs`,只保留状态。 121 | encoder_states = [state_h, state_c] 122 | 123 | # 使用 `encoder_states` 作为初始状态来设置解码器。 124 | decoder_inputs = Input(shape=(None, num_decoder_tokens)) 125 | # 我们将解码器设置为返回完整的输出序列,并返回内部状态。 126 | # 我们不在训练模型中使用返回状态,但将在推理中使用它们。 127 | decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True) 128 | decoder_outputs, _, _ = decoder_lstm(decoder_inputs, 129 | initial_state=encoder_states) 130 | decoder_dense = Dense(num_decoder_tokens, activation='softmax') 131 | decoder_outputs = decoder_dense(decoder_outputs) 132 | 133 | # 定义模型,将 `encoder_input_data` & `decoder_input_data` 转换为 `decoder_target_data` 134 | model = Model([encoder_inputs, decoder_inputs], decoder_outputs) 135 | 136 | # 执行训练 137 | model.compile(optimizer='rmsprop', loss='categorical_crossentropy', 138 | metrics=['accuracy']) 139 | model.fit([encoder_input_data, decoder_input_data], decoder_target_data, 140 | batch_size=batch_size, 141 | epochs=epochs, 142 | validation_split=0.2) 143 | # 保存模型 144 | model.save('s2s.h5') 145 | 146 | # 接下来: 推理模式 (采样)。 147 | # 这是演习: 148 | # 1) 编码输入并检索初始解码器状态 149 | # 2) 以该初始状态和 "序列开始" token 为目标运行解码器的一步。 输出将是下一个目标 token。 150 | # 3) 重复当前目标 token 和当前状态 151 | 152 | # 定义采样模型 153 | encoder_model = Model(encoder_inputs, encoder_states) 154 | 155 | decoder_state_input_h = Input(shape=(latent_dim,)) 156 | decoder_state_input_c = Input(shape=(latent_dim,)) 157 | decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c] 158 | decoder_outputs, state_h, state_c = decoder_lstm( 159 | decoder_inputs, initial_state=decoder_states_inputs) 160 | decoder_states = [state_h, state_c] 161 | decoder_outputs = decoder_dense(decoder_outputs) 162 | decoder_model = Model( 163 | [decoder_inputs] + decoder_states_inputs, 164 | [decoder_outputs] + decoder_states) 165 | 166 | # 反向查询 token 索引可将序列解码回可读的内容。 167 | reverse_input_char_index = dict( 168 | (i, char) for char, i in input_token_index.items()) 169 | reverse_target_char_index = dict( 170 | (i, char) for char, i in target_token_index.items()) 171 | 172 | 173 | def decode_sequence(input_seq): 174 | # 将输入编码为状态向量。 175 | states_value = encoder_model.predict(input_seq) 176 | 177 | # 生成长度为 1 的空目标序列。 178 | target_seq = np.zeros((1, 1, num_decoder_tokens)) 179 | # 用起始字符填充目标序列的第一个字符。 180 | target_seq[0, 0, target_token_index['\t']] = 1. 181 | 182 | # 一批序列的采样循环 183 | # (为了简化,这里我们假设一批大小为 1)。 184 | stop_condition = False 185 | decoded_sentence = '' 186 | while not stop_condition: 187 | output_tokens, h, c = decoder_model.predict( 188 | [target_seq] + states_value) 189 | 190 | # 采样一个 token 191 | sampled_token_index = np.argmax(output_tokens[0, -1, :]) 192 | sampled_char = reverse_target_char_index[sampled_token_index] 193 | decoded_sentence += sampled_char 194 | 195 | # 退出条件:达到最大长度或找到停止符。 196 | if (sampled_char == '\n' or 197 | len(decoded_sentence) > max_decoder_seq_length): 198 | stop_condition = True 199 | 200 | # 更新目标序列(长度为 1)。 201 | target_seq = np.zeros((1, 1, num_decoder_tokens)) 202 | target_seq[0, 0, sampled_token_index] = 1. 203 | 204 | # 更新状态 205 | states_value = [h, c] 206 | 207 | return decoded_sentence 208 | 209 | 210 | for seq_index in range(100): 211 | # 抽取一个序列(训练集的一部分)进行解码。 212 | input_seq = encoder_input_data[seq_index: seq_index + 1] 213 | decoded_sentence = decode_sequence(input_seq) 214 | print('-') 215 | print('Input sentence:', input_texts[seq_index]) 216 | print('Decoded sentence:', decoded_sentence) 217 | ``` 218 | -------------------------------------------------------------------------------- /sources/examples/lstm_seq2seq_restore.md: -------------------------------------------------------------------------------- 1 | 2 | # 还原字符级序列到序列模型以生成预测。 3 | 4 | 该脚本载入由 [lstm_seq2seq.py](/examples/lstm_seq2seq/) 保存的 ```s2s.h5``` 模型,并从中生成序列。 5 | 它假设其未作任何改变(例如,```latent_dim```、输入数据和模型结构均不变)。 6 | 7 | 有关模型结构细节以及如何训练,参见 [lstm_seq2seq.py](/examples/lstm_seq2seq/)。 8 | 9 | 10 | ```python 11 | from __future__ import print_function 12 | 13 | from keras.models import Model, load_model 14 | from keras.layers import Input 15 | import numpy as np 16 | 17 | batch_size = 64 # 训练批次大小。 18 | epochs = 100 # 训练轮次数。 19 | latent_dim = 256 # 编码空间隐层维度。 20 | num_samples = 10000 # 训练样本数。 21 | # 磁盘中数据文件路径。 22 | data_path = 'fra-eng/fra.txt' 23 | 24 | # 向量化数据。使用与训练脚本相同的方法。 25 | # 注意: 数据必须相同,以使字符->整数映射保持一致。 26 | # 我们省略对 target_texts 的编码,因为不需要它们。 27 | input_texts = [] 28 | target_texts = [] 29 | input_characters = set() 30 | target_characters = set() 31 | with open(data_path, 'r', encoding='utf-8') as f: 32 | lines = f.read().split('\n') 33 | for line in lines[: min(num_samples, len(lines) - 1)]: 34 | input_text, target_text = line.split('\t') 35 | # 我们使用 "tab" 作为目标的 "开始序列" 字符,并使用 "\n" 作为 "结束序列" 字符。 36 | target_text = '\t' + target_text + '\n' 37 | input_texts.append(input_text) 38 | target_texts.append(target_text) 39 | for char in input_text: 40 | if char not in input_characters: 41 | input_characters.add(char) 42 | for char in target_text: 43 | if char not in target_characters: 44 | target_characters.add(char) 45 | 46 | input_characters = sorted(list(input_characters)) 47 | target_characters = sorted(list(target_characters)) 48 | num_encoder_tokens = len(input_characters) 49 | num_decoder_tokens = len(target_characters) 50 | max_encoder_seq_length = max([len(txt) for txt in input_texts]) 51 | max_decoder_seq_length = max([len(txt) for txt in target_texts]) 52 | 53 | print('Number of samples:', len(input_texts)) 54 | print('Number of unique input tokens:', num_encoder_tokens) 55 | print('Number of unique output tokens:', num_decoder_tokens) 56 | print('Max sequence length for inputs:', max_encoder_seq_length) 57 | print('Max sequence length for outputs:', max_decoder_seq_length) 58 | 59 | input_token_index = dict( 60 | [(char, i) for i, char in enumerate(input_characters)]) 61 | target_token_index = dict( 62 | [(char, i) for i, char in enumerate(target_characters)]) 63 | 64 | encoder_input_data = np.zeros( 65 | (len(input_texts), max_encoder_seq_length, num_encoder_tokens), 66 | dtype='float32') 67 | 68 | for i, input_text in enumerate(input_texts): 69 | for t, char in enumerate(input_text): 70 | encoder_input_data[i, t, input_token_index[char]] = 1. 71 | 72 | # 恢复模型并构造编码器和解码器。 73 | model = load_model('s2s.h5') 74 | 75 | encoder_inputs = model.input[0] # input_1 76 | encoder_outputs, state_h_enc, state_c_enc = model.layers[2].output # lstm_1 77 | encoder_states = [state_h_enc, state_c_enc] 78 | encoder_model = Model(encoder_inputs, encoder_states) 79 | 80 | decoder_inputs = model.input[1] # input_2 81 | decoder_state_input_h = Input(shape=(latent_dim,), name='input_3') 82 | decoder_state_input_c = Input(shape=(latent_dim,), name='input_4') 83 | decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c] 84 | decoder_lstm = model.layers[3] 85 | decoder_outputs, state_h_dec, state_c_dec = decoder_lstm( 86 | decoder_inputs, initial_state=decoder_states_inputs) 87 | decoder_states = [state_h_dec, state_c_dec] 88 | decoder_dense = model.layers[4] 89 | decoder_outputs = decoder_dense(decoder_outputs) 90 | decoder_model = Model( 91 | [decoder_inputs] + decoder_states_inputs, 92 | [decoder_outputs] + decoder_states) 93 | 94 | # 反向查询 token 索引可将序列解码回可读的内容。 95 | reverse_input_char_index = dict( 96 | (i, char) for char, i in input_token_index.items()) 97 | reverse_target_char_index = dict( 98 | (i, char) for char, i in target_token_index.items()) 99 | 100 | 101 | # 解码输入序列。未来的工作应支持波束搜索。 102 | def decode_sequence(input_seq): 103 | # 将输入编码为状态向量。 104 | states_value = encoder_model.predict(input_seq) 105 | 106 | # 生成长度为 1 的空目标序列。 107 | target_seq = np.zeros((1, 1, num_decoder_tokens)) 108 | # 用起始字符填充目标序列的第一个字符。 109 | target_seq[0, 0, target_token_index['\t']] = 1. 110 | 111 | # 一批序列的采样循环 112 | # (为了简化,这里我们假设一批大小为 1)。 113 | stop_condition = False 114 | decoded_sentence = '' 115 | while not stop_condition: 116 | output_tokens, h, c = decoder_model.predict( 117 | [target_seq] + states_value) 118 | 119 | # 采样一个 token 120 | sampled_token_index = np.argmax(output_tokens[0, -1, :]) 121 | sampled_char = reverse_target_char_index[sampled_token_index] 122 | decoded_sentence += sampled_char 123 | 124 | # 退出条件:达到最大长度或找到停止符。 125 | if (sampled_char == '\n' or 126 | len(decoded_sentence) > max_decoder_seq_length): 127 | stop_condition = True 128 | 129 | # 更新目标序列(长度为 1)。 130 | target_seq = np.zeros((1, 1, num_decoder_tokens)) 131 | target_seq[0, 0, sampled_token_index] = 1. 132 | 133 | # 更新状态 134 | states_value = [h, c] 135 | 136 | return decoded_sentence 137 | 138 | 139 | for seq_index in range(100): 140 | # 抽取一个序列(训练集的一部分)进行解码。 141 | input_seq = encoder_input_data[seq_index: seq_index + 1] 142 | decoded_sentence = decode_sequence(input_seq) 143 | print('-') 144 | print('Input sentence:', input_texts[seq_index]) 145 | print('Decoded sentence:', decoded_sentence) 146 | ``` -------------------------------------------------------------------------------- /sources/examples/lstm_stateful.md: -------------------------------------------------------------------------------- 1 | 2 | # 如何使用有状态 LSTM 模型,有状态与无状态 LSTM 性能比较 3 | 4 | [有关 Keras LSTM 模型的更多文档](/layers/recurrent/#lstm) 5 | 6 | 在输入/输出对上训练模型,其中输入是生成的长度为 `input_len` 的均匀分布随机序列, 7 | 输出是窗口长度为 `tsteps` 的输入的移动平均值。`input_len` 和 `tsteps` 都在 "可编辑参数" 部分中定义。 8 | 9 | 较大的 `tsteps` 值意味着 LSTM 需要更多的内存来确定输入输出关系。 10 | 该内存长度由 `lahead` 变量控制(下面有更多详细信息)。 11 | 12 | 其余参数为: 13 | 14 | - `input_len`: 生成的输入序列的长度 15 | - `lahead`: LSTM 针对每个输出点训练的输入序列长度 16 | - `batch_size`, `epochs`: 与 `model.fit(...)` 函数中的参数相同 17 | 18 | 当 `lahead > 1` 时,模型输入将预处理为数据的 "滚动窗口视图",窗口长度为 `lahead`。 19 | 这类似于 sklearn 的 `view_as_windows`, 20 | 其中 `window_shape` [是一个数字。](http://scikit-image.org/docs/0.10.x/api/skimage.util.html#view-as-windows) 21 | 22 | 当 `lahead < tsteps` 时,只有有状态的 LSTM 会收敛,因为它的有状态性使其能够看到超出 lahead 赋予其的 n 点平均值的能力。 23 | 无状态 LSTM 不具备此功能,因此受到其 `lahead` 参数的限制,该参数不足以查看 n 点平均值。 24 | 25 | 当 `lahead >= tsteps` 时,有状态和无状态 LSTM 都会收敛。 26 | 27 | 28 | ```python 29 | from __future__ import print_function 30 | import numpy as np 31 | import matplotlib.pyplot as plt 32 | import pandas as pd 33 | from keras.models import Sequential 34 | from keras.layers import Dense, LSTM 35 | 36 | # ---------------------------------------------------------- 37 | # 可编辑参数 38 | # 阅读脚本头中的文档以获取更多详细信息 39 | # ---------------------------------------------------------- 40 | 41 | # 输入长度 42 | input_len = 1000 43 | 44 | # 用于从训练 LSTM 的输入/输出对中的输入生成输出的移动平均值的窗口长度 45 | # 例如,如果 tsteps=2,input=[1, 2, 3, 4, 5], 46 | # 那么 output=[1.5, 2.5, 3.5, 4.5] 47 | tsteps = 2 48 | 49 | # LSTM 针对每个输出点训练的输入序列长度 50 | lahead = 1 51 | 52 | # 传递给 "model.fit(...)" 的训练参数 53 | batch_size = 1 54 | epochs = 10 55 | 56 | # ------------ 57 | # 主程序 58 | # ------------ 59 | 60 | print("*" * 33) 61 | if lahead >= tsteps: 62 | print("STATELESS LSTM WILL ALSO CONVERGE") 63 | else: 64 | print("STATELESS LSTM WILL NOT CONVERGE") 65 | print("*" * 33) 66 | 67 | np.random.seed(1986) 68 | 69 | print('Generating Data...') 70 | 71 | 72 | def gen_uniform_amp(amp=1, xn=10000): 73 | """生成 -amp 和 +amp 之间且长度为 xn 的均匀随机数据 74 | 75 | # 参数 76 | amp: 统一数据的最大/最小范围 77 | xn: 系列长度 78 | """ 79 | data_input = np.random.uniform(-1 * amp, +1 * amp, xn) 80 | data_input = pd.DataFrame(data_input) 81 | return data_input 82 | 83 | # 由于输出是输入的移动平均值, 84 | # 因此输出的前几个点将是 NaN, 85 | # 并且在训练 LSTM 之前将其从生成的数据中删除。 86 | # 同样,当 lahead > 1时,"滚动窗口视图" 87 | # 后面的预处理步骤也将导致某些点丢失。 88 | # 出于美学原因,为了在预处理后保持生成的数据长度等于 input_len,请添加一些点以说明将丢失的值。 89 | to_drop = max(tsteps - 1, lahead - 1) 90 | data_input = gen_uniform_amp(amp=0.1, xn=input_len + to_drop) 91 | 92 | # 将目标设置为输入的 N 点平均值 93 | expected_output = data_input.rolling(window=tsteps, center=False).mean() 94 | 95 | # 当 lahead > 1时,需要将输入转换为 "滚动窗口视图" 96 | # https://docs.scipy.org/doc/numpy/reference/generated/numpy.repeat.html 97 | if lahead > 1: 98 | data_input = np.repeat(data_input.values, repeats=lahead, axis=1) 99 | data_input = pd.DataFrame(data_input) 100 | for i, c in enumerate(data_input.columns): 101 | data_input[c] = data_input[c].shift(i) 102 | 103 | # 丢弃 nan 104 | expected_output = expected_output[to_drop:] 105 | data_input = data_input[to_drop:] 106 | 107 | print('Input shape:', data_input.shape) 108 | print('Output shape:', expected_output.shape) 109 | print('Input head: ') 110 | print(data_input.head()) 111 | print('Output head: ') 112 | print(expected_output.head()) 113 | print('Input tail: ') 114 | print(data_input.tail()) 115 | print('Output tail: ') 116 | print(expected_output.tail()) 117 | 118 | print('Plotting input and expected output') 119 | plt.plot(data_input[0][:10], '.') 120 | plt.plot(expected_output[0][:10], '-') 121 | plt.legend(['Input', 'Expected output']) 122 | plt.title('Input') 123 | plt.show() 124 | 125 | 126 | def create_model(stateful): 127 | model = Sequential() 128 | model.add(LSTM(20, 129 | input_shape=(lahead, 1), 130 | batch_size=batch_size, 131 | stateful=stateful)) 132 | model.add(Dense(1)) 133 | model.compile(loss='mse', optimizer='adam') 134 | return model 135 | 136 | print('Creating Stateful Model...') 137 | model_stateful = create_model(stateful=True) 138 | 139 | 140 | # 切分训练/测试数据 141 | def split_data(x, y, ratio=0.8): 142 | to_train = int(input_len * ratio) 143 | # 进行调整以匹配 batch_size 144 | to_train -= to_train % batch_size 145 | 146 | x_train = x[:to_train] 147 | y_train = y[:to_train] 148 | x_test = x[to_train:] 149 | y_test = y[to_train:] 150 | 151 | # 进行调整以匹配 batch_size 152 | to_drop = x.shape[0] % batch_size 153 | if to_drop > 0: 154 | x_test = x_test[:-1 * to_drop] 155 | y_test = y_test[:-1 * to_drop] 156 | 157 | # 一些重塑 158 | reshape_3 = lambda x: x.values.reshape((x.shape[0], x.shape[1], 1)) 159 | x_train = reshape_3(x_train) 160 | x_test = reshape_3(x_test) 161 | 162 | reshape_2 = lambda x: x.values.reshape((x.shape[0], 1)) 163 | y_train = reshape_2(y_train) 164 | y_test = reshape_2(y_test) 165 | 166 | return (x_train, y_train), (x_test, y_test) 167 | 168 | 169 | (x_train, y_train), (x_test, y_test) = split_data(data_input, expected_output) 170 | print('x_train.shape: ', x_train.shape) 171 | print('y_train.shape: ', y_train.shape) 172 | print('x_test.shape: ', x_test.shape) 173 | print('y_test.shape: ', y_test.shape) 174 | 175 | print('Training') 176 | for i in range(epochs): 177 | print('Epoch', i + 1, '/', epochs) 178 | # 请注意,批次 i 中样品 i 的最后状态将用作下一批中样品 i 的初始状态。 179 | # 因此,我们同时以低于 data_input 中包含的原始序列的分辨率对 batch_size 系列进行训练。 180 | # 这些系列中的每一个都偏移一个步骤,并且可以使用 data_input[i::batch_size] 提取。 181 | model_stateful.fit(x_train, 182 | y_train, 183 | batch_size=batch_size, 184 | epochs=1, 185 | verbose=1, 186 | validation_data=(x_test, y_test), 187 | shuffle=False) 188 | model_stateful.reset_states() 189 | 190 | print('Predicting') 191 | predicted_stateful = model_stateful.predict(x_test, batch_size=batch_size) 192 | 193 | print('Creating Stateless Model...') 194 | model_stateless = create_model(stateful=False) 195 | 196 | print('Training') 197 | model_stateless.fit(x_train, 198 | y_train, 199 | batch_size=batch_size, 200 | epochs=epochs, 201 | verbose=1, 202 | validation_data=(x_test, y_test), 203 | shuffle=False) 204 | 205 | print('Predicting') 206 | predicted_stateless = model_stateless.predict(x_test, batch_size=batch_size) 207 | 208 | # ---------------------------- 209 | 210 | print('Plotting Results') 211 | plt.subplot(3, 1, 1) 212 | plt.plot(y_test) 213 | plt.title('Expected') 214 | plt.subplot(3, 1, 2) 215 | # 删除第一个 "tsteps-1",因为不可能预测它们,因为不存在要使用的 "上一个" 时间步 216 | plt.plot((y_test - predicted_stateful).flatten()[tsteps - 1:]) 217 | plt.title('Stateful: Expected - Predicted') 218 | plt.subplot(3, 1, 3) 219 | plt.plot((y_test - predicted_stateless).flatten()) 220 | plt.title('Stateless: Expected - Predicted') 221 | plt.show() 222 | ``` -------------------------------------------------------------------------------- /sources/examples/lstm_text_generation.md: -------------------------------------------------------------------------------- 1 | 2 | # 从尼采作品生成文本的示例脚本。 3 | 4 | 生成的文本开始听起来连贯之前,至少需要 20 个轮次。 5 | 6 | 建议在 GPU 上运行此脚本,因为循环网络的计算量很大。 7 | 8 | 如果在新数据上尝试使用此脚本,请确保您的语料库至少包含约 10 万个字符。〜1M 更好。 9 | 10 | 11 | ```python 12 | from __future__ import print_function 13 | from keras.callbacks import LambdaCallback 14 | from keras.models import Sequential 15 | from keras.layers import Dense 16 | from keras.layers import LSTM 17 | from keras.optimizers import RMSprop 18 | from keras.utils.data_utils import get_file 19 | import numpy as np 20 | import random 21 | import sys 22 | import io 23 | 24 | path = get_file( 25 | 'nietzsche.txt', 26 | origin='https://s3.amazonaws.com/text-datasets/nietzsche.txt') 27 | with io.open(path, encoding='utf-8') as f: 28 | text = f.read().lower() 29 | print('corpus length:', len(text)) 30 | 31 | chars = sorted(list(set(text))) 32 | print('total chars:', len(chars)) 33 | char_indices = dict((c, i) for i, c in enumerate(chars)) 34 | indices_char = dict((i, c) for i, c in enumerate(chars)) 35 | 36 | # 以 maxlen 字符的半冗余序列剪切文本 37 | maxlen = 40 38 | step = 3 39 | sentences = [] 40 | next_chars = [] 41 | for i in range(0, len(text) - maxlen, step): 42 | sentences.append(text[i: i + maxlen]) 43 | next_chars.append(text[i + maxlen]) 44 | print('nb sequences:', len(sentences)) 45 | 46 | print('Vectorization...') 47 | x = np.zeros((len(sentences), maxlen, len(chars)), dtype=np.bool) 48 | y = np.zeros((len(sentences), len(chars)), dtype=np.bool) 49 | for i, sentence in enumerate(sentences): 50 | for t, char in enumerate(sentence): 51 | x[i, t, char_indices[char]] = 1 52 | y[i, char_indices[next_chars[i]]] = 1 53 | 54 | 55 | # 建立模型:单个 LSTM 56 | print('Build model...') 57 | model = Sequential() 58 | model.add(LSTM(128, input_shape=(maxlen, len(chars)))) 59 | model.add(Dense(len(chars), activation='softmax')) 60 | 61 | optimizer = RMSprop(learning_rate=0.01) 62 | model.compile(loss='categorical_crossentropy', optimizer=optimizer) 63 | 64 | 65 | def sample(preds, temperature=1.0): 66 | # 辅助函数从概率数组中采样索引 67 | preds = np.asarray(preds).astype('float64') 68 | preds = np.log(preds) / temperature 69 | exp_preds = np.exp(preds) 70 | preds = exp_preds / np.sum(exp_preds) 71 | probas = np.random.multinomial(1, preds, 1) 72 | return np.argmax(probas) 73 | 74 | 75 | def on_epoch_end(epoch, _): 76 | # 在每个轮次结束时调用的函数。 打印生成的文本。 77 | print() 78 | print('----- Generating text after Epoch: %d' % epoch) 79 | 80 | start_index = random.randint(0, len(text) - maxlen - 1) 81 | for diversity in [0.2, 0.5, 1.0, 1.2]: 82 | print('----- diversity:', diversity) 83 | 84 | generated = '' 85 | sentence = text[start_index: start_index + maxlen] 86 | generated += sentence 87 | print('----- Generating with seed: "' + sentence + '"') 88 | sys.stdout.write(generated) 89 | 90 | for i in range(400): 91 | x_pred = np.zeros((1, maxlen, len(chars))) 92 | for t, char in enumerate(sentence): 93 | x_pred[0, t, char_indices[char]] = 1. 94 | 95 | preds = model.predict(x_pred, verbose=0)[0] 96 | next_index = sample(preds, diversity) 97 | next_char = indices_char[next_index] 98 | 99 | sentence = sentence[1:] + next_char 100 | 101 | sys.stdout.write(next_char) 102 | sys.stdout.flush() 103 | print() 104 | 105 | print_callback = LambdaCallback(on_epoch_end=on_epoch_end) 106 | 107 | model.fit(x, y, 108 | batch_size=128, 109 | epochs=60, 110 | callbacks=[print_callback]) 111 | ``` -------------------------------------------------------------------------------- /sources/examples/mnist_cnn.md: -------------------------------------------------------------------------------- 1 | # 在 MNIST 数据集上训练一个简单的 convnet。 2 | 3 | 12 个轮次后达到 99.25% 的测试准确度 4 | (参数调整仍有很多余地)。 5 | 在 GRID K520 GPU 上,每个轮次 16秒。 6 | 7 | 8 | ```python 9 | from __future__ import print_function 10 | import keras 11 | from keras.datasets import mnist 12 | from keras.models import Sequential 13 | from keras.layers import Dense, Dropout, Flatten 14 | from keras.layers import Conv2D, MaxPooling2D 15 | from keras import backend as K 16 | 17 | batch_size = 128 18 | num_classes = 10 19 | epochs = 12 20 | 21 | # 输入图像尺寸 22 | img_rows, img_cols = 28, 28 23 | 24 | # 数据,分为训练集和测试集 25 | (x_train, y_train), (x_test, y_test) = mnist.load_data() 26 | 27 | if K.image_data_format() == 'channels_first': 28 | x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols) 29 | x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols) 30 | input_shape = (1, img_rows, img_cols) 31 | else: 32 | x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1) 33 | x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1) 34 | input_shape = (img_rows, img_cols, 1) 35 | 36 | x_train = x_train.astype('float32') 37 | x_test = x_test.astype('float32') 38 | x_train /= 255 39 | x_test /= 255 40 | print('x_train shape:', x_train.shape) 41 | print(x_train.shape[0], 'train samples') 42 | print(x_test.shape[0], 'test samples') 43 | 44 | # 将类向量转换为二进制类矩阵 45 | y_train = keras.utils.to_categorical(y_train, num_classes) 46 | y_test = keras.utils.to_categorical(y_test, num_classes) 47 | 48 | model = Sequential() 49 | model.add(Conv2D(32, kernel_size=(3, 3), 50 | activation='relu', 51 | input_shape=input_shape)) 52 | model.add(Conv2D(64, (3, 3), activation='relu')) 53 | model.add(MaxPooling2D(pool_size=(2, 2))) 54 | model.add(Dropout(0.25)) 55 | model.add(Flatten()) 56 | model.add(Dense(128, activation='relu')) 57 | model.add(Dropout(0.5)) 58 | model.add(Dense(num_classes, activation='softmax')) 59 | 60 | model.compile(loss=keras.losses.categorical_crossentropy, 61 | optimizer=keras.optimizers.Adadelta(), 62 | metrics=['accuracy']) 63 | 64 | model.fit(x_train, y_train, 65 | batch_size=batch_size, 66 | epochs=epochs, 67 | verbose=1, 68 | validation_data=(x_test, y_test)) 69 | score = model.evaluate(x_test, y_test, verbose=0) 70 | print('Test loss:', score[0]) 71 | print('Test accuracy:', score[1]) 72 | ``` -------------------------------------------------------------------------------- /sources/examples/mnist_denoising_autoencoder.md: -------------------------------------------------------------------------------- 1 | # 在 MNIST 数据集上训练去噪自动编码器。 2 | 3 | 去噪是自动编码器的经典应用之一。 4 | 去噪过程去除了破坏真实信号的有害噪声。 5 | 6 | 噪声 + 数据 ---> 去噪自动编码器 ---> 数据 7 | 8 | 给定训练数据集的损坏数据作为输入,输出真实信号作为输出, 9 | 去噪自动编码器可以恢复隐藏的结构以生成干净的数据。 10 | 11 | 此示例具有模块化设计。编码器、解码器和自动编码器是 3 种共享权重的模型。 12 | 例如,在训练自动编码器之后,编码器可用于生成输入数据的潜在矢量,以实现低维可视化(如 PCA 或 TSNE)。 13 | 14 | 15 | ```python 16 | from __future__ import absolute_import 17 | from __future__ import division 18 | from __future__ import print_function 19 | import keras 20 | from keras.layers import Activation, Dense, Input 21 | from keras.layers import Conv2D, Flatten 22 | from keras.layers import Reshape, Conv2DTranspose 23 | from keras.models import Model 24 | from keras import backend as K 25 | from keras.datasets import mnist 26 | import numpy as np 27 | import matplotlib.pyplot as plt 28 | from PIL import Image 29 | 30 | np.random.seed(1337) 31 | 32 | # MNIST 数据集 33 | (x_train, _), (x_test, _) = mnist.load_data() 34 | 35 | image_size = x_train.shape[1] 36 | x_train = np.reshape(x_train, [-1, image_size, image_size, 1]) 37 | x_test = np.reshape(x_test, [-1, image_size, image_size, 1]) 38 | x_train = x_train.astype('float32') / 255 39 | x_test = x_test.astype('float32') / 255 40 | 41 | # 通过添加法线距离为 0.5 且 std=0.5 的噪声来生成损坏的 MNIST 图像 42 | noise = np.random.normal(loc=0.5, scale=0.5, size=x_train.shape) 43 | x_train_noisy = x_train + noise 44 | noise = np.random.normal(loc=0.5, scale=0.5, size=x_test.shape) 45 | x_test_noisy = x_test + noise 46 | 47 | x_train_noisy = np.clip(x_train_noisy, 0., 1.) 48 | x_test_noisy = np.clip(x_test_noisy, 0., 1.) 49 | 50 | # 网络参数 51 | input_shape = (image_size, image_size, 1) 52 | batch_size = 128 53 | kernel_size = 3 54 | latent_dim = 16 55 | # CNN 层和每层过滤器的编码器/解码器数量 56 | layer_filters = [32, 64] 57 | 58 | # 建立自动编码器模型 59 | # 首先建立编码器模型 60 | inputs = Input(shape=input_shape, name='encoder_input') 61 | x = inputs 62 | # Conv2D块的堆栈 63 | # 注意: 64 | # 1) 在深度网络上的 ReLU 之前使用批处理规范化 65 | # 2) 使用 MaxPooling2D 替代 strides>1 66 | # - 更快但不如 strides>1 好 67 | for filters in layer_filters: 68 | x = Conv2D(filters=filters, 69 | kernel_size=kernel_size, 70 | strides=2, 71 | activation='relu', 72 | padding='same')(x) 73 | 74 | # 构建解码器模型所需的形状信息 75 | shape = K.int_shape(x) 76 | 77 | # 生成潜在向量 78 | x = Flatten()(x) 79 | latent = Dense(latent_dim, name='latent_vector')(x) 80 | 81 | # 实例化编码器模型 82 | encoder = Model(inputs, latent, name='encoder') 83 | encoder.summary() 84 | 85 | # 建立解码器模型 86 | latent_inputs = Input(shape=(latent_dim,), name='decoder_input') 87 | x = Dense(shape[1] * shape[2] * shape[3])(latent_inputs) 88 | x = Reshape((shape[1], shape[2], shape[3]))(x) 89 | 90 | # 转置 Conv2D 块的堆栈 91 | # 注意: 92 | # 1) 在深度网络上的 ReLU 之前使用批处理规范化 93 | # 2) 使用 UpSampling2D 替代 strides>1 94 | # - 更快但不如 strides>1 好 95 | for filters in layer_filters[::-1]: 96 | x = Conv2DTranspose(filters=filters, 97 | kernel_size=kernel_size, 98 | strides=2, 99 | activation='relu', 100 | padding='same')(x) 101 | 102 | x = Conv2DTranspose(filters=1, 103 | kernel_size=kernel_size, 104 | padding='same')(x) 105 | 106 | outputs = Activation('sigmoid', name='decoder_output')(x) 107 | 108 | # 实例化解码器模型 109 | decoder = Model(latent_inputs, outputs, name='decoder') 110 | decoder.summary() 111 | 112 | # Autoencoder = Encoder + Decoder 113 | # 实例化自动编码器模型 114 | autoencoder = Model(inputs, decoder(encoder(inputs)), name='autoencoder') 115 | autoencoder.summary() 116 | 117 | autoencoder.compile(loss='mse', optimizer='adam') 118 | 119 | # 训练自动编码器 120 | autoencoder.fit(x_train_noisy, 121 | x_train, 122 | validation_data=(x_test_noisy, x_test), 123 | epochs=30, 124 | batch_size=batch_size) 125 | 126 | # 根据损坏的测试图像预测自动编码器的输出 127 | x_decoded = autoencoder.predict(x_test_noisy) 128 | 129 | # 显示第 1 个 8 张损坏和去噪的图像 130 | rows, cols = 10, 30 131 | num = rows * cols 132 | imgs = np.concatenate([x_test[:num], x_test_noisy[:num], x_decoded[:num]]) 133 | imgs = imgs.reshape((rows * 3, cols, image_size, image_size)) 134 | imgs = np.vstack(np.split(imgs, rows, axis=1)) 135 | imgs = imgs.reshape((rows * 3, -1, image_size, image_size)) 136 | imgs = np.vstack([np.hstack(i) for i in imgs]) 137 | imgs = (imgs * 255).astype(np.uint8) 138 | plt.figure() 139 | plt.axis('off') 140 | plt.title('Original images: top rows, ' 141 | 'Corrupted Input: middle rows, ' 142 | 'Denoised Input: third rows') 143 | plt.imshow(imgs, interpolation='none', cmap='gray') 144 | Image.fromarray(imgs).save('corrupted_and_denoised.png') 145 | plt.show() 146 | ``` -------------------------------------------------------------------------------- /sources/examples/mnist_hierarchical_rnn.md: -------------------------------------------------------------------------------- 1 | # 使用分层 RNN (HRNN) 对 MNIST 数字进行分类的示例。 2 | 3 | HRNN 可以跨复杂序列跨多个时间层次学习。 4 | 通常,HRNN 的第一循环层将句子(例如单词向量)编码成句子向量。 5 | 然后,第二循环层将这样的向量序列(由第一层编码)编码为文档向量。 6 | 该文档向量被认为既可以保留上下文的单词级结构也可以保留句子级结构。 7 | 8 | # 参考文献 9 | 10 | - [A Hierarchical Neural Autoencoder for Paragraphs and Documents](https://arxiv.org/abs/1506.01057) 11 | 使用 HRNN 对段落和文档进行编码。 12 | 结果表明,HRNN 优于标准 RNN,并且可能在摘要或问题解答等更复杂的生成任务中发挥某些作用。 13 | - [Hierarchical recurrent neural network for skeleton based action recognition](http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=7298714) 14 | 通过 3 级双向 HRNN 与完全连接的层相结合,在基于骨骼的动作识别方面取得了最新的成果。 15 | 16 | 在下面的 MNIST 示例中,第一 LSTM 层首先将形状 (28, 1) 的每一列像素编码为形状 (128,) 的列矢量。 17 | 然后,第二个 LSTM 层将形状 (28, 128) 的这 28 个列向量编码为代表整个图像的图像向量。 18 | 添加最终的密集层以进行预测。 19 | 20 | 5 个轮次后:train acc:0.9858, val acc:0.9864 21 | 22 | 23 | ```python 24 | from __future__ import print_function 25 | 26 | import keras 27 | from keras.datasets import mnist 28 | from keras.models import Model 29 | from keras.layers import Input, Dense, TimeDistributed 30 | from keras.layers import LSTM 31 | 32 | # 训练参数。 33 | batch_size = 32 34 | num_classes = 10 35 | epochs = 5 36 | 37 | # 嵌入尺寸。 38 | row_hidden = 128 39 | col_hidden = 128 40 | 41 | # 数据,分为训练集和测试集。 42 | (x_train, y_train), (x_test, y_test) = mnist.load_data() 43 | 44 | # 将数据重塑为 4D 以进行分层 RNN。 45 | x_train = x_train.reshape(x_train.shape[0], 28, 28, 1) 46 | x_test = x_test.reshape(x_test.shape[0], 28, 28, 1) 47 | x_train = x_train.astype('float32') 48 | x_test = x_test.astype('float32') 49 | x_train /= 255 50 | x_test /= 255 51 | print('x_train shape:', x_train.shape) 52 | print(x_train.shape[0], 'train samples') 53 | print(x_test.shape[0], 'test samples') 54 | 55 | # 将类向量转换为二进制类矩阵。 56 | y_train = keras.utils.to_categorical(y_train, num_classes) 57 | y_test = keras.utils.to_categorical(y_test, num_classes) 58 | 59 | row, col, pixel = x_train.shape[1:] 60 | 61 | # 4D 输入。 62 | x = Input(shape=(row, col, pixel)) 63 | 64 | # 使用 TimeDistributed Wrapper 对一行像素进行编码。 65 | encoded_rows = TimeDistributed(LSTM(row_hidden))(x) 66 | 67 | # 对已编码行的列进行编码。 68 | encoded_columns = LSTM(col_hidden)(encoded_rows) 69 | 70 | # 最终预测和模型。 71 | prediction = Dense(num_classes, activation='softmax')(encoded_columns) 72 | model = Model(x, prediction) 73 | model.compile(loss='categorical_crossentropy', 74 | optimizer='rmsprop', 75 | metrics=['accuracy']) 76 | 77 | # 训练。 78 | model.fit(x_train, y_train, 79 | batch_size=batch_size, 80 | epochs=epochs, 81 | verbose=1, 82 | validation_data=(x_test, y_test)) 83 | 84 | # 评估。 85 | scores = model.evaluate(x_test, y_test, verbose=0) 86 | print('Test loss:', scores[0]) 87 | print('Test accuracy:', scores[1]) 88 | ``` -------------------------------------------------------------------------------- /sources/examples/mnist_irnn.md: -------------------------------------------------------------------------------- 1 | 这是由 Quoc V. Le, Navdeep Jaitly, Geoffrey E. Hinton 撰写的 "A Simple Way to Initialize Recurrent Networks of Rectified Linear Units" 中逐像素顺序 MNIST 的 IRNN 实验的复现。 2 | 3 | arxiv:1504.00941v2 [cs.NE] 7 Apr 2015 4 | http://arxiv.org/pdf/1504.00941v2.pdf 5 | 6 | 优化器由 RMSprop 代替,从而获得了更加稳定和稳定的改进。 7 | 8 | 900 个轮次后达到 0.93 的训练/测试精度 9 | (这大致相当于原始论文中的 1687500 步。) 10 | 11 | 12 | ```python 13 | from __future__ import print_function 14 | 15 | import keras 16 | from keras.datasets import mnist 17 | from keras.models import Sequential 18 | from keras.layers import Dense, Activation 19 | from keras.layers import SimpleRNN 20 | from keras import initializers 21 | from keras.optimizers import RMSprop 22 | 23 | batch_size = 32 24 | num_classes = 10 25 | epochs = 200 26 | hidden_units = 100 27 | 28 | learning_rate = 1e-6 29 | clip_norm = 1.0 30 | 31 | # 数据,分为训练集和测试集 32 | (x_train, y_train), (x_test, y_test) = mnist.load_data() 33 | 34 | x_train = x_train.reshape(x_train.shape[0], -1, 1) 35 | x_test = x_test.reshape(x_test.shape[0], -1, 1) 36 | x_train = x_train.astype('float32') 37 | x_test = x_test.astype('float32') 38 | x_train /= 255 39 | x_test /= 255 40 | print('x_train shape:', x_train.shape) 41 | print(x_train.shape[0], 'train samples') 42 | print(x_test.shape[0], 'test samples') 43 | 44 | # 将类向量转换为二进制类矩阵 45 | y_train = keras.utils.to_categorical(y_train, num_classes) 46 | y_test = keras.utils.to_categorical(y_test, num_classes) 47 | 48 | print('Evaluate IRNN...') 49 | model = Sequential() 50 | model.add(SimpleRNN(hidden_units, 51 | kernel_initializer=initializers.RandomNormal(stddev=0.001), 52 | recurrent_initializer=initializers.Identity(gain=1.0), 53 | activation='relu', 54 | input_shape=x_train.shape[1:])) 55 | model.add(Dense(num_classes)) 56 | model.add(Activation('softmax')) 57 | rmsprop = RMSprop(learning_rate=learning_rate) 58 | model.compile(loss='categorical_crossentropy', 59 | optimizer=rmsprop, 60 | metrics=['accuracy']) 61 | 62 | model.fit(x_train, y_train, 63 | batch_size=batch_size, 64 | epochs=epochs, 65 | verbose=1, 66 | validation_data=(x_test, y_test)) 67 | 68 | scores = model.evaluate(x_test, y_test, verbose=0) 69 | print('IRNN test score:', scores[0]) 70 | print('IRNN test accuracy:', scores[1]) 71 | ``` -------------------------------------------------------------------------------- /sources/examples/mnist_mlp.md: -------------------------------------------------------------------------------- 1 | # 在 MNIST 数据集上训练简单的深度 NN。 2 | 3 | 20 个轮次后达到 98.40% 的测试准确度 4 | (参数调整有*很大*的空间)。 5 | 在 K520 GPU 上,每个轮次 2 秒。 6 | 7 | 8 | ```python 9 | from __future__ import print_function 10 | 11 | import keras 12 | from keras.datasets import mnist 13 | from keras.models import Sequential 14 | from keras.layers import Dense, Dropout 15 | from keras.optimizers import RMSprop 16 | 17 | batch_size = 128 18 | num_classes = 10 19 | epochs = 20 20 | 21 | # 数据,分为训练集和测试集 22 | (x_train, y_train), (x_test, y_test) = mnist.load_data() 23 | 24 | x_train = x_train.reshape(60000, 784) 25 | x_test = x_test.reshape(10000, 784) 26 | x_train = x_train.astype('float32') 27 | x_test = x_test.astype('float32') 28 | x_train /= 255 29 | x_test /= 255 30 | print(x_train.shape[0], 'train samples') 31 | print(x_test.shape[0], 'test samples') 32 | 33 | # 将类向量转换为二进制类矩阵 34 | y_train = keras.utils.to_categorical(y_train, num_classes) 35 | y_test = keras.utils.to_categorical(y_test, num_classes) 36 | 37 | model = Sequential() 38 | model.add(Dense(512, activation='relu', input_shape=(784,))) 39 | model.add(Dropout(0.2)) 40 | model.add(Dense(512, activation='relu')) 41 | model.add(Dropout(0.2)) 42 | model.add(Dense(num_classes, activation='softmax')) 43 | 44 | model.summary() 45 | 46 | model.compile(loss='categorical_crossentropy', 47 | optimizer=RMSprop(), 48 | metrics=['accuracy']) 49 | 50 | history = model.fit(x_train, y_train, 51 | batch_size=batch_size, 52 | epochs=epochs, 53 | verbose=1, 54 | validation_data=(x_test, y_test)) 55 | score = model.evaluate(x_test, y_test, verbose=0) 56 | print('Test loss:', score[0]) 57 | print('Test accuracy:', score[1]) 58 | ``` -------------------------------------------------------------------------------- /sources/examples/mnist_siamese.md: -------------------------------------------------------------------------------- 1 | # 在 MNIST 数据集中的成对数字上训练 Siamese MLP。 2 | 3 | 它遵循 Hadsell-et-al.'06 [1],通过计算共享网络输出上的欧几里得距离并优化对比损失(有关更多信息,请参见论文)。 4 | 5 | # 参考文献 6 | 7 | - [Dimensionality Reduction by Learning an Invariant Mapping](http://yann.lecun.com/exdb/publis/pdf/hadsell-chopra-lecun-06.pdf) 8 | 9 | 20 个轮次后达到 97.2% 的测试准确度。 10 | 在 Titan X Maxwell GPU 上,每个轮次 2 秒。 11 | 12 | 13 | ```python 14 | from __future__ import absolute_import 15 | from __future__ import print_function 16 | import numpy as np 17 | 18 | import random 19 | from keras.datasets import mnist 20 | from keras.models import Model 21 | from keras.layers import Input, Flatten, Dense, Dropout, Lambda 22 | from keras.optimizers import RMSprop 23 | from keras import backend as K 24 | 25 | num_classes = 10 26 | epochs = 20 27 | 28 | 29 | def euclidean_distance(vects): 30 | x, y = vects 31 | sum_square = K.sum(K.square(x - y), axis=1, keepdims=True) 32 | return K.sqrt(K.maximum(sum_square, K.epsilon())) 33 | 34 | 35 | def eucl_dist_output_shape(shapes): 36 | shape1, shape2 = shapes 37 | return (shape1[0], 1) 38 | 39 | 40 | def contrastive_loss(y_true, y_pred): 41 | '''对比损失,来自 Hadsell-et-al.'06 42 | http://yann.lecun.com/exdb/publis/pdf/hadsell-chopra-lecun-06.pdf 43 | ''' 44 | margin = 1 45 | square_pred = K.square(y_pred) 46 | margin_square = K.square(K.maximum(margin - y_pred, 0)) 47 | return K.mean(y_true * square_pred + (1 - y_true) * margin_square) 48 | 49 | 50 | def create_pairs(x, digit_indices): 51 | '''正负对创建。 52 | 在正对和负对之间交替。 53 | ''' 54 | pairs = [] 55 | labels = [] 56 | n = min([len(digit_indices[d]) for d in range(num_classes)]) - 1 57 | for d in range(num_classes): 58 | for i in range(n): 59 | z1, z2 = digit_indices[d][i], digit_indices[d][i + 1] 60 | pairs += [[x[z1], x[z2]]] 61 | inc = random.randrange(1, num_classes) 62 | dn = (d + inc) % num_classes 63 | z1, z2 = digit_indices[d][i], digit_indices[dn][i] 64 | pairs += [[x[z1], x[z2]]] 65 | labels += [1, 0] 66 | return np.array(pairs), np.array(labels) 67 | 68 | 69 | def create_base_network(input_shape): 70 | '''要共享的基本网络(等同于特征提取)。 71 | ''' 72 | input = Input(shape=input_shape) 73 | x = Flatten()(input) 74 | x = Dense(128, activation='relu')(x) 75 | x = Dropout(0.1)(x) 76 | x = Dense(128, activation='relu')(x) 77 | x = Dropout(0.1)(x) 78 | x = Dense(128, activation='relu')(x) 79 | return Model(input, x) 80 | 81 | 82 | def compute_accuracy(y_true, y_pred): 83 | '''使用固定的距离阈值计算分类精度。 84 | ''' 85 | pred = y_pred.ravel() < 0.5 86 | return np.mean(pred == y_true) 87 | 88 | 89 | def accuracy(y_true, y_pred): 90 | '''使用固定的距离阈值计算分类精度。 91 | ''' 92 | return K.mean(K.equal(y_true, K.cast(y_pred < 0.5, y_true.dtype))) 93 | 94 | 95 | # 数据,分为训练集和测试集 96 | (x_train, y_train), (x_test, y_test) = mnist.load_data() 97 | x_train = x_train.astype('float32') 98 | x_test = x_test.astype('float32') 99 | x_train /= 255 100 | x_test /= 255 101 | input_shape = x_train.shape[1:] 102 | 103 | # 创建训练+测试正负对 104 | digit_indices = [np.where(y_train == i)[0] for i in range(num_classes)] 105 | tr_pairs, tr_y = create_pairs(x_train, digit_indices) 106 | 107 | digit_indices = [np.where(y_test == i)[0] for i in range(num_classes)] 108 | te_pairs, te_y = create_pairs(x_test, digit_indices) 109 | 110 | # 网络定义 111 | base_network = create_base_network(input_shape) 112 | 113 | input_a = Input(shape=input_shape) 114 | input_b = Input(shape=input_shape) 115 | 116 | # 因为我们重复使用了相同的实例 `base_network`, 117 | # 所以网络的权重将在两个分支之间共享 118 | processed_a = base_network(input_a) 119 | processed_b = base_network(input_b) 120 | 121 | distance = Lambda(euclidean_distance, 122 | output_shape=eucl_dist_output_shape)([processed_a, processed_b]) 123 | 124 | model = Model([input_a, input_b], distance) 125 | 126 | # 训练 127 | rms = RMSprop() 128 | model.compile(loss=contrastive_loss, optimizer=rms, metrics=[accuracy]) 129 | model.fit([tr_pairs[:, 0], tr_pairs[:, 1]], tr_y, 130 | batch_size=128, 131 | epochs=epochs, 132 | validation_data=([te_pairs[:, 0], te_pairs[:, 1]], te_y)) 133 | 134 | # 计算训练和测试集的最终精度 135 | y_pred = model.predict([tr_pairs[:, 0], tr_pairs[:, 1]]) 136 | tr_acc = compute_accuracy(tr_y, y_pred) 137 | y_pred = model.predict([te_pairs[:, 0], te_pairs[:, 1]]) 138 | te_acc = compute_accuracy(te_y, y_pred) 139 | 140 | print('* Accuracy on training set: %0.2f%%' % (100 * tr_acc)) 141 | print('* Accuracy on test set: %0.2f%%' % (100 * te_acc)) 142 | ``` -------------------------------------------------------------------------------- /sources/examples/mnist_sklearn_wrapper.md: -------------------------------------------------------------------------------- 1 | # 如何使用 sklearn 包装器的示例 2 | 3 | 在 MNIST 上构建简单的 CNN 模型,并使用 sklearn 的 GridSearchCV 查找最佳模型 4 | 5 | 6 | ```python 7 | from __future__ import print_function 8 | 9 | import keras 10 | from keras.datasets import mnist 11 | from keras.models import Sequential 12 | from keras.layers import Dense, Dropout, Activation, Flatten 13 | from keras.layers import Conv2D, MaxPooling2D 14 | from keras.wrappers.scikit_learn import KerasClassifier 15 | from keras import backend as K 16 | from sklearn.model_selection import GridSearchCV 17 | 18 | 19 | num_classes = 10 20 | 21 | # 输入图像尺寸 22 | img_rows, img_cols = 28, 28 23 | 24 | # 加载训练数据并进行基本数据归一化 25 | (x_train, y_train), (x_test, y_test) = mnist.load_data() 26 | 27 | if K.image_data_format() == 'channels_first': 28 | x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols) 29 | x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols) 30 | input_shape = (1, img_rows, img_cols) 31 | else: 32 | x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1) 33 | x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1) 34 | input_shape = (img_rows, img_cols, 1) 35 | 36 | x_train = x_train.astype('float32') 37 | x_test = x_test.astype('float32') 38 | x_train /= 255 39 | x_test /= 255 40 | 41 | # 将类向量转换为二进制类矩阵 42 | y_train = keras.utils.to_categorical(y_train, num_classes) 43 | y_test = keras.utils.to_categorical(y_test, num_classes) 44 | 45 | 46 | def make_model(dense_layer_sizes, filters, kernel_size, pool_size): 47 | '''创建由 2 个卷积层和紧随其后的密集层组成的模型 48 | 49 | dense_layer_sizes: 网络层大小列表。 50 | 此列表每一层都有一个数字。 51 | filters: 每个卷积层中的卷积滤波器数量 52 | kernel_size: 卷积核大小 53 | pool_size: 最大共享池的大小 54 | ''' 55 | 56 | model = Sequential() 57 | model.add(Conv2D(filters, kernel_size, 58 | padding='valid', 59 | input_shape=input_shape)) 60 | model.add(Activation('relu')) 61 | model.add(Conv2D(filters, kernel_size)) 62 | model.add(Activation('relu')) 63 | model.add(MaxPooling2D(pool_size=pool_size)) 64 | model.add(Dropout(0.25)) 65 | 66 | model.add(Flatten()) 67 | for layer_size in dense_layer_sizes: 68 | model.add(Dense(layer_size)) 69 | model.add(Activation('relu')) 70 | model.add(Dropout(0.5)) 71 | model.add(Dense(num_classes)) 72 | model.add(Activation('softmax')) 73 | 74 | model.compile(loss='categorical_crossentropy', 75 | optimizer='adadelta', 76 | metrics=['accuracy']) 77 | return model 78 | 79 | 80 | dense_size_candidates = [[32], [64], [32, 32], [64, 64]] 81 | my_classifier = KerasClassifier(make_model, batch_size=32) 82 | validator = GridSearchCV(my_classifier, 83 | param_grid={'dense_layer_sizes': dense_size_candidates, 84 | # epochs 可用于调整,即使不是模型构建函数的参数 85 | 'epochs': [3, 6], 86 | 'filters': [8], 87 | 'kernel_size': [3], 88 | 'pool_size': [2]}, 89 | scoring='neg_log_loss', 90 | n_jobs=1) 91 | validator.fit(x_train, y_train) 92 | 93 | print('The parameters of the best model are: ') 94 | print(validator.best_params_) 95 | 96 | # validator.best_estimator_ 返回 sklearn-wrapped 版本的最佳模型 97 | # validator.best_estimator_.model 返回非包装的 keras 模型 98 | best_model = validator.best_estimator_.model 99 | metric_names = best_model.metrics_names 100 | metric_values = best_model.evaluate(x_test, y_test) 101 | for metric, value in zip(metric_names, metric_values): 102 | print(metric, ': ', value) 103 | ``` -------------------------------------------------------------------------------- /sources/examples/mnist_swwae.md: -------------------------------------------------------------------------------- 1 | # 训练基于 MNIST 数据集上残差块的堆叠式自动编码器。 2 | 3 | 它举例说明了过去几年开发的两种有影响力的方法。 4 | 5 | 首先是适当地 "分拆" 的想法。在任何最大池化期间,都会丢失合并的接收场中最大值的确切位置(where),但是在输入图像的整体重建中可能非常有用。 6 | 因此,如果将 "位置" 从编码器传递到相应的解码器层,则可以将要解码的特征 "放置" 在正确的位置,从而可以实现更高保真度的重构。 7 | 8 | # 参考文献 9 | 10 | - [Visualizing and Understanding Convolutional Networks, Matthew D Zeiler, Rob Fergus](https://arxiv.org/abs/1311.2901v3) 11 | - [Stacked What-Where Auto-encoders, Junbo Zhao, Michael Mathieu, Ross Goroshin, Yann LeCun](https://arxiv.org/abs/1506.02351v8) 12 | 13 | 这里利用的第二个想法是残差学习的想法。残差块通过允许跳过连接使网络能够按照数据认为合适的线性(或非线性)能力简化训练过程。 14 | 这样可以轻松地训练很多深度的网络。残差元素在该示例的上下文中似乎是有利的,因为它允许编码器和解码器之间的良好对称性。 15 | 通常,在解码器中,对重构图像的空间的最终投影是线性的,但是对于残差块,则不必如此,因为其输出是线性还是非线性的程度取决于被馈送的像素数据。 16 | 但是,为了限制此示例中的重建,因为我们知道 MNIST 数字映射到 [0, 1],所以将硬 softmax 用作偏置。 17 | 18 | # 参考文献 19 | - [Deep Residual Learning for Image Recognition, Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun](https://arxiv.org/abs/1512.03385v1) 20 | - [Identity Mappings in Deep Residual Networks, Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun](https://arxiv.org/abs/1603.05027v3) 21 | 22 | 23 | ```python 24 | from __future__ import print_function 25 | import numpy as np 26 | 27 | from keras.datasets import mnist 28 | from keras.models import Model 29 | from keras.layers import Activation 30 | from keras.layers import UpSampling2D, Conv2D, MaxPooling2D 31 | from keras.layers import Input, BatchNormalization, ELU 32 | import matplotlib.pyplot as plt 33 | import keras.backend as K 34 | from keras import layers 35 | 36 | 37 | def convresblock(x, nfeats=8, ksize=3, nskipped=2, elu=True): 38 | """[4] 中提出的残差块。 39 | 40 | 以 elu=True 运行将使用 ELU 非线性,而以 elu=False 运行将使用 BatchNorm+RELU 非线性。 41 | 尽管 ELU 由于不受 BatchNorm 开销的困扰而很快,但它们可能会过拟合, 42 | 因为它们不提供 BatchNorm 批处理过程的随机因素,而后者是一个很好的正则化工具。 43 | 44 | # 参数 45 | x: 4D 张量, 穿过块的张量 46 | nfeats: 整数。卷积层的特征图大小。 47 | ksize: 整数,第一个卷积中 conv 核的宽度和高度。 48 | nskipped: 整数,残差函数的卷积层数。 49 | elu: 布尔值,是使用 ELU 还是 BN+RELU。 50 | 51 | # 输入尺寸 52 | 4D 张量,尺寸为: 53 | `(batch, channels, rows, cols)` 54 | 55 | # 输出尺寸 56 | 4D 张量,尺寸为: 57 | `(batch, filters, rows, cols)` 58 | """ 59 | y0 = Conv2D(nfeats, ksize, padding='same')(x) 60 | y = y0 61 | for i in range(nskipped): 62 | if elu: 63 | y = ELU()(y) 64 | else: 65 | y = BatchNormalization(axis=1)(y) 66 | y = Activation('relu')(y) 67 | y = Conv2D(nfeats, 1, padding='same')(y) 68 | return layers.add([y0, y]) 69 | 70 | 71 | def getwhere(x): 72 | '''计算包含开关的 'where' 掩码,该掩码指示应用 MaxPool2D 时哪个索引包含最大值。 73 | 使用总和的梯度是使所有内容保持高水平的不错的技巧。''' 74 | y_prepool, y_postpool = x 75 | return K.gradients(K.sum(y_postpool), y_prepool) 76 | 77 | # 本示例假定 'channels_first' 数据格式。 78 | K.set_image_data_format('channels_first') 79 | 80 | # 输入图像尺寸 81 | img_rows, img_cols = 28, 28 82 | 83 | # 数据,分为训练集和测试集 84 | (x_train, _), (x_test, _) = mnist.load_data() 85 | 86 | x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols) 87 | x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols) 88 | x_train = x_train.astype('float32') 89 | x_test = x_test.astype('float32') 90 | x_train /= 255 91 | x_test /= 255 92 | print('x_train shape:', x_train.shape) 93 | print(x_train.shape[0], 'train samples') 94 | print(x_test.shape[0], 'test samples') 95 | 96 | # MaxPooling2D 使用的内核大小 97 | pool_size = 2 98 | # 每层特征图的总数 99 | nfeats = [8, 16, 32, 64, 128] 100 | # 每层池化内核的大小 101 | pool_sizes = np.array([1, 1, 1, 1, 1]) * pool_size 102 | # 卷积核大小 103 | ksize = 3 104 | # 要训练的轮次数 105 | epochs = 5 106 | # 训练期间的批次大小 107 | batch_size = 128 108 | 109 | if pool_size == 2: 110 | # 如果使用 pool_size = 2 的 5 层网络 111 | x_train = np.pad(x_train, [[0, 0], [0, 0], [2, 2], [2, 2]], 112 | mode='constant') 113 | x_test = np.pad(x_test, [[0, 0], [0, 0], [2, 2], [2, 2]], mode='constant') 114 | nlayers = 5 115 | elif pool_size == 3: 116 | # 如果使用 pool_size = 3 的 3 层网 117 | x_train = x_train[:, :, :-1, :-1] 118 | x_test = x_test[:, :, :-1, :-1] 119 | nlayers = 3 120 | else: 121 | import sys 122 | sys.exit('Script supports pool_size of 2 and 3.') 123 | 124 | # 训练输入的形状(请注意,模型是完全卷积的) 125 | input_shape = x_train.shape[1:] 126 | # axis=1 的所有层的尺寸最终大小,包括输入 127 | nfeats_all = [input_shape[0]] + nfeats 128 | 129 | # 首先构建编码器,同时始终跟踪 'where' 掩码 130 | img_input = Input(shape=input_shape) 131 | 132 | # 我们将 'where' 掩码推到下面的列表中 133 | wheres = [None] * nlayers 134 | y = img_input 135 | for i in range(nlayers): 136 | y_prepool = convresblock(y, nfeats=nfeats_all[i + 1], ksize=ksize) 137 | y = MaxPooling2D(pool_size=(pool_sizes[i], pool_sizes[i]))(y_prepool) 138 | wheres[i] = layers.Lambda( 139 | getwhere, output_shape=lambda x: x[0])([y_prepool, y]) 140 | 141 | # 现在构建解码器,并使用存储的 'where' 掩码放置特征 142 | for i in range(nlayers): 143 | ind = nlayers - 1 - i 144 | y = UpSampling2D(size=(pool_sizes[ind], pool_sizes[ind]))(y) 145 | y = layers.multiply([y, wheres[ind]]) 146 | y = convresblock(y, nfeats=nfeats_all[ind], ksize=ksize) 147 | 148 | # 使用 hard_sigmoid 裁剪重建范围 149 | y = Activation('hard_sigmoid')(y) 150 | 151 | # 定义模型及其均方误差损失,并使用 Adam 进行编译 152 | model = Model(img_input, y) 153 | model.compile('adam', 'mse') 154 | 155 | # 拟合模型 156 | model.fit(x_train, x_train, 157 | batch_size=batch_size, 158 | epochs=epochs, 159 | validation_data=(x_test, x_test)) 160 | 161 | # 绘图 162 | x_recon = model.predict(x_test[:25]) 163 | x_plot = np.concatenate((x_test[:25], x_recon), axis=1) 164 | x_plot = x_plot.reshape((5, 10, input_shape[-2], input_shape[-1])) 165 | x_plot = np.vstack([np.hstack(x) for x in x_plot]) 166 | plt.figure() 167 | plt.axis('off') 168 | plt.title('Test Samples: Originals/Reconstructions') 169 | plt.imshow(x_plot, interpolation='none', cmap='gray') 170 | plt.savefig('reconstructions.png') 171 | ``` -------------------------------------------------------------------------------- /sources/examples/mnist_transfer_cnn.md: -------------------------------------------------------------------------------- 1 | # 转移学习玩具示例。 2 | 3 | 1 - 在 MNIST 数据集的前 5 位 [0..4] 上训练简单的 convnet。 4 | 2 - 冻结卷积层并微调密集层以进行数字分类 [5..9]。 5 | 6 | 迁移+微调后的前五个数字分类器经过 5 个轮次后,测试准确率达到 99.8%,最后 5 个数字达到 99.2%。 7 | 8 | 9 | ```python 10 | from __future__ import print_function 11 | 12 | import datetime 13 | import keras 14 | from keras.datasets import mnist 15 | from keras.models import Sequential 16 | from keras.layers import Dense, Dropout, Activation, Flatten 17 | from keras.layers import Conv2D, MaxPooling2D 18 | from keras import backend as K 19 | 20 | now = datetime.datetime.now 21 | 22 | batch_size = 128 23 | num_classes = 5 24 | epochs = 5 25 | 26 | # 输入图像尺寸 27 | img_rows, img_cols = 28, 28 28 | # 使用的卷积滤波器数量 29 | filters = 32 30 | # 最大池的池区域大小 31 | pool_size = 2 32 | # 卷积核大小 33 | kernel_size = 3 34 | 35 | if K.image_data_format() == 'channels_first': 36 | input_shape = (1, img_rows, img_cols) 37 | else: 38 | input_shape = (img_rows, img_cols, 1) 39 | 40 | 41 | def train_model(model, train, test, num_classes): 42 | x_train = train[0].reshape((train[0].shape[0],) + input_shape) 43 | x_test = test[0].reshape((test[0].shape[0],) + input_shape) 44 | x_train = x_train.astype('float32') 45 | x_test = x_test.astype('float32') 46 | x_train /= 255 47 | x_test /= 255 48 | print('x_train shape:', x_train.shape) 49 | print(x_train.shape[0], 'train samples') 50 | print(x_test.shape[0], 'test samples') 51 | 52 | # 将类向量转换为二进制类矩阵 53 | y_train = keras.utils.to_categorical(train[1], num_classes) 54 | y_test = keras.utils.to_categorical(test[1], num_classes) 55 | 56 | model.compile(loss='categorical_crossentropy', 57 | optimizer='adadelta', 58 | metrics=['accuracy']) 59 | 60 | t = now() 61 | model.fit(x_train, y_train, 62 | batch_size=batch_size, 63 | epochs=epochs, 64 | verbose=1, 65 | validation_data=(x_test, y_test)) 66 | print('Training time: %s' % (now() - t)) 67 | score = model.evaluate(x_test, y_test, verbose=0) 68 | print('Test score:', score[0]) 69 | print('Test accuracy:', score[1]) 70 | 71 | 72 | # 数据,分为训练集和测试集 73 | (x_train, y_train), (x_test, y_test) = mnist.load_data() 74 | 75 | # 创建两个数据集,一个的数字小于 5,另一个的数字大于等于 5 76 | x_train_lt5 = x_train[y_train < 5] 77 | y_train_lt5 = y_train[y_train < 5] 78 | x_test_lt5 = x_test[y_test < 5] 79 | y_test_lt5 = y_test[y_test < 5] 80 | 81 | x_train_gte5 = x_train[y_train >= 5] 82 | y_train_gte5 = y_train[y_train >= 5] - 5 83 | x_test_gte5 = x_test[y_test >= 5] 84 | y_test_gte5 = y_test[y_test >= 5] - 5 85 | 86 | # 定义两组网络层:特征(卷积)和分类(密集) 87 | feature_layers = [ 88 | Conv2D(filters, kernel_size, 89 | padding='valid', 90 | input_shape=input_shape), 91 | Activation('relu'), 92 | Conv2D(filters, kernel_size), 93 | Activation('relu'), 94 | MaxPooling2D(pool_size=pool_size), 95 | Dropout(0.25), 96 | Flatten(), 97 | ] 98 | 99 | classification_layers = [ 100 | Dense(128), 101 | Activation('relu'), 102 | Dropout(0.5), 103 | Dense(num_classes), 104 | Activation('softmax') 105 | ] 106 | 107 | # 创建完整的模型 108 | model = Sequential(feature_layers + classification_layers) 109 | 110 | # 5位分类的训练模型[0..4] 111 | train_model(model, 112 | (x_train_lt5, y_train_lt5), 113 | (x_test_lt5, y_test_lt5), num_classes) 114 | 115 | # 冻结特征层并重建模型 116 | for l in feature_layers: 117 | l.trainable = False 118 | 119 | # 迁移:为新的分类任务训练密集层 [5..9] 120 | train_model(model, 121 | (x_train_gte5, y_train_gte5), 122 | (x_test_gte5, y_test_gte5), num_classes) 123 | ``` -------------------------------------------------------------------------------- /sources/examples/pretrained_word_embeddings.md: -------------------------------------------------------------------------------- 1 | # 加载预训练词嵌入 2 | 3 | 该脚本将预训练的词嵌入(GloVe 嵌入)加载到冻结的 Keras 嵌入层中,并使用它在 20 个新闻组数据集上训练文本分类模型(将新闻组消息分类为 20 个不同的类别)。 4 | 5 | 可以在以下位置找到 GloVe 嵌入数据: 6 | http://nlp.stanford.edu/data/glove.6B.zip 7 | (source page: http://nlp.stanford.edu/projects/glove/) 8 | 9 | 20个新闻组数据可在以下位置找到: 10 | http://www.cs.cmu.edu/afs/cs.cmu.edu/project/theo-20/www/data/news20.html 11 | 12 | 13 | ```python 14 | from __future__ import print_function 15 | 16 | import os 17 | import sys 18 | import numpy as np 19 | from keras.preprocessing.text import Tokenizer 20 | from keras.preprocessing.sequence import pad_sequences 21 | from keras.utils import to_categorical 22 | from keras.layers import Dense, Input, GlobalMaxPooling1D 23 | from keras.layers import Conv1D, MaxPooling1D, Embedding 24 | from keras.models import Model 25 | from keras.initializers import Constant 26 | 27 | 28 | BASE_DIR = '' 29 | GLOVE_DIR = os.path.join(BASE_DIR, 'glove.6B') 30 | TEXT_DATA_DIR = os.path.join(BASE_DIR, '20_newsgroup') 31 | MAX_SEQUENCE_LENGTH = 1000 32 | MAX_NUM_WORDS = 20000 33 | EMBEDDING_DIM = 100 34 | VALIDATION_SPLIT = 0.2 35 | 36 | # 首先,在嵌入集中将索引映射词构建为其嵌入向量 37 | 38 | print('Indexing word vectors.') 39 | 40 | embeddings_index = {} 41 | with open(os.path.join(GLOVE_DIR, 'glove.6B.100d.txt')) as f: 42 | for line in f: 43 | word, coefs = line.split(maxsplit=1) 44 | coefs = np.fromstring(coefs, 'f', sep=' ') 45 | embeddings_index[word] = coefs 46 | 47 | print('Found %s word vectors.' % len(embeddings_index)) 48 | 49 | # 其次,准备文本样本及其标签 50 | print('Processing text dataset') 51 | 52 | texts = [] # 文字样本列表 53 | labels_index = {} # 将标签名称映射到数字 ID 的字典 54 | labels = [] # 标签 ID 列表 55 | for name in sorted(os.listdir(TEXT_DATA_DIR)): 56 | path = os.path.join(TEXT_DATA_DIR, name) 57 | if os.path.isdir(path): 58 | label_id = len(labels_index) 59 | labels_index[name] = label_id 60 | for fname in sorted(os.listdir(path)): 61 | if fname.isdigit(): 62 | fpath = os.path.join(path, fname) 63 | args = {} if sys.version_info < (3,) else {'encoding': 'latin-1'} 64 | with open(fpath, **args) as f: 65 | t = f.read() 66 | i = t.find('\n\n') # 跳过标题 67 | if 0 < i: 68 | t = t[i:] 69 | texts.append(t) 70 | labels.append(label_id) 71 | 72 | print('Found %s texts.' % len(texts)) 73 | 74 | # 最后,将文本样本向量化为 2D 整数张量 75 | tokenizer = Tokenizer(num_words=MAX_NUM_WORDS) 76 | tokenizer.fit_on_texts(texts) 77 | sequences = tokenizer.texts_to_sequences(texts) 78 | 79 | word_index = tokenizer.word_index 80 | print('Found %s unique tokens.' % len(word_index)) 81 | 82 | data = pad_sequences(sequences, maxlen=MAX_SEQUENCE_LENGTH) 83 | 84 | labels = to_categorical(np.asarray(labels)) 85 | print('Shape of data tensor:', data.shape) 86 | print('Shape of label tensor:', labels.shape) 87 | 88 | # 将数据分为训练集和验证集 89 | indices = np.arange(data.shape[0]) 90 | np.random.shuffle(indices) 91 | data = data[indices] 92 | labels = labels[indices] 93 | num_validation_samples = int(VALIDATION_SPLIT * data.shape[0]) 94 | 95 | x_train = data[:-num_validation_samples] 96 | y_train = labels[:-num_validation_samples] 97 | x_val = data[-num_validation_samples:] 98 | y_val = labels[-num_validation_samples:] 99 | 100 | print('Preparing embedding matrix.') 101 | 102 | # 准备嵌入矩阵 103 | num_words = min(MAX_NUM_WORDS, len(word_index) + 1) 104 | embedding_matrix = np.zeros((num_words, EMBEDDING_DIM)) 105 | for word, i in word_index.items(): 106 | if i >= MAX_NUM_WORDS: 107 | continue 108 | embedding_vector = embeddings_index.get(word) 109 | if embedding_vector is not None: 110 | # 嵌入索引中找不到的单词将为全零。 111 | embedding_matrix[i] = embedding_vector 112 | 113 | # 将预训练的词嵌入加载到嵌入层中 114 | # 请注意,我们设置了 trainable = False,以便保持嵌入固定 115 | embedding_layer = Embedding(num_words, 116 | EMBEDDING_DIM, 117 | embeddings_initializer=Constant(embedding_matrix), 118 | input_length=MAX_SEQUENCE_LENGTH, 119 | trainable=False) 120 | 121 | print('Training model.') 122 | 123 | # 使用全局 maxpooling 训练 1D convnet 124 | sequence_input = Input(shape=(MAX_SEQUENCE_LENGTH,), dtype='int32') 125 | embedded_sequences = embedding_layer(sequence_input) 126 | x = Conv1D(128, 5, activation='relu')(embedded_sequences) 127 | x = MaxPooling1D(5)(x) 128 | x = Conv1D(128, 5, activation='relu')(x) 129 | x = MaxPooling1D(5)(x) 130 | x = Conv1D(128, 5, activation='relu')(x) 131 | x = GlobalMaxPooling1D()(x) 132 | x = Dense(128, activation='relu')(x) 133 | preds = Dense(len(labels_index), activation='softmax')(x) 134 | 135 | model = Model(sequence_input, preds) 136 | model.compile(loss='categorical_crossentropy', 137 | optimizer='rmsprop', 138 | metrics=['acc']) 139 | 140 | model.fit(x_train, y_train, 141 | batch_size=128, 142 | epochs=10, 143 | validation_data=(x_val, y_val)) 144 | ``` -------------------------------------------------------------------------------- /sources/examples/reuters_mlp.md: -------------------------------------------------------------------------------- 1 | # 在路透社新闻分类主题任务上训练和评估一个简单的 MLP。 2 | 3 | 4 | ```python 5 | from __future__ import print_function 6 | 7 | import numpy as np 8 | import keras 9 | from keras.datasets import reuters 10 | from keras.models import Sequential 11 | from keras.layers import Dense, Dropout, Activation 12 | from keras.preprocessing.text import Tokenizer 13 | 14 | max_words = 1000 15 | batch_size = 32 16 | epochs = 5 17 | 18 | print('Loading data...') 19 | (x_train, y_train), (x_test, y_test) = reuters.load_data(num_words=max_words, 20 | test_split=0.2) 21 | print(len(x_train), 'train sequences') 22 | print(len(x_test), 'test sequences') 23 | 24 | num_classes = np.max(y_train) + 1 25 | print(num_classes, 'classes') 26 | 27 | print('Vectorizing sequence data...') 28 | tokenizer = Tokenizer(num_words=max_words) 29 | x_train = tokenizer.sequences_to_matrix(x_train, mode='binary') 30 | x_test = tokenizer.sequences_to_matrix(x_test, mode='binary') 31 | print('x_train shape:', x_train.shape) 32 | print('x_test shape:', x_test.shape) 33 | 34 | print('Convert class vector to binary class matrix ' 35 | '(for use with categorical_crossentropy)') 36 | y_train = keras.utils.to_categorical(y_train, num_classes) 37 | y_test = keras.utils.to_categorical(y_test, num_classes) 38 | print('y_train shape:', y_train.shape) 39 | print('y_test shape:', y_test.shape) 40 | 41 | print('Building model...') 42 | model = Sequential() 43 | model.add(Dense(512, input_shape=(max_words,))) 44 | model.add(Activation('relu')) 45 | model.add(Dropout(0.5)) 46 | model.add(Dense(num_classes)) 47 | model.add(Activation('softmax')) 48 | 49 | model.compile(loss='categorical_crossentropy', 50 | optimizer='adam', 51 | metrics=['accuracy']) 52 | 53 | history = model.fit(x_train, y_train, 54 | batch_size=batch_size, 55 | epochs=epochs, 56 | verbose=1, 57 | validation_split=0.1) 58 | score = model.evaluate(x_test, y_test, 59 | batch_size=batch_size, verbose=1) 60 | print('Test score:', score[0]) 61 | print('Test accuracy:', score[1]) 62 | ``` -------------------------------------------------------------------------------- /sources/examples/reuters_mlp_relu_vs_selu.md: -------------------------------------------------------------------------------- 1 | # 将自规范化 MLP 与常规 MLP 进行比较。 2 | 3 | 使用两种不同的激活函数(路透社新闻分类主题任务上的 RELU 和 SELU)比较简单 MLP 的性能。 4 | 5 | # 参考文献 6 | 7 | - Klambauer, G., Unterthiner, T., Mayr, A., & Hochreiter, S. (2017). 8 | [Self-Normalizing Neural Networks. arXiv preprint arXiv:1706.02515.](https://arxiv.org/abs/1706.02515) 9 | 10 | 11 | ```python 12 | from __future__ import print_function 13 | 14 | import numpy as np 15 | import matplotlib.pyplot as plt 16 | import keras 17 | from keras.datasets import reuters 18 | from keras.models import Sequential 19 | from keras.layers import Dense, Activation, Dropout 20 | from keras.layers.noise import AlphaDropout 21 | from keras.preprocessing.text import Tokenizer 22 | 23 | max_words = 1000 24 | batch_size = 16 25 | epochs = 40 26 | plot = True 27 | 28 | 29 | def create_network(n_dense=6, 30 | dense_units=16, 31 | activation='selu', 32 | dropout=AlphaDropout, 33 | dropout_rate=0.1, 34 | kernel_initializer='lecun_normal', 35 | optimizer='adam', 36 | num_classes=1, 37 | max_words=max_words): 38 | """泛型函数可创建完全连接的神经网络。 39 | 40 | # 参数 41 | n_dense: int > 0. 全连接层数。 42 | dense_units: int > 0. 每层的全连接单元数。 43 | dropout: keras.layers.Layer. 要应用的 dropout 层。 44 | dropout_rate: 0 <= float <= 1. dropout 率。 45 | kernel_initializer: str. 权重的初始化程序。 46 | optimizer: str/keras.optimizers.Optimizer. 要使用的优化程序。 47 | num_classes: int > 0. 要预测的类数。 48 | max_words: int > 0. 每个数据点的最大字数。 49 | 50 | # 返回 51 | Keras 模型实例(已编译)。 52 | """ 53 | model = Sequential() 54 | model.add(Dense(dense_units, input_shape=(max_words,), 55 | kernel_initializer=kernel_initializer)) 56 | model.add(Activation(activation)) 57 | model.add(dropout(dropout_rate)) 58 | 59 | for i in range(n_dense - 1): 60 | model.add(Dense(dense_units, kernel_initializer=kernel_initializer)) 61 | model.add(Activation(activation)) 62 | model.add(dropout(dropout_rate)) 63 | 64 | model.add(Dense(num_classes)) 65 | model.add(Activation('softmax')) 66 | model.compile(loss='categorical_crossentropy', 67 | optimizer=optimizer, 68 | metrics=['accuracy']) 69 | return model 70 | 71 | 72 | network1 = { 73 | 'n_dense': 6, 74 | 'dense_units': 16, 75 | 'activation': 'relu', 76 | 'dropout': Dropout, 77 | 'dropout_rate': 0.5, 78 | 'kernel_initializer': 'glorot_uniform', 79 | 'optimizer': 'sgd' 80 | } 81 | 82 | network2 = { 83 | 'n_dense': 6, 84 | 'dense_units': 16, 85 | 'activation': 'selu', 86 | 'dropout': AlphaDropout, 87 | 'dropout_rate': 0.1, 88 | 'kernel_initializer': 'lecun_normal', 89 | 'optimizer': 'sgd' 90 | } 91 | 92 | print('Loading data...') 93 | (x_train, y_train), (x_test, y_test) = reuters.load_data(num_words=max_words, 94 | test_split=0.2) 95 | print(len(x_train), 'train sequences') 96 | print(len(x_test), 'test sequences') 97 | 98 | num_classes = np.max(y_train) + 1 99 | print(num_classes, 'classes') 100 | 101 | print('Vectorizing sequence data...') 102 | tokenizer = Tokenizer(num_words=max_words) 103 | x_train = tokenizer.sequences_to_matrix(x_train, mode='binary') 104 | x_test = tokenizer.sequences_to_matrix(x_test, mode='binary') 105 | print('x_train shape:', x_train.shape) 106 | print('x_test shape:', x_test.shape) 107 | 108 | print('Convert class vector to binary class matrix ' 109 | '(for use with categorical_crossentropy)') 110 | y_train = keras.utils.to_categorical(y_train, num_classes) 111 | y_test = keras.utils.to_categorical(y_test, num_classes) 112 | print('y_train shape:', y_train.shape) 113 | print('y_test shape:', y_test.shape) 114 | 115 | print('\nBuilding network 1...') 116 | 117 | model1 = create_network(num_classes=num_classes, **network1) 118 | history_model1 = model1.fit(x_train, 119 | y_train, 120 | batch_size=batch_size, 121 | epochs=epochs, 122 | verbose=1, 123 | validation_split=0.1) 124 | 125 | score_model1 = model1.evaluate(x_test, 126 | y_test, 127 | batch_size=batch_size, 128 | verbose=1) 129 | 130 | 131 | print('\nBuilding network 2...') 132 | model2 = create_network(num_classes=num_classes, **network2) 133 | 134 | history_model2 = model2.fit(x_train, 135 | y_train, 136 | batch_size=batch_size, 137 | epochs=epochs, 138 | verbose=1, 139 | validation_split=0.1) 140 | 141 | score_model2 = model2.evaluate(x_test, 142 | y_test, 143 | batch_size=batch_size, 144 | verbose=1) 145 | 146 | print('\nNetwork 1 results') 147 | print('Hyperparameters:', network1) 148 | print('Test score:', score_model1[0]) 149 | print('Test accuracy:', score_model1[1]) 150 | print('Network 2 results') 151 | print('Hyperparameters:', network2) 152 | print('Test score:', score_model2[0]) 153 | print('Test accuracy:', score_model2[1]) 154 | 155 | plt.plot(range(epochs), 156 | history_model1.history['val_loss'], 157 | 'g-', 158 | label='Network 1 Val Loss') 159 | plt.plot(range(epochs), 160 | history_model2.history['val_loss'], 161 | 'r-', 162 | label='Network 2 Val Loss') 163 | plt.plot(range(epochs), 164 | history_model1.history['loss'], 165 | 'g--', 166 | label='Network 1 Loss') 167 | plt.plot(range(epochs), 168 | history_model2.history['loss'], 169 | 'r--', 170 | label='Network 2 Loss') 171 | plt.xlabel('Epochs') 172 | plt.ylabel('Loss') 173 | plt.legend() 174 | plt.savefig('comparison_of_networks.png') 175 | ``` -------------------------------------------------------------------------------- /sources/examples/variational_autoencoder.md: -------------------------------------------------------------------------------- 1 | # 使用 MLP 的 MNIST 数据集上的 VAE 示例 2 | 3 | VAE 具有模块化设计。编码器、解码器和 VAE 是 3 种共享权重的模型。训练 VAE 模型后,编码器可用于生成潜矢量。 4 | 通过从 mean=0 和 std=1 的高斯分布中采样潜矢量,可以将解码器用于生成 MNIST 数字。 5 | 6 | # 参考文献 7 | 8 | [1] Kingma, Diederik P., and Max Welling. 9 | ["Auto-Encoding Variational Bayes."](https://arxiv.org/abs/1312.6114) 10 | 11 | 12 | ```python 13 | from __future__ import absolute_import 14 | from __future__ import division 15 | from __future__ import print_function 16 | 17 | from keras.layers import Lambda, Input, Dense 18 | from keras.models import Model 19 | from keras.datasets import mnist 20 | from keras.losses import mse, binary_crossentropy 21 | from keras.utils import plot_model 22 | from keras import backend as K 23 | 24 | import numpy as np 25 | import matplotlib.pyplot as plt 26 | import argparse 27 | import os 28 | 29 | 30 | # 重新参数化技巧 31 | # 代替从 Q(z|X) 采样, 采样 epsilon = N(0,I) 32 | # z = z_mean + sqrt(var) * epsilon 33 | def sampling(args): 34 | """通过从各向同性单位高斯采样来进行重新参数化技巧。 35 | 36 | # 参数 37 | args (tensor): Q(z|X) 的均值和方差对数 38 | 39 | # 返回 40 | z (tensor): 采样的潜在向量 41 | """ 42 | 43 | z_mean, z_log_var = args 44 | batch = K.shape(z_mean)[0] 45 | dim = K.int_shape(z_mean)[1] 46 | # 默认情况下,random_normal 的 mean = 0,std = 1.0 47 | epsilon = K.random_normal(shape=(batch, dim)) 48 | return z_mean + K.exp(0.5 * z_log_var) * epsilon 49 | 50 | 51 | def plot_results(models, 52 | data, 53 | batch_size=128, 54 | model_name="vae_mnist"): 55 | """绘制标签和 MNIST 数字作为 2D 潜矢量的函数 56 | 57 | # 参数 58 | models (tuple): 编码器和解码器型号 59 | data (tuple): 测试数据和标签 60 | batch_size (int): 预测批次大小 61 | model_name (string): 哪个模型正在使用此功能 62 | """ 63 | 64 | encoder, decoder = models 65 | x_test, y_test = data 66 | os.makedirs(model_name, exist_ok=True) 67 | 68 | filename = os.path.join(model_name, "vae_mean.png") 69 | # 在潜在空间中显示数字类的二维图 70 | z_mean, _, _ = encoder.predict(x_test, 71 | batch_size=batch_size) 72 | plt.figure(figsize=(12, 10)) 73 | plt.scatter(z_mean[:, 0], z_mean[:, 1], c=y_test) 74 | plt.colorbar() 75 | plt.xlabel("z[0]") 76 | plt.ylabel("z[1]") 77 | plt.savefig(filename) 78 | plt.show() 79 | 80 | filename = os.path.join(model_name, "digits_over_latent.png") 81 | # 显示 30x30 的 2D 数字流形 82 | n = 30 83 | digit_size = 28 84 | figure = np.zeros((digit_size * n, digit_size * n)) 85 | # 线性空间坐标,对应于潜在空间中数字类的二维图 86 | grid_x = np.linspace(-4, 4, n) 87 | grid_y = np.linspace(-4, 4, n)[::-1] 88 | 89 | for i, yi in enumerate(grid_y): 90 | for j, xi in enumerate(grid_x): 91 | z_sample = np.array([[xi, yi]]) 92 | x_decoded = decoder.predict(z_sample) 93 | digit = x_decoded[0].reshape(digit_size, digit_size) 94 | figure[i * digit_size: (i + 1) * digit_size, 95 | j * digit_size: (j + 1) * digit_size] = digit 96 | 97 | plt.figure(figsize=(10, 10)) 98 | start_range = digit_size // 2 99 | end_range = n * digit_size + start_range + 1 100 | pixel_range = np.arange(start_range, end_range, digit_size) 101 | sample_range_x = np.round(grid_x, 1) 102 | sample_range_y = np.round(grid_y, 1) 103 | plt.xticks(pixel_range, sample_range_x) 104 | plt.yticks(pixel_range, sample_range_y) 105 | plt.xlabel("z[0]") 106 | plt.ylabel("z[1]") 107 | plt.imshow(figure, cmap='Greys_r') 108 | plt.savefig(filename) 109 | plt.show() 110 | 111 | 112 | # MNIST 数据集 113 | (x_train, y_train), (x_test, y_test) = mnist.load_data() 114 | 115 | image_size = x_train.shape[1] 116 | original_dim = image_size * image_size 117 | x_train = np.reshape(x_train, [-1, original_dim]) 118 | x_test = np.reshape(x_test, [-1, original_dim]) 119 | x_train = x_train.astype('float32') / 255 120 | x_test = x_test.astype('float32') / 255 121 | 122 | # 网络参数 123 | input_shape = (original_dim, ) 124 | intermediate_dim = 512 125 | batch_size = 128 126 | latent_dim = 2 127 | epochs = 50 128 | 129 | # VAE model = encoder + decoder 130 | # 建立编码器模型 131 | inputs = Input(shape=input_shape, name='encoder_input') 132 | x = Dense(intermediate_dim, activation='relu')(inputs) 133 | z_mean = Dense(latent_dim, name='z_mean')(x) 134 | z_log_var = Dense(latent_dim, name='z_log_var')(x) 135 | 136 | # 使用重新参数化技巧将采样作为输入推送 137 | # 注意 TensorFlow 后端不需要 "output_shape" 138 | z = Lambda(sampling, output_shape=(latent_dim,), name='z')([z_mean, z_log_var]) 139 | 140 | # 实例化编码器模型 141 | encoder = Model(inputs, [z_mean, z_log_var, z], name='encoder') 142 | encoder.summary() 143 | plot_model(encoder, to_file='vae_mlp_encoder.png', show_shapes=True) 144 | 145 | # 建立解码器模型 146 | latent_inputs = Input(shape=(latent_dim,), name='z_sampling') 147 | x = Dense(intermediate_dim, activation='relu')(latent_inputs) 148 | outputs = Dense(original_dim, activation='sigmoid')(x) 149 | 150 | # 实例化解码器模型 151 | decoder = Model(latent_inputs, outputs, name='decoder') 152 | decoder.summary() 153 | plot_model(decoder, to_file='vae_mlp_decoder.png', show_shapes=True) 154 | 155 | # 实例化 VAE 模型 156 | outputs = decoder(encoder(inputs)[2]) 157 | vae = Model(inputs, outputs, name='vae_mlp') 158 | 159 | if __name__ == '__main__': 160 | parser = argparse.ArgumentParser() 161 | help_ = "Load h5 model trained weights" 162 | parser.add_argument("-w", "--weights", help=help_) 163 | help_ = "Use mse loss instead of binary cross entropy (default)" 164 | parser.add_argument("-m", 165 | "--mse", 166 | help=help_, action='store_true') 167 | args = parser.parse_args() 168 | models = (encoder, decoder) 169 | data = (x_test, y_test) 170 | 171 | # VAE loss = mse_loss or xent_loss + kl_loss 172 | if args.mse: 173 | reconstruction_loss = mse(inputs, outputs) 174 | else: 175 | reconstruction_loss = binary_crossentropy(inputs, 176 | outputs) 177 | 178 | reconstruction_loss *= original_dim 179 | kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var) 180 | kl_loss = K.sum(kl_loss, axis=-1) 181 | kl_loss *= -0.5 182 | vae_loss = K.mean(reconstruction_loss + kl_loss) 183 | vae.add_loss(vae_loss) 184 | vae.compile(optimizer='adam') 185 | vae.summary() 186 | plot_model(vae, 187 | to_file='vae_mlp.png', 188 | show_shapes=True) 189 | 190 | if args.weights: 191 | vae.load_weights(args.weights) 192 | else: 193 | # 训练自动编码器 194 | vae.fit(x_train, 195 | epochs=epochs, 196 | batch_size=batch_size, 197 | validation_data=(x_test, None)) 198 | vae.save_weights('vae_mlp_mnist.h5') 199 | 200 | plot_results(models, 201 | data, 202 | batch_size=batch_size, 203 | model_name="vae_mlp") 204 | ``` -------------------------------------------------------------------------------- /sources/examples/variational_autoencoder_deconv.md: -------------------------------------------------------------------------------- 1 | # 使用 CNN 的 MNIST 数据集上的 VAE 示例 2 | 3 | VAE 具有模块化设计。编码器、解码器和 VAE 是 3 种共享权重的模型。训练 VAE 模型后,编码器可用于生成潜矢量。 4 | 通过从 mean=0 和 std=1 的高斯分布中采样潜矢量,可以将解码器用于生成 MNIST 数字。 5 | 6 | # 参考文献 7 | 8 | [1] Kingma, Diederik P., and Max Welling. 9 | ["Auto-encoding variational bayes."](https://arxiv.org/abs/1312.6114) 10 | 11 | 12 | ```python 13 | from __future__ import absolute_import 14 | from __future__ import division 15 | from __future__ import print_function 16 | 17 | from keras.layers import Dense, Input 18 | from keras.layers import Conv2D, Flatten, Lambda 19 | from keras.layers import Reshape, Conv2DTranspose 20 | from keras.models import Model 21 | from keras.datasets import mnist 22 | from keras.losses import mse, binary_crossentropy 23 | from keras.utils import plot_model 24 | from keras import backend as K 25 | 26 | import numpy as np 27 | import matplotlib.pyplot as plt 28 | import argparse 29 | import os 30 | 31 | 32 | # 重新参数化技巧 33 | # 代替从 Q(z|X) 采样, 采样 eps = N(0,I) 34 | # 然后 z = z_mean + sqrt(var)*eps 35 | def sampling(args): 36 | """通过向各向同性单位高斯采样来进行重新参数化技巧。 37 | 38 | # 参数 39 | args (tensor): Q(z|X) 的均值和对数 40 | 41 | # 返回 42 | z (tensor): 采样的潜在向量 43 | """ 44 | 45 | z_mean, z_log_var = args 46 | batch = K.shape(z_mean)[0] 47 | dim = K.int_shape(z_mean)[1] 48 | # by default, random_normal has mean=0 and std=1.0 49 | epsilon = K.random_normal(shape=(batch, dim)) 50 | return z_mean + K.exp(0.5 * z_log_var) * epsilon 51 | 52 | 53 | def plot_results(models, 54 | data, 55 | batch_size=128, 56 | model_name="vae_mnist"): 57 | """绘制标签和 MNIST 数字作为 2 维潜矢量的函数 58 | 59 | # 参数 60 | models (tuple): 编码器和解码器模型 61 | data (tuple): 测试数据和标签 62 | batch_size (int): 预测批次大小 63 | model_name (string): 哪个模型正在使用此功能 64 | """ 65 | 66 | encoder, decoder = models 67 | x_test, y_test = data 68 | os.makedirs(model_name, exist_ok=True) 69 | 70 | filename = os.path.join(model_name, "vae_mean.png") 71 | # 在潜在空间中显示数字类的二维图 72 | z_mean, _, _ = encoder.predict(x_test, 73 | batch_size=batch_size) 74 | plt.figure(figsize=(12, 10)) 75 | plt.scatter(z_mean[:, 0], z_mean[:, 1], c=y_test) 76 | plt.colorbar() 77 | plt.xlabel("z[0]") 78 | plt.ylabel("z[1]") 79 | plt.savefig(filename) 80 | plt.show() 81 | 82 | filename = os.path.join(model_name, "digits_over_latent.png") 83 | # 显示 30x30 的 2D 数字流形 84 | n = 30 85 | digit_size = 28 86 | figure = np.zeros((digit_size * n, digit_size * n)) 87 | # 线性空间坐标,对应于潜在空间中数字类的二维图 88 | grid_x = np.linspace(-4, 4, n) 89 | grid_y = np.linspace(-4, 4, n)[::-1] 90 | 91 | for i, yi in enumerate(grid_y): 92 | for j, xi in enumerate(grid_x): 93 | z_sample = np.array([[xi, yi]]) 94 | x_decoded = decoder.predict(z_sample) 95 | digit = x_decoded[0].reshape(digit_size, digit_size) 96 | figure[i * digit_size: (i + 1) * digit_size, 97 | j * digit_size: (j + 1) * digit_size] = digit 98 | 99 | plt.figure(figsize=(10, 10)) 100 | start_range = digit_size // 2 101 | end_range = n * digit_size + start_range + 1 102 | pixel_range = np.arange(start_range, end_range, digit_size) 103 | sample_range_x = np.round(grid_x, 1) 104 | sample_range_y = np.round(grid_y, 1) 105 | plt.xticks(pixel_range, sample_range_x) 106 | plt.yticks(pixel_range, sample_range_y) 107 | plt.xlabel("z[0]") 108 | plt.ylabel("z[1]") 109 | plt.imshow(figure, cmap='Greys_r') 110 | plt.savefig(filename) 111 | plt.show() 112 | 113 | 114 | # MNIST 数据集 115 | (x_train, y_train), (x_test, y_test) = mnist.load_data() 116 | 117 | image_size = x_train.shape[1] 118 | x_train = np.reshape(x_train, [-1, image_size, image_size, 1]) 119 | x_test = np.reshape(x_test, [-1, image_size, image_size, 1]) 120 | x_train = x_train.astype('float32') / 255 121 | x_test = x_test.astype('float32') / 255 122 | 123 | # 网络参数 124 | input_shape = (image_size, image_size, 1) 125 | batch_size = 128 126 | kernel_size = 3 127 | filters = 16 128 | latent_dim = 2 129 | epochs = 30 130 | 131 | # VAE model = encoder + decoder 132 | # 建立编码器模型 133 | inputs = Input(shape=input_shape, name='encoder_input') 134 | x = inputs 135 | for i in range(2): 136 | filters *= 2 137 | x = Conv2D(filters=filters, 138 | kernel_size=kernel_size, 139 | activation='relu', 140 | strides=2, 141 | padding='same')(x) 142 | 143 | # 构建解码器模型所需的形状信息 144 | shape = K.int_shape(x) 145 | 146 | # 生成潜在向量 Q(z|X) 147 | x = Flatten()(x) 148 | x = Dense(16, activation='relu')(x) 149 | z_mean = Dense(latent_dim, name='z_mean')(x) 150 | z_log_var = Dense(latent_dim, name='z_log_var')(x) 151 | 152 | # 使用重新参数化技巧将采样作为输入推送 153 | # 注意 TensorFlow 后端不需要 "output_shape" 154 | z = Lambda(sampling, output_shape=(latent_dim,), name='z')([z_mean, z_log_var]) 155 | 156 | # 实例化编码器模型 157 | encoder = Model(inputs, [z_mean, z_log_var, z], name='encoder') 158 | encoder.summary() 159 | plot_model(encoder, to_file='vae_cnn_encoder.png', show_shapes=True) 160 | 161 | # 建立解码器模型 162 | latent_inputs = Input(shape=(latent_dim,), name='z_sampling') 163 | x = Dense(shape[1] * shape[2] * shape[3], activation='relu')(latent_inputs) 164 | x = Reshape((shape[1], shape[2], shape[3]))(x) 165 | 166 | for i in range(2): 167 | x = Conv2DTranspose(filters=filters, 168 | kernel_size=kernel_size, 169 | activation='relu', 170 | strides=2, 171 | padding='same')(x) 172 | filters //= 2 173 | 174 | outputs = Conv2DTranspose(filters=1, 175 | kernel_size=kernel_size, 176 | activation='sigmoid', 177 | padding='same', 178 | name='decoder_output')(x) 179 | 180 | # 实例化解码器模型 181 | decoder = Model(latent_inputs, outputs, name='decoder') 182 | decoder.summary() 183 | plot_model(decoder, to_file='vae_cnn_decoder.png', show_shapes=True) 184 | 185 | # 实例化VAE模型 186 | outputs = decoder(encoder(inputs)[2]) 187 | vae = Model(inputs, outputs, name='vae') 188 | 189 | if __name__ == '__main__': 190 | parser = argparse.ArgumentParser() 191 | help_ = "Load h5 model trained weights" 192 | parser.add_argument("-w", "--weights", help=help_) 193 | help_ = "Use mse loss instead of binary cross entropy (default)" 194 | parser.add_argument("-m", "--mse", help=help_, action='store_true') 195 | args = parser.parse_args() 196 | models = (encoder, decoder) 197 | data = (x_test, y_test) 198 | 199 | # VAE loss = mse_loss or xent_loss + kl_loss 200 | if args.mse: 201 | reconstruction_loss = mse(K.flatten(inputs), K.flatten(outputs)) 202 | else: 203 | reconstruction_loss = binary_crossentropy(K.flatten(inputs), 204 | K.flatten(outputs)) 205 | 206 | reconstruction_loss *= image_size * image_size 207 | kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var) 208 | kl_loss = K.sum(kl_loss, axis=-1) 209 | kl_loss *= -0.5 210 | vae_loss = K.mean(reconstruction_loss + kl_loss) 211 | vae.add_loss(vae_loss) 212 | vae.compile(optimizer='rmsprop') 213 | vae.summary() 214 | plot_model(vae, to_file='vae_cnn.png', show_shapes=True) 215 | 216 | if args.weights: 217 | vae.load_weights(args.weights) 218 | else: 219 | # 训练自动编码器 220 | vae.fit(x_train, 221 | epochs=epochs, 222 | batch_size=batch_size, 223 | validation_data=(x_test, None)) 224 | vae.save_weights('vae_cnn_mnist.h5') 225 | 226 | plot_results(models, data, batch_size=batch_size, model_name="vae_cnn") 227 | ``` -------------------------------------------------------------------------------- /sources/img/aws-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keras-team/keras-docs-zh/ec3b1674f29cf21a50f0e9d72d6875330b68ce9f/sources/img/aws-logo.png -------------------------------------------------------------------------------- /sources/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keras-team/keras-docs-zh/ec3b1674f29cf21a50f0e9d72d6875330b68ce9f/sources/img/favicon.ico -------------------------------------------------------------------------------- /sources/img/google-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keras-team/keras-docs-zh/ec3b1674f29cf21a50f0e9d72d6875330b68ce9f/sources/img/google-logo.png -------------------------------------------------------------------------------- /sources/img/keras-logo-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keras-team/keras-docs-zh/ec3b1674f29cf21a50f0e9d72d6875330b68ce9f/sources/img/keras-logo-small.jpg -------------------------------------------------------------------------------- /sources/img/microsoft-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keras-team/keras-docs-zh/ec3b1674f29cf21a50f0e9d72d6875330b68ce9f/sources/img/microsoft-logo.png -------------------------------------------------------------------------------- /sources/img/multi-input-multi-output-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keras-team/keras-docs-zh/ec3b1674f29cf21a50f0e9d72d6875330b68ce9f/sources/img/multi-input-multi-output-graph.png -------------------------------------------------------------------------------- /sources/img/nvidia-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keras-team/keras-docs-zh/ec3b1674f29cf21a50f0e9d72d6875330b68ce9f/sources/img/nvidia-logo.png -------------------------------------------------------------------------------- /sources/img/regular_stacked_lstm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keras-team/keras-docs-zh/ec3b1674f29cf21a50f0e9d72d6875330b68ce9f/sources/img/regular_stacked_lstm.png -------------------------------------------------------------------------------- /sources/index.md: -------------------------------------------------------------------------------- 1 | # Keras: 基于 Python 的深度学习库 2 | 3 | 4 | 5 | 6 | 7 | ## 你恰好发现了 Keras。 8 | 9 | Keras 是一个用 Python 编写的高级神经网络 API,它能够以 [TensorFlow](https://github.com/tensorflow/tensorflow), [CNTK](https://github.com/Microsoft/cntk) 或者 [Theano](https://github.com/Theano/Theano) 作为后端运行。Keras 的开发重点是支持快速的实验。*能够以最小的时延把你的想法转换为实验结果,是做好研究的关键。* 10 | 11 | 如果你在以下情况下需要深度学习库,请使用 Keras: 12 | 13 | - 允许简单而快速的原型设计(由于用户友好,高度模块化,可扩展性)。 14 | - 同时支持卷积神经网络和循环神经网络,以及两者的组合。 15 | - 在 CPU 和 GPU 上无缝运行。 16 | 17 | 查看文档,请访问 [Keras.io](https://keras.io/zh/)。备份网址:[Keras-zh](https://keras-zh.readthedocs.io/)。 18 | 19 | Keras 兼容的 Python 版本: __Python 2.7-3.6__。 20 | 21 | 22 | ------------------ 23 | 24 | ## 多后端 Keras 和 tf.keras: 25 | 26 | **目前,我们推荐使用 TensorFlow 后端的 Keras 用户切换至 TensorFlow 2.0 的 `tf.keras`。** 27 | `tf.keras` 具有更好的维护,并且更好地集成了 TensorFlow 功能(eager执行,分布式支持及其他)。 28 | 29 | Keras 2.2.5 是最后一个实现 2.2.* API 的 Keras 版本。它是最后一个仅支持 TensorFlow 1(以及 Theano 和 CNTK)的版本。 30 | 31 | Keras 的当前版本是 2.3.0,它对 API 做了重大的调整,并且添加了 TensorFlow 2.0 的支持。2.3.0 将会是最后一个多后端 Keras 主版本。多后端 Keras 已被 `tf.keras` 取代。 32 | 33 | 多后端 Keras 中存在的错误修复仅会持续到 2020 年 4 月(作为次要版本的一部分)。 34 | 35 | 关于 Keras 未来的更多信息,详见 [the Keras meeting notes](http://bit.ly/keras-meeting-notes)。 36 | 37 | 38 | ## 指导原则 39 | 40 | - __用户友好。__ Keras 是为人类而不是为机器设计的 API。它把用户体验放在首要和中心位置。Keras 遵循减少认知困难的最佳实践:它提供一致且简单的 API,将常见用例所需的用户操作数量降至最低,并且在用户错误时提供清晰和可操作的反馈。 41 | 42 | - __模块化。__ 模型被理解为由独立的、完全可配置的模块构成的序列或图。这些模块可以以尽可能少的限制组装在一起。特别是神经网络层、损失函数、优化器、初始化方法、激活函数、正则化方法,它们都是可以结合起来构建新模型的模块。 43 | 44 | - __易扩展性。__ 新的模块是很容易添加的(作为新的类和函数),现有的模块已经提供了充足的示例。由于能够轻松地创建可以提高表现力的新模块,Keras 更加适合高级研究。 45 | 46 | - __基于 Python 实现。__ Keras 没有特定格式的单独配置文件。模型定义在 Python 代码中,这些代码紧凑,易于调试,并且易于扩展。 47 | 48 | 49 | ------------------ 50 | 51 | 52 | ## 快速开始:30 秒上手 Keras 53 | 54 | Keras 的核心数据结构是 __model__,一种组织网络层的方式。最简单的模型是 [Sequential 顺序模型](/getting-started/sequential-model-guide),它由多个网络层线性堆叠。对于更复杂的结构,你应该使用 [Keras 函数式 API](/getting-started/functional-api-guide),它允许构建任意的神经网络图。 55 | 56 | `Sequential` 模型如下所示: 57 | 58 | ```python 59 | from keras.models import Sequential 60 | 61 | model = Sequential() 62 | ``` 63 | 64 | 可以简单地使用 `.add()` 来堆叠模型: 65 | 66 | ```python 67 | from keras.layers import Dense 68 | 69 | model.add(Dense(units=64, activation='relu', input_dim=100)) 70 | model.add(Dense(units=10, activation='softmax')) 71 | ``` 72 | 73 | 在完成了模型的构建后, 可以使用 `.compile()` 来配置学习过程: 74 | 75 | ```python 76 | model.compile(loss='categorical_crossentropy', 77 | optimizer='sgd', 78 | metrics=['accuracy']) 79 | ``` 80 | 81 | 如果需要,你还可以进一步地配置你的优化器。Keras 的核心原则是使事情变得相当简单,同时又允许用户在需要的时候能够进行完全的控制(终极的控制是源代码的易扩展性)。 82 | 83 | ```python 84 | model.compile(loss=keras.losses.categorical_crossentropy, 85 | optimizer=keras.optimizers.SGD(lr=0.01, momentum=0.9, nesterov=True)) 86 | ``` 87 | 88 | 现在,你可以批量地在训练数据上进行迭代了: 89 | 90 | ```python 91 | # x_train 和 y_train 是 Numpy 数组 -- 就像在 Scikit-Learn API 中一样。 92 | model.fit(x_train, y_train, epochs=5, batch_size=32) 93 | ``` 94 | 95 | 或者,你可以手动地将批次的数据提供给模型: 96 | 97 | ```python 98 | model.train_on_batch(x_batch, y_batch) 99 | ``` 100 | 101 | 只需一行代码就能评估模型性能: 102 | 103 | ```python 104 | loss_and_metrics = model.evaluate(x_test, y_test, batch_size=128) 105 | ``` 106 | 107 | 或者对新的数据生成预测: 108 | 109 | ```python 110 | classes = model.predict(x_test, batch_size=128) 111 | ``` 112 | 113 | 构建一个问答系统,一个图像分类模型,一个神经图灵机,或者其他的任何模型,就是这么的快。深度学习背后的思想很简单,那么它们的实现又何必要那么痛苦呢? 114 | 115 | 有关 Keras 更深入的教程,请查看: 116 | 117 | - [开始使用 Sequential 模型](/getting-started/sequential-model-guide) 118 | - [开始使用函数式 API](/getting-started/functional-api-guide) 119 | 120 | 在代码仓库的 [examples](https://github.com/keras-team/keras/tree/master/examples) 目录中,你会找到更多高级模型:基于记忆网络的问答系统、基于栈式 LSTM 的文本生成等等。 121 | 122 | 123 | ------------------ 124 | 125 | 126 | ## 安装指引 127 | 128 | 在安装 Keras 之前,请安装以下后端引擎之一: TensorFlow, Theano 或者 CNTK。我们推荐 TensorFlow 后端。 129 | 130 | - [TensorFlow 安装指引](https://www.tensorflow.org/install/)。 131 | - [Theano 安装指引](http://deeplearning.net/software/theano/install.html#install)。 132 | - [CNTK 安装指引](https://docs.microsoft.com/en-us/cognitive-toolkit/setup-cntk-on-your-machine)。 133 | 134 | 你也可以考虑安装以下**可选依赖**: 135 | 136 | - [cuDNN](https://docs.nvidia.com/deeplearning/sdk/cudnn-install/) (如果你计划在 GPU 上运行 Keras,建议安装)。 137 | - HDF5 和 [h5py](http://docs.h5py.org/en/latest/build.html) (如果你需要将 Keras 模型保存到磁盘,则需要这些)。 138 | - [graphviz](https://graphviz.gitlab.io/download/) 和 [pydot](https://github.com/erocarrera/pydot) (用于绘制模型图的[可视化工具](https://keras.io/zh/visualization/))。 139 | 140 | 然后你就可以安装 Keras 本身了。有两种方法安装 Keras: 141 | 142 | - **使用 PyPI 安装 Keras(推荐):** 143 | 144 | 注意:这些安装步骤假定你在 Linux 或 Mac 环境中。 145 | 如果你使用的是 Windows,则需要删除 `sudo` 才能运行以下命令。 146 | 147 | ```sh 148 | sudo pip install keras 149 | ``` 150 | 151 | 如果你使用 virtualenv 虚拟环境, 你可以避免使用 sudo: 152 | 153 | ```sh 154 | pip install keras 155 | ``` 156 | 157 | - **或者:使用 GitHub 源码安装 Keras:** 158 | 159 | 首先,使用 `git` 来克隆 Keras: 160 | 161 | ```sh 162 | git clone https://github.com/keras-team/keras.git 163 | ``` 164 | 165 | 然后,`cd` 到 Keras 目录并且运行安装命令: 166 | 167 | ```sh 168 | cd keras 169 | sudo python setup.py install 170 | ``` 171 | 172 | ------------------ 173 | 174 | 175 | ## 配置你的 Keras 后端 176 | 177 | 默认情况下,Keras 将使用 TensorFlow 作为其张量操作库。请[跟随这些指引](https://keras.io/zh/backend/)来配置其他 Keras 后端。 178 | 179 | ------------------ 180 | 181 | 182 | ## 技术支持 183 | 184 | 你可以提出问题并参与开发讨论: 185 | 186 | - [Keras Google group](https://groups.google.com/forum/#!forum/keras-users)。 187 | - [Keras Slack channel](https://kerasteam.slack.com)。使用 [这个链接](https://keras-slack-autojoin.herokuapp.com/) 向该频道请求邀请函。 188 | - 或者加入 Keras 深度学习交流群,协助文档的翻译工作,群号为 951623081。 189 | 190 | 你也可以在 [GitHub issues](https://github.com/keras-team/keras/issues) 中发布**漏洞报告和新功能请求**(仅限于此)。注意请先阅读[规范文档](https://github.com/keras-team/keras/blob/master/CONTRIBUTING.md)。 191 | 192 | 193 | ------------------ 194 | 195 | 196 | ## 为什么取名为 Keras? 197 | 198 | Keras (κέρας) 在希腊语中意为 *号角* 。它来自古希腊和拉丁文学中的一个文学形象,首先出现于 *《奥德赛》* 中, 梦神 (_Oneiroi_, singular _Oneiros_) 从这两类人中分离出来:那些用虚幻的景象欺骗人类,通过象牙之门抵达地球之人,以及那些宣告未来即将到来,通过号角之门抵达之人。 它类似于文字寓意,κέρας (号角) / κραίνω (履行),以及 ἐλέφας (象牙) / ἐλεφαίρομαι (欺骗)。 199 | 200 | Keras 最初是作为 ONEIROS 项目(开放式神经电子智能机器人操作系统)研究工作的一部分而开发的。 201 | 202 | >_"Oneiroi 超出了我们的理解 - 谁能确定它们讲述了什么故事?并不是所有人都能找到。那里有两扇门,就是通往短暂的 Oneiroi 的通道;一个是用号角制造的,一个是用象牙制造的。穿过尖锐的象牙的 Oneiroi 是诡计多端的,他们带有一些不会实现的信息; 那些穿过抛光的喇叭出来的人背后具有真理,对于看到他们的人来说是完成的。"_ Homer, Odyssey 19. 562 ff (Shewring translation). 203 | 204 | ------------------ 205 | -------------------------------------------------------------------------------- /sources/layers/about-keras-layers.md: -------------------------------------------------------------------------------- 1 | # 关于 Keras 网络层 2 | 3 | 所有 Keras 网络层都有很多共同的函数: 4 | 5 | - `layer.get_weights()`: 以含有Numpy矩阵的列表形式返回层的权重。 6 | - `layer.set_weights(weights)`: 从含有Numpy矩阵的列表中设置层的权重(与`get_weights`的输出形状相同)。 7 | - `layer.get_config()`: 返回包含层配置的字典。此图层可以通过以下方式重置: 8 | 9 | ```python 10 | layer = Dense(32) 11 | config = layer.get_config() 12 | reconstructed_layer = Dense.from_config(config) 13 | ``` 14 | 15 | 或: 16 | 17 | ```python 18 | from keras import layers 19 | 20 | config = layer.get_config() 21 | layer = layers.deserialize({'class_name': layer.__class__.__name__, 22 | 'config': config}) 23 | ``` 24 | 25 | 如果一个层具有单个节点 (i.e. 如果它不是共享层), 你可以得到它的输入张量、输出张量、输入尺寸和输出尺寸: 26 | 27 | - `layer.input` 28 | - `layer.output` 29 | - `layer.input_shape` 30 | - `layer.output_shape` 31 | 32 | 如果层有多个节点 (参见: [层节点和共享层的概念](/getting-started/functional-api-guide/#the-concept-of-layer-node)), 您可以使用以下函数: 33 | 34 | - `layer.get_input_at(node_index)` 35 | - `layer.get_output_at(node_index)` 36 | - `layer.get_input_shape_at(node_index)` 37 | - `layer.get_output_shape_at(node_index)` 38 | -------------------------------------------------------------------------------- /sources/layers/advanced-activations.md: -------------------------------------------------------------------------------- 1 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/advanced_activations.py#L19) 2 | ### LeakyReLU 3 | 4 | ```python 5 | keras.layers.LeakyReLU(alpha=0.3) 6 | ``` 7 | 8 | 带泄漏的 ReLU。 9 | 10 | 当神经元未激活时,它仍允许赋予一个很小的梯度: 11 | `f(x) = alpha * x for x < 0`, 12 | `f(x) = x for x >= 0`. 13 | 14 | __输入尺寸__ 15 | 16 | 可以是任意的。如果将该层作为模型的第一层, 17 | 则需要指定 `input_shape` 参数 18 | (整数元组,不包含样本数量的维度)。 19 | 20 | __输出尺寸__ 21 | 22 | 与输入相同。 23 | 24 | __参数__ 25 | 26 | - __alpha__: float >= 0。负斜率系数。 27 | 28 | __参考文献__ 29 | 30 | - [Rectifier Nonlinearities Improve Neural Network Acoustic Models](https://web.stanford.edu/~awni/papers/relu_hybrid_icml2013_final.pdf) 31 | 32 | ---- 33 | 34 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/advanced_activations.py#L59) 35 | ### PReLU 36 | 37 | ```python 38 | keras.layers.PReLU(alpha_initializer='zeros', alpha_regularizer=None, alpha_constraint=None, shared_axes=None) 39 | ``` 40 | 41 | 参数化的 ReLU。 42 | 43 | 形式: 44 | `f(x) = alpha * x for x < 0`, 45 | `f(x) = x for x >= 0`, 46 | 其中 `alpha` 是一个可学习的数组,尺寸与 x 相同。 47 | 48 | __输入尺寸__ 49 | 50 | 可以是任意的。如果将这一层作为模型的第一层, 51 | 则需要指定 `input_shape` 参数 52 | (整数元组,不包含样本数量的维度)。 53 | 54 | __输出尺寸__ 55 | 56 | 与输入相同。 57 | 58 | __参数__ 59 | 60 | - __alpha_initializer__: 权重的初始化函数。 61 | - __alpha_regularizer__: 权重的正则化方法。 62 | - __alpha_constraint__: 权重的约束。 63 | - __shared_axes__: 激活函数共享可学习参数的轴。 64 | 例如,如果输入特征图来自输出形状为 `(batch, height, width, channels)` 65 | 的 2D 卷积层,而且你希望跨空间共享参数,以便每个滤波器只有一组参数, 66 | 可设置 `shared_axes=[1, 2]`。 67 | 68 | __参考文献__ 69 | 70 | - [Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification](https://arxiv.org/abs/1502.01852) 71 | 72 | ---- 73 | 74 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/advanced_activations.py#L153) 75 | ### ELU 76 | 77 | ```python 78 | keras.layers.ELU(alpha=1.0) 79 | ``` 80 | 81 | 指数线性单元。 82 | 83 | 形式: 84 | `f(x) = alpha * (exp(x) - 1.) for x < 0`, 85 | `f(x) = x for x >= 0`. 86 | 87 | __输入尺寸__ 88 | 89 | 可以是任意的。如果将这一层作为模型的第一层, 90 | 则需要指定 `input_shape` 参数 91 | (整数元组,不包含样本数量的维度)。 92 | 93 | __输出尺寸__ 94 | 95 | 与输入相同。 96 | 97 | __参数__ 98 | 99 | - __alpha__: 负因子的尺度。 100 | 101 | __参考文献__ 102 | 103 | - [Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs)](https://arxiv.org/abs/1511.07289v1) 104 | 105 | ---- 106 | 107 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/advanced_activations.py#L193) 108 | ### ThresholdedReLU 109 | 110 | ```python 111 | keras.layers.ThresholdedReLU(theta=1.0) 112 | ``` 113 | 114 | 带阈值的修正线性单元。 115 | 116 | 形式: 117 | `f(x) = x for x > theta`, 118 | `f(x) = 0 otherwise`. 119 | 120 | __输入尺寸__ 121 | 122 | 可以是任意的。如果将这一层作为模型的第一层, 123 | 则需要指定 `input_shape` 参数 124 | (整数元组,不包含样本数量的维度)。 125 | 126 | __输出尺寸__ 127 | 128 | 与输入相同。 129 | 130 | __参数__ 131 | 132 | - __theta__: float >= 0。激活的阈值位。 133 | 134 | __参考文献__ 135 | 136 | - [Zero-Bias Autoencoders and the Benefits of Co-Adapting Features](http://arxiv.org/abs/1402.3337) 137 | 138 | ---- 139 | 140 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/advanced_activations.py#L233) 141 | ### Softmax 142 | 143 | ```python 144 | keras.layers.Softmax(axis=-1) 145 | ``` 146 | 147 | Softmax 激活函数。 148 | 149 | __输入尺寸__ 150 | 151 | 可以是任意的。如果将这一层作为模型的第一层, 152 | 则需要指定 `input_shape` 参数 153 | (整数元组,不包含样本数量的维度)。 154 | 155 | __输出尺寸__ 156 | 157 | 与输入相同。 158 | 159 | __参数__ 160 | 161 | - __axis__: 整数,应用 softmax 标准化的轴。 162 | 163 | ---- 164 | 165 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/advanced_activations.py#L265) 166 | ### ReLU 167 | 168 | ```python 169 | keras.layers.ReLU(max_value=None, negative_slope=0.0, threshold=0.0) 170 | ``` 171 | 172 | ReLU 激活函数。 173 | 174 | 使用默认值时,它返回逐个元素的 `max(x,0)`。 175 | 176 | 否则: 177 | 178 | - 如果 `x >= max_value`,返回 `f(x) = max_value`, 179 | - 如果 `threshold <= x < max_value`,返回 `f(x) = x`, 180 | - 否则,返回 `f(x) = negative_slope * (x - threshold)`。 181 | 182 | __输入尺寸__ 183 | 184 | 可以是任意的。如果将这一层作为模型的第一层, 185 | 则需要指定 `input_shape` 参数 186 | (整数元组,不包含样本数量的维度)。 187 | 188 | __输出尺寸__ 189 | 190 | 与输入相同。 191 | 192 | __参数__ 193 | 194 | - __max_value__: 浮点数,最大的输出值。 195 | - __negative_slope__: float >= 0. 负斜率系数。 196 | - __threshold__: float。"thresholded activation" 的阈值。 197 | -------------------------------------------------------------------------------- /sources/layers/embeddings.md: -------------------------------------------------------------------------------- 1 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/embeddings.py#L16) 2 | ### Embedding 3 | 4 | ```python 5 | keras.layers.Embedding(input_dim, output_dim, embeddings_initializer='uniform', embeddings_regularizer=None, activity_regularizer=None, embeddings_constraint=None, mask_zero=False, input_length=None) 6 | ``` 7 | 8 | 将正整数(索引值)转换为固定尺寸的稠密向量。 9 | 例如: [[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]] 10 | 11 | 该层只能用作模型中的第一层。 12 | 13 | __示例__ 14 | 15 | 16 | ```python 17 | model = Sequential() 18 | model.add(Embedding(1000, 64, input_length=10)) 19 | # 模型将输入一个大小为 (batch, input_length) 的整数矩阵。 20 | # 输入中最大的整数(即词索引)不应该大于 999 (词汇表大小) 21 | # 现在 model.output_shape == (None, 10, 64),其中 None 是 batch 的维度。 22 | 23 | input_array = np.random.randint(1000, size=(32, 10)) 24 | 25 | model.compile('rmsprop', 'mse') 26 | output_array = model.predict(input_array) 27 | assert output_array.shape == (32, 10, 64) 28 | ``` 29 | 30 | __参数__ 31 | 32 | - __input_dim__: int > 0。词汇表大小, 33 | 即,最大整数 index + 1。 34 | - __output_dim__: int >= 0。词向量的维度。 35 | - __embeddings_initializer__: `embeddings` 矩阵的初始化方法 36 | (详见 [initializers](../initializers.md))。 37 | - __embeddings_regularizer__: `embeddings` matrix 的正则化方法 38 | (详见 [regularizer](../regularizers.md))。 39 | - __activity_regularizer__: 应用到层输出的正则化函数 (它的 "activation")。 40 | (详见 [regularizer](../regularizers.md))。 41 | - __embeddings_constraint__: `embeddings` matrix 的约束函数 42 | (详见 [constraints](../constraints.md))。 43 | - __mask_zero__: 是否把 0 看作为一个应该被遮蔽的特殊的 "padding" 值。 44 | 这对于可变长的[循环神经网络层](recurrent.md) 十分有用。 45 | 如果设定为 `True`,那么接下来的所有层都必须支持 masking,否则就会抛出异常。 46 | 如果 mask_zero 为 `True`,作为结果,索引 0 就不能被用于词汇表中 47 | (input_dim 应该与 vocabulary + 1 大小相同)。 48 | - __input_length__: 输入序列的长度,当它是固定的时。 49 | 如果你需要连接 `Flatten` 和 `Dense` 层,则这个参数是必须的 50 | (没有它,dense 层的输出尺寸就无法计算)。 51 | 52 | __输入尺寸__ 53 | 54 | 尺寸为 `(batch_size, sequence_length)` 的 2D 张量。 55 | 56 | __输出尺寸__ 57 | 58 | 尺寸为 `(batch_size, sequence_length, output_dim)` 的 3D 张量。 59 | 60 | __参考文献__ 61 | 62 | - [A Theoretically Grounded Application of Dropout in Recurrent Neural Networks](http://arxiv.org/abs/1512.05287) 63 | -------------------------------------------------------------------------------- /sources/layers/local.md: -------------------------------------------------------------------------------- 1 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/local.py#L19) 2 | ### LocallyConnected1D 3 | 4 | ```python 5 | keras.layers.LocallyConnected1D(filters, kernel_size, strides=1, padding='valid', data_format=None, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None) 6 | ``` 7 | 8 | 1D 输入的局部连接层。 9 | 10 | `LocallyConnected1D` 层与 `Conv1D` 层的工作方式相同,除了权值不共享外, 11 | 也就是说,在输入的每个不同部分应用不同的一组过滤器。 12 | 13 | __示例__ 14 | 15 | ```python 16 | # 将长度为 3 的非共享权重 1D 卷积应用于 17 | # 具有 10 个时间步长的序列,并使用 64个 输出滤波器 18 | model = Sequential() 19 | model.add(LocallyConnected1D(64, 3, input_shape=(10, 32))) 20 | # 现在 model.output_shape == (None, 8, 64) 21 | # 在上面再添加一个新的 conv1d 22 | model.add(LocallyConnected1D(32, 3)) 23 | # 现在 model.output_shape == (None, 6, 32) 24 | ``` 25 | 26 | __参数__ 27 | 28 | - __filters__: 整数,输出空间的维度 29 | (即卷积中滤波器的输出数量)。 30 | - __kernel_size__: 一个整数,或者单个整数表示的元组或列表, 31 | 指明 1D 卷积窗口的长度。 32 | - __strides__: 一个整数,或者单个整数表示的元组或列表, 33 | 指明卷积的步长。 34 | 指定任何 `stride!=1` 与指定 `dilation_rate!=1` 两者不兼容。 35 | - __padding__: 当前仅支持 `"valid"` (大小写敏感)。 36 | `"same"` 可能会在未来支持。 37 | - __data_format__: 字符串,`channels_first`, `channels_last` 之一。 38 | - __activation__: 要使用的激活函数 39 | (详见 [activations](../activations.md))。 40 | 如果你不指定,则不使用激活函数 41 | (即线性激活: `a(x) = x`)。 42 | - __use_bias__: 布尔值,该层是否使用偏置向量。 43 | - __kernel_initializer__: `kernel` 权值矩阵的初始化器 44 | (详见 [initializers](../initializers.md))。 45 | - __bias_initializer__: 偏置向量的初始化器 46 | (详见 [initializers](../initializers.md))。 47 | - __kernel_regularizer__: 运用到 `kernel` 权值矩阵的正则化函数 48 | (详见 [regularizer](../regularizers.md))。 49 | - __bias_regularizer__: 运用到偏置向量的正则化函数 50 | (详见 [regularizer](../regularizers.md))。 51 | - __activity_regularizer__: 运用到层输出(它的激活值)的正则化函数 52 | (详见 [regularizer](../regularizers.md))。 53 | - __kernel_constraint__: 运用到 `kernel` 权值矩阵的约束函数 54 | (详见 [constraints](../constraints.md))。 55 | - __bias_constraint__: 运用到偏置向量的约束函数 56 | (详见 [constraints](../constraints.md))。 57 | 58 | __输入尺寸__ 59 | 60 | 3D 张量,尺寸为: `(batch_size, steps, input_dim)`。 61 | 62 | __输出尺寸__ 63 | 64 | 3D 张量 ,尺寸为:`(batch_size, new_steps, filters)`, 65 | `steps` 值可能因填充或步长而改变。 66 | 67 | ---- 68 | 69 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/local.py#L183) 70 | ### LocallyConnected2D 71 | 72 | ```python 73 | keras.layers.LocallyConnected2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None) 74 | ``` 75 | 76 | 2D 输入的局部连接层。 77 | 78 | `LocallyConnected2D` 层与 `Conv2D` 层的工作方式相同,除了权值不共享外, 79 | 也就是说,在输入的每个不同部分应用不同的一组过滤器。 80 | 81 | __示例__ 82 | 83 | ```python 84 | # 在 32x32 图像上应用 3x3 非共享权值和64个输出过滤器的卷积 85 | # 数据格式 `data_format="channels_last"`: 86 | model = Sequential() 87 | model.add(LocallyConnected2D(64, (3, 3), input_shape=(32, 32, 3))) 88 | # 现在 model.output_shape == (None, 30, 30, 64) 89 | # 注意这一层的参数数量为 (30*30)*(3*3*3*64) + (30*30)*64 90 | 91 | # 在上面再加一个 3x3 非共享权值和 32 个输出滤波器的卷积: 92 | model.add(LocallyConnected2D(32, (3, 3))) 93 | # 现在 model.output_shape == (None, 28, 28, 32) 94 | ``` 95 | 96 | __参数__ 97 | 98 | - __filters__: 整数,输出空间的维度 99 | (即卷积中滤波器的输出数量)。 100 | - __kernel_size__: 一个整数,或者 2 个整数表示的元组或列表, 101 | 指明 2D 卷积窗口的宽度和高度。 102 | 可以是一个整数,为所有空间维度指定相同的值。 103 | - __strides__: 一个整数,或者 2 个整数表示的元组或列表, 104 | 指明卷积沿宽度和高度方向的步长。 105 | 可以是一个整数,为所有空间维度指定相同的值。 106 | - __padding__: 当前仅支持 `"valid"` (大小写敏感)。 107 | `"same"` 可能会在未来支持。 108 | - __data_format__: 字符串, 109 | `channels_last` (默认) 或 `channels_first` 之一。 110 | 输入中维度的顺序。 111 | `channels_last` 对应输入尺寸为 `(batch, height, width, channels)`, 112 | `channels_first` 对应输入尺寸为 `(batch, channels, height, width)`。 113 | 它默认为从 Keras 配置文件 `~/.keras/keras.json` 中 114 | 找到的 `image_data_format` 值。 115 | 如果你从未设置它,将使用 "channels_last"。 116 | - __activation__: 要使用的激活函数 117 | (详见 [activations](../activations.md))。 118 | 如果你不指定,则不使用激活函数 119 | (即线性激活: `a(x) = x`)。 120 | - __use_bias__: 布尔值,该层是否使用偏置向量。 121 | - __kernel_initializer__: `kernel` 权值矩阵的初始化器 122 | (详见 [initializers](../initializers.md))。 123 | - __bias_initializer__: 偏置向量的初始化器 124 | (详见 [initializers](../initializers.md))。 125 | - __kernel_regularizer__: 运用到 `kernel` 权值矩阵的正则化函数 126 | (详见 [regularizer](../regularizers.md))。 127 | - __bias_regularizer__: 运用到偏置向量的正则化函数 128 | (详见 [regularizer](../regularizers.md))。 129 | - __activity_regularizer__: 运用到层输出(它的激活值)的正则化函数 130 | (详见 [regularizer](../regularizers.md))。 131 | - __kernel_constraint__: 运用到 `kernel` 权值矩阵的约束函数 132 | (详见 [constraints](../constraints.md))。 133 | - __bias_constraint__: 运用到偏置向量的约束函数 134 | (详见 [constraints](../constraints.md))。 135 | 136 | __输入尺寸__ 137 | 138 | 4D 张量,尺寸为: 139 | `(samples, channels, rows, cols)`,如果 `data_format='channels_first'`; 140 | 或者 4D 张量,尺寸为: 141 | `(samples, rows, cols, channels)`,如果 `data_format='channels_last'`。 142 | 143 | __输出尺寸__ 144 | 145 | 4D 张量,尺寸为: 146 | `(samples, filters, new_rows, new_cols)`,如果 data_format='channels_first'; 147 | 或者 4D 张量,尺寸为: 148 | `(samples, new_rows, new_cols, filters)`,如果 data_format='channels_last'。 149 | `rows` 和 `cols` 的值可能因填充而改变。 150 | -------------------------------------------------------------------------------- /sources/layers/merge.md: -------------------------------------------------------------------------------- 1 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/merge.py#L200) 2 | ### Add 3 | 4 | ```python 5 | keras.layers.Add() 6 | ``` 7 | 8 | 计算输入张量列表的和。 9 | 10 | 它接受一个张量的列表, 11 | 所有的张量必须有相同的输入尺寸, 12 | 然后返回一个张量(和输入张量尺寸相同)。 13 | 14 | __示例__ 15 | 16 | 17 | ```python 18 | import keras 19 | 20 | input1 = keras.layers.Input(shape=(16,)) 21 | x1 = keras.layers.Dense(8, activation='relu')(input1) 22 | input2 = keras.layers.Input(shape=(32,)) 23 | x2 = keras.layers.Dense(8, activation='relu')(input2) 24 | # 相当于 added = keras.layers.add([x1, x2]) 25 | added = keras.layers.Add()([x1, x2]) 26 | 27 | out = keras.layers.Dense(4)(added) 28 | model = keras.models.Model(inputs=[input1, input2], outputs=out) 29 | ``` 30 | 31 | ---- 32 | 33 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/merge.py#L231) 34 | ### Subtract 35 | 36 | ```python 37 | keras.layers.Subtract() 38 | ``` 39 | 40 | 计算两个输入张量的差。 41 | 42 | 它接受一个长度为 2 的张量列表, 43 | 两个张量必须有相同的尺寸,然后返回一个值为 (inputs[0] - inputs[1]) 的张量, 44 | 输出张量和输入张量尺寸相同。 45 | 46 | __示例__ 47 | 48 | 49 | ```python 50 | import keras 51 | 52 | input1 = keras.layers.Input(shape=(16,)) 53 | x1 = keras.layers.Dense(8, activation='relu')(input1) 54 | input2 = keras.layers.Input(shape=(32,)) 55 | x2 = keras.layers.Dense(8, activation='relu')(input2) 56 | # 相当于 subtracted = keras.layers.subtract([x1, x2]) 57 | subtracted = keras.layers.Subtract()([x1, x2]) 58 | 59 | out = keras.layers.Dense(4)(subtracted) 60 | model = keras.models.Model(inputs=[input1, input2], outputs=out) 61 | ``` 62 | 63 | ---- 64 | 65 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/merge.py#L268) 66 | ### Multiply 67 | 68 | ```python 69 | keras.layers.Multiply() 70 | ``` 71 | 72 | 计算输入张量列表的(逐元素间的)乘积。 73 | 74 | 它接受一个张量的列表, 75 | 所有的张量必须有相同的输入尺寸, 76 | 然后返回一个张量(和输入张量尺寸相同)。 77 | 78 | ---- 79 | 80 | [[source]][[source]](https://github.com/keras-team/keras/blob/master/keras/layers/merge.py#L283) 81 | ### Average 82 | 83 | ```python 84 | keras.layers.Average() 85 | ``` 86 | 87 | 计算输入张量列表的平均值。 88 | 89 | 它接受一个张量的列表, 90 | 所有的张量必须有相同的输入尺寸, 91 | 然后返回一个张量(和输入张量尺寸相同)。 92 | 93 | ---- 94 | 95 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/merge.py#L298) 96 | ### Maximum 97 | 98 | ```python 99 | keras.layers.Maximum() 100 | ``` 101 | 102 | 计算输入张量列表的(逐元素间的)最大值。 103 | 104 | 它接受一个张量的列表, 105 | 所有的张量必须有相同的输入尺寸, 106 | 然后返回一个张量(和输入张量尺寸相同)。 107 | 108 | ---- 109 | 110 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/merge.py#L313) 111 | ### Minimum 112 | 113 | ```python 114 | keras.layers.Minimum() 115 | ``` 116 | 117 | 计算输入张量列表的(逐元素间的)最小值。 118 | 119 | 它接受一个张量的列表, 120 | 所有的张量必须有相同的输入尺寸, 121 | 然后返回一个张量(和输入张量尺寸相同)。 122 | 123 | ---- 124 | 125 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/merge.py#L320) 126 | ### Concatenate 127 | 128 | ```python 129 | keras.layers.Concatenate(axis=-1) 130 | ``` 131 | 132 | 连接一个输入张量的列表。 133 | 134 | 它接受一个张量的列表, 135 | 除了连接轴之外,其他的尺寸都必须相同, 136 | 然后返回一个由所有输入张量连接起来的输出张量。 137 | 138 | __参数__ 139 | 140 | - __axis__: 连接的轴。 141 | - __**kwargs__: 层关键字参数。 142 | 143 | ---- 144 | 145 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/merge.py#L416) 146 | ### Dot 147 | 148 | ```python 149 | keras.layers.Dot(axes, normalize=False) 150 | ``` 151 | 152 | 计算两个张量之间样本的点积。 153 | 154 | 例如,如果作用于输入尺寸为 `(batch_size, n)` 的两个张量 `a` 和 `b`, 155 | 那么输出结果就会是尺寸为 `(batch_size, 1)` 的一个张量。 156 | 在这个张量中,每一个条目 `i` 是 `a[i]` 和 `b[i]` 之间的点积。 157 | 158 | __参数__ 159 | 160 | - __axes__: 整数或者整数元组, 161 | 一个或者几个进行点积的轴。 162 | - __normalize__: 是否在点积之前对即将进行点积的轴进行 L2 标准化。 163 | 如果设置成 `True`,那么输出两个样本之间的余弦相似值。 164 | - __**kwargs__: 层关键字参数。 165 | 166 | ---- 167 | 168 | ### add 169 | 170 | 171 | ```python 172 | keras.layers.add(inputs) 173 | ``` 174 | 175 | `Add` 层的函数式接口。 176 | 177 | __参数__ 178 | 179 | - __inputs__: 一个输入张量的列表(列表大小至少为 2)。 180 | - __**kwargs__: 层关键字参数。 181 | 182 | __返回__ 183 | 184 | 一个张量,所有输入张量的和。 185 | 186 | __示例__ 187 | 188 | 189 | ```python 190 | import keras 191 | 192 | input1 = keras.layers.Input(shape=(16,)) 193 | x1 = keras.layers.Dense(8, activation='relu')(input1) 194 | input2 = keras.layers.Input(shape=(32,)) 195 | x2 = keras.layers.Dense(8, activation='relu')(input2) 196 | added = keras.layers.add([x1, x2]) 197 | 198 | out = keras.layers.Dense(4)(added) 199 | model = keras.models.Model(inputs=[input1, input2], outputs=out) 200 | ``` 201 | 202 | ---- 203 | 204 | ### subtract 205 | 206 | 207 | ```python 208 | keras.layers.subtract(inputs) 209 | ``` 210 | 211 | `Subtract` 层的函数式接口。 212 | 213 | __参数__ 214 | 215 | - __inputs__: 一个列表的输入张量(列表大小准确为 2)。 216 | - __**kwargs__: 层的关键字参数。 217 | 218 | __返回__ 219 | 220 | 一个张量,两个输入张量的差。 221 | 222 | __示例__ 223 | 224 | 225 | ```python 226 | import keras 227 | 228 | input1 = keras.layers.Input(shape=(16,)) 229 | x1 = keras.layers.Dense(8, activation='relu')(input1) 230 | input2 = keras.layers.Input(shape=(32,)) 231 | x2 = keras.layers.Dense(8, activation='relu')(input2) 232 | subtracted = keras.layers.subtract([x1, x2]) 233 | 234 | out = keras.layers.Dense(4)(subtracted) 235 | model = keras.models.Model(inputs=[input1, input2], outputs=out) 236 | ``` 237 | 238 | ---- 239 | 240 | ### multiply 241 | 242 | 243 | ```python 244 | keras.layers.multiply(inputs) 245 | ``` 246 | 247 | 248 | `Multiply` 层的函数式接口。 249 | 250 | __参数__ 251 | 252 | - __inputs__: 一个列表的输入张量(列表大小至少为 2)。 253 | - __**kwargs__: 层的关键字参数。 254 | 255 | __返回__ 256 | 257 | 一个张量,所有输入张量的逐元素乘积。 258 | 259 | ---- 260 | 261 | ### average 262 | 263 | 264 | ```python 265 | keras.layers.average(inputs) 266 | ``` 267 | 268 | 269 | `Average` 层的函数式接口。 270 | 271 | __参数__ 272 | 273 | - __inputs__: 一个列表的输入张量(列表大小至少为 2)。 274 | - __**kwargs__: 层的关键字参数。 275 | 276 | __返回__ 277 | 278 | 一个张量,所有输入张量的平均值。 279 | 280 | ---- 281 | 282 | ### maximum 283 | 284 | 285 | ```python 286 | keras.layers.maximum(inputs) 287 | ``` 288 | 289 | `Maximum` 层的函数式接口。 290 | 291 | __参数__ 292 | 293 | - __inputs__: 一个列表的输入张量(列表大小至少为 2)。 294 | - __**kwargs__: 层的关键字参数。 295 | 296 | __返回__ 297 | 298 | 一个张量,所有张量的逐元素的最大值。 299 | 300 | ---- 301 | 302 | ### minimum 303 | 304 | 305 | ```python 306 | keras.layers.minimum(inputs) 307 | ``` 308 | 309 | 310 | `Minimum` 层的函数式接口。 311 | 312 | __参数__ 313 | 314 | - __inputs__: 一个列表的输入张量(列表大小至少为 2)。 315 | - __**kwargs__: 层的关键字参数。 316 | 317 | __返回__ 318 | 319 | 一个张量,所有张量的逐元素的最小值。 320 | 321 | ---- 322 | 323 | ### concatenate 324 | 325 | 326 | ```python 327 | keras.layers.concatenate(inputs, axis=-1) 328 | ``` 329 | 330 | 331 | `Concatenate` 层的函数式接口。 332 | 333 | __参数__ 334 | 335 | - __inputs__: 一个列表的输入张量(列表大小至少为 2)。 336 | - __axis__: 串联的轴。 337 | - __**kwargs__: 层的关键字参数。 338 | 339 | __返回__ 340 | 341 | 一个张量,所有输入张量通过 `axis` 轴串联起来的输出张量。 342 | 343 | ---- 344 | 345 | ### dot 346 | 347 | 348 | ```python 349 | keras.layers.dot(inputs, axes, normalize=False) 350 | ``` 351 | 352 | 353 | `Dot` 层的函数式接口。 354 | 355 | __参数__ 356 | 357 | - __inputs__: 一个列表的输入张量(列表大小至少为 2)。 358 | - __axes__: 整数或者整数元组, 359 | 一个或者几个进行点积的轴。 360 | - __normalize__: 是否在点积之前对即将进行点积的轴进行 L2 标准化。 361 | 如果设置成 True,那么输出两个样本之间的余弦相似值。 362 | - __**kwargs__: 层的关键字参数。 363 | 364 | __返回__ 365 | 366 | 一个张量,所有输入张量样本之间的点积。 367 | -------------------------------------------------------------------------------- /sources/layers/noise.md: -------------------------------------------------------------------------------- 1 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/noise.py#L14) 2 | ### GaussianNoise 3 | 4 | ```python 5 | keras.layers.GaussianNoise(stddev) 6 | ``` 7 | 8 | 应用以 0 为中心的加性高斯噪声。 9 | 10 | 这对缓解过拟合很有用 11 | (你可以将其视为随机数据增强的一种形式)。 12 | 高斯噪声(GS)是对真实输入的腐蚀过程的自然选择。 13 | 14 | 由于它是一个正则化层,因此它只在训练时才被激活。 15 | 16 | __参数__ 17 | 18 | - __stddev__: float,噪声分布的标准差。 19 | 20 | __输入尺寸__ 21 | 22 | 可以是任意的。 23 | 如果将该层作为模型的第一层,则需要指定 `input_shape` 参数 24 | (整数元组,不包含样本数量的维度)。 25 | 26 | __输出尺寸__ 27 | 28 | 与输入相同。 29 | 30 | ---- 31 | 32 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/noise.py#L58) 33 | ### GaussianDropout 34 | 35 | ```python 36 | keras.layers.GaussianDropout(rate) 37 | ``` 38 | 39 | 应用以 1 为中心的 乘性高斯噪声。 40 | 41 | 由于它是一个正则化层,因此它只在训练时才被激活。 42 | 43 | __参数__ 44 | 45 | - __rate__: float,丢弃概率(与 `Dropout` 相同)。 46 | 这个乘性噪声的标准差为 `sqrt(rate / (1 - rate))`。 47 | 48 | __输入尺寸__ 49 | 50 | 可以是任意的。 51 | 如果将该层作为模型的第一层,则需要指定 `input_shape` 参数 52 | (整数元组,不包含样本数量的维度)。 53 | 54 | __输出尺寸__ 55 | 56 | 与输入相同。 57 | 58 | __参考文献__ 59 | 60 | - [Dropout: A Simple Way to Prevent Neural Networks from Overfitting Srivastava, Hinton, et al. 2014](http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf) 61 | 62 | ---- 63 | 64 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/noise.py#L106) 65 | ### AlphaDropout 66 | 67 | ```python 68 | keras.layers.AlphaDropout(rate, noise_shape=None, seed=None) 69 | ``` 70 | 71 | 将 Alpha Dropout 应用到输入。 72 | 73 | Alpha Dropout 是一种 `Dropout`, 74 | 它保持输入的平均值和方差与原来的值不变, 75 | 以确保即使在 dropout 后也能实现自我归一化。 76 | 通过随机将激活设置为负饱和值, 77 | Alpha Dropout 非常适合按比例缩放的指数线性单元(SELU)。 78 | 79 | __参数__ 80 | 81 | - __rate__: float,丢弃概率(与 `Dropout` 相同)。 82 | 这个乘性噪声的标准差为 `sqrt(rate / (1 - rate))`。 83 | - __noise_shape__: 一个类型为 `int32` 的 1D `Tensor`,表示随机生成 keep/drop 标识的尺寸。 84 | - __seed__: 用作随机种子的 Python 整数。 85 | 86 | __输入尺寸__ 87 | 88 | 可以是任意的。 89 | 如果将该层作为模型的第一层,则需要指定 `input_shape` 参数 90 | (整数元组,不包含样本数量的维度)。 91 | 92 | __输出尺寸__ 93 | 94 | 与输入相同。 95 | 96 | __参考文献__ 97 | 98 | - [Self-Normalizing Neural Networks](https://arxiv.org/abs/1706.02515) 99 | -------------------------------------------------------------------------------- /sources/layers/normalization.md: -------------------------------------------------------------------------------- 1 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/normalization.py#L16) 2 | ### BatchNormalization 3 | 4 | ```python 5 | keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001, center=True, scale=True, beta_initializer='zeros', gamma_initializer='ones', moving_mean_initializer='zeros', moving_variance_initializer='ones', beta_regularizer=None, gamma_regularizer=None, beta_constraint=None, gamma_constraint=None) 6 | ``` 7 | 8 | 批量标准化层 (Ioffe and Szegedy, 2014)。 9 | 10 | 在每一个批次的数据中标准化前一层的激活项, 11 | 即,应用一个维持激活项平均值接近 0,标准差接近 1 的转换。 12 | 13 | __参数__ 14 | 15 | - __axis__: 整数,需要标准化的轴 16 | (通常是特征轴)。 17 | 例如,在 `data_format="channels_first"` 的 `Conv2D` 层之后, 18 | 在 `BatchNormalization` 中设置 `axis=1`。 19 | - __momentum__: 移动均值和移动方差的动量。 20 | - __epsilon__: 增加到方差的小的浮点数,以避免除以零。 21 | - __center__: 如果为 True,把 `beta` 的偏移量加到标准化的张量上。 22 | 如果为 False, `beta` 被忽略。 23 | - __scale__: 如果为 True,乘以 `gamma`。 24 | 如果为 False,`gamma` 不使用。 25 | 当下一层为线性层(或者例如 `nn.relu`), 26 | 这可以被禁用,因为缩放将由下一层完成。 27 | - __beta_initializer__: beta 权重的初始化方法。 28 | - __gamma_initializer__: gamma 权重的初始化方法。 29 | - __moving_mean_initializer__: 移动均值的初始化方法。 30 | - __moving_variance_initializer__: 移动方差的初始化方法。 31 | - __beta_regularizer__: 可选的 beta 权重的正则化方法。 32 | - __gamma_regularizer__: 可选的 gamma 权重的正则化方法。 33 | - __beta_constraint__: 可选的 beta 权重的约束方法。 34 | - __gamma_constraint__: 可选的 gamma 权重的约束方法。 35 | 36 | __输入尺寸__ 37 | 38 | 可以是任意的。如果将这一层作为模型的第一层, 则需要指定 `input_shape` 参数 (整数元组,不包含样本数量的维度)。 39 | 40 | __输出尺寸__ 41 | 42 | 与输入相同。 43 | 44 | __参考文献__ 45 | 46 | - [Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift](https://arxiv.org/abs/1502.03167) 47 | -------------------------------------------------------------------------------- /sources/layers/wrappers.md: -------------------------------------------------------------------------------- 1 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/wrappers.py#L116) 2 | ### TimeDistributed 3 | 4 | ```python 5 | keras.layers.TimeDistributed(layer) 6 | ``` 7 | 8 | 这个封装器将一个层应用于输入的每个时间片。 9 | 10 | 输入至少为 3D,且第一个维度应该是时间所表示的维度。 11 | 12 | 考虑 32 个样本的一个 batch, 13 | 其中每个样本是 10 个 16 维向量的序列。 14 | 那么这个 batch 的输入尺寸为 `(32, 10, 16)`, 15 | 而 `input_shape` 不包含样本数量的维度,为 `(10, 16)`。 16 | 17 | 你可以使用 `TimeDistributed` 来将 `Dense` 层独立地应用到 18 | 这 10 个时间步的每一个: 19 | 20 | ```python 21 | # 作为模型第一层 22 | model = Sequential() 23 | model.add(TimeDistributed(Dense(8), input_shape=(10, 16))) 24 | # 现在 model.output_shape == (None, 10, 8) 25 | ``` 26 | 27 | 输出的尺寸为 `(32, 10, 8)`。 28 | 29 | 在后续的层中,将不再需要 `input_shape`: 30 | 31 | ```python 32 | model.add(TimeDistributed(Dense(32))) 33 | # 现在 model.output_shape == (None, 10, 32) 34 | ``` 35 | 36 | 输出的尺寸为 `(32, 10, 32)`。 37 | 38 | `TimeDistributed` 可以应用于任意层,不仅仅是 `Dense`, 39 | 例如运用于 `Conv2D` 层: 40 | 41 | ```python 42 | model = Sequential() 43 | model.add(TimeDistributed(Conv2D(64, (3, 3)), 44 | input_shape=(10, 299, 299, 3))) 45 | ``` 46 | 47 | __参数__ 48 | 49 | - __layer__: 一个网络层实例。 50 | 51 | ---- 52 | 53 | [[source]](https://github.com/keras-team/keras/blob/master/keras/layers/wrappers.py#L335) 54 | ### Bidirectional 55 | 56 | ```python 57 | keras.layers.Bidirectional(layer, merge_mode='concat', weights=None) 58 | ``` 59 | 60 | RNN 的双向封装器,对序列进行前向和后向计算。 61 | 62 | __参数__ 63 | 64 | - __layer__: `Recurrent` 实例。 65 | - __merge_mode__: 前向和后向 RNN 的输出的结合模式。 66 | 为 {'sum', 'mul', 'concat', 'ave', None} 其中之一。 67 | 如果是 None,输出不会被结合,而是作为一个列表被返回。 68 | - __weights__: 双向模型中要加载的初始权重。 69 | 70 | __异常__ 71 | 72 | - __ValueError__: 如果参数 `merge_mode` 非法。 73 | 74 | __示例__ 75 | 76 | 77 | ```python 78 | model = Sequential() 79 | model.add(Bidirectional(LSTM(10, return_sequences=True), 80 | input_shape=(5, 10))) 81 | model.add(Bidirectional(LSTM(10))) 82 | model.add(Dense(5)) 83 | model.add(Activation('softmax')) 84 | model.compile(loss='categorical_crossentropy', optimizer='rmsprop') 85 | ``` 86 | -------------------------------------------------------------------------------- /sources/layers/writing-your-own-keras-layers.md: -------------------------------------------------------------------------------- 1 | # 编写你自己的 Keras 层 2 | 3 | 对于简单、无状态的自定义操作,你也许可以通过 `layers.core.Lambda` 层来实现。但是对于那些包含了可训练权重的自定义层,你应该自己实现这种层。 4 | 5 | 这是一个 **Keras 2.0** 中,Keras 层的骨架(如果你用的是旧的版本,请更新到新版)。你只需要实现三个方法即可: 6 | 7 | - `build(input_shape)`: 这是你定义权重的地方。这个方法必须设 `self.built = True`,可以通过调用 `super([Layer], self).build()` 完成。 8 | - `call(x)`: 这里是编写层的功能逻辑的地方。你只需要关注传入 `call` 的第一个参数:输入张量,除非你希望你的层支持masking。 9 | - `compute_output_shape(input_shape)`: 如果你的层更改了输入张量的形状,你应该在这里定义形状变化的逻辑,这让Keras能够自动推断各层的形状。 10 | 11 | ```python 12 | from keras import backend as K 13 | from keras.engine.topology import Layer 14 | 15 | class MyLayer(Layer): 16 | 17 | def __init__(self, output_dim, **kwargs): 18 | self.output_dim = output_dim 19 | super(MyLayer, self).__init__(**kwargs) 20 | 21 | def build(self, input_shape): 22 | # 为该层创建一个可训练的权重 23 | self.kernel = self.add_weight(name='kernel', 24 | shape=(input_shape[1], self.output_dim), 25 | initializer='uniform', 26 | trainable=True) 27 | super(MyLayer, self).build(input_shape) # 一定要在最后调用它 28 | 29 | def call(self, x): 30 | return K.dot(x, self.kernel) 31 | 32 | def compute_output_shape(self, input_shape): 33 | return (input_shape[0], self.output_dim) 34 | ``` 35 | 36 | 37 | 还可以定义具有多个输入张量和多个输出张量的 Keras 层。 38 | 为此,你应该假设方法 `build(input_shape)`,`call(x)` 39 | 和 `compute_output_shape(input_shape)` 的输入输出都是列表。 40 | 这里是一个例子,与上面那个相似: 41 | 42 | ```python 43 | from keras import backend as K 44 | from keras.engine.topology import Layer 45 | 46 | class MyLayer(Layer): 47 | 48 | def __init__(self, output_dim, **kwargs): 49 | self.output_dim = output_dim 50 | super(MyLayer, self).__init__(**kwargs) 51 | 52 | def build(self, input_shape): 53 | assert isinstance(input_shape, list) 54 | # 为该层创建一个可训练的权重 55 | self.kernel = self.add_weight(name='kernel', 56 | shape=(input_shape[0][1], self.output_dim), 57 | initializer='uniform', 58 | trainable=True) 59 | super(MyLayer, self).build(input_shape) # 一定要在最后调用它 60 | 61 | def call(self, x): 62 | assert isinstance(x, list) 63 | a, b = x 64 | return [K.dot(a, self.kernel) + b, K.mean(b, axis=-1)] 65 | 66 | def compute_output_shape(self, input_shape): 67 | assert isinstance(input_shape, list) 68 | shape_a, shape_b = input_shape 69 | return [(shape_a[0], self.output_dim), shape_b[:-1]] 70 | ``` 71 | 72 | 已有的 Keras 层就是实现任何层的很好例子。不要犹豫阅读源码! 73 | -------------------------------------------------------------------------------- /sources/losses.md: -------------------------------------------------------------------------------- 1 | 2 | ## 损失函数的使用 3 | 4 | 损失函数(或称目标函数、优化评分函数)是编译模型时所需的两个参数之一: 5 | 6 | ```python 7 | model.compile(loss='mean_squared_error', optimizer='sgd') 8 | ``` 9 | 10 | ```python 11 | from keras import losses 12 | 13 | model.compile(loss=losses.mean_squared_error, optimizer='sgd') 14 | ``` 15 | 16 | 你可以传递一个现有的损失函数名,或者一个 TensorFlow/Theano 符号函数。 17 | 该符号函数为每个数据点返回一个标量,有以下两个参数: 18 | 19 | - __y_true__: 真实标签。TensorFlow/Theano 张量。 20 | - __y_pred__: 预测值。TensorFlow/Theano 张量,其 shape 与 y_true 相同。 21 | 22 | 实际的优化目标是所有数据点的输出数组的平均值。 23 | 24 | 有关这些函数的几个例子,请查看 [losses source](https://github.com/keras-team/keras/blob/master/keras/losses.py)。 25 | 26 | ## 可用损失函数 27 | 28 | ### mean_squared_error 29 | 30 | 31 | ```python 32 | keras.losses.mean_squared_error(y_true, y_pred) 33 | ``` 34 | 35 | ---- 36 | 37 | ### mean_absolute_error 38 | 39 | 40 | ```python 41 | eras.losses.mean_absolute_error(y_true, y_pred) 42 | ``` 43 | 44 | ---- 45 | 46 | ### mean_absolute_percentage_error 47 | 48 | 49 | ```python 50 | keras.losses.mean_absolute_percentage_error(y_true, y_pred) 51 | ``` 52 | 53 | ---- 54 | 55 | ### mean_squared_logarithmic_error 56 | 57 | 58 | ```python 59 | keras.losses.mean_squared_logarithmic_error(y_true, y_pred) 60 | ``` 61 | 62 | ---- 63 | 64 | ### squared_hinge 65 | 66 | 67 | ```python 68 | keras.losses.squared_hinge(y_true, y_pred) 69 | ``` 70 | 71 | ---- 72 | 73 | ### hinge 74 | 75 | 76 | ```python 77 | keras.losses.hinge(y_true, y_pred) 78 | ``` 79 | 80 | ---- 81 | 82 | ### categorical_hinge 83 | 84 | 85 | ```python 86 | keras.losses.categorical_hinge(y_true, y_pred) 87 | ``` 88 | 89 | ---- 90 | 91 | ### logcosh 92 | 93 | 94 | ```python 95 | keras.losses.logcosh(y_true, y_pred) 96 | ``` 97 | 98 | 预测误差的双曲余弦的对数。 99 | 100 | 对于小的 `x`,`log(cosh(x))` 近似等于 `(x ** 2) / 2`。对于大的 `x`,近似于 `abs(x) - log(2)`。这表示 'logcosh' 与均方误差大致相同,但是不会受到偶尔疯狂的错误预测的强烈影响。 101 | 102 | __参数__ 103 | 104 | - __y_true__: 目标真实值的张量。 105 | - __y_pred__: 目标预测值的张量。 106 | 107 | __返回__ 108 | 109 | 每个样本都有一个标量损失的张量。 110 | 111 | ---- 112 | 113 | ### huber_loss 114 | 115 | 116 | ```python 117 | keras.losses.huber_loss(y_true, y_pred, delta=1.0) 118 | ``` 119 | 120 | --- 121 | 122 | ### categorical_crossentropy 123 | 124 | 125 | ```python 126 | keras.losses.categorical_crossentropy(y_true, y_pred, from_logits=False, label_smoothing=0) 127 | ``` 128 | 129 | ---- 130 | 131 | ### sparse_categorical_crossentropy 132 | 133 | 134 | ```python 135 | keras.losses.sparse_categorical_crossentropy(y_true, y_pred, from_logits=False, axis=-1) 136 | ``` 137 | 138 | ---- 139 | 140 | ### binary_crossentropy 141 | 142 | 143 | ```python 144 | keras.losses.binary_crossentropy(y_true, y_pred, from_logits=False, label_smoothing=0) 145 | ``` 146 | 147 | ---- 148 | 149 | ### kullback_leibler_divergence 150 | 151 | 152 | ```python 153 | keras.losses.kullback_leibler_divergence(y_true, y_pred) 154 | ``` 155 | 156 | ---- 157 | 158 | ### poisson 159 | 160 | 161 | ```python 162 | keras.losses.poisson(y_true, y_pred) 163 | ``` 164 | 165 | ---- 166 | 167 | ### cosine_proximity 168 | 169 | 170 | ```python 171 | keras.losses.cosine_proximity(y_true, y_pred, axis=-1) 172 | ``` 173 | 174 | --- 175 | 176 | ### is_categorical_crossentropy 177 | 178 | ```python 179 | keras.losses.is_categorical_crossentropy(loss) 180 | ``` 181 | 182 | ---- 183 | 184 | **注意**: 当使用 `categorical_crossentropy` 损失时,你的目标值应该是分类格式 (即,如果你有 10 个类,每个样本的目标值应该是一个 10 维的向量,这个向量除了表示类别的那个索引为 1,其他均为 0)。 为了将 *整数目标值* 转换为 *分类目标值*,你可以使用 Keras 实用函数 `to_categorical`: 185 | 186 | ```python 187 | from keras.utils.np_utils import to_categorical 188 | 189 | categorical_labels = to_categorical(int_labels, num_classes=None) 190 | ``` 191 | 192 | 当使用 sparse_categorical_crossentropy 损失时,你的目标应该是整数。如果你是类别目标,应该使用 categorical_crossentropy。 193 | 194 | categorical_crossentropy 是多类对数损失的另一种形式。 195 | -------------------------------------------------------------------------------- /sources/metrics.md: -------------------------------------------------------------------------------- 1 | 2 | ## 评价函数的用法 3 | 4 | 评价函数用于评估当前训练模型的性能。当模型编译后(compile),评价函数应该作为 `metrics` 的参数来输入。 5 | 6 | ```python 7 | model.compile(loss='mean_squared_error', 8 | optimizer='sgd', 9 | metrics=['mae', 'acc']) 10 | ``` 11 | 12 | ```python 13 | from keras import metrics 14 | 15 | model.compile(loss='mean_squared_error', 16 | optimizer='sgd', 17 | metrics=[metrics.mae, metrics.categorical_accuracy]) 18 | ``` 19 | 20 | 评价函数和 [损失函数](/losses) 相似,只不过评价函数的结果不会用于训练过程中。 21 | 22 | 我们可以传递已有的评价函数名称,或者传递一个自定义的 Theano/TensorFlow 函数来使用(查阅[自定义评价函数](#custom-metrics))。 23 | 24 | __参数__ 25 | 26 | - __y_true__: 真实标签,Theano/Tensorflow 张量。 27 | - __y_pred__: 预测值。和 y_true 相同尺寸的 Theano/TensorFlow 张量。 28 | 29 | __返回__ 30 | 31 |  返回一个表示全部数据点平均值的张量。 32 | 33 | ---- 34 | 35 | ## 可使用的评价函数 36 | 37 | 38 | ### accuracy 39 | 40 | 41 | ```python 42 | keras.metrics.accuracy(y_true, y_pred) 43 | ``` 44 | 45 | 46 | ### binary_accuracy 47 | 48 | 49 | ```python 50 | keras.metrics.binary_accuracy(y_true, y_pred, threshold=0.5) 51 | ``` 52 | 53 | ---- 54 | 55 | ### categorical_accuracy 56 | 57 | 58 | ```python 59 | keras.metrics.categorical_accuracy(y_true, y_pred) 60 | ``` 61 | 62 | ---- 63 | 64 | ### sparse_categorical_accuracy 65 | 66 | 67 | ```python 68 | keras.metrics.sparse_categorical_accuracy(y_true, y_pred) 69 | ``` 70 | 71 | ---- 72 | 73 | ### top_k_categorical_accuracy 74 | 75 | 76 | ```python 77 | keras.metrics.top_k_categorical_accuracy(y_true, y_pred, k=5) 78 | ``` 79 | 80 | ---- 81 | 82 | ### sparse_top_k_categorical_accuracy 83 | 84 | 85 | ```python 86 | keras.metrics.sparse_top_k_categorical_accuracy(y_true, y_pred, k=5) 87 | ``` 88 | 89 | 90 | ---- 91 | 92 | ### cosine_proximity 93 | 94 | 95 | ```python 96 | keras.metrics.cosine_proximity(y_true, y_pred, axis=-1) 97 | ``` 98 | 99 | ---- 100 | 101 | ### clone_metric 102 | 103 | 104 | ```python 105 | keras.metrics.clone_metric(metric) 106 | ``` 107 | 108 | 若有状态,返回评估指标的克隆,否则返回其本身。 109 | 110 | 111 | ---- 112 | 113 | ### clone_metrics 114 | 115 | 116 | ```python 117 | keras.metrics.clone_metrics(metrics) 118 | ``` 119 | 120 | 克隆给定的评估指标序列/字典。 121 | 122 | 除以上评估指标,你还可以使用在损失函数页描述的损失函数作为评估指标。 123 | 124 | ---- 125 | 126 | ## 自定义评价函数 127 | 128 | 自定义评价函数应该在编译的时候(compile)传递进去。该函数需要以 `(y_true, y_pred)` 作为输入参数,并返回一个张量作为输出结果。 129 | 130 | ```python 131 | import keras.backend as K 132 | 133 | def mean_pred(y_true, y_pred): 134 | return K.mean(y_pred) 135 | 136 | model.compile(optimizer='rmsprop', 137 | loss='binary_crossentropy', 138 | metrics=['accuracy', mean_pred]) 139 | ``` 140 | -------------------------------------------------------------------------------- /sources/models/about-keras-models.md: -------------------------------------------------------------------------------- 1 | # 关于 Keras 模型 2 | 3 | 在 Keras 中有两类主要的模型:[Sequential 顺序模型](/models/sequential) 和 [使用函数式 API 的 Model 类模型](/models/model)。 4 | 5 | 这些模型有许多共同的方法和属性: 6 | 7 | - `model.layers` 是包含模型网络层的展平列表。 8 | - `model.inputs` 是模型输入张量的列表。 9 | - `model.outputs` 是模型输出张量的列表。 10 | - `model.summary()` 打印出模型概述信息。 它是 [utils.print_summary](/utils/#print_summary) 的简捷调用。 11 | - `model.get_config()` 返回包含模型配置信息的字典。通过以下代码,就可以根据这些配置信息重新实例化模型: 12 | 13 | ```python 14 | config = model.get_config() 15 | model = Model.from_config(config) 16 | # 或者,对于 Sequential: 17 | model = Sequential.from_config(config) 18 | ``` 19 | 20 | - `model.get_weights()` 返回模型中所有权重张量的列表,类型为 Numpy 数组。 21 | - `model.set_weights(weights)` 从 Numpy 数组中为模型设置权重。列表中的数组必须与 `get_weights()` 返回的权重具有相同的尺寸。 22 | - `model.to_json()` 以 JSON 字符串的形式返回模型的表示。请注意,该表示不包括权重,仅包含结构。你可以通过以下方式从 JSON 字符串重新实例化同一模型(使用重新初始化的权重): 23 | 24 | ```python 25 | from keras.models import model_from_json 26 | 27 | json_string = model.to_json() 28 | model = model_from_json(json_string) 29 | ``` 30 | 31 | - `model.to_yaml()` 以 YAML 字符串的形式返回模型的表示。请注意,该表示不包括权重,只包含结构。你可以通过以下代码,从 YAML 字符串中重新实例化相同的模型(使用重新初始化的权重): 32 | 33 | ```python 34 | from keras.models import model_from_yaml 35 | 36 | yaml_string = model.to_yaml() 37 | model = model_from_yaml(yaml_string) 38 | ``` 39 | 40 | - `model.save_weights(filepath)` 将模型权重存储为 HDF5 文件。 41 | - `model.load_weights(filepath, by_name=False)`: 从 HDF5 文件(由 `save_weights` 创建)中加载权重。默认情况下,模型的结构应该是不变的。 如果想将权重载入不同的模型(部分层相同), 设置 `by_name=True` 来载入那些名字相同的层的权重。 42 | 43 | 注意:另请参阅[如何安装 HDF5 或 h5py 以保存 Keras 模型](/getting-started/faq/#how-can-i-install-HDF5-or-h5py-to-save-my-models-in-Keras),在常见问题中了解如何安装 `h5py` 的说明。 44 | 45 | ## Model 类继承 46 | 47 | 除了这两类模型之外,你还可以通过继承 `Model` 类并在 `call` 方法中实现你自己的前向传播,以创建你自己的完全定制化的模型,(`Model` 类继承 API 引入于 Keras 2.2.0)。 48 | 49 | 这里是一个用 `Model` 类继承写的简单的多层感知器的例子: 50 | 51 | ```python 52 | import keras 53 | 54 | class SimpleMLP(keras.Model): 55 | 56 | def __init__(self, use_bn=False, use_dp=False, num_classes=10): 57 | super(SimpleMLP, self).__init__(name='mlp') 58 | self.use_bn = use_bn 59 | self.use_dp = use_dp 60 | self.num_classes = num_classes 61 | 62 | self.dense1 = keras.layers.Dense(32, activation='relu') 63 | self.dense2 = keras.layers.Dense(num_classes, activation='softmax') 64 | if self.use_dp: 65 | self.dp = keras.layers.Dropout(0.5) 66 | if self.use_bn: 67 | self.bn = keras.layers.BatchNormalization(axis=-1) 68 | 69 | def call(self, inputs): 70 | x = self.dense1(inputs) 71 | if self.use_dp: 72 | x = self.dp(x) 73 | if self.use_bn: 74 | x = self.bn(x) 75 | return self.dense2(x) 76 | 77 | model = SimpleMLP() 78 | model.compile(...) 79 | model.fit(...) 80 | ``` 81 | 82 | 网络层定义在 `__init__(self, ...)` 中,前向传播在 `call(self, inputs)` 中指定。在 `call` 中,你可以指定自定义的损失函数,通过调用 `self.add_loss(loss_tensor)` (就像你在自定义层中一样)。 83 | 84 | 在类继承模型中,模型的拓扑结构是由 Python 代码定义的(而不是网络层的静态图)。这意味着该模型的拓扑结构不能被检查或序列化。因此,以下方法和属性**不适用于类继承模型**: 85 | 86 | - `model.inputs` 和 `model.outputs`。 87 | - `model.to_yaml()` 和 `model.to_json()`。 88 | - `model.get_config()` 和 `model.save()`。 89 | 90 | **关键点**:为每个任务使用正确的 API。`Model` 类继承 API 可以为实现复杂模型提供更大的灵活性,但它需要付出代价(比如缺失的特性):它更冗长,更复杂,并且有更多的用户错误机会。如果可能的话,尽可能使用函数式 API,这对用户更友好。 91 | -------------------------------------------------------------------------------- /sources/optimizers.md: -------------------------------------------------------------------------------- 1 | 2 | ## 优化器的用法 3 | 4 | 优化器 (optimizer) 是编译 Keras 模型的所需的两个参数之一: 5 | 6 | ```python 7 | from keras import optimizers 8 | 9 | model = Sequential() 10 | model.add(Dense(64, kernel_initializer='uniform', input_shape=(10,))) 11 | model.add(Activation('softmax')) 12 | 13 | sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True) 14 | model.compile(loss='mean_squared_error', optimizer=sgd) 15 | ``` 16 | 17 | 你可以先实例化一个优化器对象,然后将它传入 `model.compile()`,像上述示例中一样, 18 | 或者你可以通过名称来调用优化器。在后一种情况下,将使用优化器的默认参数。 19 | 20 | 21 | ```python 22 | # 传入优化器名称: 默认参数将被采用 23 | model.compile(loss='mean_squared_error', optimizer='sgd') 24 | ``` 25 | 26 | --- 27 | 28 | ## Keras 优化器的公共参数 29 | 30 | 31 | 参数 `clipnorm` 和 `clipvalue` 能在所有的优化器中使用,用于控制梯度裁剪(Gradient Clipping): 32 | 33 | ```python 34 | from keras import optimizers 35 | 36 | # 所有参数梯度将被裁剪,让其 l2 范数最大为 1:g * 1 / max(1, l2_norm) 37 | sgd = optimizers.SGD(lr=0.01, clipnorm=1.) 38 | ``` 39 | 40 | ```python 41 | from keras import optimizers 42 | 43 | # 所有参数 d 梯度将被裁剪到数值范围内: 44 | # 最大值 0.5 45 | # 最小值 -0.5 46 | sgd = optimizers.SGD(lr=0.01, clipvalue=0.5) 47 | ``` 48 | 49 | --- 50 | 51 | [[source]](https://github.com/keras-team/keras/blob/master/keras/optimizers.py#L164) 52 | ### SGD 53 | 54 | ```python 55 | keras.optimizers.SGD(learning_rate=0.01, momentum=0.0, nesterov=False) 56 | ``` 57 | 58 | 随机梯度下降优化器。 59 | 60 | 包含扩展功能的支持: 61 | 62 | - 动量(momentum)优化, 63 | - 学习率衰减(每次参数更新后) 64 | - Nestrov 动量 (NAG) 优化 65 | 66 | __参数__ 67 | 68 | - __learning_rate__: float >= 0. 学习率。 69 | - __momentum__: float >= 0. 参数,用于加速 SGD 在相关方向上前进,并抑制震荡。 70 | - __nesterov__: boolean. 是否使用 Nesterov 动量。 71 | 72 | ---- 73 | 74 | [[source]](https://github.com/keras-team/keras/blob/master/keras/optimizers.py#L229) 75 | ### RMSprop 76 | 77 | ```python 78 | keras.optimizers.RMSprop(learning_rate=0.001, rho=0.9) 79 | ``` 80 | 81 | RMSProp 优化器。 82 | 83 | 建议使用优化器的默认参数 84 | (除了学习率,它可以被自由调节) 85 | 86 | 87 | 这个优化器通常是训练循环神经网络 RNN 的不错选择。 88 | 89 | __参数__ 90 | 91 | - __learning_rate__: float >= 0. 学习率。 92 | - __rho__: float >= 0. RMSProp 梯度平方的移动均值的衰减率。 93 | 94 | __参考文献__ 95 | 96 | - [rmsprop: Divide the gradient by a running average of its recent magnitude](http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf) 97 | 98 | ---- 99 | 100 | [[source]](https://github.com/keras-team/keras/blob/master/keras/optimizers.py#L303) 101 | ### Adagrad 102 | 103 | ```python 104 | keras.optimizers.Adagrad(learning_rate=0.01) 105 | ``` 106 | 107 | Adagrad 优化器。 108 | 109 | Adagrad 是一种具有特定参数学习率的优化器,它根据参数在训练期间的更新频率进行自适应调整。参数接收的更新越多,更新越小。 110 | 111 | 建议使用优化器的默认参数。 112 | 113 | __参数__ 114 | 115 | - __learning_rate__: float >= 0. 学习率。 116 | 117 | __参考文献__ 118 | 119 | - [Adaptive Subgradient Methods for Online Learning and Stochastic Optimization](http://www.jmlr.org/papers/volume12/duchi11a/duchi11a.pdf) 120 | 121 | ---- 122 | 123 | [[source]](https://github.com/keras-team/keras/blob/master/keras/optimizers.py#L376) 124 | ### Adadelta 125 | 126 | ```python 127 | keras.optimizers.Adadelta(learning_rate=1.0, rho=0.95) 128 | ``` 129 | 130 | Adadelta 优化器。 131 | 132 | Adadelta 是 Adagrad 的一个具有更强鲁棒性的的扩展版本,它不是累积所有过去的梯度,而是根据渐变更新的移动窗口调整学习速率。 133 | 这样,即使进行了许多更新,Adadelta 仍在继续学习。 与 Adagrad 相比,在 Adadelta 的原始版本中,您无需设置初始学习率。 134 | 在此版本中,与大多数其他 Keras 优化器一样,可以设置初始学习速率和衰减因子。 135 | 136 | 建议使用优化器的默认参数。 137 | 138 | __参数__ 139 | 140 | - __learning_rate__: float >= 0. 初始学习率,默认为 1。建议保留默认值。 141 | - __rho__: float >= 0. Adadelta 梯度平方移动均值的衰减率。 142 | 143 | __参考文献__ 144 | 145 | - [Adadelta - an adaptive learning rate method](http://arxiv.org/abs/1212.5701) 146 | 147 | ---- 148 | 149 | [[source]](https://github.com/keras-team/keras/blob/master/keras/optimizers.py#L467) 150 | ### Adam 151 | 152 | ```python 153 | keras.optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, amsgrad=False) 154 | ``` 155 | 156 | Adam 优化器。 157 | 158 | 默认参数遵循原论文中提供的值。 159 | 160 | 161 | __参数__ 162 | 163 | - __learning_rate__: float >= 0. 学习率。 164 | - __beta_1__: float, 0 < beta < 1. 通常接近于 1。 165 | - __beta_2__: float, 0 < beta < 1. 通常接近于 1。 166 | - __amsgrad__: boolean. 是否应用此算法的 AMSGrad 变种,来自论文 "On the Convergence of Adam and Beyond"。 167 | 168 | __参考文献__ 169 | 170 | - [Adam - A Method for Stochastic Optimization](http://arxiv.org/abs/1412.6980v8) 171 | - [On the Convergence of Adam and Beyond](https://openreview.net/forum?id=ryQu7f-RZ) 172 | 173 | ---- 174 | 175 | [[source]](https://github.com/keras-team/keras/blob/master/keras/optimizers.py#L567) 176 | ### Adamax 177 | 178 | ```python 179 | keras.optimizers.Adamax(learning_rate=0.002, beta_1=0.9, beta_2=0.999) 180 | ``` 181 | 182 | Adamax 优化器,来自 Adam 论文的第七小节. 183 | 184 | 它是Adam算法基于无穷范数(infinity norm)的变种。 185 | 默认参数遵循论文中提供的值。 186 | 187 | __参数__ 188 | 189 | - __learning_rate__: float >= 0. 学习率。 190 | - __beta_1__: floats, 0 < beta < 1. 通常接近于 1。 191 | - __beta_2__: floats, 0 < beta < 1. 通常接近于 1。 192 | 193 | __参考文献__ 194 | 195 | - [Adam - A Method for Stochastic Optimization](http://arxiv.org/abs/1412.6980v8) 196 | 197 | ---- 198 | 199 | [[source]](https://github.com/keras-team/keras/blob/master/keras/optimizers.py#L645) 200 | ### Nadam 201 | 202 | ```python 203 | keras.optimizers.Nadam(learning_rate=0.002, beta_1=0.9, beta_2=0.999) 204 | ``` 205 | 206 | Nesterov 版本 Adam 优化器。 207 | 208 | 正像 Adam 本质上是 RMSProp 与动量 momentum 的结合, 209 | Nadam 是采用 Nesterov momentum 版本的 Adam 优化器。 210 | 211 | 默认参数遵循论文中提供的值。 212 | 建议使用优化器的默认参数。 213 | 214 | 215 | __参数__ 216 | 217 | - __learning_rate__: float >= 0. 学习率。 218 | - __beta_1__: floats, 0 < beta < 1. 通常接近于 1。 219 | - __beta_2__: floats, 0 < beta < 1. 通常接近于 1。 220 | 221 | __参考文献__ 222 | 223 | - [Nadam report](http://cs229.stanford.edu/proj2015/054_report.pdf) 224 | - [On the importance of initialization and momentum in deep learning](http://www.cs.toronto.edu/~fritz/absps/momentum.pdf) 225 | -------------------------------------------------------------------------------- /sources/preprocessing/sequence.md: -------------------------------------------------------------------------------- 1 | [[source]](https://github.com/keras-team/keras/blob/master/keras/preprocessing/sequence.py#L16) 2 | ### TimeseriesGenerator 3 | 4 | ```python 5 | keras.preprocessing.sequence.TimeseriesGenerator(data, targets, length, sampling_rate=1, stride=1, start_index=0, end_index=None, shuffle=False, reverse=False, batch_size=128) 6 | ``` 7 | 8 | 用于生成批量时序数据的实用工具类。 9 | 10 | 这个类以一系列由相等间隔以及一些时间序列参数(例如步长、历史长度等)汇集的数据点作为输入,以生成用于训练/验证的批次数据。 11 | 12 | __参数__ 13 | 14 | - __data__: 可索引的生成器(例如列表或 Numpy 数组),包含连续数据点(时间步)。数据应该是 2D 的,且第 0 个轴为时间维度。 15 | - __targets__: 对应于 `data` 的时间步的目标值。它应该与 `data` 的长度相同。 16 | - __length__: 输出序列的长度(以时间步数表示)。 17 | - __sampling_rate__: 序列内连续各个时间步之间的周期。对于周期 `r`, 时间步 `data[i]`, `data[i-r]`, ... `data[i - length]` 被用于生成样本序列。 18 | - __stride__: 连续输出序列之间的周期. 对于周期 `s`, 连续输出样本将为 `data[i]`, `data[i+s]`, `data[i+2*s]` 等。 19 | - __start_index__: 在 `start_index` 之前的数据点在输出序列中将不被使用。这对保留部分数据以进行测试或验证很有用。 20 | - __end_index__: 在 `end_index` 之后的数据点在输出序列中将不被使用。这对保留部分数据以进行测试或验证很有用。 21 | - __shuffle__: 是否打乱输出样本,还是按照时间顺序绘制它们。 22 | - __reverse__: 布尔值: 如果 `true`, 每个输出样本中的时间步将按照时间倒序排列。 23 | - __batch_size__: 每个批次中的时间序列样本数(可能除最后一个外)。 24 | 25 | __返回__ 26 | 27 | 一个 [Sequence](https://keras.io/zh/utils/#sequence) 实例。 28 | 29 | __示例__ 30 | 31 | ```python 32 | from keras.preprocessing.sequence import TimeseriesGenerator 33 | import numpy as np 34 | 35 | data = np.array([[i] for i in range(50)]) 36 | targets = np.array([[i] for i in range(50)]) 37 | 38 | data_gen = TimeseriesGenerator(data, targets, 39 | length=10, sampling_rate=2, 40 | batch_size=2) 41 | assert len(data_gen) == 20 42 | 43 | batch_0 = data_gen[0] 44 | x, y = batch_0 45 | assert np.array_equal(x, 46 | np.array([[[0], [2], [4], [6], [8]], 47 | [[1], [3], [5], [7], [9]]])) 48 | assert np.array_equal(y, 49 | np.array([[10], [11]])) 50 | ``` 51 | 52 | --- 53 | 54 | ### pad_sequences 55 | 56 | 57 | ```python 58 | keras.preprocessing.sequence.pad_sequences(sequences, maxlen=None, dtype='int32', padding='pre', truncating='pre', value=0.0) 59 | ``` 60 | 61 | 将多个序列截断或补齐为相同长度。 62 | 63 | 该函数将一个 `num_samples` 的序列(整数列表)转化为一个 2D Numpy 矩阵,其尺寸为 `(num_samples, num_timesteps)`。 `num_timesteps` 要么是给定的 `maxlen` 参数,要么是最长序列的长度。 64 | 65 | 比 `num_timesteps` 短的序列将在末端以 `value` 值补齐。 66 | 67 | 比 `num_timesteps` 长的序列将会被截断以满足所需要的长度。补齐或截断发生的位置分别由参数 `pading` 和 `truncating` 决定。 68 | 69 | 向前补齐为默认操作。 70 | 71 | __参数__ 72 | 73 | - __sequences__: 列表的列表,每一个元素是一个序列。 74 | - __maxlen__: 整数,所有序列的最大长度。 75 | - __dtype__: 输出序列的类型。 76 | 要使用可变长度字符串填充序列,可以使用 `object`。 77 | - __padding__: 字符串,'pre' 或 'post' ,在序列的前端补齐还是在后端补齐。 78 | - __truncating__: 字符串,'pre' 或 'post' ,移除长度大于 `maxlen` 的序列的值,要么在序列前端截断,要么在后端。 79 | - __value__: 浮点数,表示用来补齐的值。 80 | 81 | 82 | __返回__ 83 | 84 | - __x__: Numpy 矩阵,尺寸为 `(len(sequences), maxlen)`。 85 | 86 | __异常__ 87 | 88 | - ValueError: 如果截断或补齐的值无效,或者序列条目的形状无效。 89 | 90 | --- 91 | 92 | ### skipgrams 93 | 94 | 95 | ```python 96 | keras.preprocessing.sequence.skipgrams(sequence, vocabulary_size, window_size=4, negative_samples=1.0, shuffle=True, categorical=False, sampling_table=None, seed=None) 97 | ``` 98 | 99 | 生成 skipgram 词对。 100 | 101 | 该函数将一个单词索引序列(整数列表)转化为以下形式的单词元组: 102 | 103 | - (单词, 同窗口的单词),标签为 1(正样本)。 104 | - (单词, 来自词汇表的随机单词),标签为 0(负样本)。 105 | 106 | 若要了解更多和 Skipgram 有关的知识,请参阅这份由 Mikolov 等人发表的经典论文: [Efficient Estimation of Word Representations in Vector Space](http://arxiv.org/pdf/1301.3781v3.pdf) 107 | 108 | __参数__ 109 | 110 | - __sequence__: 一个编码为单词索引(整数)列表的词序列(句子)。如果使用一个 `sampling_table`,词索引应该以一个相关数据集的词的排名匹配(例如,10 将会编码为第 10 个最长出现的词)。注意词汇表中的索引 0 是非单词,将被跳过。 111 | - __vocabulary_size__: 整数,最大可能词索引 + 1 112 | - __window_size__: 整数,采样窗口大小(技术上是半个窗口)。词 `w_i` 的窗口是 `[i - window_size, i + window_size+1]`。 113 | - __negative_samples__: 大于等于 0 的浮点数。0 表示非负(即随机)采样。1 表示与正样本数相同。 114 | - __shuffle__: 是否在返回之前将这些词语打乱。 115 | - __categorical__: 布尔值。如果 False,标签将为整数(例如 `[0, 1, 1 .. ]`),如果 True,标签将为分类,例如 `[[1,0],[0,1],[0,1] .. ]`。 116 | - __sampling_table__: 尺寸为 `vocabulary_size` 的 1D 数组,其中第 i 项编码了排名为 i 的词的采样概率。 117 | - __seed__: 随机种子。 118 | 119 | __返回__ 120 | 121 | couples, labels: 其中 `couples` 是整数对,`labels` 是 0 或 1。 122 | 123 | __注意__ 124 | 125 | 按照惯例,词汇表中的索引 0 是非单词,将被跳过。 126 | 127 | --- 128 | 129 | ### make_sampling_table 130 | 131 | 132 | ```python 133 | keras.preprocessing.sequence.make_sampling_table(size, sampling_factor=1e-05) 134 | ``` 135 | 136 | 137 | 生成一个基于单词的概率采样表。 138 | 139 | 用来生成 `skipgrams` 的 `sampling_table` 参数。`sampling_table[i]` 是数据集中第 i 个最常见词的采样概率(出于平衡考虑,出现更频繁的词应该被更少地采样)。 140 | 141 | 采样概率根据 word2vec 中使用的采样分布生成: 142 | 143 | ```python 144 | p(word) = (min(1, sqrt(word_frequency / sampling_factor) / 145 | (word_frequency / sampling_factor))) 146 | ``` 147 | 148 | 我们假设单词频率遵循 Zipf 定律(s=1),来导出 frequency(rank) 的数值近似: 149 | 150 | `frequency(rank) ~ 1/(rank * (log(rank) + gamma) + 1/2 - 1/(12*rank))`,其中 `gamma` 为 Euler-Mascheroni 常量。 151 | 152 | __参数__ 153 | 154 | - __size__: 整数,可能采样的单词数量。 155 | - __sampling_factor__: word2vec 公式中的采样因子。 156 | 157 | __返回__ 158 | 159 | 一个长度为 `size` 大小的 1D Numpy 数组,其中第 i 项是排名为 i 的单词的采样概率。 160 | -------------------------------------------------------------------------------- /sources/preprocessing/text.md: -------------------------------------------------------------------------------- 1 | 2 | ### Text Preprocessing 3 | 4 | [[source]](https://github.com/keras-team/keras/blob/master/keras/preprocessing/text.py#L139) 5 | ### Tokenizer 6 | 7 | ```python 8 | keras.preprocessing.text.Tokenizer(num_words=None, 9 | filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n', 10 | lower=True, 11 | split=' ', 12 | char_level=False, 13 | oov_token=None, 14 | document_count=0) 15 | ``` 16 | 17 | 文本标记实用类。 18 | 19 | 该类允许使用两种方法向量化一个文本语料库: 20 | 将每个文本转化为一个整数序列(每个整数都是词典中标记的索引); 21 | 或者将其转化为一个向量,其中每个标记的系数可以是二进制值、词频、TF-IDF 权重等。 22 | 23 | __参数__ 24 | 25 | - __num_words__: 需要保留的最大词数,基于词频。只有最常出现的 `num_words-1` 词会被保留。 26 | - __filters__: 一个字符串,其中每个元素是一个将从文本中过滤掉的字符。默认值是所有标点符号,加上制表符和换行符,减去 `'` 字符。 27 | - __lower__: 布尔值。是否将文本转换为小写。 28 | - __split__: 字符串。按该字符串切割文本。 29 | - __char_level__: 如果为 True,则每个字符都将被视为标记。 30 | - __oov_token__: 如果给出,它将被添加到 word_index 中,并用于在 `text_to_sequence` 调用期间替换词汇表外的单词。 31 | 32 | 默认情况下,删除所有标点符号,将文本转换为空格分隔的单词序列(单词可能包含 `'` 字符)。 33 | 这些序列然后被分割成标记列表。然后它们将被索引或向量化。 34 | 35 | `0` 是不会被分配给任何单词的保留索引。 36 | 37 | 38 | ---- 39 | 40 | ### hashing_trick 41 | 42 | 43 | ```python 44 | keras.preprocessing.text.hashing_trick(text, 45 | n, 46 | hash_function=None, 47 | filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n', 48 | lower=True, 49 | split=' ') 50 | ``` 51 | 52 | 53 | 将文本转换为固定大小散列空间中的索引序列。 54 | 55 | __参数__ 56 | 57 | - __text__: 输入文本(字符串)。 58 | - __n__: 散列空间维度。 59 | - __hash_function__: 默认为 python 散列函数,可以是 'md5' 或任意接受输入字符串并返回整数的函数。注意 'hash' 不是稳定的散列函数,所以它在不同的运行中不一致,而 'md5' 是一个稳定的散列函数。 60 | - __filters__: 要过滤的字符列表(或连接),如标点符号。默认:``!"#$%&()*+,-./:;<=>?@[\]^_`{|}~\t\n``,包含基本标点符号,制表符和换行符。 61 | - __lower__: 布尔值。是否将文本转换为小写。 62 | - __split__: 字符串。按该字符串切割文本。 63 | 64 | __返回__ 65 | 66 | 整数词索引列表(唯一性无法保证)。 67 | 68 | `0` 是不会被分配给任何单词的保留索引。 69 | 70 | 由于哈希函数可能发生冲突,可能会将两个或更多字分配给同一索引。 71 | 碰撞的[概率](https://en.wikipedia.org/wiki/Birthday_problem#Probability_table)与散列空间的维度和不同对象的数量有关。 72 | 73 | 74 | ---- 75 | 76 | ### one_hot 77 | 78 | 79 | ```python 80 | keras.preprocessing.text.one_hot(text, 81 | n, 82 | filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n', 83 | lower=True, 84 | split=' ') 85 | ``` 86 | 87 | One-hot 将文本编码为大小为 n 的单词索引列表。 88 | 89 | 这是 `hashing_trick` 函数的一个封装, 90 | 使用 `hash` 作为散列函数;单词索引映射无保证唯一性。 91 | 92 | __参数__ 93 | 94 | - __text__: 输入文本(字符串)。 95 | - __n__: 整数。词汇表尺寸。 96 | - __filters__: 要过滤的字符列表(或连接),如标点符号。默认:``!"#$%&()*+,-./:;<=>?@[\]^_`{|}~\t\n``,包含基本标点符号,制表符和换行符。 97 | - __lower__: 布尔值。是否将文本转换为小写。 98 | - __split__: 字符串。按该字符串切割文本。 99 | 100 | __返回__ 101 | 102 | [1, n] 之间的整数列表。每个整数编码一个词(唯一性无法保证)。 103 | 104 | 105 | ---- 106 | 107 | 108 | ### text_to_word_sequence 109 | 110 | 111 | ```python 112 | keras.preprocessing.text.text_to_word_sequence(text, 113 | filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n', 114 | lower=True, 115 | split=' ') 116 | ``` 117 | 118 | 将文本转换为单词(或标记)的序列。 119 | 120 | __参数__ 121 | 122 | - __text__: 输入文本(字符串)。 123 | - __filters__: 要过滤的字符列表(或连接),如标点符号。默认:``!"#$%&()*+,-./:;<=>?@[\]^_`{|}~\t\n``,包含基本标点符号,制表符和换行符。 124 | - __lower__: 布尔值。是否将文本转换为小写。 125 | - __split__: 字符串。按该字符串切割文本。 126 | 127 | __返回__ 128 | 129 | 词或标记的列表。 130 | -------------------------------------------------------------------------------- /sources/regularizers.md: -------------------------------------------------------------------------------- 1 | ## 正则化器的使用 2 | 3 | 正则化器允许在优化过程中对层的参数或层的激活情况进行惩罚。 网络优化的损失函数也包括这些惩罚项。 4 | 5 | 惩罚是以层为对象进行的。具体的 API 因层而异,但 `Dense`,`Conv1D`,`Conv2D` 和 `Conv3D` 这些层具有统一的 API。 6 | 7 | 正则化器开放 3 个关键字参数: 8 | 9 | - `kernel_regularizer`: `keras.regularizers.Regularizer` 的实例 10 | - `bias_regularizer`: `keras.regularizers.Regularizer` 的实例 11 | - `activity_regularizer`: `keras.regularizers.Regularizer` 的实例 12 | 13 | 14 | ## 示例 15 | 16 | ```python 17 | from keras import regularizers 18 | model.add(Dense(64, input_dim=64, 19 | kernel_regularizer=regularizers.l2(0.01), 20 | activity_regularizer=regularizers.l1(0.01))) 21 | ``` 22 | 23 | ## 可用的正则化器 24 | 25 | ```python 26 | keras.regularizers.l1(0.) 27 | keras.regularizers.l2(0.) 28 | keras.regularizers.l1_l2(l1=0.01, l2=0.01) 29 | ``` 30 | 31 | ## 开发新的正则化器 32 | 33 | 任何输入一个权重矩阵、返回一个损失贡献张量的函数,都可以用作正则化器,例如: 34 | 35 | ```python 36 | from keras import backend as K 37 | 38 | def l1_reg(weight_matrix): 39 | return 0.01 * K.sum(K.abs(weight_matrix)) 40 | 41 | model.add(Dense(64, input_dim=64, 42 | kernel_regularizer=l1_reg)) 43 | ``` 44 | 45 | 另外,你也可以用面向对象的方式来编写正则化器的代码,例子见 [keras/regularizers.py](https://github.com/keras-team/keras/blob/master/keras/regularizers.py) 模块。 46 | -------------------------------------------------------------------------------- /sources/scikit-learn-api.md: -------------------------------------------------------------------------------- 1 | # Scikit-Learn API 的封装器 2 | 3 | 你可以使用 Keras 的 `Sequential` 模型(仅限单一输入)作为 Scikit-Learn 工作流程的一部分,通过在此找到的包装器: `keras.wrappers.scikit_learn.py`。 4 | 5 | 有两个封装器可用: 6 | 7 | `keras.wrappers.scikit_learn.KerasClassifier(build_fn=None, **sk_params)`, 这实现了Scikit-Learn 分类器接口, 8 | 9 | `keras.wrappers.scikit_learn.KerasRegressor(build_fn=None, **sk_params)`, 这实现了Scikit-Learn 回归接口。 10 | 11 | ### 参数 12 | 13 | - __build_fn__: 可调用函数或类实例 14 | - __sk_params__: 模型参数和拟合参数 15 | 16 | `build_fn` 应该建立,编译,并返回一个 Keras 模型,然后被用来训练/预测。以下三个值之一可以传递给`build_fn` 17 | 18 | 1. 一个函数; 19 | 2. 实现 `__call__` 方法的类的实例; 20 | 3. None。这意味着你实现了一个继承自 `KerasClassifier` 或 `KerasRegressor` 的类。当前类 `__call__` 方法将被视为默认的 `build_fn`。 21 | 22 | `sk_params` 同时包含模型参数和拟合参数。合法的模型参数是 `build_fn` 的参数。请注意,与 scikit-learn 中的所有其他估算器一样,`build_fn` 应为其参数提供默认值, 23 | 以便你可以创建估算器而不将任何值传递给 `sk_params`。 24 | 25 | `sk_params` 还可以接受用于调用 `fit`,`predict`,`predict_proba` 和 `score` 方法的参数(例如,`epochs`,`batch_size`)。训练(预测)参数按以下顺序选择: 26 | 27 | 1. 传递给 `fit`,`predict`,`predict_proba` 和 `score` 函数的字典参数的值; 28 | 2. 传递给 `sk_params` 的值; 29 | 3. `keras.models.Sequential` 的 `fit`,`predict`,`predict_proba` 和 `score` 方法的默认值。 30 | 31 | 当使用 scikit-learn 的 `grid_search` API 时,合法可调参数是你可以传递给 `sk_params` 的参数,包括训练参数。换句话说,你可以使用 `grid_search` 来搜索最佳的 `batch_size` 或 `epoch` 以及其他模型参数。 32 | -------------------------------------------------------------------------------- /sources/visualization.md: -------------------------------------------------------------------------------- 1 | 2 | ## 模型可视化 3 | 4 | `keras.utils.vis_utils` 模块提供了一些绘制 Keras 模型的实用功能(使用 `graphviz`)。 5 | 6 | 以下实例,将绘制一张模型图,并保存为文件: 7 | ```python 8 | from keras.utils import plot_model 9 | plot_model(model, to_file='model.png') 10 | ``` 11 | 12 | `plot_model` 有 4 个可选参数: 13 | 14 | - `show_shapes` (默认为 False) 控制是否在图中输出各层的尺寸。 15 | - `show_layer_names` (默认为 True) 控制是否在图中显示每一层的名字。 16 | - `expand_dim`(默认为 False)控制是否将嵌套模型扩展为图形中的聚类。 17 | - `dpi`(默认为 96)控制图像 dpi。 18 | 19 | 此外,你也可以直接取得 `pydot.Graph` 对象并自己渲染它。 20 | 例如,ipython notebook 中的可视化实例如下: 21 | 22 | ```python 23 | from IPython.display import SVG 24 | from keras.utils.vis_utils import model_to_dot 25 | 26 | SVG(model_to_dot(model).create(prog='dot', format='svg')) 27 | ``` 28 | 29 | ---- 30 | 31 | ## 训练历史可视化 32 | 33 | Keras `Model` 上的 `fit()` 方法返回一个 `History` 对象。`History.history` 属性是一个记录了连续迭代的训练/验证(如果存在)损失值和评估值的字典。这里是一个简单的使用 `matplotlib` 来生成训练/验证集的损失和准确率图表的例子: 34 | 35 | ```python 36 | import matplotlib.pyplot as plt 37 | 38 | history = model.fit(x, y, validation_split=0.25, epochs=50, batch_size=16, verbose=1) 39 | 40 | # 绘制训练 & 验证的准确率值 41 | plt.plot(history.history['acc']) 42 | plt.plot(history.history['val_acc']) 43 | plt.title('Model accuracy') 44 | plt.ylabel('Accuracy') 45 | plt.xlabel('Epoch') 46 | plt.legend(['Train', 'Test'], loc='upper left') 47 | plt.show() 48 | 49 | # 绘制训练 & 验证的损失值 50 | plt.plot(history.history['loss']) 51 | plt.plot(history.history['val_loss']) 52 | plt.title('Model loss') 53 | plt.ylabel('Loss') 54 | plt.xlabel('Epoch') 55 | plt.legend(['Train', 'Test'], loc='upper left') 56 | plt.show() 57 | ``` 58 | -------------------------------------------------------------------------------- /sources/why-use-keras.md: -------------------------------------------------------------------------------- 1 | # 为什么选择 Keras? 2 | 3 | 在如今无数深度学习框架中,为什么要使用 Keras 而非其他?以下是 Keras 与现有替代品的一些比较。 4 | 5 | --- 6 | 7 | ## Keras 优先考虑开发人员的经验 8 | 9 | - Keras 是为人类而非机器设计的 API。[Keras 遵循减少认知困难的最佳实践](https://blog.keras.io/user-experience-design-for-apis.html): 它提供一致且简单的 API,它将常见用例所需的用户操作数量降至最低,并且在用户错误时提供清晰和可操作的反馈。 10 | 11 | - 这使 Keras 易于学习和使用。作为 Keras 用户,你的工作效率更高,能够比竞争对手更快地尝试更多创意,从而[帮助你赢得机器学习竞赛](https://www.quora.com/Why-has-Keras-been-so-successful-lately-at-Kaggle-competitions)。 12 | 13 | - 这种易用性并不以降低灵活性为代价:因为 Keras 与底层深度学习语言(特别是 TensorFlow)集成在一起,所以它可以让你实现任何你可以用基础语言编写的东西。特别是,`tf.keras` 作为 Keras API 可以与 TensorFlow 工作流无缝集成。 14 | 15 | --- 16 | 17 | ## Keras 被工业界和学术界广泛采用 18 | 19 | 20 | 21 |

22 | Deep learning 框架排名,由 Jeff Hale 基于 7 个分类的 11 个数据源计算得出 23 | 24 |

25 | 26 | 截至 2018 年中期,Keras 拥有超过 250,000 名个人用户。与其他任何深度学习框架相比,Keras 在行业和研究领域的应用率更高(除 TensorFlow 之外,且 Keras API 是 TensorFlow 的官方前端,通过 `tf.keras` 模块使用)。 27 | 28 | 你已经不断与使用 Keras 构建的功能进行交互 - 它在 Netflix, Uber, Yelp, Instacart, Zocdoc, Square 等众多网站上被使用。它尤其受以深度学习作为产品核心的创业公司的欢迎。 29 | 30 | Keras 也是深度学习研究人员的最爱,在上传到预印本服务器 [arXiv.org](https://arxiv.org/archive/cs) 的科学论文中被提及的次数位居第二。Keras 还被大型科学组织的研究人员采用,特别是 CERN 和 NASA。 31 | 32 | --- 33 | 34 | ## Keras 可以轻松将模型转化为产品 35 | 36 | 与任何其他深度学习框架相比,你的 Keras 模型可以轻松地部署在更广泛的平台上: 37 | 38 | - 在 iOS 上,通过 [Apple’s CoreML](https://developer.apple.com/documentation/coreml)(苹果为 Keras 提供官方支持)。这里有一个[教程](https://www.pyimagesearch.com/2018/04/23/running-keras-models-on-ios-with-coreml/)。 39 | - 在 Android 上,通过 TensorFlow Android runtime。例如 [Not Hotdog app](https://medium.com/@timanglade/how-hbos-silicon-valley-built-not-hotdog-with-mobile-tensorflow-keras-react-native-ef03260747f3)。 40 | - 在浏览器中,通过 GPU 加速的 JavaScript 运行时,例如 [Keras.js](https://transcranial.github.io/keras-js/#/) 和 [WebDNN](https://mil-tokyo.github.io/webdnn/)。 41 | - 在 Google Cloud 上,通过 [TensorFlow-Serving](https://www.tensorflow.org/serving/)。 42 | - [在 Python webapp 后端中(比如 Flask app)](https://blog.keras.io/building-a-simple-keras-deep-learning-rest-api.html)。 43 | - 在 JVM 上,通过 [SkyMind 提供的 DL4J 模型导入](https://deeplearning4j.org/model-import-keras)。 44 | - 在 Raspberry Pi 树莓派上。 45 | 46 | --- 47 | 48 | ## Keras 支持多个后端引擎,不会将你锁定到一个生态系统中 49 | 50 | 你的 Keras 模型可以基于不同的[深度学习后端](https://keras.io/zh/backend/)开发。重要的是,任何仅利用内置层构建的 Keras 模型,都可以在所有这些后端中移植:你可以用一种后端训练模型,再将它载入另一种后端中(例如为了发布的需要)。支持的后端有: 51 | 52 | - 谷歌的 TensorFlow 后端 53 | - 微软的 CNTK 后端 54 | - Theano 后端 55 | 56 | 亚马逊也有一个[使用 MXNet 作为后端的 Keras 分支](https://github.com/awslabs/keras-apache-mxnet)。 57 | 58 | 如此一来,你的 Keras 模型可以在 CPU 之外的不同硬件平台上训练: 59 | 60 | - [NVIDIA GPUs](https://developer.nvidia.com/deep-learning) 61 | - [Google TPUs](https://cloud.google.com/tpu/),通过 TensorFlow 后端和 Google Cloud 62 | - OpenCL 支持的 GPUs,比如 AMD, 通过 [PlaidML Keras 后端](https://github.com/plaidml/plaidml) 63 | 64 | --- 65 | 66 | ## Keras 拥有强大的多 GPU 和分布式训练支持 67 | 68 | - Keras [内置对多 GPU 数据并行的支持](https://keras.io/zh/utils/#multi_gpu_model)。 69 | - 优步的 [Horovod](https://github.com/uber/horovod) 对 Keras 模型拥有一流的支持。 70 | - Keras 模型[可以被转换为 TensorFlow Estimators](https://www.tensorflow.org/versions/master/api_docs/python/tf/keras/estimator/model_to_estimator) 并在 [Google Cloud 的 GPU 集群](https://cloud.google.com/solutions/running-distributed-tensorflow-on-compute-engine)上训练。 71 | - Keras 可以在 Spark(通过 CERN 的 [Dist-Keras](https://github.com/cerndb/dist-keras))和 [Elephas](https://github.com/maxpumperla/elephas) 上运行。 72 | 73 | --- 74 | 75 | ## Keras 的发展得到深度学习生态系统中的关键公司的支持 76 | 77 | Keras 的开发主要由谷歌支持,Keras API 以 `tf.keras` 的形式包装在 TensorFlow 中。此外,微软维护着 Keras 的 CNTK 后端。亚马逊 AWS 正在开发 MXNet 支持。其他提供支持的公司包括 NVIDIA、优步、苹果(通过 CoreML)等。 78 | 79 | 80 | 81 | 82 | 83 | --------------------------------------------------------------------------------