神经网络 sigmoid 函数
我正在尝试制作一个神经网络,有几个问题想请教:
我的 sigmoid 函数长这样:
s = 1/(1+(2.7183**(-self.values)))
if s > self.weight:
self.value = 1
else:
self.value = 0
self.values 是一个连接节点的数组,比如第一隐藏层(HL1)中的隐藏节点(HNs)连接到所有输入节点,所以它的 self.values 是输入节点值的总和。
第二隐藏层(HL2)中的隐藏节点连接到第一隐藏层中的所有隐藏节点,它的 self.values 是第一隐藏层值的总和。
问题是,每个节点的值都是 1,不管它们的权重是多少(除非权重特别高,比如 0.90 到 0.99 之间)。
我的神经网络设置如下:
(输入,隐藏层数量,每层隐藏节点数量,输出节点数量) 输入是一个二进制值的列表:
这里有一个日志,显示了这种行为。
>>NeuralNetwork([1,0,1,1,1,0,0],3,3,1)# 3 layers, 3 nodes each, 1 output
Layer1
Node: y1 Sum: 4, Sigmoid: 0.98, Weight: 0.10, self.value: 1
Node: y2 Sum: 4, Sigmoid: 0.98, Weight: 0.59, self.value: 1
Node: y3 Sum: 4, Sigmoid: 0.98, Weight: 0.74, self.value: 1
Layer2
Node: y1 Sum: 3, Sigmoid: 0.95, Weight: 0.30, self.value: 1
Node: y2 Sum: 3, Sigmoid: 0.95, Weight: 0.37, self.value: 1
Node: y3 Sum: 3, Sigmoid: 0.95, Weight: 0.80, self.value: 1
Layer3
Node: y1 Sum: 3, Sigmoid: 0.95, Weight: 0.70, self.value: 1
Node: y2 Sum: 3, Sigmoid: 0.95, Weight: 0.56, self.value: 1
Node: y3 Sum: 3, Sigmoid: 0.95, Weight: 0.28, self.value: 1
即使我尝试在输入中使用浮点数,结果也是一样的:
>>NeuralNetwork([0.64, 0.57, 0.59, 0.87, 0.56],3,3,1)
Layer1
Node: y1 Sum: 3.23, Sigmoid: 0.96, Weight: 0.77, self.value: 1
Node: y2 Sum: 3.23, Sigmoid: 0.96, Weight: 0.45, self.value: 1
Node: y3 Sum: 3.23, Sigmoid: 0.96, Weight: 0.83, self.value: 1
Layer2
Node: y1 Sum: 3, Sigmoid: 0.95, Weight: 0.26, self.value: 1
Node: y2 Sum: 3, Sigmoid: 0.95, Weight: 0.39, self.value: 1
Node: y3 Sum: 3, Sigmoid: 0.95, Weight: 0.53, self.value: 1
Layer3
Node: y1 Sum: 3, Sigmoid: 0.95, Weight: 0.43, self.value: 1
Node: y2 Sum: 3, Sigmoid: 0.95, Weight: 0.52, self.value: 1
Node: y3 Sum: 3, Sigmoid: 0.95, Weight: 0.96, self.value: 0
注意第三层的节点 y3,它是唯一一个在经过 sigmoid 后返回 0 的节点。
我哪里做错了?
另外,真的有必要让每个节点都与前一层的每个节点连接吗?难道随机连接不是更好吗?
编辑:忘了提,这个神经网络还在开发中,我会使用遗传算法来训练网络。
编辑2:
class NeuralNetwork:
def __init__(self, inputs, num_hidden_layers, num_hidden_nodes_per_layer, num_output):
self.input_nodes = inputs
self.num_inputs = len(inputs)
self.num_hidden_layers = num_hidden_layers
self.num_hidden_nodes_per_layer = num_hidden_nodes_per_layer
self.num_output = num_output
self.createNodes()
self.weights = self.getWeights()
self.connectNodes()
self.updateNodes()
def createNodes(self):
self._input_nodes = []
for i, v in enumerate(self.input_nodes):
node = InputNode("x"+str(i+1),v)
self._input_nodes.append(node)
self._hidden_layers = []
for n in xrange(self.num_hidden_layers):
layer = HiddenLayer("Layer"+str(n+1),self.num_hidden_nodes_per_layer)
self._hidden_layers.append(layer)
def getWeights(self):
weights = []
for node in self._input_nodes:
weights.append(node.weight)
for layer in self._hidden_layers:
for node in layer.hidden_nodes:
weights.append(node.weight)
return weights
def connectNodes(self):
for i,layer in enumerate(self._hidden_layers):
for hidden_node in layer.hidden_nodes:
if i == 0:
for input_node in self._input_nodes:
hidden_node.connections.append(input_node)
else:
for previous_node in self._hidden_layers[i-1].hidden_nodes:
hidden_node.connections.append(previous_node)
def updateNodes(self):
for layer in self._hidden_layers:
for node in layer.hidden_nodes:
node.updateValue()
这是节点的 updateValue() 方法:
def updateValue(self):
value = 0
for node in self.connections:
value += node.value
self.sigmoid(value) # the function at the beginning of the question.
这些节点只包含值、名称和权重(一开始是随机的)。
1 个回答
你把几个不同的神经网络概念混在一起了。
逻辑函数(其实就是sigmoid函数的一种扩展)本身就可以作为一个阈值。具体来说,它是一个可微分的阈值,这对于反向传播学习算法是非常重要的。所以你不需要那种分段的阈值函数(if语句)。
权重就像是突触的强度,在求和(或者说前向传播)的时候会用到。所以每一对节点之间的连接都有一个权重,这个权重会和发送节点的激活水平(阈值函数的输出)相乘。
最后,即使做了这些调整,一个所有权重都是正数的全连接神经网络,输出结果可能还是全是1。你可以选择加入一些负权重来对应抑制节点,或者大幅减少连接的数量(比如说,设置一个0.1的概率,让第n层的节点连接到第n+1层的节点)。