将 Keras-Fuctional-API 转换为 Keras 子类模型
Convert Keras-Fuctional-API into a Keras Subclassed Model
我对 Keras 和 Tensorflow 比较陌生,我想学习基本的实现。为此,我想构建一个可以 learn/detect/predict 手写数字的模型,因此我使用了 Keras 的 MNIST 数据集。我已经使用 Keras Functional API 创建了这个模型,一切正常。现在我想做同样的事情,但这次我想构建一个 Keras 子类模型。问题是,当我使用 Keras 子类模型执行代码时出现错误。
这是具有功能 API 的模型代码(可以正常工作,没有任何问题):
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from keras.datasets import mnist
import numpy as np
#Load MNIST-Dataset
(x_train_full, y_train_full), (x_test, y_test) = mnist.load_data()
#Create train- and validationdata
X_valid = x_train_full[:5000]/255.0
X_train = x_train_full[5000:] / 255.0
y_valid, y_train = y_train_full[:5000], y_train_full[5000:]
#Create the model with the keras functional-API
inputs = keras.layers.Input(shape=(28, 28))
flatten = keras.layers.Flatten(input_shape=(28, 28))(inputs)
hidden1 = keras.layers.Dense(256, activation="relu")(flatten)
hidden2 = keras.layers.Dense(128, activation='relu')(hidden1)
outputs = keras.layers.Dense(10, activation='softmax')(hidden2)
model = keras.Model(inputs=[inputs], outputs=[outputs])
model.compile(loss="sparse_categorical_crossentropy", optimizer="sgd", metrics=["accuracy"])
h = model.fit(X_train, y_train, epochs=5, validation_data=(X_valid, y_valid))
#Evaluate the model with testdata
test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)
print('\nTest accuracy: ', test_acc)
print('\nTest loss: ', test_loss)
#Create Predictions:
myPrediction = model.predict(x_test)
#Prediction example of one testpicture
print(myPrediction[0])
print('Predicted Item: ', np.argmax(myPrediction[0]))
print('Actual Item: ', y_test[0])
这里是 Keras 子类模型的(不工作)代码,它应该做与上面的代码完全相同的事情:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from keras.datasets import mnist
import numpy as np
#Load MNIST-Dataset
(x_train_full, y_train_full), (x_test, y_test) = mnist.load_data()
#Create train- and validationdata
X_valid = x_train_full[:5000]/255.0
X_train = x_train_full[5000:] / 255.0
y_valid, y_train = y_train_full[:5000], y_train_full[5000:]
#Create a keras-subclassing-model:
class MyModel(tf.keras.Model):
def __init__(self):
super(MyModel, self).__init__()
#Define layers
self.input_ = keras.layers.Input(shape=(28, 28))
self.flatten = keras.layers.Flatten(input_shape=(28, 28))
self.dense_1 = keras.layers.Dense(256, activation="relu")
self.dense_2 = keras.layers.Dense(128, activation="relu")
self.output_ = keras.layers.Dense(10, activation="softmax")
def call(self, inputs):
x = self.input_(inputs)
x = self.flatten(x)
x = self.dense_1(x)
x = self.dense_2(x)
x = self.output_(x)
return x
model = MyModel()
model.compile(loss="sparse_categorical_crossentropy", optimizer="sgd", metrics=["accuracy"])
h = model.fit(X_train, y_train, epochs=10, validation_data=(X_valid, y_valid))
每次我 运行 这段代码时都会遇到同样的错误。调用fit(...)
-方法时出现的错误:
Traceback (most recent call last):
File "c:/Users/MichaelM/Documents/PythonSkripte/MachineLearning/SubclassedModel.py", line 39, in <module>
h = model.fit(X_train, y_train, epochs=10, validation_data=(X_valid, y_valid))
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 819, in fit
use_multiprocessing=use_multiprocessing)
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\training_v2.py", line 235, in fit
use_multiprocessing=use_multiprocessing)
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\training_v2.py", line 593, in _process_training_inputs
use_multiprocessing=use_multiprocessing)
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\training_v2.py", line 646, in _process_inputs
x, y, sample_weight=sample_weights)
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 2346, in _standardize_user_data
all_inputs, y_input, dict_inputs = self._build_model_with_inputs(x, y)
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 2572, in _build_model_with_inputs
self._set_inputs(cast_inputs)
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 2659, in _set_inputs
outputs = self(inputs, **kwargs)
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\base_layer.py", line 773, in __call__
outputs = call_fn(cast_inputs, *args, **kwargs)
File "C:\Python37\lib\site-packages\tensorflow_core\python\autograph\impl\api.py", line 237, in wrapper
raise e.ag_error_metadata.to_exception(e)
TypeError: in converted code:
c:/Users/MichaelM/Documents/PythonSkripte/MachineLearning/SubclassedModel.py:28 call *
x = self.input_(inputs)
C:\Python37\lib\site-packages\tensorflow_core\python\autograph\impl\api.py:447 converted_call
f in m.__dict__.values() for m in (collections, pdb, copy, inspect, re)):
C:\Python37\lib\site-packages\tensorflow_core\python\autograph\impl\api.py:447 <genexpr>
f in m.__dict__.values() for m in (collections, pdb, copy, inspect, re)):
C:\Python37\lib\site-packages\tensorflow_core\python\ops\math_ops.py:1351 tensor_equals
return gen_math_ops.equal(self, other, incompatible_shape_error=False)
C:\Python37\lib\site-packages\tensorflow_core\python\ops\gen_math_ops.py:3240 equal
name=name)
C:\Python37\lib\site-packages\tensorflow_core\python\framework\op_def_library.py:477 _apply_op_helper
repr(values), type(values).__name__, err))
TypeError: Expected float32 passed to parameter 'y' of op 'Equal', got 'collections' of type 'str' instead. Error: Expected float32, got 'collections' of type 'str' instead.
能否请您帮我解决这个问题,也许可以解释为什么这不起作用,因为我不知道这个错误的实际含义。然后我可以像在函数 API 代码中那样调用 evaluate(...)
和 predict(...)
方法吗?我使用以下配置:
- Visual Studio 代码 Python-扩展名为 IDE
- Python-版本:3.7.6
- TensorFlow-版本:2.1.0
- Keras-版本:2.2.4-tf
实际上,您不需要在调用方法中实现Input,因为您直接将数据传递给子类。我更新了代码,它按预期运行良好。请检查下面。
#Create a keras-subclassing-model:
class MyModel(tf.keras.Model):
def __init__(self):
super(MyModel, self).__init__()
#Define layers
#self.input_ = keras.layers.Input(shape=(28, 28))
self.flatten = keras.layers.Flatten(input_shape=(28, 28))
self.dense_1 = keras.layers.Dense(256, activation="relu")
self.dense_2 = keras.layers.Dense(128, activation="relu")
self.output_ = keras.layers.Dense(10, activation="softmax")
def call(self, inputs):
#x = self.input_(inputs)
x = self.flatten(inputs)
x = self.dense_1(x)
x = self.dense_2(x)
x = self.output_(x)
return x
model = MyModel()
model.compile(loss="sparse_categorical_crossentropy", optimizer="sgd", metrics=["accuracy"])
h = model.fit(X_train, y_train, epochs=10, validation_data=(X_valid, y_valid))
输出如下
Epoch 1/10
1719/1719 [==============================] - 6s 3ms/step - loss: 0.6251 - accuracy: 0.8327 - val_loss: 0.3068 - val_accuracy: 0.9180
....
....
Epoch 10/10
1719/1719 [==============================] - 6s 3ms/step - loss: 0.1097 - accuracy: 0.9687 - val_loss: 0.1215 - val_accuracy: 0.9648
完整代码为 here.
我对 Keras 和 Tensorflow 比较陌生,我想学习基本的实现。为此,我想构建一个可以 learn/detect/predict 手写数字的模型,因此我使用了 Keras 的 MNIST 数据集。我已经使用 Keras Functional API 创建了这个模型,一切正常。现在我想做同样的事情,但这次我想构建一个 Keras 子类模型。问题是,当我使用 Keras 子类模型执行代码时出现错误。 这是具有功能 API 的模型代码(可以正常工作,没有任何问题):
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from keras.datasets import mnist
import numpy as np
#Load MNIST-Dataset
(x_train_full, y_train_full), (x_test, y_test) = mnist.load_data()
#Create train- and validationdata
X_valid = x_train_full[:5000]/255.0
X_train = x_train_full[5000:] / 255.0
y_valid, y_train = y_train_full[:5000], y_train_full[5000:]
#Create the model with the keras functional-API
inputs = keras.layers.Input(shape=(28, 28))
flatten = keras.layers.Flatten(input_shape=(28, 28))(inputs)
hidden1 = keras.layers.Dense(256, activation="relu")(flatten)
hidden2 = keras.layers.Dense(128, activation='relu')(hidden1)
outputs = keras.layers.Dense(10, activation='softmax')(hidden2)
model = keras.Model(inputs=[inputs], outputs=[outputs])
model.compile(loss="sparse_categorical_crossentropy", optimizer="sgd", metrics=["accuracy"])
h = model.fit(X_train, y_train, epochs=5, validation_data=(X_valid, y_valid))
#Evaluate the model with testdata
test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)
print('\nTest accuracy: ', test_acc)
print('\nTest loss: ', test_loss)
#Create Predictions:
myPrediction = model.predict(x_test)
#Prediction example of one testpicture
print(myPrediction[0])
print('Predicted Item: ', np.argmax(myPrediction[0]))
print('Actual Item: ', y_test[0])
这里是 Keras 子类模型的(不工作)代码,它应该做与上面的代码完全相同的事情:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from keras.datasets import mnist
import numpy as np
#Load MNIST-Dataset
(x_train_full, y_train_full), (x_test, y_test) = mnist.load_data()
#Create train- and validationdata
X_valid = x_train_full[:5000]/255.0
X_train = x_train_full[5000:] / 255.0
y_valid, y_train = y_train_full[:5000], y_train_full[5000:]
#Create a keras-subclassing-model:
class MyModel(tf.keras.Model):
def __init__(self):
super(MyModel, self).__init__()
#Define layers
self.input_ = keras.layers.Input(shape=(28, 28))
self.flatten = keras.layers.Flatten(input_shape=(28, 28))
self.dense_1 = keras.layers.Dense(256, activation="relu")
self.dense_2 = keras.layers.Dense(128, activation="relu")
self.output_ = keras.layers.Dense(10, activation="softmax")
def call(self, inputs):
x = self.input_(inputs)
x = self.flatten(x)
x = self.dense_1(x)
x = self.dense_2(x)
x = self.output_(x)
return x
model = MyModel()
model.compile(loss="sparse_categorical_crossentropy", optimizer="sgd", metrics=["accuracy"])
h = model.fit(X_train, y_train, epochs=10, validation_data=(X_valid, y_valid))
每次我 运行 这段代码时都会遇到同样的错误。调用fit(...)
-方法时出现的错误:
Traceback (most recent call last):
File "c:/Users/MichaelM/Documents/PythonSkripte/MachineLearning/SubclassedModel.py", line 39, in <module>
h = model.fit(X_train, y_train, epochs=10, validation_data=(X_valid, y_valid))
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 819, in fit
use_multiprocessing=use_multiprocessing)
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\training_v2.py", line 235, in fit
use_multiprocessing=use_multiprocessing)
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\training_v2.py", line 593, in _process_training_inputs
use_multiprocessing=use_multiprocessing)
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\training_v2.py", line 646, in _process_inputs
x, y, sample_weight=sample_weights)
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 2346, in _standardize_user_data
all_inputs, y_input, dict_inputs = self._build_model_with_inputs(x, y)
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 2572, in _build_model_with_inputs
self._set_inputs(cast_inputs)
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 2659, in _set_inputs
outputs = self(inputs, **kwargs)
File "C:\Python37\lib\site-packages\tensorflow_core\python\keras\engine\base_layer.py", line 773, in __call__
outputs = call_fn(cast_inputs, *args, **kwargs)
File "C:\Python37\lib\site-packages\tensorflow_core\python\autograph\impl\api.py", line 237, in wrapper
raise e.ag_error_metadata.to_exception(e)
TypeError: in converted code:
c:/Users/MichaelM/Documents/PythonSkripte/MachineLearning/SubclassedModel.py:28 call *
x = self.input_(inputs)
C:\Python37\lib\site-packages\tensorflow_core\python\autograph\impl\api.py:447 converted_call
f in m.__dict__.values() for m in (collections, pdb, copy, inspect, re)):
C:\Python37\lib\site-packages\tensorflow_core\python\autograph\impl\api.py:447 <genexpr>
f in m.__dict__.values() for m in (collections, pdb, copy, inspect, re)):
C:\Python37\lib\site-packages\tensorflow_core\python\ops\math_ops.py:1351 tensor_equals
return gen_math_ops.equal(self, other, incompatible_shape_error=False)
C:\Python37\lib\site-packages\tensorflow_core\python\ops\gen_math_ops.py:3240 equal
name=name)
C:\Python37\lib\site-packages\tensorflow_core\python\framework\op_def_library.py:477 _apply_op_helper
repr(values), type(values).__name__, err))
TypeError: Expected float32 passed to parameter 'y' of op 'Equal', got 'collections' of type 'str' instead. Error: Expected float32, got 'collections' of type 'str' instead.
能否请您帮我解决这个问题,也许可以解释为什么这不起作用,因为我不知道这个错误的实际含义。然后我可以像在函数 API 代码中那样调用 evaluate(...)
和 predict(...)
方法吗?我使用以下配置:
- Visual Studio 代码 Python-扩展名为 IDE
- Python-版本:3.7.6
- TensorFlow-版本:2.1.0
- Keras-版本:2.2.4-tf
实际上,您不需要在调用方法中实现Input,因为您直接将数据传递给子类。我更新了代码,它按预期运行良好。请检查下面。
#Create a keras-subclassing-model:
class MyModel(tf.keras.Model):
def __init__(self):
super(MyModel, self).__init__()
#Define layers
#self.input_ = keras.layers.Input(shape=(28, 28))
self.flatten = keras.layers.Flatten(input_shape=(28, 28))
self.dense_1 = keras.layers.Dense(256, activation="relu")
self.dense_2 = keras.layers.Dense(128, activation="relu")
self.output_ = keras.layers.Dense(10, activation="softmax")
def call(self, inputs):
#x = self.input_(inputs)
x = self.flatten(inputs)
x = self.dense_1(x)
x = self.dense_2(x)
x = self.output_(x)
return x
model = MyModel()
model.compile(loss="sparse_categorical_crossentropy", optimizer="sgd", metrics=["accuracy"])
h = model.fit(X_train, y_train, epochs=10, validation_data=(X_valid, y_valid))
输出如下
Epoch 1/10
1719/1719 [==============================] - 6s 3ms/step - loss: 0.6251 - accuracy: 0.8327 - val_loss: 0.3068 - val_accuracy: 0.9180
....
....
Epoch 10/10
1719/1719 [==============================] - 6s 3ms/step - loss: 0.1097 - accuracy: 0.9687 - val_loss: 0.1215 - val_accuracy: 0.9648
完整代码为 here.