我根据链接中的指南实现了一个序列生成器对象。
import tensorflow as tf
from cv2 import imread, resize
from sklearn.utils import shuffle
from cv2 import imread, resize
import numpy as np
from tensorflow.keras import utils
import math
import keras as ks
class reader(tf.keras.utils.Sequence):
def __init__(self, x, y, batch_size, n_class):
self.x, self.y = x, y
self.batch_size = batch_size
self.n_class = n_class
def __len__(self):
return math.ceil(len(self.x) / self.batch_size)
def __getitem__(self, idx):
print('getitem', idx)
batch_x = self.x[idx * self.batch_size:(idx + 1) *
self.batch_size]
batch_y = self.y[idx * self.batch_size:(idx + 1) *
self.batch_size]
data_x = list()
for batch in batch_x:
tmp = list()
for img_path in batch:
try:
img = imread(img_path)
tmp.append(img)
except Exception as e:
print(e)
print('failed to find path {}'.format(img_path))
data_x.append(tmp)
#
data_x = np.array(data_x, dtype='object')
data_y = np.array(batch_y)
data_y = utils.to_categorical(data_y, self.n_class)
print('return item')
print(data_x.shape)
return (data_x, data_y)
def on_epoch_end(self):
# option method to run some logic at the end of each epoch: e.g. reshuffling
print('on epoch end')
seed = np.random.randint()
self.x = shuffle(self.x, random_state=seed)
self.y = shuffle(self.y, random_state=seed)
但是,它不适用于 tensorflow 模型的 fit api。下面是我用来复制这个问题的简单模型架构。
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv3D(10, input_shape=(TEMPORAL_LENGTH,HEIGHT,WIDTH,CHANNEL), kernel_size=(2,2,2), strides=2))
model.add(tf.keras.layers.Conv3D(10, kernel_size=(2,3,3), strides=2))
model.add(tf.keras.layers.Conv3D(10, kernel_size=(2,3,3), strides=2))
model.add(tf.keras.layers.Conv3D(10, kernel_size=(2,3,3), strides=2))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(10))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy', tf.keras.metrics.Precision(), tf.keras.metrics.Recall()])
model.summary()
让我创建一个阅读器
r1 = reader(x_train, y_train, 20, 10)
然后我调用 model.fit api。
train_history = model.fit(r1, epochs=3, steps_per_epoch=5, verbose=1)
### output ###
getitem 0
return item
(20, 16, 192, 256, 3)
WARNING:tensorflow:sample_weight modes were coerced from
...
to
['...']
Train for 5 steps
Epoch 1/3
如果我不打扰,它将永远保持这种状态。出于好奇,我使用从 Keras api 创建的模型尝试了这种方法,令我惊讶的是它居然可以工作!
model = ks.models.Sequential()
model.add(ks.layers.Conv3D(10, input_shape=(TEMPORAL_LENGTH,HEIGHT,WIDTH,CHANNEL), kernel_size=(2,2,2), strides=2))
model.add(ks.layers.Conv3D(10, kernel_size=(2,3,3), strides=2))
model.add(ks.layers.Conv3D(10, kernel_size=(2,3,3), strides=2))
model.add(ks.layers.Conv3D(10, kernel_size=(2,3,3), strides=2))
model.add(ks.layers.Flatten())
model.add(ks.layers.Dense(10))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary()
train_history = model.fit(r1, epochs=3, steps_per_epoch=5, verbose=1)
### output ###
Epoch 1/3
getitem 586
return item
(20, 16, 192, 256, 3)
getitem 169
1/5 [=====>........................] - ETA: 22s - loss: 11.0373 - accuracy: 0.0000e+00return item
(20, 16, 192, 256, 3)
getitem 601
2/5 [===========>..................] - ETA: 12s - loss: 7.9983 - accuracy: 0.0250 return item
(20, 16, 192, 256, 3)
getitem 426
3/5 [=================>............] - ETA: 8s - loss: 10.7049 - accuracy: 0.2500return item
(20, 16, 192, 256, 3)
getitem 243
4/5 [=======================>......] - ETA: 3s - loss: 8.5093 - accuracy: 0.1875
依赖项
- 张量流GPU:2.1
- keras GPU:2.3.1