使用Keras训练模型时遇TypeError: Protocols cannot be instantiated错误求助
解决Keras中model.fit()报TypeError: Protocols cannot be instantiated的问题
问题重现
用户实现的MNIST分类模型代码如下:
(x_train,y_train),(x_test,y_test) = mnist.load_data() x_train = x_train.reshape(60000,784) x_test = x_test.reshape(10000,784) x_train = x_train.astype('float32') x_test = x_test.astype('float32') #Normalize x_train /= 255 x_test /= 255 #convert label to one hot y_train = np_utils.to_categorical(y_train) y_test = np_utils.to_categorical(y_test) myModel = Sequential() myModel.add(Dense(500, activation='relu',input_shape=(784,))) myModel.add(Dense(100,activation='relu')) myModel.add(Dense(10,activation='softmax')) myModel.compile(optimizer=SGD(lr=0.001),loss=categorical_crossentropy,metrics=['accuracy']) network_history = myModel.fit(x_train,y_train,batch_size=128,epochs=2)
调用model.fit()时触发报错:
network_history = myModel.fit(x_train,y_train,batch_size=(128)) Traceback (most recent call last): File "C:\Users\Parisima\AppData\Local\Temp/ipykernel_13876/4252018919.py", line 1, in <module> network_history = myModel.fit(x_train,y_train,batch_size=(128)) File "C:\Users\Parisima\anaconda3\envs\tf_envs\lib\site-packages\keras\utils\traceback_utils.py", line 67, in error_handler raise e.with_traceback(filtered_tb) from None File "C:\Users\Parisima\anaconda3\envs\tf_envs\lib\typing.py", line 1083, in _no_init raise TypeError('Protocols cannot be instantiated') TypeError: Protocols cannot be instantiated
错误原因分析
这个错误核心原因是模块导入不规范或版本兼容性问题:
- 代码中未显式导入
Sequential、Dense、SGD、categorical_crossentropy、np_utils等组件,可能导致Python解析时误将这些标识符当成了typing模块中的Protocol类,从而触发实例化错误。 - 旧版本TensorFlow/Keras与Python 3.8+的typing模块存在适配问题,Protocol类被错误调用。
- 报错堆栈中出现
batch_size=(128),这是将参数写成了元组,虽然用户代码里是batch_size=128,但测试时的写法也可能触发异常。
解决步骤
添加正确的导入语句
确保所有Keras组件都从对应模块导入,建议使用TensorFlow集成的Keras(tf.keras)以避免版本冲突:import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense from tensorflow.keras.optimizers import SGD from tensorflow.keras.losses import categorical_crossentropy from tensorflow.keras.utils import to_categorical from tensorflow.keras.datasets import mnist注意:原代码中的
np_utils.to_categorical可以替换为tf.keras.utils.to_categorical,无需额外导入numpy的utils模块。修正参数写法
确保batch_size是整数类型,不要写成元组(即batch_size=128而非batch_size=(128))。版本兼容性检查
如果使用Python 3.8及以上版本,建议升级TensorFlow到2.5+版本,避免旧版本typing模块的Bug。
修正后的完整代码
import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense from tensorflow.keras.optimizers import SGD from tensorflow.keras.losses import categorical_crossentropy from tensorflow.keras.datasets import mnist # 加载数据 (x_train,y_train),(x_test,y_test) = mnist.load_data() x_train = x_train.reshape(60000,784) x_test = x_test.reshape(10000,784) # 类型转换与归一化 x_train = x_train.astype('float32') / 255.0 x_test = x_test.astype('float32') / 255.0 # 标签转为one-hot编码 y_train = tf.keras.utils.to_categorical(y_train, 10) y_test = tf.keras.utils.to_categorical(y_test, 10) # 构建模型 myModel = Sequential() myModel.add(Dense(500, activation='relu', input_shape=(784,))) myModel.add(Dense(100, activation='relu')) myModel.add(Dense(10, activation='softmax')) # 编译模型 # 注意:SGD的lr参数在新版本中建议用learning_rate myModel.compile(optimizer=SGD(learning_rate=0.001), loss=categorical_crossentropy, metrics=['accuracy']) # 训练模型 network_history = myModel.fit(x_train, y_train, batch_size=128, epochs=2)
内容的提问来源于stack exchange,提问作者paricma
相关产品推荐
相关产品推荐

