<p dir="auto">As per <a href="https://stackoverflow.com/questions/52267297/why-does-an-instance-of-the-keras-sequence-iterate-forever" rel="nofollow">Goodword's question</a>, the <code class="notranslate">keras.utils.Sequence</code> class seems to iterate forever instead of stopping after a full epoch. To duplicate, run the following snippet.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="class InfiniteGenerator(object):
    def __init__(self, alist):
        self.alist = alist

    def __getitem__(self, idx):
        return self.alist[idx]

    def __len__(self):
        return len(self.alist)

    def __iter__(self):
        for item in (self[i] for i in range(len(self))):
            yield item

from keras.utils import Sequence

class KGen(Sequence):
    def __init__(self, alist):
        self.alist = alist

    def __getitem__(self, idx):
        return self.alist[idx]

    def __len__(self):
        return len(self.alist)


if __name__ ==  '__main__':
    ig = InfiniteGenerator(list(range(4)))
    for item in ig:
        print(item)


    print('now trying second iterator')

    import time
    time.sleep(1)

    kg = KGen(list(range(4)))
    for item in kg:
        print(item)"><pre class="notranslate"><code class="notranslate">class InfiniteGenerator(object):
    def __init__(self, alist):
        self.alist = alist

    def __getitem__(self, idx):
        return self.alist[idx]

    def __len__(self):
        return len(self.alist)

    def __iter__(self):
        for item in (self[i] for i in range(len(self))):
            yield item

from keras.utils import Sequence

class KGen(Sequence):
    def __init__(self, alist):
        self.alist = alist

    def __getitem__(self, idx):
        return self.alist[idx]

    def __len__(self):
        return len(self.alist)


if __name__ ==  '__main__':
    ig = InfiniteGenerator(list(range(4)))
    for item in ig:
        print(item)


    print('now trying second iterator')

    import time
    time.sleep(1)

    kg = KGen(list(range(4)))
    for item in kg:
        print(item)
</code></pre></div>
<p dir="auto">The output will be as follows:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="0
1
2
3
now trying second iterator
0
1
2
3
0
1
2
3
0
1
2
3
and so on ..."><pre class="notranslate"><code class="notranslate">0
1
2
3
now trying second iterator
0
1
2
3
0
1
2
3
0
1
2
3
and so on ...
</code></pre></div>
<p dir="auto">Tested on</p>
<ul dir="auto">
<li>Ubuntu 18.04</li>
<li>Keras 2.2.4</li>
<li>Tensorflow 1.11.0</li>
</ul>
<p dir="auto">Hi, guys. I want to extract features through CNN and do sequence labeling. I have looked at <a href="https://github.com/fchollet/keras/issues/129" data-hovercard-type="issue" data-hovercard-url="/keras-team/keras/issues/129/hovercard">#129</a>, but could not catch it. I'm trying to implement <a href="https://arxiv.org/ftp/arxiv/papers/1604/1604.04573.pdf" rel="nofollow">this model</a>. The model figure is like follows:</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/30307594/28408138-0be8f83a-6d69-11e7-98a3-beffa6df3aad.png"><img src="https://user-images.githubusercontent.com/30307594/28408138-0be8f83a-6d69-11e7-98a3-beffa6df3aad.png" alt="_20170720163116" style="max-width: 100%;"></a></p>
<p dir="auto">This is a multi-label question.  At each timestep, the LSTM input is the previous predicted label, and target is the next label to predicted.  As the number of the label may be different for each sample, so the length of each sample is different, I use batch size == 1 to train the model.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="import numpy as np
from keras.layers import Input, concatenate
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.layers.recurrent import LSTM
from keras.layers.embeddings import Embedding
from keras.layers.core import Dense, Flatten, Reshape
from keras.layers.wrappers import TimeDistributed
from keras.models import Model, Sequential
from keras.optimizers import Adam
from keras.utils import to_categorical
class_num = 10
embed_size = 128
def build_model():
    model = Sequential()
    image_input = Input(shape=[None, 28, 28, 3])
    conv1 = TimeDistributed(Convolution2D(filters=32, kernel_size=(3, 3), strides=(1, 1),
                         padding='same', activation='relu', name='conv1'))(image_input)
    pool1 = TimeDistributed(MaxPooling2D(pool_size=(2, 2), name='pool1'))(conv1)
    conv_flatten = TimeDistributed(Flatten(name='conv_flatten'))(pool1)
    label_input = Input(shape=[None])
    embedding1 = Embedding(class_num + 1, embed_size)(label_input)
    lstm1 = LSTM(output_dim=128, return_sequences=True)(embedding1)
    # lstm_flatten = Reshape(name='lstm_flatten')(lstm1)
    conca_output = concatenate([conv_flatten, lstm1])
    dense1 = TimeDistributed(Dense(units=100, activation='relu', name='dense1'))(conca_output)
    dense2 = TimeDistributed(Dense(units=class_num, activation='softmax', name='output'))(dense1)
    model = Model(inputs=[image_input, label_input], outputs=dense2)
    model.compile(loss='categorical_crossentropy', optimizer=Adam(lr=1e-3))
    model.summary()
