我正在学习神经网络,最近有了这样一个想法:尝试给神经网络提供函数$f(x) = 2x$的训练数据。问题是,神经网络能否准确预测它需要将输入数字翻倍以给出正确的输出?
这只是一个“思维练习”,以更好地理解神经网络的工作原理。
我的Python代码不起作用,以下是我尝试过的内容:
神经网络类:
import numpy as npclass NeuralNetwork: def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate): self.inodes = inputnodes self.hnodes = hiddennodes self.onodes = outputnodes self.lr = learningrate self.wih = np.random.normal(0.0, pow(self.inodes, -0.5), (self.hnodes, self.inodes)) self.who = np.random.normal(0.0, pow(self.hnodes, -0.5), (self.onodes, self.hnodes)) def train(self, inputs_list, targets_list): inputs = np.array(inputs_list, ndmin=2).T targets = np.array(targets_list, ndmin=2).T hidden_outputs = np.dot(self.wih, inputs) final_outputs = np.dot(self.who, hidden_outputs) output_errors = targets - final_outputs hidden_errors = np.dot(self.who.T, output_errors) self.who += self.lr * np.dot( (output_errors * final_outputs * (1.0 - final_outputs)), np.transpose(hidden_outputs) ) self.wih += self.lr * np.dot( (hidden_errors * hidden_outputs * (1.0 - hidden_outputs)), np.transpose(inputs) ) def query(self, inputs_list): inputs = np.array(inputs_list, ndmin=2).T hidden_outputs = np.dot(self.wih, inputs) final_outputs = np.dot(self.who, hidden_outputs) return final_outputs
训练网络并预测一个值:
input_nodes = 1hidden_nodes = 20output_nodes = 1learning_rate = 0.3nn = NeuralNetwork(input_nodes, hidden_nodes, output_nodes, learning_rate)for i in range(10): i += 1 inputs = np.log(i) targets = np.log(2*i) nn.train(inputs, targets)print(nn.query(np.asfarray([4])))
运行这段代码时,我得到的输出是这样的:
x.py:26: RuntimeWarning: overflow encountered in multiply (output_errors * final_outputs * (1.0 - final_outputs)), x.py:31: RuntimeWarning: overflow encountered in multiply (hidden_errors * hidden_outputs * (1.0 - hidden_outputs)), [[nan]]
我不知道如何解释这些结果,以及我的设计是否适合这个应用。任何帮助都将不胜感激。
谢谢。
回答:
一些建议:
- 由于我们关注的函数(
f(x)=2x
)是线性的,只需要一个权重,我们可以大大简化网络,只使用1个权重和0个隐藏层。我们在调试问题,所以应该尽可能简化以消除错误来源。使用带有多个隐藏节点的隐藏层意味着我们需要找到满足W1.dot(W2)=2
的矩阵,因为我们寻求函数x.dot(W1).dot(W2)
,这更难,因为改变一个权重会改变整个乘积;找到正确答案需要调整所有这些权重。 - 由于我们关注的函数是线性的,我们知道任何非线性函数的使用都是干扰。此外,sigmoid和tanh函数的饱和,或者ReLU的死亡现象,可能给优化动态带来额外的问题,可能会阻止我们取得进展。参见:https://stats.stackexchange.com/questions/301285/what-is-vanishing-gradient
- 学习率可能过大。我认为这是问题所在,因为你遇到了数值溢出;当优化器持续超过最小值时,可能会发生这种情况。参见:https://stats.stackexchange.com/questions/364360/how-can-change-in-cost-function-be-positive
- 缩放回归问题的输入和目标可以显著改善优化器的动态。例如,参见https://stats.stackexchange.com/questions/432707/alternating-negative-and-positive-value-of-slope-and-y-intercept-in-gradient-des/432714#432714
- 关于训练神经网络的更多提示,请参见:https://stats.stackexchange.com/questions/352036/what-should-i-do-when-my-neural-network-doesnt-learn/352037#352037