TF.Keras Как подогнать модель к набору данных TFRECORDS?

Я написал простой файл TFRECORDS, содержащий три функции и метку. Поскольку я следую руководствам, мне кажется, что для использования этих TFRECORDS мне нужно создать набор данных, проанализировать примеры, сделать другие вещи, такие как нормализация с помощью map (). Если это неправильный рабочий процесс, я был бы признателен!

    dataset = tf.data.TFRecordDataset("dataset.tfrecords")
    
    #parse the protobuffer
    
    def _parse_function(proto):
        # define your tfrecord again. 
        keys_to_features = {'weight_pounds': tf.io.FixedLenFeature([], tf.float32),
                            'gestation_weeks': tf.io.FixedLenFeature([], tf.float32),
                            'plurality': tf.io.FixedLenFeature([], tf.float32),
                            'isMale': tf.io.FixedLenFeature([], tf.float32),
                          
                           
                           }
        
        # Load one example
        parsed_features = tf.io.parse_example(proto, keys_to_features)
        
        # Turn your saved image string into an array
        #parsed_features['image'] = tf.decode_raw(
        #    parsed_features['image'], tf.uint8)
        
        return parsed_features
    
    hold_meanstd={
        'weight_pounds':[7.234738,1.330294],
        'gestation_weeks':[38.346464,4.153269],
        'plurality':[1.035285,0.196870]
    }
    
    def normalize(example):
        example['weight_pounds']=(example['weight_pounds']-hold_meanstd['weight_pounds'][0])/hold_meanstd['weight_pounds'][1]
        example['gestation_weeks']=(example['gestation_weeks']-hold_meanstd['gestation_weeks'][0])/hold_meanstd['gestation_weeks'][1]
        example['plurality']=(example['plurality']-hold_meanstd['plurality'][0])/hold_meanstd['plurality'][1]
        label=example.pop('isMale')
        return(example,label)

dataset = tf.data.TFRecordDataset(["dataset.tfrecords"]).map(_parse_function)
dataset =dataset.map(normalize)
dataset =dataset.batch(64)

Затем, получив этот набор данных, я подумал, что могу использовать модель Keras:

Dense = keras.layers.Dense
model = keras.Sequential(
        [
            Dense(500, activation="relu", kernel_initializer='uniform',
                  input_shape=(3,)),
            Dense(200, activation="relu"),
            Dense(100, activation="relu"),
            Dense(25, activation="relu"),
            Dense(1, activation="sigmoid")
        ])

optimizer = keras.optimizers.RMSprop(lr=0.01)

    # Compile Keras model
model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=[tf.keras.metrics.AUC()])
    
model.fit(dataset)

Это вызывает ошибку:

 ValueError: Layer sequential_1 expects 1 inputs, but it received 3 input tensors. Inputs received: [<tf.Tensor 'ExpandDims:0' shape=(None, 1) dtype=float32>, <tf.Tensor 'ExpandDims_1:0' shape=(None, 1) dtype=float32>, <tf.Tensor 'ExpandDims_2:0' shape=(None, 1) dtype=float32>]

Кажется, проблема в том, что входной набор данных выглядит как три входа вместо одного? Как разрешить Керасу тренироваться на наборе данных TF RECORDS?


person B_Miner    schedule 19.10.2020    source источник


Ответы (1)


После указания input_shape=(3,) в вашем первом плотном слое ваша модель keras ожидает на входе тензор с формой (None,3) (где None определяет размер пакета). Например, можно взять следующее:

[
[0.0,0.0,0.0]
]

Если мы посмотрим на ваш tf.data.Dataset, мы увидим, что он возвращает словарь. Каждый ввод будет выглядеть так:

{
"weight_pounds":[0.0],
"gestation_weeks":[0.0],
"plurality":[0.0]
}

который немного отличается от указанного выше input_shape!

Чтобы исправить это, у вас есть два решения:

  • отбросить структуру данных словаря. Для этого вы можете немного изменить свою функцию нормализации:
def normalize(example):
    example['weight_pounds']=(example['weight_pounds']-hold_meanstd['weight_pounds'][0])/hold_meanstd['weight_pounds'][1]
    example['gestation_weeks']=(example['gestation_weeks']-hold_meanstd['gestation_weeks'][0])/hold_meanstd['gestation_weeks'][1]
    example['plurality']=(example['plurality']-hold_meanstd['plurality'][0])/hold_meanstd['plurality'][1]
    label=example.pop('isMale')
    # removing the dict struct
    data_input = [example['weight_pounds'], example['gestation_weeks'], example['plurality']]
    return(data_input,label)


  • используйте Layers.DenseFeatures в качестве входных данных. слой::
from keras.layers import Dense, DenseFeatures
from tensorflow.feature_column import numeric_column

feature_names = ['weight_pounds', 'gestation_weeks', 'plurality']
columns = [numeric_column(header) for header in feature_names]

model = keras.Sequential(
        [
            DenseFeatures(columns)
            Dense(500, activation="relu", kernel_initializer='uniform'),
            Dense(200, activation="relu"),
            Dense(100, activation="relu"),
            Dense(25, activation="relu"),
            Dense(1, activation="sigmoid")
        ])
person Lescurel    schedule 19.10.2020