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

如何用神经网络预测伪随机数?模型仅返回高频数求助

问题分析与解决方案

任务可行性说明

你当前的任务本质上不可行,因为你生成的序列是完全独立的伪随机数:每个数的生成逻辑和前面的序列没有任何关联,属于**独立同分布(i.i.d.)**数据。这种情况下,没有任何可被模型学习的模式,模型能做的最优策略就是预测出现频率最高的类别(也就是0类,占比48%),这就是为什么你的模型只输出0。

问题原因拆解

  • 数据无序列相关性:generate_sequence函数里每个数都是通过randint独立生成的,前20个数和下一个数没有逻辑关联,模型无法找到任何预测线索。
  • 不必要的预处理:对离散类别输入使用tf.keras.utils.normalize没有意义,反而会破坏类别之间的离散特征,干扰模型学习。
  • 类别不平衡:0类的生成概率是48%,远高于1类(24%)、2类(16%)、3类(8%)、4类(4%),模型为了追求更高准确率,会自然偏向预测占比最高的类别。

改进方向

1. 调整任务目标(如果想练习序列预测)

如果是为了学习序列预测,需要生成有依赖关系的序列,比如让下一个数和前面的数存在逻辑关联。例如修改生成函数:

def generate_sequence(length=1000000):
    rList = []
    # 初始值
    prev = randint(0,4)
    rList.append(prev)
    for i in range(1, length):
        # 简单依赖:下一个数是前一个数+1取模5(可自定义更复杂逻辑)
        prev = (prev + 1) % 5
        rList.append(prev)
    return rList

这种序列有明确的序列模式,模型可以学习到预测规律。

2. 针对当前代码的优化(仅解决类别不平衡问题)

虽然无法实现真正的预测,但可以调整代码让模型不再只输出最高频类别:

  • 移除归一化步骤:离散类别不需要归一化。
  • 使用类别权重平衡:在训练时给低频率类别更高的权重,避免模型偏向高频类。

修改后的代码:

from random import randint
import numpy as np
import tensorflow as tf

def generate_sequence(length=1000000):
    rList = []
    for i in range(length):
        rInt = randint(0, 99)
        if rInt >= 0 and rInt <= 47:
            rList.append(0)
        elif rInt > 47 and rInt <= 71:
            rList.append(1)
        elif rInt > 71 and rInt <= 87:
            rList.append(2)
        elif rInt > 87 and rInt <= 95:
            rList.append(3)
        else:
            rList.append(4)
    return rList

data = generate_sequence()
train_data = data[:800000]
test_data = data[800000:]
x_train = []
y_train = []
x_test = []
y_test = []

for i in range(0, 799980, 20):
    x_train.append(train_data[i:i+20])
    y_train.append(train_data[i+20])

for i in range(0, 199980, 20):
    x_test.append(test_data[i:i+20])
    y_test.append(test_data[i+20])

# 移除归一化步骤
x_train = np.asarray(x_train)
y_train = np.asarray(y_train)
x_test = np.asarray(x_test)
y_test = np.asarray(y_test)

# 计算类别权重:根据每个类别的频率倒数计算
class_counts = np.bincount(y_train)
total = len(y_train)
class_weights = {i: total / (5 * class_counts[i]) for i in range(5)}

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(625, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(125, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(25, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(5, activation=tf.nn.softmax))

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
# 加入class_weight参数
model.fit(x_train, y_train, epochs=5, class_weight=class_weights)

val_loss, val_acc = model.evaluate(x_test, y_test)
print(val_loss, val_acc)

prediction = model.predict(x_test)
for pred in prediction:
    print(np.argmax(pred))

3. 序列模型适配(仅当数据有依赖时有用)

如果使用有依赖的序列,建议改用循环神经网络(如LSTM)来处理序列输入,示例结构:

model = tf.keras.models.Sequential()
# 调整输入形状为(序列长度, 特征数),这里每个时间步是1个特征
model.add(tf.keras.layers.LSTM(64, input_shape=(20, 1)))
model.add(tf.keras.layers.Dense(32, activation='relu'))
model.add(tf.keras.layers.Dense(5, activation='softmax'))
# 注意:输入需要调整形状为(样本数, 20, 1)
x_train = x_train.reshape(-1, 20, 1)
x_test = x_test.reshape(-1, 20, 1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 13:35:44