如何用CNN代码修复Python "IndexError: list index out of range"?

问题描述 投票:0回答:1

我正试图构建一个 ResNet34 编码器 作为我的CNN的一部分,在Python 3.7上使用以下函数。

import tensorflow as tf

from tensorpack import *
from tensorpack.models import BatchNorm, BNReLU, Conv2D, MaxPooling, FixedUnPooling
from tensorpack.tfutils.summary import add_moving_summary, add_param_summary
from .utils import *
import sys

sys.path.append("..") # adds higher directory to python modules path.
try: # HACK: import beyond current level, may need to restructure
    from config import Config
except ImportError:
    assert False, 'Fail to import config.py'
def res_blk(name, l, ch, ksize, count, split=1, strides=1, freeze=False):
    ch_in = l.get_shape().as_list()
    with tf.variable_scope(name):
        for i in range(0, count):
            with tf.variable_scope('block' + str(i)):  
                x = l if i == 0 else BNReLU('preact', l)
                x = Conv2D('conv1', x, ch[0], ksize[0], activation=BNReLU)
                x = Conv2D('conv2', x, ch[1], ksize[1], split=split, 
                                strides=strides if i == 0 else 1, activation=BNReLU)
                x = Conv2D('conv3', x, ch[2], ksize[2], activation=tf.identity)
                if (strides != 1 or ch_in[1] != ch[2]) and i == 0:
                    l = Conv2D('convshortcut', l, ch[2], 1, strides=strides)
                x = tf.stop_gradient(x) if freeze else x
                l = l + x
        l = BNReLU('bnlast',l)  
    return l

def encoder(i, freeze):
    d1 = Conv2D('conv0',  i, 64, 7, padding='valid', strides=1, activation=BNReLU)
    d1 = res_blk('group0', d1, [ 64,  64], [3, 3], 3, strides=1, freeze=freeze)

    d2 = res_blk('group1', d1, [128, 128], [3, 3], 4, strides=2, freeze=freeze)
    d2 = tf.stop_gradient(d2) if freeze else d2

    d3 = res_blk('group2', d2, [256, 256], [3, 3], 6, strides=2, freeze=freeze)
    d3 = tf.stop_gradient(d3) if freeze else d3

    d4 = res_blk('group3', d3, [512, 512], [3, 3], 3, strides=2, freeze=freeze)
    d4 = tf.stop_gradient(d4) if freeze else d4

    d4 = Conv2D('conv_bot',  d4, 1024, 1, padding='same')
    return [d1, d2, d3, d4]

然后我得到了错误信息

 line 67, in encoder
    d1 = res_blk('group0', d1, [ 64,  64], [3, 3], 3, strides=1, freeze=freeze)                       
  File "....", line 34, in res_blk
    x = Conv2D('conv3', x, ch[2], ksize[2], activation=tf.identity)
IndexError: list index out of range

这个错误的原因是什么,我该如何解决?原来的代码是Resnet50,它工作正常,即代码将是

d1 = res_blk('group0', d1, [ 64, 64, 256], [1, 3, 1], 3, strides=1, freeze=freeze)

python tensorflow conv-neural-network
1个回答
0
投票

在你包含的链接中,我发现的关键一点是 "每个ResNet块要么是两层深(用于ResNet 18,34这样的小型网络),要么是3层深(ResNet 50,101,152)"。

你提供的代码是针对ResNet 50、101和152所需的三层,但没有适应更简单的两层方法,据我所知,就是这个例子。

可能还有更多的调整要做,但你应该可以只删除最后一层,类似于我下面的,否则在50层以上的ResNet架构中是必要的。

import tensorflow as tf

from tensorpack import *
from tensorpack.models import BatchNorm, BNReLU, Conv2D, MaxPooling, FixedUnPooling
from tensorpack.tfutils.summary import add_moving_summary, add_param_summary
from .utils import *
import sys

sys.path.append("..") # adds higher directory to python modules path.
try: # HACK: import beyond current level, may need to restructure
    from config import Config
except ImportError:
    assert False, 'Fail to import config.py'
def res_blk(name, l, ch, ksize, count, split=1, strides=1, freeze=False):
    ch_in = l.get_shape().as_list()
    with tf.variable_scope(name):
        for i in range(0, count):
            with tf.variable_scope('block' + str(i)):  
                x = l if i == 0 else BNReLU('preact', l)
                x = Conv2D('conv1', x, ch[0], ksize[0], activation=BNReLU)
                x = Conv2D('conv2', x, ch[1], ksize[1], split=split, 
                                strides=strides if i == 0 else 1, activation=BNReLU)
                x = tf.stop_gradient(x) if freeze else x
                l = l + x
        l = BNReLU('bnlast',l)  
    return l

def encoder(i, freeze):
    d1 = Conv2D('conv0',  i, 64, 7, padding='valid', strides=1, activation=BNReLU)
    d1 = res_blk('group0', d1, [ 64,  64], [3, 3], 3, strides=1, freeze=freeze)

    d2 = res_blk('group1', d1, [128, 128], [3, 3], 4, strides=2, freeze=freeze)
    d2 = tf.stop_gradient(d2) if freeze else d2

    d3 = res_blk('group2', d2, [256, 256], [3, 3], 6, strides=2, freeze=freeze)
    d3 = tf.stop_gradient(d3) if freeze else d3

    d4 = res_blk('group3', d3, [512, 512], [3, 3], 3, strides=2, freeze=freeze)
    d4 = tf.stop_gradient(d4) if freeze else d4

    d4 = Conv2D('conv_bot',  d4, 1024, 1, padding='same')
    return [d1, d2, d3, d4]
© www.soinside.com 2019 - 2024. All rights reserved.