Как начинающий TensorFlow, я пытаюсь получить семантическую модель сегментации изображений, работающую с использованием функционального API TensorFlow Keras и категориальной кросс-энтропии для каждого пикселя (по крайней мере, это и есть намерение):
from __future__ import absolute_import, division, print_function
import tensorflow as tf
import numpy as np
import os
tf.enable_eager_execution()
NUM_TRAINING_SAMPLES = 123
NUM_CLASSES = 24
RES_WIDTH = 256
RES_HEIGHT = 256
BATCH_SIZE = 5
NUM_EPOCHS = 3
images = np.random.random((NUM_TRAINING_SAMPLES, RES_WIDTH, RES_HEIGHT, 3))
annotations = np.zeros(((NUM_TRAINING_SAMPLES, RES_WIDTH, RES_HEIGHT, NUM_CLASSES)))
one_hot_pixel = np.eye(1, NUM_CLASSES)[0]
annotations[:, :, :] = one_hot_pixel
map(np.random.shuffle, annotations[:])
dataset = tf.data.Dataset.from_tensor_slices((images, annotations))
dataset = dataset.batch(3)
def conv_block(input_layer, num_filters):
layer = tf.keras.layers.Conv2D(num_filters, (3, 3), padding='same')(input_layer)
layer = tf.keras.layers.BatchNormalization()(layer)
layer = tf.keras.layers.Activation('relu')(layer)
layer = tf.keras.layers.Conv2D(num_filters, (3, 3), padding='same')(layer)
layer = tf.keras.layers.BatchNormalization()(layer)
layer = tf.keras.layers.Activation('relu')(layer)
layer = tf.keras.layers.MaxPooling2D((2, 2), strides=(2, 2))(layer)
return layer
def deconv_block(input_layer, num_filters):
layer = tf.keras.layers.Conv2DTranspose(num_filters, (2, 2), strides=(2, 2), padding='same')(input_layer)
layer = tf.keras.layers.BatchNormalization()(layer)
layer = tf.keras.layers.Activation('relu')(layer)
layer = tf.keras.layers.Conv2D(num_filters, (3, 3), padding='same')(layer)
layer = tf.keras.layers.BatchNormalization()(layer)
layer = tf.keras.layers.Activation('relu')(layer)
layer = tf.keras.layers.Conv2D(num_filters, (3, 3), padding='same')(layer)
layer = tf.keras.layers.BatchNormalization()(layer)
layer = tf.keras.layers.Activation('relu')(layer)
return layer
inputs = tf.keras.layers.Input(shape=(RES_WIDTH, RES_HEIGHT, 3)) # 256
encoder0 = conv_block(inputs, 32) # 128
encoder1 = conv_block(encoder0, 64) # 64
encoder2 = conv_block(encoder1, 128) # 32
encoder3 = conv_block(encoder2, 256) # 16
encoder4 = conv_block(encoder3, 512) # 8
center = conv_block(encoder4, 1024) # center
decoder4 = conv_block(center, 512) # 16
decoder3 = conv_block(decoder4, 256) # 32
decoder2 = conv_block(decoder3, 128) # 64
decoder1 = conv_block(decoder2, 64) # 128
decoder0 = conv_block(decoder1, 32) # 256
outputs = tf.keras.layers.Conv2D(NUM_CLASSES, (1, 1), activation='sigmoid')(decoder0)
model = tf.keras.Model(inputs=[inputs], outputs=[outputs]) #model = tf.keras.Model(inputs=[images], outputs=[output])
model.compile(optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.001), loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(dataset, batch_size=BATCH_SIZE, epochs=NUM_EPOCHS, steps_per_epoch=40, callbacks=[tf.keras.callbacks.TensorBoard(log_dir='./logs')])
Пока я просто симулирую входные данные и знаю, что мои аннотации одинаковы для каждого пикселя.Сначала я просто хочу кое-что потренировать.Однако, когда я запускаю это, я получаю следующую трассировку стека:
---------------------------------------------------------------------------
InvalidArgumentError Traceback (most recent call last)
<ipython-input-52-0905074e93d1> in <module>
63 model.compile(optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.001), loss='categorical_crossentropy', metrics=['accuracy'])
64
---> 65 model.fit(dataset, batch_size=BATCH_SIZE, epochs=NUM_EPOCHS, steps_per_epoch=40, callbacks=[tf.keras.callbacks.TensorBoard(log_dir='./logs')])
C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\engine\training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, max_queue_size, workers, use_multiprocessing, **kwargs)
849 validation_steps=validation_steps,
850 workers=0,
--> 851 initial_epoch=initial_epoch)
852 elif distributed_training_utils.is_tpu_strategy(
853 self._distribution_strategy):
C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\engine\training_generator.py in model_iteration(model, data, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch, mode, batch_size, **kwargs)
189 progbar.on_batch_begin(step, batch_logs)
190
--> 191 batch_outs = batch_function(*batch_data)
192 if not isinstance(batch_outs, list):
193 batch_outs = [batch_outs]
C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\engine\training.py in train_on_batch(self, x, y, sample_weight, class_weight, reset_metrics)
1177 if self.run_eagerly:
1178 outputs = training_eager.train_on_batch(
-> 1179 self, x, y, sample_weights=sample_weights)
1180 else:
1181 if not isinstance(K.symbolic_learning_phase(), int):
C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\engine\training_eager.py in train_on_batch(model, inputs, targets, sample_weights)
258
259 outs, loss, loss_metrics, _, masks = _process_single_batch(
--> 260 model, inputs, targets, sample_weights=sample_weights, training=True)
261 if not isinstance(outs, list):
262 outs = [outs]
C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\engine\training_eager.py in _process_single_batch(model, inputs, targets, output_loss_metrics, sample_weights, training)
212 output_loss_metrics=output_loss_metrics,
213 sample_weights=sample_weights,
--> 214 training=training)
215 if loss is None:
216 raise ValueError('The model cannot be run '
C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\engine\training_eager.py in _model_loss(model, inputs, targets, output_loss_metrics, sample_weights, training)
140 weighted_masked_fn = training_utils.weighted_masked_objective(loss_fn)
141 output_loss = weighted_masked_fn(
--> 142 targets[i], outs[i], weights, mask=mask)
143
144 # If the number of outputs is 1 then we don't append the loss metric
C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\engine\training_utils.py in weighted(y_true, y_pred, weights, mask)
645 """
646 # score_array has ndim >= 2
--> 647 score_array = fn(y_true, y_pred)
648 if mask is not None:
649 mask = math_ops.cast(mask, y_pred.dtype)
C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\losses.py in categorical_crossentropy(y_true, y_pred, from_logits)
484 'keras.losses.categorical_crossentropy')
485 def categorical_crossentropy(y_true, y_pred, from_logits=False):
--> 486 return K.categorical_crossentropy(y_true, y_pred, from_logits=from_logits)
487
488
C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\backend.py in categorical_crossentropy(target, output, from_logits, axis)
3866 epsilon_ = _to_tensor(epsilon(), output.dtype.base_dtype)
3867 output = clip_ops.clip_by_value(output, epsilon_, 1. - epsilon_)
-> 3868 return -math_ops.reduce_sum(target * math_ops.log(output), axis)
3869 else:
3870 return nn.softmax_cross_entropy_with_logits_v2(labels=target, logits=output)
C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\ops\math_ops.py in binary_op_wrapper(x, y)
810 with ops.name_scope(None, op_name, [x, y]) as name:
811 if isinstance(x, ops.Tensor) and isinstance(y, ops.Tensor):
--> 812 return func(x, y, name=name)
813 elif not isinstance(y, sparse_tensor.SparseTensor):
814 try:
C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\ops\math_ops.py in _mul_dispatch(x, y, name)
1076 is_tensor_y = isinstance(y, ops.Tensor)
1077 if is_tensor_y:
-> 1078 return gen_math_ops.mul(x, y, name=name)
1079 else:
1080 assert isinstance(y, sparse_tensor.SparseTensor) # Case: Dense * Sparse.
C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\ops\gen_math_ops.py in mul(x, y, name)
5854 else:
5855 message = e.message
-> 5856 _six.raise_from(_core._status_to_exception(e.code, message), None)
5857 # Add nodes to the TensorFlow graph.
5858 _, _, _op = _op_def_lib._apply_op_helper(
C:\ProgramData\Anaconda3\lib\site-packages\six.py in raise_from(value, from_value)
InvalidArgumentError: Incompatible shapes: [3,256,256,24] vs. [3,0,0,24] [Op:Mul] name: loss/conv2d_252_loss/mul/
Я знаю, что это как-то связано с моим имитированным набором данных, но я не уверен, что делать дальше.Любая помощь с благодарностью!