keras 在我的tf.函数中创建的tf.变量已被垃圾收集

inn6fuwd  于 2023-10-19  发布在  其他
关注(0)|答案(2)|浏览(228)

运行env:Google Colab
主存储库:https://github.com/grausof/keras-sincnet
我定制的源代码:没有
我正在使用SincNet Paper实现说话人识别目标。我实现我的层,但当尝试model.fit我看到的错误,我将在下面显示。
第一次跑步,我看到:

  1. ValueError: in user code:
  2. /usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/def_function.py:903 fn_with_cond *
  3. raise ValueError(
  4. ValueError: A tf.Variable created inside your tf.function has been garbage-collected. Your code needs to keep Python references to variables created inside `tf.function`s.
  5. A common way to raise this error is to create and return a variable only referenced inside your function:
  6. @tf.function
  7. def f():
  8. v = tf.Variable(1.0)
  9. return v
  10. v = f() # Crashes with this error message!
  11. The reason this crashes is that @tf.function annotated function returns a **`tf.Tensor`** with the **value** of the variable when the function is called rather than the variable instance itself. As such there is no code holding a reference to the `v` created inside the function and Python garbage collects it.
  12. The simplest way to fix this issue is to create variables outside the function and capture them:
  13. v = tf.Variable(1.0)
  14. @tf.function
  15. def f():
  16. return v
  17. f() # <tf.Tensor: numpy=1.>
  18. v.assign_add(1.)
  19. f() # <tf.Tensor: numpy=2.>

我看到了下一轮

  1. ValueError: in user code:
  2. /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:805 train_function *
  3. return step_function(self, iterator)
  4. <ipython-input-60-c4b5571aed6d>:112 call *
  5. low_pass1 = 2 * self.filt_beg_freq[i] * sinc(self.filt_beg_freq[i] * self.freq_scale, self.t_right)
  6. <ipython-input-60-c4b5571aed6d>:158 sinc *
  7. y = K.concatenate([y_left, K.variable(K.ones(1)), y_right])
  8. /usr/local/lib/python3.6/dist-packages/tensorflow/python/util/dispatch.py:201 wrapper **
  9. return target(*args, **kwargs)
  10. /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/backend.py:1521 ones
  11. return variable(v, dtype=dtype, name=name)
  12. /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/backend.py:983 variable
  13. constraint=constraint)
  14. /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/variables.py:262 __call__
  15. return cls._variable_v2_call(*args, **kwargs)
  16. /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/variables.py:256 _variable_v2_call
  17. shape=shape)
  18. /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/variables.py:67 getter
  19. return captured_getter(captured_previous, **kwargs)
  20. /usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:3332 creator
  21. return next_creator(**kwargs)
  22. /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/variables.py:67 getter
  23. return captured_getter(captured_previous, **kwargs)
  24. /usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:3332 creator
  25. return next_creator(**kwargs)
  26. /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/variables.py:67 getter
  27. return captured_getter(captured_previous, **kwargs)
  28. /usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:3332 creator
  29. return next_creator(**kwargs)
  30. /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/variables.py:67 getter
  31. return captured_getter(captured_previous, **kwargs)
  32. /usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/def_function.py:731 invalid_creator_scope
  33. "tf.function-decorated function tried to create "
  34. ValueError: tf.function-decorated function tried to create variables on non-first call.

