ожидается, что input_1 будет иметь 3 измерения, но получит массив с формой (3, 4) - PullRequest
4 голосов
/ 14 апреля 2019

Это упрощенная версия моего кода, которая выдает ошибку, упомянутую в заголовке:

import tensorflow as tf

BATCH_SIZE = 3
SEQ_LENGTH = 4
NUM_CLASSES = 2
LSTM_UNITS = 64
NUM_SHARDS = 4
NUM_CHANNELS = 2

tf.enable_eager_execution()

def keras_model():
    inputs = tf.keras.layers.Input(shape=(SEQ_LENGTH, NUM_CHANNELS))
    x = tf.keras.layers.Bidirectional(
        tf.keras.layers.LSTM(LSTM_UNITS, return_sequences=True))(inputs)
    outputs = tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(NUM_CLASSES, activation='relu'))(x)
    return tf.keras.Model(inputs, outputs)

dataset = tf.data.experimental.CsvDataset(filenames='../../input/aFile.csv', header=True,record_defaults=[tf.int64] * 3, select_cols=[0,1,2])
dataset=  dataset.window(size=SEQ_LENGTH, shift=1, drop_remainder=True).flat_map(lambda f1,f2, label:
            tf.data.Dataset.zip((tf.data.Dataset.zip((f1.batch(SEQ_LENGTH),f2.batch(SEQ_LENGTH))), label.batch(SEQ_LENGTH))))
dataset = dataset.batch(BATCH_SIZE, drop_remainder=True)


train_iterator = dataset.make_one_shot_iterator()
train_features, train_labels = train_iterator.get_next()

print(train_features)
print(train_labels)

model = keras_model()
model.summary()
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
model.fit(x=train_features,y=train_labels, batch_size=BATCH_SIZE,epochs=1, steps_per_epoch=10)

, и это вывод кода:

...
(<tf.Tensor: id=44, shape=(3, 4), dtype=int64, numpy=
array([[0, 1, 2, 3],
       [1, 2, 3, 4],
       [2, 3, 4, 5]], dtype=int64)>, <tf.Tensor: id=45, shape=(3, 4), dtype=int64, numpy=
array([[100, 101, 102, 103],
       [101, 102, 103, 104],
       [102, 103, 104, 105]], dtype=int64)>)
tf.Tensor(
[[0 0 0 0]
 [0 0 0 1]
 [0 0 1 0]], shape=(3, 4), dtype=int64)
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 4, 2)              0         
_________________________________________________________________
bidirectional (Bidirectional (None, 4, 128)            34304     
_________________________________________________________________
time_distributed (TimeDistri (None, 4, 2)              258       
=================================================================
Total params: 34,562
Trainable params: 34,562
Non-trainable params: 0
_________________________________________________________________
...
ValueError: Error when checking input: expected input_1 to have 3 dimensions, but got array with shape (3, 4)

Process finished with exit code 1

I'mиспользуя этот CSV-файл для демонстрации

f1,f2,label
0,100,0
1,101,0
2,102,0
3,103,0
4,104,1
5,105,0
6,106,0
7,107,0
8,108,1
9,109,0
10,110,0

Два первых столбца - это столбцы объектов, поступающие из двух разных каналов, а последний столбец содержит метки.Мне нужно использовать последовательность, например, из четырех строк данных, в качестве времени для подачи в модель, в то время как размер пакета, например, равен трем, поэтому форма ввода будет похожа на три пакета из четырех строк, где каждая строка содержит два значения.Я думаю, что мне нужно использовать какую-то функцию изменения формы, но не могу понять, как.Может кто-нибудь сказать, пожалуйста, как решить проблему?

Ответы [ 2 ]

1 голос
/ 17 мая 2019

Сегодня я снова посмотрел на это, и я думаю, что вы можете решить эту проблему, изменив функцию разбора следующим образом:

def parse_values(f1, f2, label):
    features = tf.stack([f1, f2], 0)
    return features, label
1 голос
/ 19 апреля 2019

при первой попытке решить проблемы, я изменил код, чтобы сначала объединить каналы, чтобы построить столбцы объектов, а затем создать последовательность столбцов объектов.Это изменило форму ввода с [batch_size, channel_num, sequence_length] на [batch_size, sequence_length, channel_num] и добавило измерение к меткам, как и ожидает модель.Вот новый код:

import tensorflow as tf
import numpy as np

BATCH_SIZE = 3
SEQ_LENGTH = 4
NUM_CLASSES = 2
LSTM_UNITS = 64
NUM_SHARDS = 4
NUM_CHANNELS = 2

tf.enable_eager_execution()

def parse_values(f1, f2, label):
    features = [f1,f2]
    return features, label

def keras_model():
    inputs = tf.keras.layers.Input(shape=(SEQ_LENGTH,NUM_CHANNELS))
    x = tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(LSTM_UNITS, return_sequences=True))(inputs)
    outputs = tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(NUM_CLASSES, activation='relu'))(x)
    return tf.keras.Model(inputs, outputs)

dataset = tf.data.experimental.CsvDataset(filenames='../../input/aFile.csv', header=True,record_defaults=[tf.int64] * 3, select_cols=[0,1,2])
dataset=  dataset.map(parse_values).window(size=SEQ_LENGTH, shift=1, drop_remainder=True).flat_map(lambda features, label:
            tf.data.Dataset.zip((features.batch(SEQ_LENGTH), label.batch(SEQ_LENGTH))))
dataset = dataset.batch(BATCH_SIZE, drop_remainder=True)


