之前写简单的DNN demo就是复制粘贴模型,今天有时间系统得看了看构造的一些事情
问题describe
创建多层RNN网络,一开始用的是tf的tf.nn.rnn_cell.GRUCell, 但是报错如下
The added layer must be an instance of class Layer. Found: <tensorflow.python.ops.rnn_cell_impl.MultiRNN
原因
This won't work because a tensorflow.keras layer is getting added to a keras Model
创建模型时,embedding层用的是keras的库,而创建RNN时用的是tensorflow的库。
def my_emb_MultiGRU(max_len, m, layer_nums):
# 用的是keras的
model = ks.models.Sequential()
model.add(ks.layers.Masking(mask_value=0, input_shape=(500,max_len)))
# 用的是tensorflow的库
cell_list = [tf.nn.rnn_cell.GRUCell(num_units=m) for _ in range(layer_nums)]
multiRnn_layer = tf.nn.rnn_cell.MultiRNNCell(cell_list)
model.add(multiRnn_layer)
model.add(Dense(m, activation="relu", name="FC1"))
model.add(Dropout(0.5))
model.add(Dense(9, activation="softmax", name="FC2"))
return model
修改策略
keras官网给出了两个实例:
基于栈式 LSTM 的序列分类以及"stateful" 渲染的的栈式 LSTM 模型
根据RNN的特性以及本次实验需求,使用"stateful" 渲染的的栈式 GRU 模型
有状态 (stateful) 的循环神经网络模型中,在一个 batch 的样本处理完成后,其内部状态(记忆)会被记录并作为下一个 batch 的样本的初始状态。这允许处理更长的序列,同时保持计算复杂度的可控性。
实现讲解
参考keras的官方文档
1 keras的sequence()创造多层网络
顺序模型是多个网络层的线性堆叠。
可以网络层实例的列表传递给 Sequential
的构造器,也可以通过add()来实现
注: 接受的模型,第一层需要接受参数(获取输入的尺寸)
顺序模型中的第一层(且只有第一层,因为下面的层可以自动地推断尺寸)需要接收关于其输入尺寸的信息
- 传递一个
input_shape
参数给第一层。它是一个表示尺寸的元组 (一个由整数或 None
组成的元组,其中 None
表示可能为任何正整数)。在 input_shape
中不包含数据的 batch 大小。
- 某些 2D 层,例如
Dense
,支持通过参数 input_dim
指定输入尺寸,某些 3D 时序层支持 input_dim
和 input_length
参数。
- 如果你需要为你的输入指定一个固定的 batch 大小(这对 stateful RNNs 很有用),你可以传递一个
batch_size
参数给一个层。如果你同时将 batch_size=32
和 input_shape=(6, 8)
传递给一个层,那么每一批输入的尺寸就为 (32,6,8)
2 keras的compile编译模型,配置学习过程
在训练模型之前,您需要配置学习过程,这是通过 compile
方法完成的。它接收三个参数:
- 优化器 optimizer。它可以是现有优化器的字符串标识符,如
rmsprop
或 adagrad
,也可以是 Optimizer 类的实例。详见:optimizers。
- 损失函数 loss,模型试图最小化的目标函数。它可以是现有损失函数的字符串标识符,如
categorical_crossentropy
或 mse
,也可以是一个目标函数。详见:losses。
- 评估标准 metrics。对于任何分类问题,你都希望将其设置为
metrics = ['accuracy']
。评估标准可以是现有的标准的字符串标识符,也可以是自定义的评估标准函数。
3 fit函数训练