def evaluate(architecture, waves, trues, labels, infos, gpu_id, waveFs,
             fileParam):
    if cupy is not None and gpu_id >= 0:
        xp = cupy
        cupy.cuda.Device(gpu_id).use()
    else:
        xp = np

    valIndex = coreTestIndex(infos)

    devBatchSizeUpper = 2**8
    devSegmentSecUpper = 0.1
    devSegmentLenUpper = int(devSegmentSecUpper * waveFs)

    devIndex = sorted(valIndex, key=lambda i: len(waves[i]))
    devIndex = np.array(devIndex)
    devBatchIndex = np.array_split(
        devIndex, int(np.ceil(len(devIndex) / devBatchSizeUpper)))
    devLabelSize = np.zeros(len(labels), int32)
    for i in devIndex:
        for li, la in enumerate(labels):
            devLabelSize[li] += (trues[i] == li).sum()

    net = Net(len(labels), architecture, functions.elu)
    serializers.load_hdf5(fileParam, net)
    if gpu_id >= 0: net.to_gpu(gpu_id)
    inputLength = totalInputLength(architecture)

    with chainer.using_config("enable_backprop", False):
        confusion = np.zeros((len(labels), len(labels)), int32)
        for index in devBatchIndex:
            waveLen = len(waves[index[-1]])
            segmentTimes = np.array_split(
                np.arange(waveLen), int(np.ceil(waveLen / devSegmentLenUpper)))
            net.reset()
            for si, segTime in enumerate(segmentTimes):
                t0 = segTime[0]
                t1 = segTime[-1] + 1
                x = np.zeros((len(index), t1 - t0), float32)
                tr = -np.ones((len(index), t1 - t0), int32)
                for xi, wi in enumerate(index):
                    if len(waves[wi]) > t0:
                        w = waves[wi][t0:t1]
                        x[xi, :len(w)] = w
                    if len(waves[wi]) > t0: tr[xi, :len(w)] = trues[wi][t0:t1]

                x = x[:, newaxis, :, newaxis]
                x = xp.asarray(x)
                x = Variable(x)
                x = net(x, False)

                x = xp.argmax(x.data, axis=1)
                if cupy is not None: x = cupy.asnumpy(x)
                x = x.flatten()
                tr = tr.flatten()
                for xi, ti in zip(x, tr):
                    if ti >= 0: confusion[ti, xi] += 1

        assert (np.sum(confusion, axis=1) == devLabelSize).all()
        return confusion
def evaluate(architecture, waves, infos, gpu_id, waveFs, fileParam):
    if cupy is not None and gpu_id >= 0:
        xp = cupy
        cupy.cuda.Device(gpu_id).use()
    else:
        xp = np

    inputLength = totalInputLength(architecture)
    labels = getLabels()
    numLabel = len(labels)
    groupFold = ((0, 1, 2), (3, ), (4, ))

    devSize = 2**1
    devSegmentSecUpper = 10

    net = Net(numLabel, architecture, functions.elu)
    serializers.load_hdf5(fileParam, net)
    if gpu_id >= 0: net.to_gpu(gpu_id)

    devSegmentLenUpper = int(devSegmentSecUpper * waveFs)
    devFold = sorted(set(groupFold[2]))
    devLabelWave = groupLabelWave((devFold, ), infos)[0]
    devLabelWave = list(
        itertools.chain.from_iterable([[(li, i) for i in devLabelWave[la]]
                                       for li, la in enumerate(labels)]))
    devLabelWave = sorted(devLabelWave, key=lambda lw: len(waves[lw[1]]))
    devBatchIndex = np.array_split(np.arange(len(devLabelWave)),
                                   int(np.ceil(len(devLabelWave) / devSize)))
    devLabelSize = np.zeros(numLabel, int32)
    for li, wi in devLabelWave:
        devLabelSize[li] += len(waves[wi])

    devWaves = {}
    for li, wi in devLabelWave:
        wave = waves[wi]
        wave = np.concatenate((wave, np.zeros((inputLength - 1) // 2,
                                              float32)))
        devWaves[wi] = wave

    with chainer.using_config("enable_backprop", False):
        confusion = np.zeros((numLabel, numLabel), int32)
        for bi, index in enumerate(devBatchIndex):
            waveIndex = np.array([devLabelWave[i][1] for i in index])
            tru = np.array([devLabelWave[i][0] for i in index])
            waveLen = len(devWaves[waveIndex[-1]])
            segmentTimes = np.array_split(
                np.arange(waveLen), int(np.ceil(
                    (waveLen) / devSegmentLenUpper)))
            net.reset()
            for si, segTime in enumerate(segmentTimes):
                t0 = segTime[0]
                t1 = segTime[-1] + 1
                x = np.zeros((len(index), t1 - t0), float32)
                tr = -np.ones((len(index), t1 - t0), int32)
                for xi, wi in enumerate(waveIndex):
                    if len(devWaves[wi]) <= t0: continue
                    w = devWaves[wi][t0:t1]
                    x[xi, :len(w)] = w
                    tr[xi, :len(w)] = tru[xi]
                if t0 < (inputLength - 1) // 2:
                    tr[:, :(inputLength - 1) // 2 - t0] = -1

                x = x[:, newaxis, :, newaxis]
                x = xp.asarray(x)
                x = Variable(x)
                x = net(x, False)
                x.unchain_backward()

                x = xp.argmax(x.data, axis=1)
                if gpu_id >= 0: x = cupy.asnumpy(x)
                x = x.flatten()
                tr = tr.flatten()
                for xi, ti in zip(x[tr >= 0], tr[tr >= 0]):
                    confusion[ti, xi] += 1

        net.reset()
        assert (np.sum(confusion, axis=1) == devLabelSize).all()
        return confusion