神经网络 sigmoid 函数

1 投票
1 回答
1794 浏览
提问于 2025-04-18 14:50

我正在尝试制作一个神经网络,有几个问题想请教:

我的 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 个回答

4

你把几个不同的神经网络概念混在一起了。

逻辑函数(其实就是sigmoid函数的一种扩展)本身就可以作为一个阈值。具体来说,它是一个可微分的阈值,这对于反向传播学习算法是非常重要的。所以你不需要那种分段的阈值函数(if语句)。

权重就像是突触的强度,在求和(或者说前向传播)的时候会用到。所以每一对节点之间的连接都有一个权重,这个权重会和发送节点的激活水平(阈值函数的输出)相乘。

最后,即使做了这些调整,一个所有权重都是正数的全连接神经网络,输出结果可能还是全是1。你可以选择加入一些负权重来对应抑制节点,或者大幅减少连接的数量(比如说,设置一个0.1的概率,让第n层的节点连接到第n+1层的节点)。

撰写回答