【问题标题】:TensorFlow 2.0 GradientTape NoneType errorTensorFlow 2.0 GradientTape NoneType 错误
【发布时间】:2019-11-26 07:58:29
【问题描述】:

我正在尝试使用 TensorFlow 2.0 进行 MNIST 分类。

我的神经网络架构如下:

输入层有784个神经元(28 * 28)

隐藏层有 512 个神经元

输出层有 10 个神经元

隐藏层使用ReLU激活函数,输出层有10个神经元。

我的代码如下:

# Load and prepare the MNIST dataset-
mnist = tf.keras.datasets.mnist

# type(mnist)
# module

(X_train, y_train), (X_test, y_test) = mnist.load_data()

# type(X_train), type(y_train), type(X_test), type(y_test)
# (numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray)


# Normalize and convert samples from integers to floating-point numbers-
X_train, X_test = X_train / 255.0, X_test / 255.0

X_train = tf.cast(X_train, dtype=tf.float32)
X_test = tf.cast(X_test, dtype=tf.float32)
y_train = tf.cast(y_train, dtype=tf.float32)
y_test = tf.cast(y_test, dtype=tf.float32)

print("\nShapes of training and testing sets are:")
print("X_train.shape = {0}, y_train.shape = {1}, X_test.shape = {2} & y_test.shape = {3}\n".format(X_train.shape, y_train.shape, X_test.shape, y_test.shape))
# Shapes of training and testing sets are:
# X_train.shape = (60000, 28, 28), y_train.shape = (60000,), X_test.shape = (10000, 28, 28) & y_test.shape = (10000,)


# Reshape training and testing sets-
X_train = tf.reshape(X_train, shape=(X_train.shape[0], 784))
X_test = tf.reshape(X_test, shape=(X_test.shape[0], 784))

print("\nDimensions of training and testing sets AFTER reshaping are:")
print("X_train.shape = {0} and X_test.shape = {1}\n".format(X_train.shape, X_test.shape))
# Dimensions of training and testing sets AFTER reshaping are:
# X_train.shape = (60000, 784) and X_test.shape = (10000, 784)


def relu(x):
    '''
    Function to calculate ReLU for
    given 'x'
    '''
    # return np.maximum(x, 0)
    return tf.cast(tf.math.maximum(x, 0), dtype = tf.float32)


def relu_derivative(x):
    '''
    Function to calculate derivative
    of ReLU
    '''
    # return np.where(x <= 0, 0, 1)
    # return tf.where(x <=0, 0, 1)
    return tf.cast(tf.where(x <=0, 0, 1), dtype=tf.float32)


def softmax_stable(z):
    '''
    Function to compute softmax activation function.
    Numerically stable
    '''
    # First cast 'z' to floating type-
    z = tf.cast(z, dtype = tf.float32)

    # Get largest element in 'z'-
    largest = tf.math.reduce_max(z)

    # Raise each value to exp('z - largest')-
    z_exp = tf.math.exp(z - largest)

    # Compute softmax activation values-
    s = z_exp / tf.math.reduce_sum(z_exp)

    return s


def initialize_parameters():
    W1 = tf.Variable(tf.random.uniform(shape=(784, 512), minval=0, maxval=1))
    b1 = tf.Variable(tf.random.uniform(shape = (1, 512), minval = 0, maxval=1))
    W2 = tf.Variable(tf.random.uniform(shape = (512, 10), minval=0, maxval=1))
    b2 = tf.Variable(tf.random.uniform(shape = (1, 10), minval=0, maxval=1))

    return {'W1': W1, 'W2': W2,
        'b1': b1, 'b2': b2}


def forward_propagation(parameters, X, Y):
    W1 = parameters['W1']
    W2 = parameters['W2']
    b1 = parameters['b1']
    b2 = parameters['b2']

    Z1 = tf.matmul(X_train, W1) + b1    # (6000, 512)
    A1 = relu(Z1)                       # (6000, 512)

    Z2 = tf.matmul(A1, W2) + b2         # (6000, 10)
    # A2 = softmax(Z2)                  # (6000, 10)
    # OR-
    A2 = tf.nn.softmax(Z2)          # (6000, 10)

    return A2


def cost(parameters, X, Y):
    y_pred_temp = forward_propagation(parameters, X, Y)
    loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

    return loss_fn(y_true = Y, y_pred = y_pred_temp)



def train_model(parameters, X, Y, learning_rate):

    W1 = parameters['W1']
    W2 = parameters['W2']
    b1 = parameters['b1']
    b2 = parameters['b2']

    with tf.GradientTape(persistent = True) as t:
        current_loss = cost(parameters, X_train, y_train)

    dW2, dW1, db2, db1 = t.gradient(current_loss, [W2, W1, b2, b1])

    W2 = W2 - (learning_rate * dW2)
    W1 = W1 - (learning_rate * dW1)
    b2 = b2 - (learning_rate * db2)
    b1 = b1 - (learning_rate * db1)

    updated_params = {'W1': W1, 'W2': W2,
        'b1': b1, 'b2': b2}

    return updated_params

params = initialize_parameters()

updated_params, cost_val = train_model(params, X_train, y_train, 0.01)

现在,如果我想在循环中使用“train_model()”来更新它的值,如下所示:

for epoch in range(100):
    updated_params, cost_val = train_model(updated_params, X_train, y_train, 0.01)

对“train_model()”的后续调用返回“dW2”、“dW1”、“db2”、“db1” 作为“无类型”

怎么了?

谢谢!

【问题讨论】:

    标签: python tensorflow neural-network


    【解决方案1】:

    问题在于您的initialize_parameters() 函数。您创建的不是tf.Variables,而是tf.Tensors。你需要你的参数是tf.Variables 如果你需要衍生 w.r.t.他们。

    
    def initialize_parameters():
        W1 = tf.Variable(tf.random.uniform(shape=(784, 512), minval=0, maxval=1))
        b1 = tf.Variable(tf.random.uniform(shape = (1, 512), minval = 0, maxval=1))
        W2 = tf.Variable(tf.random.uniform(shape = (512, 10), minval=0, maxval=1))
        b2 = tf.Variable(tf.random.uniform(shape = (1, 10), minval=0, maxval=1))
    
        return {'W1': W1, 'W2': W2,
            'b1': b1, 'b2': b2}
    

    【讨论】:

    • 即使在更改为tf.Variable 之后,对“train_model()”的第二次调用也会使“dW2”、“dW1”、“db2”和“db1”成为 NoneType。怎么了?
    • 我没有得到同样的错误。它运行良好(测试了 10 个 epochs )在我这边。您能否重置您的运行时间并重新运行,看看错误是否仍然存在。
    • 我在“for”循环中犯了一个错误。在 for 循环中,放入以下内容-updated_pa​​rams, cost_val = train_model(updated_pa​​rams, X_train, y_train, 0.01) 这将产生错误。为什么?
    • W2 = W2 - (learning_rate * dW2) \ W1 = W1 - (learning_rate * dW1) … 是罪魁祸首。这些导致W2, W1, … 成为张量。所以在第一次迭代之后,它们不再是tf.Variables
    • 所以不要手动执行此操作,只需使用您选择的优化器中的 apply_gradients 方法
    猜你喜欢
    • 2020-04-22
    • 1970-01-01
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 2020-03-24
    • 2020-06-14
    • 1970-01-01
    • 2020-07-31
    相关资源
    最近更新 更多