def train(architecture, waves, infos, gpu_id, waveFs, numEpoch, seed):
    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, ))

    insLabelSize = 2**2

    np.random.seed(seed)
    net = Net(numLabel, architecture, functions.elu)
    # 	opt=Eve(1e-4)
    opt = optimizers.Adam(1e-4)
    opt.setup(net)
    if gpu_id >= 0: net.to_gpu(gpu_id)

    insFold = set(itertools.chain.from_iterable(groupFold[:2]))
    insLabelWave = groupLabelWave((insFold, ), infos)[0]
    insLabelWaveIndex = [[] for i in range(len(labels))]
    for li, la in enumerate(labels):
        for i in insLabelWave[la]:
            wave = waves[i]
            timeIndex = np.arange(len(wave))
            waveIndex = np.ones(len(wave), int32) * i
            index = np.stack((waveIndex, timeIndex), axis=1)
            insLabelWaveIndex[li].append(index)
        insLabelWaveIndex[li] = np.concatenate(insLabelWaveIndex[li], axis=0)

    insRemainingLabelWave = [
        np.random.permutation(insLabelWaveIndex[li])
        for li in range(len(labels))
    ]

    for epoch in range(numEpoch):
        print("Training: Epoch", epoch, "/", numEpoch)

        x, tr = makeInpTru(insLabelWaveIndex, waves, insRemainingLabelWave,
                           inputLength, insLabelSize, numLabel)
        x = x[:, newaxis, :, newaxis]
        x = xp.asarray(x)
        x = Variable(x)
        x = net.callSingle(x, True)
        tr = tr[..., newaxis, newaxis]
        tr = xp.asarray(tr)
        e = functions.softmax_cross_entropy(x, tr)

        net.cleargrads()
        e.backward()
        e.unchain_backward()
        opt.update(loss=e.data)


# 		opt.update()

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

    valIndex = coreTestIndex(infos)
    np.random.seed(0)
    insIndex, = traGroupIndex(infos, 1)
    insIndex = np.array(insIndex)
    insLabelIndexTime = makeLabelIndexTime(insIndex, labels, trues)

    insLabelSize = 2**2  #la12 tot4096 ch128

    inputLength = totalInputLength(architecture)

    np.random.seed(seed)
    net = Net(len(labels), architecture, functions.elu)
    opt = optimizers.Adam(1e-4)
    # 	opt=Eve(1e-4)
    opt.setup(net)
    if gpu_id >= 0: net.to_gpu(gpu_id)

    remainingInsLabelIndexTime = [
        np.random.permutation(lt) for lt in insLabelIndexTime
    ]
    for epoch in range(numEpoch):
        print("Training: Epoch", epoch, "/", numEpoch)
        for li, lit in enumerate(remainingInsLabelIndexTime):
            if len(lit) < insLabelSize:
                remainingInsLabelIndexTime[li] = np.concatenate(
                    (lit, np.random.permutation(insLabelIndexTime[li])))
        x, tr = makeInpTru(labels, insLabelSize, inputLength,
                           remainingInsLabelIndexTime, waves, trues)

        x = x[:, newaxis, :, newaxis]
        x = xp.asarray(x)
        x = Variable(x)
        x = net.callSingle(x, True)
        tr = tr[..., newaxis, newaxis]
        tr = xp.asarray(tr)
        e = functions.softmax_cross_entropy(x, tr, normalize=True)

        net.cleargrads()
        e.backward()
        e.unchain_backward()
        opt.update()


# 		opt.update(loss=e.data)

    return net
