如何解决 Resnet 模型中关于输出张量的值错误?
How to solve value error regarding output tensors in Resnet model?
正在尝试使用 https://github.com/jzuern/cifar-classifier 中的代码在 Google Colab 上实施 ResNet-CIFAR 10 模型。
我没有使用 ReLU 激活,而是使用我自己的自定义激活函数。这是代码:
def fonlaaf(x):
return x/(1-tf.exp(-x))
def resnet_layer(inputs,
num_filters=16,
kernel_size=3,
strides=1, activation='fonlaaf',
batch_normalization=True,
conv_first=True):
"""2D Convolution-Batch Normalization-Activation stack builder
# Arguments
inputs (tensor): input tensor from input image or previous layer
num_filters (int): Conv2D number of filters
kernel_size (int): Conv2D square kernel dimensions
strides (int): Conv2D square stride dimensions
activation (string): activation name
batch_normalization (bool): whether to include batch normalization
conv_first (bool): conv-bn-activation (True) or
bn-activation-conv (False)
# Returns
x (tensor): tensor as input to the next layer
"""
conv = Conv2D(num_filters,
kernel_size=kernel_size,
strides=strides,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=tf.keras.regularizers.l2(1e-4))
x = inputs
if conv_first:
x = conv(x)
if batch_normalization:
x = BatchNormalization()(x)
if activation is not None:
x = fonlaaf(x)
else:
if batch_normalization:
x = BatchNormalization()(x)
if activation is not None:
x = fonlaaf(x)
x = conv(x)
return x
def resnet_v2(input_shape, depth=20, num_classes=10):
"""ResNet Version 2 Model builder [b]
Stacks of (1 x 1)-(3 x 3)-(1 x 1) BN-ReLU-Conv2D or also known as
bottleneck layer
First shortcut connection per layer is 1 x 1 Conv2D.
Second and onwards shortcut connection is identity.
At the beginning of each stage, the feature map size is halved (downsampled)
by a convolutional layer with strides=2, while the number of filter maps is
doubled. Within each stage, the layers have the same number filters and the
same filter map sizes.
Features maps sizes:
conv1 : 32x32, 16
stage 0: 32x32, 64
stage 1: 16x16, 128
stage 2: 8x8, 256
# Arguments
input_shape (tensor): shape of input image tensor
depth (int): number of core convolutional layers
num_classes (int): number of classes (CIFAR10 has 10)
# Returns
model (Model): Keras model instance
"""
if (depth - 2) % 9 != 0:
raise ValueError('depth should be 9n+2 (eg 56 or 110 in [b])')
# Start model definition.
num_filters_in = 16
num_res_blocks = int((depth - 2) / 9)
inputs = Input(shape=input_shape)
# v2 performs Conv2D with BN-ReLU on input before splitting into 2 paths
x = resnet_layer(inputs=inputs,
num_filters=num_filters_in,
conv_first=True)
# Instantiate the stack of residual units
for stage in range(3):
for res_block in range(num_res_blocks):
activation = 'relu'
batch_normalization = True
strides = 1
if stage == 0:
num_filters_out = num_filters_in * 4
if res_block == 0: # first layer and first stage
activation = None
batch_normalization = False
else:
num_filters_out = num_filters_in * 2
if res_block == 0: # first layer but not first stage
strides = 2 # downsample
# bottleneck residual unit
y = resnet_layer(inputs=x,
num_filters=num_filters_in,
kernel_size=1,
strides=strides,
activation=activation,
batch_normalization=batch_normalization,
conv_first=False)
y = resnet_layer(inputs=y,
num_filters=num_filters_in,
conv_first=False)
y = resnet_layer(inputs=y,
num_filters=num_filters_out,
kernel_size=1,
conv_first=False)
if res_block == 0:
# linear projection residual shortcut connection to match
# changed dims
x = resnet_layer(inputs=x,
num_filters=num_filters_out,
kernel_size=1,
strides=strides,
activation=None,
batch_normalization=False)
x = tf.keras.layers.add([x, y])
num_filters_in = num_filters_out
# Add classifier on top.
# v2 has BN-ReLU before Pooling
x = BatchNormalization()(x)
x = fonlaaf(x)
x = AveragePooling2D(pool_size=8)(x)
y = Flatten()(x)
outputs = Dense(num_classes,
activation='softmax',
kernel_initializer='he_normal')(y)
# Instantiate model.
model = Model(inputs=inputs, outputs=outputs)
model.compile(loss='sparse_categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(lr=hparams.learning_rate),
metrics=['accuracy'])
return model
tf.logging.set_verbosity(tf.logging.DEBUG)
resnet_model = resnet_v2((32, 32, 3), depth=56, num_classes=hparams.n_classes)
# Download and extract CIFAR-10 data
maybe_download_and_extract()
# training data
x_train, y_train = load_training_data()
# Validation data
x_val, y_val = load_validation_data()
# Testing data
x_test, y_test = load_testing_data()
# Define callbacks
callbacks = [
tf.keras.callbacks.TensorBoard(log_dir=hparams.checkpoint_dir)
]
# This will do preprocessing and realtime data augmentation:
datagen = ImageDataGenerator(
featurewise_center=False, # set input mean to 0 over the dataset
samplewise_center=False, # set each sample mean to 0
featurewise_std_normalization=False, # divide inputs by std of the dataset
samplewise_std_normalization=False, # divide each input by its std
zca_whitening=False, # apply ZCA whitening
zca_epsilon=1e-06, # epsilon for ZCA whitening
rotation_range=0, # randomly rotate images in the range (degrees, 0 to 180)
# randomly shift images horizontally (fraction of total width)
width_shift_range=0.1,
# randomly shift images vertically (fraction of total height)
height_shift_range=0.1,
# set mode for filling points outside the input boundaries
fill_mode='nearest',
cval=0., # value used for fill_mode = "constant"
horizontal_flip=True, # randomly flip images
vertical_flip=False)
# Compute quantities required for feature-wise normalization
# (std, mean, and principal components if ZCA whitening is applied).
datagen.fit(x_train)
# Fit the model on the batches generated by datagen.flow().
resnet_model.fit_generator(
datagen.flow(x_train, y_train,batch_size=hparams.train_batch_size),
epochs=hparams.n_epochs,
validation_data=(x_val, y_val),
workers=4,
callbacks=callbacks)
出现以下错误:ValueError:模型的输出张量必须是 TensorFlow Layer
的输出(因此保留过去的层元数据)。发现:Tensor("dense/Softmax:0", shape=(?, 10), dtype=float32)
之前针对此错误的大部分答案都没有奏效。我在这里错过了什么?
如错误所述,您必须传递图层的输出。由于 fonlaaf() 是一个没有状态的激活函数,您可以使用 Lambda 层。
替换,
def fonlaaf(x):
return x/(1-tf.exp(-x))
和
def fonlaaf(x):
return tf.keras.layers.Lambda(lambda x: x/(1-tf.exp(-x)))(x)
https://www.tensorflow.org/guide/keras/#custom_layers
https://www.tensorflow.org/api_docs/python/tf/keras/layers/Lambda
正在尝试使用 https://github.com/jzuern/cifar-classifier 中的代码在 Google Colab 上实施 ResNet-CIFAR 10 模型。 我没有使用 ReLU 激活,而是使用我自己的自定义激活函数。这是代码:
def fonlaaf(x):
return x/(1-tf.exp(-x))
def resnet_layer(inputs,
num_filters=16,
kernel_size=3,
strides=1, activation='fonlaaf',
batch_normalization=True,
conv_first=True):
"""2D Convolution-Batch Normalization-Activation stack builder
# Arguments
inputs (tensor): input tensor from input image or previous layer
num_filters (int): Conv2D number of filters
kernel_size (int): Conv2D square kernel dimensions
strides (int): Conv2D square stride dimensions
activation (string): activation name
batch_normalization (bool): whether to include batch normalization
conv_first (bool): conv-bn-activation (True) or
bn-activation-conv (False)
# Returns
x (tensor): tensor as input to the next layer
"""
conv = Conv2D(num_filters,
kernel_size=kernel_size,
strides=strides,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=tf.keras.regularizers.l2(1e-4))
x = inputs
if conv_first:
x = conv(x)
if batch_normalization:
x = BatchNormalization()(x)
if activation is not None:
x = fonlaaf(x)
else:
if batch_normalization:
x = BatchNormalization()(x)
if activation is not None:
x = fonlaaf(x)
x = conv(x)
return x
def resnet_v2(input_shape, depth=20, num_classes=10):
"""ResNet Version 2 Model builder [b]
Stacks of (1 x 1)-(3 x 3)-(1 x 1) BN-ReLU-Conv2D or also known as
bottleneck layer
First shortcut connection per layer is 1 x 1 Conv2D.
Second and onwards shortcut connection is identity.
At the beginning of each stage, the feature map size is halved (downsampled)
by a convolutional layer with strides=2, while the number of filter maps is
doubled. Within each stage, the layers have the same number filters and the
same filter map sizes.
Features maps sizes:
conv1 : 32x32, 16
stage 0: 32x32, 64
stage 1: 16x16, 128
stage 2: 8x8, 256
# Arguments
input_shape (tensor): shape of input image tensor
depth (int): number of core convolutional layers
num_classes (int): number of classes (CIFAR10 has 10)
# Returns
model (Model): Keras model instance
"""
if (depth - 2) % 9 != 0:
raise ValueError('depth should be 9n+2 (eg 56 or 110 in [b])')
# Start model definition.
num_filters_in = 16
num_res_blocks = int((depth - 2) / 9)
inputs = Input(shape=input_shape)
# v2 performs Conv2D with BN-ReLU on input before splitting into 2 paths
x = resnet_layer(inputs=inputs,
num_filters=num_filters_in,
conv_first=True)
# Instantiate the stack of residual units
for stage in range(3):
for res_block in range(num_res_blocks):
activation = 'relu'
batch_normalization = True
strides = 1
if stage == 0:
num_filters_out = num_filters_in * 4
if res_block == 0: # first layer and first stage
activation = None
batch_normalization = False
else:
num_filters_out = num_filters_in * 2
if res_block == 0: # first layer but not first stage
strides = 2 # downsample
# bottleneck residual unit
y = resnet_layer(inputs=x,
num_filters=num_filters_in,
kernel_size=1,
strides=strides,
activation=activation,
batch_normalization=batch_normalization,
conv_first=False)
y = resnet_layer(inputs=y,
num_filters=num_filters_in,
conv_first=False)
y = resnet_layer(inputs=y,
num_filters=num_filters_out,
kernel_size=1,
conv_first=False)
if res_block == 0:
# linear projection residual shortcut connection to match
# changed dims
x = resnet_layer(inputs=x,
num_filters=num_filters_out,
kernel_size=1,
strides=strides,
activation=None,
batch_normalization=False)
x = tf.keras.layers.add([x, y])
num_filters_in = num_filters_out
# Add classifier on top.
# v2 has BN-ReLU before Pooling
x = BatchNormalization()(x)
x = fonlaaf(x)
x = AveragePooling2D(pool_size=8)(x)
y = Flatten()(x)
outputs = Dense(num_classes,
activation='softmax',
kernel_initializer='he_normal')(y)
# Instantiate model.
model = Model(inputs=inputs, outputs=outputs)
model.compile(loss='sparse_categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(lr=hparams.learning_rate),
metrics=['accuracy'])
return model
tf.logging.set_verbosity(tf.logging.DEBUG)
resnet_model = resnet_v2((32, 32, 3), depth=56, num_classes=hparams.n_classes)
# Download and extract CIFAR-10 data
maybe_download_and_extract()
# training data
x_train, y_train = load_training_data()
# Validation data
x_val, y_val = load_validation_data()
# Testing data
x_test, y_test = load_testing_data()
# Define callbacks
callbacks = [
tf.keras.callbacks.TensorBoard(log_dir=hparams.checkpoint_dir)
]
# This will do preprocessing and realtime data augmentation:
datagen = ImageDataGenerator(
featurewise_center=False, # set input mean to 0 over the dataset
samplewise_center=False, # set each sample mean to 0
featurewise_std_normalization=False, # divide inputs by std of the dataset
samplewise_std_normalization=False, # divide each input by its std
zca_whitening=False, # apply ZCA whitening
zca_epsilon=1e-06, # epsilon for ZCA whitening
rotation_range=0, # randomly rotate images in the range (degrees, 0 to 180)
# randomly shift images horizontally (fraction of total width)
width_shift_range=0.1,
# randomly shift images vertically (fraction of total height)
height_shift_range=0.1,
# set mode for filling points outside the input boundaries
fill_mode='nearest',
cval=0., # value used for fill_mode = "constant"
horizontal_flip=True, # randomly flip images
vertical_flip=False)
# Compute quantities required for feature-wise normalization
# (std, mean, and principal components if ZCA whitening is applied).
datagen.fit(x_train)
# Fit the model on the batches generated by datagen.flow().
resnet_model.fit_generator(
datagen.flow(x_train, y_train,batch_size=hparams.train_batch_size),
epochs=hparams.n_epochs,
validation_data=(x_val, y_val),
workers=4,
callbacks=callbacks)
出现以下错误:ValueError:模型的输出张量必须是 TensorFlow Layer
的输出(因此保留过去的层元数据)。发现:Tensor("dense/Softmax:0", shape=(?, 10), dtype=float32)
之前针对此错误的大部分答案都没有奏效。我在这里错过了什么?
如错误所述,您必须传递图层的输出。由于 fonlaaf() 是一个没有状态的激活函数,您可以使用 Lambda 层。
替换,
def fonlaaf(x):
return x/(1-tf.exp(-x))
和
def fonlaaf(x):
return tf.keras.layers.Lambda(lambda x: x/(1-tf.exp(-x)))(x)
https://www.tensorflow.org/guide/keras/#custom_layers https://www.tensorflow.org/api_docs/python/tf/keras/layers/Lambda