神经网络脚本中的Python索引超出范围

0 投票
1 回答
558 浏览
提问于 2025-04-17 21:42

我刚开始学习Python,这还是我第一次写比较长的代码。最近我在跟着一个教程写神经网络,但遇到了一个错误信息,我不知道怎么解决。我在Stack Overflow上搜索了“IndexError: list index out of range”,了解到这个错误通常是因为试图访问一个列表中不存在的元素,比如你想访问第n个元素,但这个列表只有n-1个元素。不过,我不知道是哪个列表出错了,也不知道该怎么修复。任何帮助都非常感谢,如果有办法运行脚本并提供更多关于哪个列表超出索引的信息,那就太好了。下面是错误信息和代码...

我一直收到这样的错误信息:

(2, 2, 1)
[array([[ 0.09438987,  0.08228006, -0.00851927],
       [-0.09384243, -0.07417094,  0.1341281 ]]), array([[-0.20913607,  0.02783653, -0.07682221]])]
Traceback (most recent call last):
  File "BackProp.py", line 126, in <module>
    err = bpn.TrainEpoch(lvInput, lvTarget)
  File "BackProp.py", line 93, in TrainEpoch
    weightDelta = np.sum(layerOutput[None,:,:].transpose(2, 0, 1) * delta[delta_index][None,:,:].transpose(2, 1, 0), axis = 0)
IndexError: list index out of range

...还有代码....

import numpy as np$
$
class BackPropagationNetwork:$
    """A back-propagation network"""$
$
    #$
    # Class Members$
    #$
    layerCount = 0$
    shape = None$
    weights = []$
$
    #$
    # Class Methods$
    #$
    def __init__(self, layerSize):$
        """Initialize the network"""$
$
        # Layer info$
        self.layerCount = len(layerSize) - 1$
        self.shape = layerSize$
$
        #Input/Output data from last Run$
        self._layerInput = []$
        self._layerOutput = []$
$
        # Create the weight arrays$
        for (l1, l2) in zip(layerSize[:-1], layerSize[1:]):$
            self.weights.append(np.random.normal(scale=0.1, size = (l2, l1+1)))$
$
    #$
    # Run Method$
    #$
    def Run(self, input):$
        """Run the network based on the input data"""$
$
        lnCases = input.shape[0]$
$
        #Clear out the previous intermediate value lists$
        self._layerInput = []$
        self._layerOutput = []$
$
        # Run it$
#$
    def Run(self, input):$
        """Run the network based on the input data"""$
$
        lnCases = input.shape[0]$
$
        #Clear out the previous intermediate value lists$
        self._layerInput = []$
        self._layerOutput = []$
$
        # Run it$
        for index in range(self.layerCount):$
            # Determine layer input$
            if index == 0:$
                layerInput = self.weights[0].dot(np.vstack([input.T, np.ones([1, lnCases])]))$
            else:$
                layerInput = self.weights[index].dot(np.vstack([self._layerOutput[-1], np.ones([1, lnCases])]))$
$
            self._layerInput.append(layerInput)$
            self._layerOutput.append(self.sgm(layerInput))$
$
        return self._layerOutput[-1].T$
$
    #$
    # TrainEpoch method$
    #$
    def TrainEpoch(self, input, target, trainingRate = 0.2):$
        """This method trains the network for one epoch"""$
$
        delta = []$
        lnCases = input.shape[0]$
$
        # First run the network$
        self.Run(input)$
$
        # Calculate our deltas$
        for index in reversed(range(self.layerCount)):$
            if index == self.layerCount - 1:$
                # Compare to the target values$
                output_delta = self._layerOutput[index] - target.T$
                error = np.sum(output_delta**2)$
                delta.append(output_delta * self.sgm(self._layerInput[index], True))$
            else:$
                # compare to the following layer's delta$
                delta_pullback = self.weights[index + 1].T.dot(delta[-1])$
                delta.append(delta_pullback[:-1, :] * self.sgm(self._layerInput[index], True))$
            # Compute weight deltas$
            for index in range(self.layerCount):$
                delta_index = self.layerCount - 1 - index$
$
                if index == 0:$
                    layerOutput = np.vstack([input.T, np.ones([1, lnCases])])$
                else:$
                    layerOutput = np.vstack([self._layerOutput[index - 1], np.ones([1, self._layerOutput[index - 1].shape[1]])])$
$
                weightDelta = np.sum(layerOutput[None,:,:].transpose(2, 0, 1) * delta[delta_index][None,:,:].transpose(2, 1, 0), axis = 0)$
                self.weights[index] -= trainingRate * weightDelta$
$
            return error$
$
$
$
$
$
$
    # Transfer Functions$
    def sgm(self, x, Derivative=False):$
        if not Derivative:$
            return 1/(1+np.exp(-x))$
        else:$
            out = self.sgm(x)$
            return out*(1-out)$
$
$
#$
# If run as a script, create a test object$
#$
if __name__ == "__main__":$
    bpn = BackPropagationNetwork((2,2,1))$
    print(bpn.shape)$
    print(bpn.weights)$
$
    lvInput = np.array([[0, 0], [1, 1], [0,1], [1,0]])$
    lvTarget = np.array([[0.05], [0.05], [0.95], [0.95]])$
$
    lnMax = 100000$
    lnErr = 1e-5$
    for i in range(lnMax-1):$
        err = bpn.TrainEpoch(lvInput, lvTarget)$
        if i % 2500 == 0:$
            print("Iteration {0}\tError: {1:0.6f}".format(i, err))$
        if err <= lnErr:$
            print("Minimum error reached at iteration {0}".format(i))$
            break$
$
    # Display output$
    lvOutput = bpn.Run(lvInput)$
    print("Input: {0}\nOutput: {1}".format(lvInput, lvOutput))$
$

1 个回答

0

看起来你在 TrainEpoch 里的第二个 for 循环缩进得太深了,这就是导致 IndexError 的原因。换句话说,下面这一行:

for index in range(self.layerCount):

应该和另一个 for 循环保持在同一个缩进级别:

for index in reversed(range(self.layerCount)):

撰写回答