def findNumEpoch(architecture, waves, infos, gpu_id, waveFs):
    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, ))

    np.random.seed()
    seed = np.random.randint(0, np.iinfo(int32).max)
    np.random.seed(seed)
    net = Net(numLabel, architecture, functions.elu)
    # 	opt=Eve(1e-4)
    opt = optimizers.Adam(1e-4)
    opt.setup(net)
    if gpu_id >= 0: net.to_gpu(gpu_id)

    insLabelSize = 2**2
    devSize = 2**1
    devSegmentSecUpper = 10

    devEpoch = 2**5
    convergenceEpoch = 2**5 * devEpoch
    devSegmentLenUpper = int(devSegmentSecUpper * waveFs)
    devFold = sorted(set(groupFold[1]))
    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

    insFold = sorted(set(groupFold[0]))
    insLabelWave = groupLabelWave((insFold, ), infos)[0]
    insLabelWaveIndex = [[] for i in range(len(labels))]
    for li, la in enumerate(labels):
        for i in insLabelWave[la]:
            wave = waves[i]
            timeIndex = np.arange(len(wave))
            waveIndex = np.ones(len(wave), int32) * i
            index = np.stack((waveIndex, timeIndex), axis=1)
            insLabelWaveIndex[li].append(index)
        insLabelWaveIndex[li] = np.concatenate(insLabelWaveIndex[li], axis=0)

    insRemainingLabelWave = [
        np.random.permutation(insLabelWaveIndex[li])
        for li in range(len(labels))
    ]

    epoch = 0
    bestEpoch = 0
    epochIncorrect = {}
    while epoch < bestEpoch + convergenceEpoch:
        x, tr = makeInpTru(insLabelWaveIndex, waves, insRemainingLabelWave,
                           inputLength, insLabelSize, numLabel)
        x = x[:, newaxis, :, newaxis]
        x = xp.asarray(x)
        x = Variable(x)
        x = net.callSingle(x, True)
        tr = tr[..., newaxis, newaxis]
        tr = xp.asarray(tr)
        e = functions.softmax_cross_entropy(x, tr)

        net.cleargrads()
        e.backward()
        e.unchain_backward()
        # 		opt.update(loss=e.data)
        opt.update()

        if epoch % devEpoch != devEpoch - 1:
            epoch += 1
            continue
        incorrect = xp.zeros(numLabel, int32)
        with chainer.using_config("enable_backprop", False):
            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)
                    tr = tr[..., newaxis]
                    tr = xp.asarray(tr)
                    for li, la in enumerate(labels):
                        incorrect[li] += (x[tr == li] != li).sum()

            net.reset()
            if gpu_id >= 0: incorrect = cupy.asnumpy(incorrect)
            incorrect = (incorrect / devLabelSize).mean()
            print("epoch", epoch, "incorrect", incorrect)

        if len(epochIncorrect) == 0 or incorrect < epochIncorrect[bestEpoch]:
            bestEpoch = epoch
        epochIncorrect[epoch] = incorrect
        epoch += 1

    devEpochs = np.array(sorted(epochIncorrect), int32)
    bestScore = epochIncorrect[bestEpoch]
    epochIncorrect = np.array([epochIncorrect[ep] for ep in devEpochs])

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

    valIndex = coreTestIndex(infos)
    np.random.seed(0)
    insIndex, devIndex = traGroupIndex(infos, 2)
    insIndex = np.array(insIndex)
    insLabelIndexTime = makeLabelIndexTime(insIndex, labels, trues)

    insLabelSize = 2**2
    devEpoch = 2**5
    convergenceEpoch = 2**5 * devEpoch

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

    devIndex = sorted(devIndex, 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()

    inputLength = totalInputLength(architecture)

    np.random.seed()
    seed = np.random.randint(0, np.iinfo(int32).max)
    np.random.seed(seed)

    net = Net(len(labels), architecture, functions.elu)
    opt = optimizers.Adam(1e-4)
    # 	opt=Eve(1e-4)
    opt.setup(net)
    if gpu_id >= 0: net.to_gpu(gpu_id)

    remainingInsLabelIndexTime = [
        np.random.permutation(lt) for lt in insLabelIndexTime
    ]

    epoch = 0
    bestEpoch = 0
    epochIncorrect = {}
    while epoch < bestEpoch + convergenceEpoch:
        for li, lit in enumerate(remainingInsLabelIndexTime):
            if len(lit) < insLabelSize:
                remainingInsLabelIndexTime[li] = np.concatenate(
                    (lit, np.random.permutation(insLabelIndexTime[li])))
        x, tr = makeInpTru(labels, insLabelSize, inputLength,
                           remainingInsLabelIndexTime, waves, trues)

        x = x[:, newaxis, :, newaxis]
        x = xp.asarray(x)
        x = Variable(x)
        x = net.callSingle(x, True)
        tr = tr[..., newaxis, newaxis]
        tr = xp.asarray(tr)
        e = functions.softmax_cross_entropy(x, tr, normalize=True)

        net.cleargrads()
        e.backward()
        e.unchain_backward()
        opt.update()
        # 		opt.update(loss=e.data)

        if epoch % devEpoch != devEpoch - 1:
            epoch += 1
            continue
        incorrect = xp.zeros(len(labels), int32)
        with chainer.using_config("enable_backprop", False):
            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.unchain_backward()

                    x = xp.argmax(x.data, axis=1)
                    tr = tr[..., newaxis]
                    tr = xp.asarray(tr)
                    for li, la in enumerate(labels):
                        incorrect[li] += (x[tr == li] != li).sum()

            net.reset()
            if cupy is not None: incorrect = cupy.asnumpy(incorrect)
            incorrect = (incorrect / devLabelSize).mean()
            print("epoch", epoch, "incorrect", incorrect)

            if len(epochIncorrect) == 0 or incorrect < min(
                [epochIncorrect[ep] for ep in epochIncorrect]):
                bestEpoch = epoch
            epochIncorrect[epoch] = incorrect
            epoch += 1

    devEpochs = np.array(sorted(epochIncorrect), int32)
    epochIncorrect = np.array([epochIncorrect[ep] for ep in devEpochs])
    bestIncorrect = epochIncorrect.min()

    return bestEpoch, bestIncorrect, seed