train_iterator = dataset.make_one_shot_iterator()
train_features, train_labels = train_iterator.get_next()

print(train_features)
#train_labels = train_labels[:,SEQ_LENGTH-1] # output => [0 1 0]
#print(train_labels)
train_labels = np.expand_dims(train_labels, axis=2)
print(train_labels)

model = keras_model()
model.summary()
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
model.fit(x=train_features,y=train_labels, batch_size=BATCH_SIZE,epochs=1, steps_per_epoch=10)

И ниже вывод:

...tf.Tensor(
[[[  0 100]
  [  1 101]
  [  2 102]
  [  3 103]]

 [[  1 101]
  [  2 102]
  [  3 103]
  [  4 104]]

 [[  2 102]
  [  3 103]
  [  4 104]
  [  5 105]]], shape=(3, 4, 2), dtype=int64)
[[[0]
  [0]
  [0]
  [0]]

 [[0]
  [0]
  [0]
  [1]]

 [[0]
  [0]
  [1]
  [0]]]
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 4, 2)              0         
_________________________________________________________________
bidirectional (Bidirectional (None, 4, 128)            34304     
_________________________________________________________________
time_distributed (TimeDistri (None, 4, 2)              258       
=================================================================
Total params: 34,562
Trainable params: 34,562
Non-trainable params: 0
_________________________________________________________________

 1/10 [==>...........................] - ETA: 8s - loss: 13.3860 - acc: 0.1667
10/10 [==============================] - 1s 101ms/step - loss: 12.9909 - acc: 0.1667

Process finished with exit code 0

Для меня было бы более разумно иметь только одну метку на последовательность, которая определяет, принадлежит ли последовательностьк категории 0 или 1 (в моем случае 3 значения для каждой партии, так как размер партии равен 3).Я попытался сделать это, добавив строку кода (показанную ниже), которую мне пришлось позже закомментировать, так как это вызвало исключение «Несовместимые формы: [3] против [3,4]»

train_labels = train_labels [:, SEQ_LENGTH-1] # output => [0 1 0]

Я не мог понять, как исправить эту ошибку, поэтому, как вы могли видеть в выводе, который я выдалметки всех строк, содержащихся в последовательности к модели.Позже я придумал хитрость, чтобы иметь одинаковый ярлык для всех элементов в последовательности.Я решил установить все метки в последовательности до последней метки в последовательности.Например, [0 0 0 1] изменится на [1 1 1 1], а [0 0 1 0] изменится на [0 0 0 0].Я также изменил функцию потерь на 'binary_crossentropy', поскольку проблема заключается в бинарной классификации здесь.Ниже приведен код:

import tensorflow as tf
import numpy as np

BATCH_SIZE = 3
SEQ_LENGTH = 4
NUM_CLASSES = 1
LSTM_UNITS = 64
NUM_SHARDS = 4
NUM_CHANNELS = 2

tf.enable_eager_execution()

def parse_values(f1, f2, label):
    features = [f1,f2]
    return features, label

def map_label(features, label):
    sequence_label1 = tf.fill([SEQ_LENGTH],label[SEQ_LENGTH-1])
    return features, sequence_label1

def keras_model():
    inputs = tf.keras.layers.Input(shape=(SEQ_LENGTH,NUM_CHANNELS),batch_size=BATCH_SIZE)
    x = tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(LSTM_UNITS, return_sequences=True))(inputs)
    outputs = tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(NUM_CLASSES, activation='sigmoid'))(x)
    return tf.keras.Model(inputs, outputs)

dataset = tf.data.experimental.CsvDataset(filenames='../../input/aFile.csv', header=True,record_defaults=[tf.int64] * 3, select_cols=[0,1,2])
dataset=  dataset.map(parse_values).window(size=SEQ_LENGTH, shift=1, drop_remainder=True).flat_map(lambda features, label:
            tf.data.Dataset.zip((features.batch(SEQ_LENGTH), label.batch(SEQ_LENGTH)))).map(map_label)
dataset = dataset.batch(BATCH_SIZE, drop_remainder=True)

train_iterator = dataset.make_one_shot_iterator()
train_features, train_labels = train_iterator.get_next()

print(train_features)
train_labels = np.expand_dims(train_labels, axis=2)
print(train_labels)

model = keras_model()
model.summary()
model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])
model.fit(x=train_features,y=train_labels, batch_size=BATCH_SIZE,epochs=1, steps_per_epoch=10)   

И ниже вывод:

...tf.Tensor(
[[[  0 100]
  [  1 101]
  [  2 102]
  [  3 103]]

 [[  1 101]
  [  2 102]
  [  3 103]
  [  4 104]]

 [[  2 102]
  [  3 103]
  [  4 104]
  [  5 105]]], shape=(3, 4, 2), dtype=int64)
[[[0]
  [0]
  [0]
  [0]]

 [[1]
  [1]
  [1]
  [1]]

 [[0]
  [0]
  [0]
  [0]]]
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (3, 4, 2)                 0         
_________________________________________________________________
bidirectional (Bidirectional (3, 4, 128)               34304     
_________________________________________________________________
time_distributed (TimeDistri (3, 4, 1)                 129       
=================================================================
Total params: 34,433
Trainable params: 34,433
Non-trainable params: 0
_________________________________________________________________
...

 1/10 [==>...........................] - ETA: 10s - loss: 0.6866 - acc: 0.5833
10/10 [==============================] - 1s 124ms/step - loss: 0.6571 - acc: 0.6500

Process finished with exit code 0

Надеюсь, это поможет всем, кто сталкивается с подобными проблемами.

...