return model


def train():
    num_cases = 32
    batch_size = 1
    image = np.random.randn(num_cases, 28, 28, 3)
    x_label = []
    y_label = []
    for i in range(32):
        # indicate how many samples in a label
        label_len = np.random.choice(class_num + 1)
        if label_len == 0:
            label_len += 1
        cnt_label = np.random.choice(class_num, size=label_len)
        categorical_label = cnt_label
        x_label.append(categorical_label)
        cnt_label = cnt_label[1:]
        # use class_num to indicate end label
        cnt_label = np.append(cnt_label, [class_num])
        categorical_label = to_categorical(cnt_label)
        y_label.append(categorical_label)
    model = build_model()
    num_batch = num_cases / batch_size
    for i in range(num_batch):
        loss = model.train_on_batch([np.expand_dims(image[i, :, :, :], 0), np.expand_dims(x_label[i], 0)],
                                    np.expand_dims(y_label[i], 0))
        print '%.3f' % loss
if __name__ == '__main__':
    np.random.seed(42)
    train()"><pre class="notranslate"><code class="notranslate">import numpy as np
from keras.layers import Input, concatenate
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.layers.recurrent import LSTM
from keras.layers.embeddings import Embedding
from keras.layers.core import Dense, Flatten, Reshape
from keras.layers.wrappers import TimeDistributed
from keras.models import Model, Sequential
from keras.optimizers import Adam
from keras.utils import to_categorical
class_num = 10
embed_size = 128
def build_model():
    model = Sequential()
    image_input = Input(shape=[None, 28, 28, 3])
    conv1 = TimeDistributed(Convolution2D(filters=32, kernel_size=(3, 3), strides=(1, 1),
                         padding='same', activation='relu', name='conv1'))(image_input)
    pool1 = TimeDistributed(MaxPooling2D(pool_size=(2, 2), name='pool1'))(conv1)
    conv_flatten = TimeDistributed(Flatten(name='conv_flatten'))(pool1)
    label_input = Input(shape=[None])
    embedding1 = Embedding(class_num + 1, embed_size)(label_input)
    lstm1 = LSTM(output_dim=128, return_sequences=True)(embedding1)
    # lstm_flatten = Reshape(name='lstm_flatten')(lstm1)
    conca_output = concatenate([conv_flatten, lstm1])
    dense1 = TimeDistributed(Dense(units=100, activation='relu', name='dense1'))(conca_output)
    dense2 = TimeDistributed(Dense(units=class_num, activation='softmax', name='output'))(dense1)
    model = Model(inputs=[image_input, label_input], outputs=dense2)
    model.compile(loss='categorical_crossentropy', optimizer=Adam(lr=1e-3))
    model.summary()
return model


def train():
    num_cases = 32
    batch_size = 1
    image = np.random.randn(num_cases, 28, 28, 3)
    x_label = []
    y_label = []
    for i in range(32):
        # indicate how many samples in a label
        label_len = np.random.choice(class_num + 1)
        if label_len == 0:
            label_len += 1
        cnt_label = np.random.choice(class_num, size=label_len)
        categorical_label = cnt_label
        x_label.append(categorical_label)
        cnt_label = cnt_label[1:]
        # use class_num to indicate end label
        cnt_label = np.append(cnt_label, [class_num])
        categorical_label = to_categorical(cnt_label)
        y_label.append(categorical_label)
    model = build_model()
    num_batch = num_cases / batch_size
    for i in range(num_batch):
        loss = model.train_on_batch([np.expand_dims(image[i, :, :, :], 0), np.expand_dims(x_label[i], 0)],
                                    np.expand_dims(y_label[i], 0))
        print '%.3f' % loss
if __name__ == '__main__':
    np.random.seed(42)
    train()
</code></pre></div>
<p dir="auto">My question is:</p>
<ol dir="auto">
<li>How to use batch size == 32 to train this model? (e.g. Use mask layer, however, the flatten layer does not support mask)</li>
<li>The input to CNN is (n_samples, n_timesteps, row, column, channel). I need to duplicate the images across time steps (As for each time step, I input the same image). Is there any elegant way to do it? I want to use RepeatVector Layer, but for each sample, the timesteps are different. What is the parameter input to the RepeatVector?</li>
</ol>