keras自定义层加载数据
keras custom layer to load data
我正在按照 this 教程使用自定义图层进行预处理。
def pre_process(file_path):
# loading file from disk and transforming into [90,13,1]
class PreProcessBlock(layers.Layer):
def __init__(self):
super(PreProcessBlock,self).__init__()
def call(self, inputs):
return pre_process(inputs.numpy())
def compute_output_shape(self, input_shape):
return input_shape
preprocess = tf.keras.Sequential([
PreProcessBlock()
])
model = keras.Sequential(
[
preprocess,
layers.Dense(256, activation = "relu"),
layers.Dropout(.5),
layers.Dense(len(LABELS))]
我将我的数据集创建为
files = ['file1,'file2`]
labels = [0,1]
def get_data_set(files, labels, is_training=False):
dataset = tf.data.Dataset.from_tensor_slices((files, labels))
if is_training:
dataset = dataset.shuffle(SHUFFLE_BUFFER_SIZE, reshuffle_each_iteration = True)
dataset = dataset.batch(BATCH_SIZE)
dataset = dataset.prefetch(AUTOTUNE)
return dataset
train_dataset = get_data_set(files, labels, is_training=True)
val_dataset = get_data_set(files, labels)
模型拟合失败并出现错误
model.fit(train_dataset, epochs=1, verbose=1,validation_data=val_dataset)
错误
AttributeError: in user code:
/opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py:806 train_function *
return step_function(self, iterator)
<ipython-input-158-3f6d9dd39f2f>:6 call *
return pre_process(inputs.numpy())
AttributeError: 'Tensor' object has no attribute 'numpy'
我的问题
这是实现模型管道的有效方式吗?
层的结构以及将所有预处理层组织到一个顺序层中非常棒。您不应该分层加载任何学习示例(它不是模型的一部分,并且会降低可移植性)。
两个问题:
您没有 numpy()
方法,因为 。我建议坚持使用静态图,不要尝试将 keras 图中的任何内容转换为 numpy,除非绝对必要——性能问题。大多数张量运算都可以使用 tf
.
完成
您的自定义预处理层应继承自 tensorflow.keras.layers.experimental.preprocessing.PreprocessingLayer
(来自 tf.keras.layers.experimental.preprocessing
的所有层直接或通过 CombinerPreprocessingLayer
从同一包继承)。 PreprocessingLayer
class 的源代码中没有太多内容,但所有内容都很重要:
PreprocessingLayer
为 adapt
方法提供接口:
adapt(self, data, reset_state=True)
。请参阅“纯”keras docs 为什么以及何时需要它。
PreprocessingLayer
class 有标志 _must_restore_from_config = True
我们从 Layer
文档中读到:
When loading from a SavedModel, Layers typically can be revived into a
generic Layer wrapper. Sometimes, however, layers may implement
methods that go beyond this wrapper, as in the case of
PreprocessingLayers' adapt
method. When this is the case, layer
implementers can override must_restore_from_config to return
True; layers with this property must be restored into their actual
objects (and will fail if the object is not available to the
restoration code).
让我们以Resizing
层代码为例(为了便于阅读,省略了注释):
class Resizing(PreprocessingLayer):
def __init__(self,
height,
width,
interpolation='bilinear',
name=None,
**kwargs):
self.target_height = height
self.target_width = width
self.interpolation = interpolation
self._interpolation_method = get_interpolation(interpolation)
self.input_spec = InputSpec(ndim=4)
super(Resizing, self).__init__(name=name, **kwargs)
base_preprocessing_layer._kpl_gauge.get_cell('V2').set('Resizing')
def call(self, inputs):
outputs = image_ops.resize_images_v2(
images=inputs,
size=[self.target_height, self.target_width],
method=self._interpolation_method)
return outputs
def compute_output_shape(self, input_shape):
input_shape = tensor_shape.TensorShape(input_shape).as_list()
return tensor_shape.TensorShape(
[input_shape[0], self.target_height, self.target_width, input_shape[3]])
def get_config(self):
config = {
'height': self.target_height,
'width': self.target_width,
'interpolation': self.interpolation,
}
base_config = super(Resizing, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
这是一个非常通用的图层。它可以将图像调整到一定的宽度和高度。然而,预处理层的要点是将整个端到端管道保存在一个模型中。因此,在 你的 管道中,你将具有特定的宽度和高度,并且你不想在进行推理时使用适当的参数实例化层而烦恼 - 它应该与训练中的相同(适用任何预处理方法,真的)。所以在 get_config()
方法中,除了基本的配置外,高度和宽度都被保存了,以后在重新建模时可以很容易地读取。请注意,该层不会覆盖 adapt
方法,因为它对数据是不变的。
我正在按照 this 教程使用自定义图层进行预处理。
def pre_process(file_path):
# loading file from disk and transforming into [90,13,1]
class PreProcessBlock(layers.Layer):
def __init__(self):
super(PreProcessBlock,self).__init__()
def call(self, inputs):
return pre_process(inputs.numpy())
def compute_output_shape(self, input_shape):
return input_shape
preprocess = tf.keras.Sequential([
PreProcessBlock()
])
model = keras.Sequential(
[
preprocess,
layers.Dense(256, activation = "relu"),
layers.Dropout(.5),
layers.Dense(len(LABELS))]
我将我的数据集创建为
files = ['file1,'file2`]
labels = [0,1]
def get_data_set(files, labels, is_training=False):
dataset = tf.data.Dataset.from_tensor_slices((files, labels))
if is_training:
dataset = dataset.shuffle(SHUFFLE_BUFFER_SIZE, reshuffle_each_iteration = True)
dataset = dataset.batch(BATCH_SIZE)
dataset = dataset.prefetch(AUTOTUNE)
return dataset
train_dataset = get_data_set(files, labels, is_training=True)
val_dataset = get_data_set(files, labels)
模型拟合失败并出现错误
model.fit(train_dataset, epochs=1, verbose=1,validation_data=val_dataset)
错误
AttributeError: in user code:
/opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py:806 train_function *
return step_function(self, iterator)
<ipython-input-158-3f6d9dd39f2f>:6 call *
return pre_process(inputs.numpy())
AttributeError: 'Tensor' object has no attribute 'numpy'
我的问题
这是实现模型管道的有效方式吗?
层的结构以及将所有预处理层组织到一个顺序层中非常棒。您不应该分层加载任何学习示例(它不是模型的一部分,并且会降低可移植性)。
两个问题:
您没有 numpy()
方法,因为 tf
.
您的自定义预处理层应继承自 tensorflow.keras.layers.experimental.preprocessing.PreprocessingLayer
(来自 tf.keras.layers.experimental.preprocessing
的所有层直接或通过 CombinerPreprocessingLayer
从同一包继承)。 PreprocessingLayer
class 的源代码中没有太多内容,但所有内容都很重要:
PreprocessingLayer
为adapt
方法提供接口:
adapt(self, data, reset_state=True)
。请参阅“纯”keras docs 为什么以及何时需要它。PreprocessingLayer
class 有标志_must_restore_from_config = True
我们从Layer
文档中读到:
When loading from a SavedModel, Layers typically can be revived into a generic Layer wrapper. Sometimes, however, layers may implement methods that go beyond this wrapper, as in the case of PreprocessingLayers'
adapt
method. When this is the case, layer implementers can override must_restore_from_config to return True; layers with this property must be restored into their actual objects (and will fail if the object is not available to the restoration code).
让我们以Resizing
层代码为例(为了便于阅读,省略了注释):
class Resizing(PreprocessingLayer):
def __init__(self,
height,
width,
interpolation='bilinear',
name=None,
**kwargs):
self.target_height = height
self.target_width = width
self.interpolation = interpolation
self._interpolation_method = get_interpolation(interpolation)
self.input_spec = InputSpec(ndim=4)
super(Resizing, self).__init__(name=name, **kwargs)
base_preprocessing_layer._kpl_gauge.get_cell('V2').set('Resizing')
def call(self, inputs):
outputs = image_ops.resize_images_v2(
images=inputs,
size=[self.target_height, self.target_width],
method=self._interpolation_method)
return outputs
def compute_output_shape(self, input_shape):
input_shape = tensor_shape.TensorShape(input_shape).as_list()
return tensor_shape.TensorShape(
[input_shape[0], self.target_height, self.target_width, input_shape[3]])
def get_config(self):
config = {
'height': self.target_height,
'width': self.target_width,
'interpolation': self.interpolation,
}
base_config = super(Resizing, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
这是一个非常通用的图层。它可以将图像调整到一定的宽度和高度。然而,预处理层的要点是将整个端到端管道保存在一个模型中。因此,在 你的 管道中,你将具有特定的宽度和高度,并且你不想在进行推理时使用适当的参数实例化层而烦恼 - 它应该与训练中的相同(适用任何预处理方法,真的)。所以在 get_config()
方法中,除了基本的配置外,高度和宽度都被保存了,以后在重新建模时可以很容易地读取。请注意,该层不会覆盖 adapt
方法,因为它对数据是不变的。