tf2.0 Keras:将自定义张量流代码用于RNN

时间:2019-08-15 09:43:39

标签: python keras recurrent-neural-network tensorflow2.0

我正在使用Keras API在tf2中编写一个编码器循环解码器模型。在解码阶段,我想将一些自定义函数应用于模型输出。但是,一旦我开始将“张量流”代码“嵌入”到我的功能性Keras模型中,就无法再保存权重-而是发生ValueError异常:

ValueError: Unable to create group (name already exists)

该模型可以进行了培训,并且损失正在减少,正如我所期望的那样。唯一的问题是事后存储权重。

整个错误消息:

ValueError                                Traceback (most recent call last)
<ipython-input-4-5edae36ba5fe> in <module>()
     57 model.compile(loss='MSE', optimizer='adam')
     58 
---> 59 model.save_weights('/tmp/dummy.h5')
     60 print('saved')

2 frames
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/network.py in save_weights(self, filepath, overwrite, save_format)
   1310     if save_format == 'h5':
   1311       with h5py.File(filepath, 'w') as f:
-> 1312         saving.save_weights_to_hdf5_group(f, self.layers)
   1313     else:
   1314       if context.executing_eagerly():

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/saving/hdf5_format.py in save_weights_to_hdf5_group(f, layers)
    617 
    618   for layer in layers:
--> 619     g = f.create_group(layer.name)
    620     weights = _legacy_weights(layer)
    621     weight_values = K.batch_get_value(weights)

/usr/local/lib/python3.6/dist-packages/h5py/_hl/group.py in create_group(self, name, track_order)
     58             name, lcpl = self._e(name, lcpl=True)
     59             gcpl = Group._gcpl_crt_order if track_order else None
---> 60             gid = h5g.create(self.id, name, lcpl=lcpl, gcpl=gcpl)
     61             return Group(gid)
     62 

h5py/_objects.pyx in h5py._objects.with_phil.wrapper()

h5py/_objects.pyx in h5py._objects.with_phil.wrapper()

h5py/h5g.pyx in h5py.h5g.create()

ValueError: Unable to create group (name already exists)

到目前为止我尝试过的事情:

  • tf 1.14.0也会发生错误
  • 在有问题的代码部分周围添加named_scope并没有帮助:with tf.name_scope('something' + str(step)):
  • 明确命名tf.reshape操作并没有帮助:outputs = tf.reshape(..., name='custom_reshape1_' + str(step))
  • 该错误可以在 Google Colab
  • 中重现
  • 这不是已经创建权重文件的问题,因为我在运行代码之前删除了所有数据。此外,当删除有问题的张量流代码时,该代码可以正常工作
import tensorflow as tf
print('version=', tf.__version__)
import numpy as np

keras = tf.keras # pylint: disable=no-member
KL = keras.layers
KM = keras.models
K = keras.backend
KR = keras.regularizers
# GRU = tf.compat.v1.keras.layers.CuDNNGRU
GRU = KL.GRU

n_in = 20
n_out = 10
dim = 128
hidden_units = 1024

encoder_inputs = KL.Input(shape=(n_in, dim))
encoder = GRU(hidden_units,
              return_state=True)
_, state_h = encoder(encoder_inputs)

decoder_gru = GRU(hidden_units,
                  return_sequences=True,
                  return_state=True)
decoder_dense = KL.Dense(dim)

last_pose = KL.Lambda(lambda a: a[:, -1, :],
                      output_shape=(None, dim))(encoder_inputs)
last_pose = KL.Reshape((1, dim))(last_pose)


all_outputs = []
inputs = last_pose
for step in range(n_out):
  outputs, state_h = decoder_gru(inputs, initial_state=state_h)
  outputs = decoder_dense(outputs)

  # ~~~~~~~~~~~~~~~~~~~~~~~~ comment out to "fix" issue
  # -- problem cause (start)
  n_batch = tf.shape(outputs)[0]
  outputs = tf.reshape(outputs, (n_batch * 32, 4))
  # ... custom function stuff
  outputs = tf.reshape(outputs, (n_batch, 1, 32*4))
  # -- problem cause (end)
  # ~~~~~~~~~~~~~~~~~~~~~~~~

  all_outputs.append(outputs)
  inputs = outputs

decoder_outputs = KL.Concatenate()(all_outputs)
decoder_outputs = KL.Reshape((n_out, dim))(decoder_outputs)
model = KM.Model(inputs=encoder_inputs,
                 outputs=decoder_outputs)

model = KM.Model(inputs=encoder_inputs, outputs=state_h)


model.compile(loss='MSE', optimizer='adam')

model.save_weights('/tmp/dummy.h5')
print('saved')

我不确定出什么问题了,我希望能够减轻重量!该模型可以训练,并且损失减少,仅存储权重会引起问题。

1 个答案:

答案 0 :(得分:0)

看来tf.shape是罪魁祸首。在没有代码的情况下重新编写代码可使模型按预期方式存储。我仍然很好奇为什么会发生这种情况。

import tensorflow as tf
print('version=', tf.__version__)
import numpy as np

keras = tf.keras # pylint: disable=no-member
KL = keras.layers
KM = keras.models
K = keras.backend
KR = keras.regularizers
# GRU = tf.compat.v1.keras.layers.CuDNNGRU
GRU = KL.GRU

n_in = 20
n_out = 10
dim = 128
hidden_units = 1024

encoder_inputs = KL.Input(shape=(n_in, dim))
encoder = GRU(hidden_units,
              return_state=True)
_, state_h = encoder(encoder_inputs)

decoder_gru = GRU(hidden_units,
                  return_sequences=True,
                  return_state=True)
decoder_dense = KL.Dense(dim)

last_pose = KL.Lambda(lambda a: a[:, -1, :],
                      output_shape=(None, dim))(encoder_inputs)
last_pose = KL.Reshape((1, dim))(last_pose)


all_outputs = []
inputs = last_pose
for step in range(n_out):
  outputs, state_h = decoder_gru(inputs, initial_state=state_h)
  outputs = decoder_dense(outputs)

  # ~~~~~~~~~~~~~~~~~~~~~~~~ comment out to "fix" issue
  # -- problem cause (start)
  # n_batch = tf.shape(outputs)[0]
  outputs = tf.reshape(outputs, (-1, 4))
  # ... custom function stuff
  outputs = tf.reshape(outputs, (-1, 1, 32*4))
  # -- problem cause (end)
  # ~~~~~~~~~~~~~~~~~~~~~~~~

  all_outputs.append(outputs)
  inputs = outputs

decoder_outputs = KL.Concatenate()(all_outputs)
decoder_outputs = KL.Reshape((n_out, dim))(decoder_outputs)
model = KM.Model(inputs=encoder_inputs,
                 outputs=decoder_outputs)

model = KM.Model(inputs=encoder_inputs, outputs=state_h)


model.compile(loss='MSE', optimizer='adam')

model.save_weights('/tmp/dummy.h5')
print('saved')