我最近发现LayerNormBasicLSTMCell是LSTM的一个版本,它实现了Layer Normalization和dropout.因此,我使用LSTMCell替换了我的原始代码和LayerNormBasicLSTMCell.这种变化不仅将测试精度从~96%降低到~92%,而且需要更长的时间(~33小时)进行训练(原始训练时间约为6小时).所有参数都相同:历元数(10),堆叠层数(3),隐藏矢量大小数(250),丢失保持概率(0.5),......硬件也相同.
我的问题是:我在这里做错了什么?
我原来的模型(使用LSTMCell):
# Batch normalization of the raw input
tf_b_VCCs_AMs_BN1 = tf.layers.batch_normalization(
tf_b_VCCs_AMs, # the input vector, size [#batches, #time_steps, 2]
axis=-1, # axis that should be normalized
training=Flg_training, # Flg_training = True during training, and False during test
trainable=True,
name="Inputs_BN"
)
# Bidirectional dynamic stacked LSTM
##### The part I changed in the new model (start) #####
dropcells = []
for iiLyr in range(3):
cell_iiLyr = tf.nn.rnn_cell.LSTMCell(num_units=250, state_is_tuple=True)
dropcells.append(tf.nn.rnn_cell.DropoutWrapper(cell=cell_iiLyr, output_keep_prob=0.5))
##### The part I changed in the …Run Code Online (Sandbox Code Playgroud) 我担心使用相同的初始化器、正则化器和约束在(张量流)keras 层中创建的变量可能会在层之间连接。如果它们可以是字符串(例如“he_normal”),那么没有问题,但是对于那些带有参数的参数,我必须传递实际的函数。例如,在__init__自定义层中,
initializer_1 = tf.keras.initializers.he_normal()
regularizer_1 = tf.keras.regularizers.l2(l=0.001)
constraint_1 = tf.keras.constraints.MaxNorm(max_value=2, axis=[0,1,2])
layer_A = tf.keras.layers.Conv2D(
...
kernel_initializer=initializer_1,
kernel_regularizer=regularizer_1,
kernel_constraint=constraint_1,
...
)
layer_B = tf.keras.layers.Conv2D(
...
kernel_initializer=initializer_1,
kernel_regularizer=regularizer_1,
kernel_constraint=constraint_1,
...
)
Run Code Online (Sandbox Code Playgroud)
这安全吗?
我正在尝试将cache转换用于dataset。这是我当前的代码(简体):
dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads=1)
dataset = dataset.apply(tf.contrib.data.shuffle_and_repeat(buffer_size=5000, count=1))
dataset = dataset.map(_parser_a, num_parallel_calls=12)
dataset = dataset.padded_batch(
20,
padded_shapes=padded_shapes,
padding_values=padding_values
)
dataset = dataset.prefetch(buffer_size=1)
dataset = dataset.cache()
Run Code Online (Sandbox Code Playgroud)
在第一个时期之后,我收到以下错误消息:
调用迭代器没有完全读取我们尝试缓存的数据集。为了避免序列的意外截断,将丢弃当前的[部分缓存]序列。如果您的序列与相似,则会发生这种情况
dataset.cache().take(k).repeat()。相反,请交换订单(即dataset.take(k).cache().repeat())
然后,代码继续进行,仍然从硬盘驱动器而不是从缓存读取数据。那么,应该在哪里放置dataset.cache()以避免该错误?谢谢。