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

神经网络实现除法遇未知秩形状错误及结果异常的解决求助

问题描述

尝试通过神经网络实现两数乘除法运算:先训练加减、单个数平方的模型,除法通过「被除数 × 除数倒数」转换为乘法,利用公式 ab = [(a+b)² -a² -b²]/2 计算结果。乘法运行正常,但除法出现以下问题:

  1. 初始代码中Ydiv = 1/Y时,报错:
Exception encountered when calling Sequential.call().
Cannot take the length of shape with unknown rank.
  1. 修改为Ydiv = np.reciprocal(Y)后错误消失,但除法结果始终近似为某个固定值(每次运行固定值不同)。

原始代码:

import tensorflow as tf
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras import regularizers

#Models for adding and subtracting two numbers
num_train = 1000
X_train = np.random.rand(num_train, 2)
y_train_add = X_train[:, 0] + X_train[:, 1]
y_train_subtract = X_train[:, 0] - X_train[:, 1]

model_add = Sequential(
        [
            Dense(10),
            Dense(1)
            ]
        )

model_subtract = Sequential(
        [
            Dense(10),
            Dense(1)
            ]
        )

batch_size = 32
epochs = 100

model_add.compile(loss = 'mse', optimizer='adam')
model_add.fit(X_train, y_train_add, batch_size=batch_size, epochs=epochs, verbose = 1)

model_subtract.compile(loss = 'mse', optimizer='adam')
model_subtract.fit(X_train, y_train_subtract, batch_size=batch_size, epochs=epochs, verbose = 1)

#Model for squaring a number
x_train = np.random.random((10000,1))*100-50
y_train = np.square(x_train)

model_sqr = Sequential(
        [
            Dense(8, activation = 'relu', kernel_regularizer = regularizers.l2(0.001), input_shape = (1,)),
            Dense(8, activation = 'relu',  kernel_regularizer = regularizers.l2(0.001)),
            Dense(1)
            ]
        )

batch_size = 64
epochs = 2000

model_sqr.compile(loss = 'mse', optimizer='adam')
model_sqr.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose = 1)

#Code for calculating the product and quotient of two numbers using models
x = "n" 
while True:
    print("enter first num:")
    x = input()
    if x == "end":
        break

    print("Enter operation:")
    op= input()

    print("enter second num:")
    y = input()

    X = int(x)
    Y = int(y)
    Ydiv = 1/Y

    if op == "*":
        predicted_product = model_sqr.predict(model_add.predict(np.array([[X, Y]]))) - model_sqr.predict(np.array([X])) -  model_sqr.predict(np.array([Y]))
        print(predicted_product/2)
    elif op =="/":
        predicted_quot = model_sqr.predict(model_add.predict(np.array([[X, Ydiv]]))) - model_sqr.predict(np.array([X])) -  model_sqr.predict(np.array([Ydiv]))
        print(predicted_quot/2)
问题解答

1. 原错误产生的原因

model_sqr的输入要求是二维张量(形状为(None, 1)),对应训练时的输入x_train是(10000,1)的二维数组。

  • 当使用Ydiv = 1/Y时,Ydiv是Python float类型,np.array([Ydiv])生成的是一维数组(形状(1,)),TensorFlow无法识别该输入的维度(rank),因此抛出"Cannot take the length of shape with unknown rank"错误。
  • np.reciprocal(Y)返回的是numpy float标量,np.array([Ydiv])同样是一维数组,但numpy的类型转换让TensorFlow暂时绕过了维度检查,不过输入维度不匹配的问题依然存在,这也是后续结果固定的根源之一。

2. 除法运算问题的修正方案

核心修正点:

  • 统一输入维度:所有传给model_sqr.predict的输入必须是二维数组,即把np.array([X])改为np.array([[X]]),np.array([Ydiv])改为np.array([[Ydiv]])。
  • 统一训练数据范围:加减模型的训练数据X_train仅覆盖0-1区间,但平方模型覆盖-50到50,除法中输入的X(整数)和Ydiv(分数)大概率超出加减模型的训练范围,导致model_add预测X+Ydiv严重失真。需将加减模型的训练数据范围改为与平方模型一致:
    X_train = np.random.random((num_train,2))*100 -50
    
  • 增加除数非零判断:避免除法运算中除数为0的崩溃。
  • 可选优化:适当提升加减模型的拟合能力,比如增加神经元数量或层数,应对更大范围的输入。

修正后的关键代码片段:

# 修正加减模型训练数据范围
X_train = np.random.random((num_train,2))*100 -50

# 修正乘除法计算部分的输入维度与除数判断
if op == "*":
    # 所有predict输入改为二维数组
    sum_ab = model_add.predict(np.array([[X, Y]]))
    sqr_sum = model_sqr.predict(sum_ab)
    sqr_a = model_sqr.predict(np.array([[X]]))
    sqr_b = model_sqr.predict(np.array([[Y]]))
    predicted_product = (sqr_sum - sqr_a - sqr_b)/2
    print(predicted_product)
elif op =="/":
    if Y == 0:
        print("Error: Divisor cannot be zero")
        continue
    Ydiv = 1.0/Y
    sum_a_invb = model_add.predict(np.array([[X, Ydiv]]))
    sqr_sum = model_sqr.predict(sum_a_invb)
    sqr_a = model_sqr.predict(np.array([[X]]))
    sqr_invb = model_sqr.predict(np.array([[Ydiv]]))
    predicted_quot = (sqr_sum - sqr_a - sqr_invb)/2
    print(predicted_quot)

内容的提问来源于stack exchange,提问作者harry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 23:15:01