我的图层是:

  1. from tensorflow.keras import backend as K
  2. from tensorflow.keras.layers import Layer
  3. from tensorflow.python.keras.utils import conv_utils
  4. import numpy as np
  5. import math
  6. debug = False
  7. from keras import initializers
  8. class LayerNorm(Layer):
  9. """ Layer Normalization in the style of https://arxiv.org/abs/1607.06450 """
  10. def __init__(self, scale_initializer='ones', bias_initializer='zeros', **kwargs):
  11. super(LayerNorm, self).__init__(**kwargs)
  12. self.epsilon = 1e-6
  13. self.scale_initializer = initializers.get(scale_initializer)
  14. self.bias_initializer = initializers.get(bias_initializer)
  15. def build(self, input_shape):
  16. self.scale = self.add_weight(shape=(input_shape[-1],),
  17. initializer=self.scale_initializer,
  18. trainable=True,
  19. name='{}_scale'.format(self.name))
  20. self.bias = self.add_weight(shape=(input_shape[-1],),
  21. initializer=self.bias_initializer,
  22. trainable=True,
  23. name='{}_bias'.format(self.name))
  24. self.built = True
  25. def call(self, x, mask=None):
  26. mean = K.mean(x, axis=-1, keepdims=True)
  27. std = K.std(x, axis=-1, keepdims=True)
  28. norm = (x - mean) * (1 / (std + self.epsilon))
  29. return norm * self.scale + self.bias
  30. def compute_output_shape(self, input_shape):
  31. return input_shape
  32. def debug_print(*objects):
  33. if debug:
  34. print(*objects)
  35. class SincConv1D(Layer):
  36. def __init__(
  37. self,
  38. N_filt,
  39. Filt_dim,
  40. fs,
  41. **kwargs):
  42. self.N_filt = N_filt
  43. self.Filt_dim = Filt_dim
  44. self.fs = fs
  45. super(SincConv1D, self).__init__(**kwargs)
  46. def build(self, input_shape):
  47. # The filters are trainable parameters.
  48. self.filt_b1 = self.add_weight(
  49. name='filt_b1',
  50. shape=(self.N_filt,),
  51. initializer='uniform',
  52. trainable=True)
  53. self.filt_band = self.add_weight(
  54. name='filt_band',
  55. shape=(self.N_filt,),
  56. initializer='uniform',
  57. trainable=True)
  58. # Mel Initialization of the filterbanks
  59. low_freq_mel = 80
  60. high_freq_mel = (2595 * np.log10(1 + (self.fs / 2) / 700)) # Convert Hz to Mel
  61. mel_points = np.linspace(low_freq_mel, high_freq_mel, self.N_filt) # Equally spaced in Mel scale
  62. f_cos = (700 * (10 ** (mel_points / 2595) - 1)) # Convert Mel to Hz
  63. b1 = np.roll(f_cos, 1)
  64. b2 = np.roll(f_cos, -1)
  65. b1[0] = 30
  66. b2[-1] = (self.fs / 2) - 100
  67. self.freq_scale = self.fs * 1.0
  68. self.set_weights([b1 / self.freq_scale, (b2 - b1) / self.freq_scale])
  69. # Get beginning and end frequencies of the filters.
  70. min_freq = 50.0
  71. min_band = 50.0
  72. self.filt_beg_freq = K.abs(self.filt_b1) + min_freq / self.freq_scale
  73. self.filt_end_freq = self.filt_beg_freq + (K.abs(self.filt_band) + min_band / self.freq_scale)
  74. # Filter window (hamming).
  75. n = np.linspace(0, self.Filt_dim, self.Filt_dim)
  76. window = 0.54 - 0.46 * K.cos(2 * math.pi * n / self.Filt_dim)
  77. window = K.cast(window, "float32")
  78. self.window = K.variable(window)
  79. debug_print(" window", self.window.shape)
  80. # TODO what is this?
  81. t_right_linspace = np.linspace(1, (self.Filt_dim - 1) / 2, int((self.Filt_dim - 1) / 2))
  82. self.t_right = K.variable(t_right_linspace / self.fs)
  83. debug_print(" t_right", self.t_right)
  84. super(SincConv1D, self).build(input_shape) # Be sure to call this at the end
  85. def call(self, x, **kwargs):
  86. debug_print("call")
  87. # filters = K.zeros(shape=(N_filt, Filt_dim))
  88. # Compute the filters.
  89. output_list = []
  90. for i in range(self.N_filt):
  91. low_pass1 = 2 * self.filt_beg_freq[i] * sinc(self.filt_beg_freq[i] * self.freq_scale, self.t_right)
  92. low_pass2 = 2 * self.filt_end_freq[i] * sinc(self.filt_end_freq[i] * self.freq_scale, self.t_right)
  93. band_pass = (low_pass2 - low_pass1)
  94. band_pass = band_pass / K.max(band_pass)
  95. output_list.append(band_pass * self.window)
  96. filters = K.stack(output_list) # (80, 251)
  97. filters = K.transpose(filters) # (251, 80)
  98. filters = K.reshape(filters, (self.Filt_dim, 1,
  99. self.N_filt)) # (251,1,80) in TF: (filter_width, in_channels, out_channels) in
  100. # PyTorch (out_channels, in_channels, filter_width)
  101. '''Given an input tensor of shape [batch, in_width, in_channels] if data_format is "NWC", or [batch,
  102. in_channels, in_width] if data_format is "NCW", and a filter / kernel tensor of shape [filter_width,
  103. in_channels, out_channels], this op reshapes the arguments to pass them to conv2d to perform the equivalent
  104. convolution operation. Internally, this op reshapes the input tensors and invokes tf.nn.conv2d. For example,
  105. if data_format does not start with "NC", a tensor of shape [batch, in_width, in_channels] is reshaped to [
  106. batch, 1, in_width, in_channels], and the filter is reshaped to [1, filter_width, in_channels, out_channels].
  107. The result is then reshaped back to [batch, out_width, out_channels] (where out_width is a function of the
  108. stride and padding as in conv2d) and returned to the caller. '''
  109. # Do the convolution.
  110. debug_print("call")
  111. debug_print(" x", x)
  112. debug_print(" filters", filters)
  113. out = K.conv1d(
  114. x,
  115. kernel=filters
  116. )
  117. debug_print(" out", out)
  118. return out
  119. def compute_output_shape(self, input_shape):
  120. new_size = conv_utils.conv_output_length(
  121. input_shape[1],
  122. self.Filt_dim,
  123. padding="valid",
  124. stride=1,
  125. dilation=1)
  126. return (input_shape[0],) + (new_size,) + (self.N_filt,)
  127. def sinc(band, t_right):
  128. y_right = K.sin(2 * math.pi * band * t_right) / (2 * math.pi * band * t_right)
  129. # y_left = flip(y_right, 0) TODO remove if useless
  130. y_left = K.reverse(y_right, 0)
  131. y = K.concatenate([y_left, K.variable(K.ones(1)), y_right])
  132. return y
