You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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"])
---&gt; 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 13:43:15