Tensorflow>;r1.0 tf.layers.batch\u标准化非常糟糕的测试性能

Tensorflow>;r1.0 tf.layers.batch\u标准化非常糟糕的测试性能,tensorflow,deep-learning,Tensorflow,Deep Learning,我试图使用最新的Tensorflow API中提供的tf.layers.batch\u normalization函数来实现一个重复的批量规范化LSTM 实现如下(我修改了TF源代码): BNLSTMCell类(tf.nn.rnn_cell.RNNCell): """ 批量标准化长短时记忆单元(LSTM)递归网络单元。 参见经常性批量标准化 https://arxiv.org/abs/1603.09025 参见TensorFlow中使用批次标准化的温和指南 http://ruishu.io/2

我试图使用最新的Tensorflow API中提供的
tf.layers.batch\u normalization
函数来实现一个重复的批量规范化LSTM

实现如下(我修改了TF源代码):

BNLSTMCell类(tf.nn.rnn_cell.RNNCell):
"""
批量标准化长短时记忆单元(LSTM)递归网络单元。
参见经常性批量标准化
https://arxiv.org/abs/1603.09025
参见TensorFlow中使用批次标准化的温和指南
http://ruishu.io/2016/12/27/batchnorm/
"""
定义初始单位(自身、数量单位、仅向前单位、伽马c=1.0、伽马h=1.0、,
γx=1.0,βc=0.0,βh=0.0,βx=0.0,
输入\大小=无,使用\窥视孔=假,单元格\剪辑=无,
初始值设定项=无,num_proj=无,
num_unit_shards=1,num_proj_shards=1,
忘记_bias=1.0,state_为_tuple=False,
激活=tf.tanh):
“”“初始化LSTM单元格的参数。
Args:
num_units:int,LSTM单元格中的单位数
仅转发(u):
如果错误(培训):
1.根据小批量统计数据规范层激活。
2.在培训阶段,更新人口统计数据
通过小批量统计的移动平均值进行近似。
如果为真(测试):
1.根据估计的人口标准化层激活
统计数字。
2.未按小批量更新人口统计数据
统计数据来自测试数据。
gamma_c:单元状态规范化的规模
beta_c:单元状态规范化的偏移量
gamma_h:隐藏状态规范化的规模
beta_h:隐藏状态规范化的偏移量
(设置为0以避免冗余)
gamma_x:输入标准化的规模
beta_x:输入标准化的偏移量
(设置为0以避免冗余)
输入大小:已弃用和未使用。
使用_窥视孔:bool,设置为True以启用对角/窥视孔连接。
单元剪裁:(可选)如果单元状态被剪裁,则为浮点值
在单元输出激活之前按此值。
初始值设定项:(可选)用于权重和
投影矩阵。
num_proj:(可选)int,投影的输出维度
矩阵。如果没有,则不执行投影。
num_unit_shards:如何分割权重矩阵。如果>1,则权重
矩阵存储在num_unit_碎片上。
num_proj_shards:如何分割投影矩阵。如果>1,则
投影矩阵存储在num_proj_碎片上。
遗忘偏差:遗忘门的偏差默认初始化为1
为了减少学习开始时的遗忘程度
培训。
状态是元组:如果为真,则接受和返回的状态是
'c_state'和'm_state`。默认情况下(False),它们是连接在一起的
沿列轴。此默认行为很快将被弃用。
激活:内部状态的激活函数。
"""
如果不是,则状态为元组:
日志记录。警告(
%s:使用连接状态的速度较慢,并且很快会
“已弃用。使用状态\u is\u tuple=True。”%self)
如果输入大小不是“无”:
logging.warn(“%s:输入大小参数已弃用。”%self)
self.\u num\u units=num\u units
self.forward\u only=仅向前
自我。_gamma_c=gamma_c
self.\u beta\u c=beta\u c
自我。_gamma_h=gamma_h
self.\u beta\u h=beta\u h
自我。_gamma_x=gamma_x
self.\u beta\u x=beta\u x
自我。使用窥视孔=使用窥视孔
self.\u cell\u clip=cell\u clip
self.\u初始值设定项=初始值设定项
self.\u num\u proj=num\u proj
self.\u num\u unit\u shards=num\u unit\u shards
self.\u num\u proj\u shards=num\u proj\u shards
自我。忘记偏见=忘记偏见
self.\u state\u is\u tuple=state\u is\u tuple
自激活=激活
如果数量项目:
自身状态大小=(
tf.nn.rnn_cell.LSTMStateTuple(num_单位,num_项目)
如果状态为“元组其他数量单位+数量项目”)
自身输出大小=项目数量
其他:
自身状态大小=(
tf.nn.rnn_cell.LSTMStateTuple(num_单位,num_单位)
如果状态为元组,则为2*num\u单位)
自。\输出\大小=数量\单位
@财产
def状态_大小(自身):
返回自我。\u状态\u大小
@财产
def输出_大小(自身):
返回自我。\u输出\u大小
定义调用(自身、输入、状态、作用域=无):
“”“运行LSTM的一个步骤。
Args:
输入:输入张量、2D、批次x数量单位。
状态:如果'state_is_tuple'为False,则必须是状态张量,
`二维,批次x状态大小。如果“状态为元组”为真,则该值必须为
状态张量的元组,均为'2-D',列大小为'c_state',和
`m_state`。
范围:创建的子图的VariableScope;默认为“LSTMCell”。
返回:
包含以下内容的元组:
-A`2-D,[batch x output_dim]`,张量表示
前一个状态为“状态”时读取“输入”后的LSTM。
此处的输出尺寸为:
num_proj如果设置了num_proj,
否则为num_单位。
-表示读取'inputs'后LSTM的新状态的张量,当
上一个状态是“状态”。与“状态”的类型和形状相同。
提出:
ValueError:如果无法通过输入推断输入大小
静态形状推断。
"""
num\u proj=self.\u num\u单位,如果self.\u num\u proj不是其他self.\u num\u proj
如果self.\u state\u是\u元组:
(c_prev,m_prev)=状态
其他:
c_prev=tf.slice(状态,[0,0],-1,自数值单位])
m_prev=tf.slice(状态,[0,自数值单位],-1,数值项目])
dtype=inputs.dtype
input_size=inputs.get_shape(),具有_秩(2)[1]
如果输入_size.valu