Ввод данных в tensorflow nn, по-видимому, не в правильном формате

#python #tensorflow #point-clouds

#python #tensorflow #облака точек

Вопрос:

итак, я загружаю файлы .off в NN для классификации — просто для практики, поскольку мне нужно работать с voxelgrids, для этого я использую облака точек. я новичок во всем этом, поэтому прошу прощения, если это очевидно.

как только сеть пытается скомпилировать (в 1-ю эпоху), она останавливается с этой ошибкой:

 ValueError: Input 0 of layer sequential is incompatible with the layer: 
: expected min_ndim=5, found ndim=4. Full shape received: [None, 16, 16, 16]
 

итак, я попытался установить значение ‘channel’ с помощью tf.reshape или tf.expand_dim, но это не удается, поскольку он не может преобразовать тензорный фрагмент в тензор (вот что он говорит).

итак, в чем проблема? Мне как-то нужно добавить другое измерение в векторы — input_shape нужен канал для value, что, я думаю, здесь не имеет смысла, поскольку у меня нет RGB.

def load_train(self):

     train_set_full = []
    train_labels_full = []

    train_set = []
    train_labels = []

    validate_set = []
    validate_labels = []

    for item in listdir(self.path):

        for obj in listdir(self.path   item   "/test"):
            test1 = PyntCloud.from_file(self.path   item   "/test/"   obj)
            cloud = test1.get_sample(
                "mesh_random",
                n=self.n,
                rgb=False,
                normals=False,
                as_PyntCloud=True)

            voxelgrid_id = cloud.add_structure("voxelgrid", n_x=16, n_y=16, n_z=16)
            voxelgrid = cloud.structures[voxelgrid_id]

            train_set_full.append(voxelgrid.get_feature_vector())
            train_labels_full.append(item)
    i = round(len(train_set_full) / 1.25)
    validate_set = train_set_full[i:]
    validate_labels = train_labels_full[i:]
    train_set = train_set_full[:i]
    train_labels = train_labels_full[:i]
    np.array(train_set)
    np.array(train_labels)
    np.array(validate_set)
    np.array(validate_labels)

    train_dataset = tf.data.Dataset.from_tensor_slices((train_set, train_labels))
    train_dataset = train_dataset.shuffle(len(train_set)).batch(32)
    validate_dataset = tf.data.Dataset.from_tensor_slices((validate_set, validate_labels))
    validate_dataset = validate_dataset.shuffle(len(validate_set)).batch(32)

    return train_dataset, validate_dataset
 

класс Model1:

 def __init__(self):
    self.netmodel = models.Sequential()
    self.netmodel.add(layers.Conv3D(filters=16, kernel_size=[3, 3, 3], padding='same', activation=tf.nn.relu,
                                    input_shape=(16, 16, 16, 1), data_format="channels_last"))
    self.netmodel.add(layers.MaxPooling3D(pool_size=[2, 2, 2], strides=2))
    self.netmodel.add(layers.Conv3D(filters=32, kernel_size=[3, 3, 3], padding='same', activation=tf.nn.relu))

    #self.netmodel.add(layers.MaxPooling3D(pool_size=[2, 2, 2], strides=2))
    self.netmodel.add(layers.BatchNormalization(trainable=True))

    # self.netmodel.add(layers.MaxPooling3D((2, 2, 2), strides=2))
    # self.netmodel.add(layers.Conv3D(64, (3, 3, 3), activation='relu',data_format='channels_first'))
    self.netmodel.add(layers.Flatten())
    self.netmodel.add(layers.Dense(32, activation='relu'))
    self.netmodel.add(layers.Dense(10))

def build_model(self, train_data, validate_data):
    self.netmodel.compile(optimizer='adam',
                          loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                          metrics=['accuracy'])

    history = self.netmodel.fit(train_data, epochs=10,
                                validation_data=validate_data)
    return history
 

Ответ №1:

tf.keras.layers.Conv3D Ожидает ввода формы 5 D тензора с формой: batch_shape (channels, conv_dim1, conv_dim2, conv_dim3) если data_format=’channels_first’ или 5 D тензора с формой: batch_shape (conv_dim1, conv_dim2, conv_dim3, channels) если data_format=’channels_last’.

Соответствующим образом измените форму ввода. Или, если ваш ввод представляет собой 2D-изображение, с которым вы можете использовать ту же форму ввода tf.keras.layers.Conv2D , которая ожидает 4D input_shape.