guykilcj

guykilcj1#

在Sinc层的原始源代码中,有几行代码使其与tensorflow 2.0及以后的版本不兼容,但是,您发布的代码看起来像是与tf 2.2一起使用的更新。我尝试了这个新版本与tf 2.0和没有工作。
我修改了autors发布的以前版本的代码,并在tf 2.0中运行良好,出于某种原因,行:
window = K.cast(window, "float32")window = K.variable(window)
在编译网络时产生了一些问题,所以我只是注解了window = K.variable(window)行,工作正常。我在下面贴出了在tf2.0中对我有用的代码。

  1. class SincConv1D(Layer):
  2. def __init__(self, N_filt, Filt_dim, fs, **kwargs):
  3. self.N_filt=N_filt
  4. self.Filt_dim=Filt_dim
  5. self.fs=fs
  6. super(SincConv1D, self).__init__()
  7. def build(self, input_shape):
  8. # The filters are trainable parameters.
  9. self.filt_b1 = self.add_weight(
  10. name='filt_b1',
  11. shape=(self.N_filt,),
  12. initializer='uniform',
  13. trainable=True)
  14. self.filt_band = self.add_weight(
  15. name='filt_band',
  16. shape=(self.N_filt,),
  17. initializer='uniform',
  18. trainable=True)
  19. # Mel Initialization of the filterbanks
  20. low_freq_mel = 80
  21. high_freq_mel = (2595 * np.log10(1 + (self.fs / 2) / 700)) # Convert Hz to Mel
  22. mel_points = np.linspace(low_freq_mel, high_freq_mel, self.N_filt) # Equally spaced in Mel scale
  23. f_cos = (700 * (10**(mel_points / 2595) - 1)) # Convert Mel to Hz
  24. b1 = np.roll(f_cos, 1)
  25. b2 = np.roll(f_cos, -1)
  26. b1[0] = 30
  27. b2[-1] = (self.fs / 2) - 100
  28. self.freq_scale=self.fs * 1.0
  29. self.set_weights([b1/self.freq_scale, (b2-b1)/self.freq_scale])
  30. super(SincConv1D, self).build(input_shape) # Be sure to call this at the end
  31. def call(self, x):
  32. # print(x.shape)
  33. # debug_print("call")
  34. #filters = K.zeros(shape=(N_filt, Filt_dim))
  35. # Get beginning and end frequencies of the filters.
  36. min_freq = 50.0
  37. min_band = 50.0
  38. filt_beg_freq = K.abs(self.filt_b1) + min_freq / self.freq_scale
  39. filt_end_freq = filt_beg_freq + (K.abs(self.filt_band) + min_band / self.freq_scale)
  40. # Filter window (hamming).
  41. n = np.linspace(0, self.Filt_dim, self.Filt_dim)
  42. window = 0.54 - 0.46 * K.cos(2 * math.pi * n / self.Filt_dim)
  43. window = K.cast(window, "float32")
  44. # window = K.variable(window)
  45. # debug_print(" window", window)
  46. # TODO what is this?
  47. t_right_linspace = np.linspace(1, (self.Filt_dim - 1) / 2, int((self.Filt_dim -1) / 2))
  48. t_right = K.variable(t_right_linspace / self.fs)
  49. # debug_print(" t_right", t_right)
  50. # Compute the filters.
  51. output_list = []
  52. for i in range(self.N_filt):
  53. low_pass1 = 2 * filt_beg_freq[i] * sinc(filt_beg_freq[i] * self.freq_scale, t_right)
  54. low_pass2 = 2 * filt_end_freq[i] * sinc(filt_end_freq[i] * self.freq_scale, t_right)
  55. band_pass= (low_pass2 - low_pass1)
  56. band_pass = band_pass / K.max(band_pass)
  57. output_list.append(band_pass * window)
  58. filters = K.stack(output_list) #(80, 251)
  59. filters = K.transpose(filters) #(251, 80)
  60. filters = K.reshape(filters, (self.Filt_dim, 1,self.N_filt)) #(251,1,80) in TF: (filter_width, in_channels, out_channels) in PyTorch (out_channels, in_channels, filter_width)
  61. '''
  62. Given an input tensor of shape [batch, in_width, in_channels] if data_format is "NWC",
  63. or [batch, in_channels, in_width] if data_format is "NCW", and a filter / kernel tensor of shape [filter_width, in_channels, out_channels],
  64. this op reshapes the arguments to pass them to conv2d to perform the equivalent convolution operation.
  65. Internally, this op reshapes the input tensors and invokes tf.nn.conv2d. For example, if data_format does not start with "NC",
  66. a tensor of shape [batch, in_width, in_channels] is reshaped to [batch, 1, in_width, in_channels], and the filter is reshaped to
  67. [1, filter_width, in_channels, out_channels]. The result is then reshaped back to [batch, out_width, out_channels]
  68. (where out_width is a function of the stride and padding as in conv2d) and returned to the caller.
  69. '''
  70. # Do the convolution.
  71. # debug_print("call")
  72. # print(" x", x)
  73. # print(" filters", filters)
  74. out = K.conv1d(x, kernel=filters)
  75. # print('e')
  76. return out

我不知道为什么这些行会引起冲突,但我希望这段代码对您有用。

展开查看全部
eit6fx6z

eit6fx6z2#

也许你的导入像from keras.layers import Layerfrom tensorflow.keras.layers import Layer,你可以尝试像这样改变from tensorflow.python.keras.engine.base_layer import Layer

相关问题