У меня большой массив данных, состоящий из изображений и связанных скалярных данных. Изображения довольно большие, поэтому я не могу разместить весь свой тренировочный набор в памяти на моей машине.
Из-за этого я переместил свой код на использование наборов данных и генераторов наборов данных.
Потому что моя модель использует как данные изображения, так и скалярные данные, и модель сначала обрабатывает их отдельно перед объединением, мне пришлось написать функцию генератора, которая выдает словарь.
for i in range(len(name)):
image =tf.cast(images[i],tf.float32)
scalar=tf.cast(scalars[i],tf.float32)
value = {'img':image,'data':scalar}
localstate=tf.cast(state[i],tf.bool)
#print("yielding with state: ",localstate," with shape ",tf.shape(localstate),flush=True)
if (train):
yield value,localstate
else:
yield value
позже в моем коде, когда придет время чтобы соответствовать моей модели, вот как это выглядит.
train_dataset = tf.data.Dataset.from_generator(functools.partial(pickleGen, phase=names[phase],band=band,chunks=trainchunks)
,({'img':tf.float32,'data':tf.float32}, tf.bool)
,output_shapes=({'img':(1523,312,8,),'data':(439,)},[])
).batch(batchsize)
inputImg = tf.keras.Input(shape=(1523,312,8),name='img')
inputVec = tf.keras.Input(shape=(439),name='data')
x = tf.keras.layers.Conv2D(32,(3,3), activation='relu')(inputImg)
x = tf.keras.layers.MaxPooling2D((2,2))(x)
x = tf.keras.layers.Conv2D(64,(3,3), activation='relu')(x)
x = tf.keras.layers.MaxPooling2D((2,2))(x)
x = tf.keras.layers.Conv2D(256,(3,3), activation='relu')(x)
x = tf.keras.layers.MaxPooling2D((2,2))(x)
x = tf.keras.layers.Flatten()(x)
x = tf.keras.layers.Dense(512, activation=tf.nn.relu)(x)
x = tf.keras.layers.Dropout(rate=.2)(x)
x = tf.keras.layers.Dense(128, activation=tf.nn.relu)(x)
x = tf.keras.Model(inputs=inputImg,outputs=x)
y = tf.keras.layers.Flatten()(inputVec)
y = tf.keras.layers.Dense(512, activation=tf.nn.relu)(y)
y = tf.keras.layers.Dropout(rate=.2)(y)
y = tf.keras.layers.Dense(128, activation=tf.nn.relu)(y)
y = tf.keras.Model(inputs=inputVec,outputs=y)
combo = tf.keras.layers.concatenate([x.output,y.output],axis=1)
z = tf.keras.layers.Dense(256, activation=tf.nn.relu)(combo)
z = tf.keras.layers.Dropout(rate=.2)(z)
z = tf.keras.layers.Dense(64, activation=tf.nn.relu)(z)
z = tf.keras.layers.Dense(2, activation=tf.nn.softmax)(z)
model = tf.keras.Model(inputs=[x.input,y.input],outputs=z)
model.compile(optimizer = tf.optimizers.Adam(),
loss = 'sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(train_dataset, epochs=epochs)
Все это прекрасно работает, пока не придет время что-то сделать с моей обученной моделью.
test_dataset = tf.data.Dataset.from_generator(functools.partial(pickleGen, phase=names[phase],band=band,chunks=testchunks),
({'img':tf.float32,'data':tf.float32},tf.bool),
output_shapes=({'img':(1523,312,8,),'data':(439,)})
).batch(batchsize)
results = model.evaluate(test_dataset)
Я получаю та же ошибка при использовании предикта или оценки.
File "./trial8_apply.py", line 127, in <module>
output_shapes=({'img':(1523,312,8,),'data':(439,)})
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/data/ops/dataset_ops.py", line 540, in from_generator
output_types, tensor_shape.as_shape, output_shapes)
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/data/util/nest.py", line 464, in map_structure_up_to
assert_shallow_structure(shallow_tree, input_tree)
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/data/util/nest.py", line 305, in assert_shallow_structure
% (type(input_tree), type(shallow_tree)))
TypeError: The two structures don't have the same sequence type. Input structure has type <class 'dict'>, while shallow structure has type <class 'tuple'>.
И так как я не уверен, правильно ли я строю свой тестовый набор данных, я попробовал два разных способа сделать это, и если я это сделаю:
test_dataset = tf.data.Dataset.from_generator(functools.partial(pickleGen, phase=names[phase],band=band,chunks=testchunks,train=False),
({'img':tf.float32,'data':tf.float32}),
output_shapes=({'img':(1523,312,8,),'data':(439,)})
).batch(batchsize)
тогда я получаю другую ошибку от оценки или предсказания:
results = model.evaluate(test_dataset)
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training.py", line 833, in evaluate
use_multiprocessing=use_multiprocessing)
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2.py", line 456, in evaluate
sample_weight=sample_weight, steps=steps, callbacks=callbacks, **kwargs)
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2.py", line 444, in _model_iteration
total_epochs=1)
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2.py", line 123, in run_one_epoch
batch_outs = execution_function(iterator)
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2_utils.py", line 86, in execution_function
distributed_function(input_fn))
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py", line 457, in __call__
result = self._call(*args, **kwds)
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py", line 503, in _call
self._initialize(args, kwds, add_initializers_to=initializer_map)
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py", line 408, in _initialize
*args, **kwds))
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py", line 1848, in _get_concrete_function_internal_garbage_collected
graph_function, _, _ = self._maybe_define_function(args, kwargs)
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py", line 2150, in _maybe_define_function
graph_function = self._create_graph_function(args, kwargs)
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/eager/function.py", line 2041, in _create_graph_function
capture_by_value=self._capture_by_value),
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/framework/func_graph.py", line 915, in func_graph_from_py_func
func_outputs = python_func(*func_args, **func_kwargs)
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/eager/def_function.py", line 358, in wrapped_fn
return weak_wrapped_fn().__wrapped__(*args, **kwds)
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2_utils.py", line 66, in distributed_function
model, input_iterator, mode)
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2_utils.py", line 118, in _prepare_feed_values
inputs = [inputs[key] for key in model._feed_input_names]
File "/stage/neocam/fops/sw/vsn1.0.0/ext/anaconda3/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_v2_utils.py", line 118, in <listcomp>
inputs = [inputs[key] for key in model._feed_input_names]
KeyError: 'input_1'
Может кто-нибудь объяснить, как предполагается использовать модель, для которой требуется набор данных, который должен иметь выход словаря но вместо кортежа?
Или кто-то может объяснить, как заставить этот набор работать с набором данных на основе кортежа?
Редактировать: Вот пример того, как выглядят мои данные обучения.
yielding with state: tf.Tensor(False, shape=(), dtype=bool) and value: {'img': <tf.Tensor: id=1768, shape=(1523, 312, 8), dtype=float32, numpy=
array([[[255., 255., 255., ..., 255., 255., 255.],
[255., 255., 255., ..., 255., 255., 255.],
[255., 255., 255., ..., 255., 255., 255.],
...,
[255., 255., 255., ..., 255., 255., 255.],
[255., 255., 255., ..., 255., 255., 255.],
[255., 255., 255., ..., 255., 255., 255.]],
<snip>
[[255., 255., 255., ..., 128., 128., 255.],
[255., 255., 255., ..., 181., 181., 255.],
[255., 255., 255., ..., 181., 181., 255.],
...,
[ 0., 0., 0., ..., 255., 255., 255.],
[ 0., 0., 0., ..., 255., 255., 255.],
[ 0., 0., 0., ..., 255., 255., 255.]]], dtype=float32)>, 'data': <tf.Tensor: id=1770, shape=(439,), dtype=float32, numpy=
array([ 6.8934107e-01, 2.1273675e+00, 3.7560204e-01, 1.7010291e+00,
1.3698795e-02, 2.5334918e-01, 1.1520619e-01, 3.4945667e-02,
3.4967816e+02, 2.7520111e+01, 0.0000000e+00, -4.2899999e-01,
-2.0450001e+00, 3.0720000e+00, 1.1680000e+00, -7.1700001e-01,
-1.7660000e+00, 2.8480000e+00, 1.2050000e+00, -2.3829999e+00,
-2.4419999e+00, 2.3120000e+00, 1.3260000e+00, -3.0270000e+00
<snip>
4.9300000e+02, 4.6000000e+02, 4.0500000e+02, 4.0700000e+02,
1.3200000e+02, 1.1500000e+02, 1.4900000e+02, 4.9000000e+01,
6.3000000e+01, 9.6000000e+01, 5.2000000e+01, 2.1000000e+01,
3.5000000e+01, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00,
0.0000000e+00, 2.0000000e+01, 5.0000000e+00], dtype=float32)>}