TensorFlow/Keras训练模型报错:'str'对象无'name'属性
问题:TensorFlow版本差异导致ExponentialLearningRate回调报错
我正在学习神经网络,复习《Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow(第3版)》第10章练习10时,原封不动复制了GitHub上的参考答案,结果执行model.fit(X_train, y_train, epochs=1, validation_data=(X_valid, y_valid), callbacks=[expon_lr])时触发了属性错误。
相关代码
K = keras.backend class ExponentialLearningRate(keras.callbacks.Callback): def __init__(self, factor): self.factor = factor self.rates = [] self.losses = [] def on_batch_end(self, batch, logs): self.rates.append(K.get_value(self.model.optimizer.learning_rate)) self.losses.append(logs["loss"]) K.set_value(self.model.optimizer.learning_rate, self.model.optimizer.learning_rate * self.factor) keras.backend.clear_session() np.random.seed(42) tf.random.set_seed(42) model = keras.models.Sequential([ keras.layers.Flatten(input_shape=[28, 28]), # 输入层 keras.layers.Dense(300, activation="relu"), # 第一个隐藏层 keras.layers.Dense(200, activation="relu"), # 第二个隐藏层 keras.layers.Dense(10, activation="softmax") # 输出层 ]) model.compile(loss="sparse_categorical_crossentropy", optimizer=keras.optimizers.SGD(learning_rate=1e-3), metrics=["accuracy"]) expon_lr = ExponentialLearningRate(factor=1.005) history = model.fit(X_train, y_train, epochs=1, validation_data=(X_valid, y_valid), callbacks=[expon_lr]) plt.plot(expon_lr.rates, expon_lr.losses) plt.gca().set_xscale('log') plt.hlines(min(expon_lr.losses), min(expon_lr.rates), max(expon_lr.rates)) plt.axis([min(expon_lr.rates), max(expon_lr.rates), 0, expon_lr.losses[0]]) plt.grid() plt.xlabel("Learning rate") plt.ylabel("Loss")
错误信息
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-14-a0cc0ada5ef0> in <cell line: 1>() ----> 1 history = model.fit(X_train, y_train, epochs=1, 2 validation_data=(X_valid, y_valid), 3 callbacks=[expon_lr]) 1 frames <ipython-input-6-f87513637cd3> in on_batch_end(self, batch, logs) 9 self.rates.append(K.get_value(self.model.optimizer.learning_rate)) 10 self.losses.append(logs["loss"]) ---> 11 K.set_value(self.model.optimizer.learning_rate, self.model.optimizer.learning_rate * self.factor) AttributeError: 'str' object has no attribute 'name'
原因分析
这个错误确实是TensorFlow/Keras版本差异导致的。在新版TensorFlow中,optimizer.learning_rate返回的是字符串类型的变量标识符,不再是旧版中可直接操作的张量对象,直接使用K.set_value()进行赋值会触发类型不匹配的错误。
解决方案
修改ExponentialLearningRate回调类的on_batch_end方法,改用TensorFlow推荐的assign()方法更新学习率,兼容新版API:
修改后的完整代码
import tensorflow as tf from tensorflow import keras import numpy as np import matplotlib.pyplot as plt K = keras.backend class ExponentialLearningRate(keras.callbacks.Callback): def __init__(self, factor): self.factor = factor self.rates = [] self.losses = [] def on_batch_end(self, batch, logs): # 获取当前学习率的张量对象 lr_tensor = self.model.optimizer.learning_rate current_rate = K.get_value(lr_tensor) self.rates.append(current_rate) self.losses.append(logs["loss"]) # 使用assign方法更新学习率 new_rate = current_rate * self.factor lr_tensor.assign(new_rate) keras.backend.clear_session() np.random.seed(42) tf.random.set_seed(42) model = keras.models.Sequential([ keras.layers.Flatten(input_shape=[28, 28]), # 输入层 keras.layers.Dense(300, activation="relu"), # 第一个隐藏层 keras.layers.Dense(200, activation="relu"), # 第二个隐藏层 keras.layers.Dense(10, activation="softmax") # 输出层 ]) model.compile(loss="sparse_categorical_crossentropy", optimizer=keras.optimizers.SGD(learning_rate=1e-3), metrics=["accuracy"]) expon_lr = ExponentialLearningRate(factor=1.005) history = model.fit(X_train, y_train, epochs=1, validation_data=(X_valid, y_valid), callbacks=[expon_lr]) plt.plot(expon_lr.rates, expon_lr.losses) plt.gca().set_xscale('log') plt.hlines(min(expon_lr.losses), min(expon_lr.rates), max(expon_lr.rates)) plt.axis([min(expon_lr.rates), max(expon_lr.rates), 0, expon_lr.losses[0]]) plt.grid() plt.xlabel("Learning rate") plt.ylabel("Loss")
内容的提问来源于stack exchange,提问作者Jjvvrr
相关产品推荐
相关产品推荐

