【发布时间】:2022-01-21 05:39:05
【问题描述】:
我的目标是一个具有两个神经元的顺序神经网络,能够重现二次函数。为此,我选择第一个神经元的激活函数为lambda x: x**2,第二个神经元的激活函数为None。
每个神经元输出A(ax+b),其中A 是激活函数,a 是给定神经元的权重,b 是偏置项。第一个神经元的输出传递给第二个神经元,该神经元的输出就是结果。
那么我的网络输出的形式是:
训练模型意味着调整每个神经元的权重和偏差。选择一组非常简单的参数,即:
将我们引向一条抛物线,该抛物线应该可以通过上面描述的 2 神经元神经网络完全学习:
为了实现神经网络,我这样做了:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
定义要学习的函数:
f = lambda x: x**2 + 2*x + 2
使用上述函数生成训练输入和输出:
np.random.seed(42)
questions = np.random.rand(999)
solutions = f(questions)
定义神经网络架构:
model = tf.keras.Sequential([
tf.keras.layers.Dense(units=1, input_shape=[1],activation=lambda x: x**2),
tf.keras.layers.Dense(units=1, input_shape=[1],activation=None)
])
编译网:
model.compile(loss='mean_squared_error',
optimizer=tf.keras.optimizers.Adam(0.1))
训练模型:
history = model.fit(questions, solutions, epochs=999, batch_size = 1, verbose=1)
使用新训练的模型生成f(x) 的预测:
np.random.seed(43)
test_questions = np.random.rand(100)
test_solutions = f(test_questions)
test_answers = model.predict(test_questions)
可视化结果:
plt.figure(figsize=(10,6))
plt.scatter(test_questions, test_solutions, c='r', label='solutions')
plt.scatter(test_questions, test_answers, c='b', label='answers')
plt.legend()
红点形成了我们的模型应该学习的抛物线曲线,蓝点形成了它已经学习的曲线。这种方法显然行不通。
上述方法有什么问题,如何让神经网络真正学习抛物线?
【问题讨论】:
-
为什么在你的代码中批量大小等于 1?理想情况下,您应该在整个数据集上进行训练,但如果它太大,则需要太多时间(对于这个简单的网络来说,一千次观察不应该太多),因此必须求助于批处理。一批 one 元素提供的信息太少,IMO。您可以尝试使用更高的
batch_size,例如 100 -
谢谢。下次我会考虑增加它。目前,我在不增加它的情况下找到了答案(可能训练效率不是很高,你是对的)。
-
为什么不呢?我认为它确实学会了它,请参阅答案。
标签: python tensorflow math keras neural-network