0

我在 PyCharm 中使用 Tensorflow 和 keras 使用功能 api 创建了一个多输入网络。

如何将数据传递给这些模型的一个示例如下:

    def create_model_multiple():

    input1 = tf.keras.Input(shape=(13,), name = 'I1')
    input2 = tf.keras.Input(shape=(6,), name = 'I2')
    hidden1 = tf.keras.layers.Dense(units = 4, activation='relu')(input1)
    hidden2 = tf.keras.layers.Dense(units = 4, activation='relu')(input2)
    merge = tf.keras.layers.concatenate([hidden1, hidden2])
    hidden3 = tf.keras.layers.Dense(units = 3, activation='relu')(merge)
    output1 = tf.keras.layers.Dense(units = 2, activation='softmax', name ='O1')(hidden3)
    output2 = tf.keras.layers.Dense(units = 2, activation='softmax', name = 'O2')(hidden3)
    model = tf.keras.models.Model(inputs = [input1,input2], outputs = [output1,output2])
    model.compile(optimizer='adam',
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])
    return model


x1 = np.random.uniform(0,1, (190,13))
x2 = np.random.uniform(0,1, (190,6))
val_x1 = np.random.uniform(0,1, (50,13))
val_x2 = np.random.uniform(0,1, (50,6))

y1 = np.random.randint(0,2, 190)
y2 = np.random.randint(0,2, 190)
val_y1 = np.random.randint(0,2, 50)
val_y2 = np.random.randint(0,2, 50)


model = create_model_multiple()

history = model.fit({'I1':x1, 'I2':x2},
                    {'O1':y1, 'O2': y2},
                    validation_data=([val_x1,val_x2], [val_y1,val_y2]), # <=========
                    epochs=100,
                    verbose = 1)

在上面的示例中,数据被加载为 NumPy 并形成为[val_x1,val_x2]. 但是由于内存和数据集大小的限制,我必须使用 tf.data 来准备数据集。我的数据集由 2 个类中的图像组成(每个形状都是(5000,20)。我加载了所有图像。网络输入层是1d-Cnn每个接受的(5000,1)。假设我给网络这样的输入:

X是一个形状为(5000,20)的样本(图像),我必须将其转换为形状为(5000,1)的子样本x1,x2,......,x20,然后调用fit()方法。

model.fit([x1,x2,x3,...,x20])

我的问题就在这里。我用tf.data. 数据集的每个样本都有一个带有类的形状(5000,20)和标签(2,1)的图像样本。2现在我无法将一个 tf 数据样本转换为给出model.fit()方法的样本列表。

我用谷歌搜索并找到了这个解决方案,但它对我不起作用。

 dataset = tf.data.Dataset(....) # suppose each sample in dataset is a triple (2-features and 1 label)

def input_solver(sample):
    return {'input_1': sample[0], 'input_2': sample[1]}, sample[2]

dataset.map(input_solver) # this will map the first and the second feature in this triple-sample to the inputs.
model.fit(dataset, epochs=5)

这是我的完整代码:

import pathlib
import numpy as np
from tensorflow.keras.layers import Bidirectional,Conv1D,Input,MaxPooling1D,BatchNormalization,ReLU,concatenate,Flatten,LSTM,Dense
from tensorflow.keras.models import Model
import tensorflow as tf
import os


def conv_1d_block(num_block,visible1):
    # visible1 = Input(shape=(n_steps, n_features))
    cnn1_cnn = Conv1D(filters=32, kernel_size=1, activation='relu')(visible1)
    cnn1_pool = MaxPooling1D(pool_size=25,padding='same')(cnn1_cnn)
    cnn1_batchnorm = BatchNormalization()(cnn1_pool)
    cnn1_relu = ReLU()(cnn1_batchnorm)
    # cnn1_flat = Flatten()(cnn1_relu)

    cnn2_cnn = Conv1D(filters=64, kernel_size=1, activation='relu')(cnn1_relu)
    cnn2_pool = MaxPooling1D(pool_size=25,padding='same')(cnn2_cnn)
    cnn2_batchnorm = BatchNormalization()(cnn2_pool)
    cnn2_relu = ReLU()(cnn2_batchnorm)

    cnn3_cnn = Conv1D(filters=128, kernel_size=1, activation='relu')(cnn2_relu)
    cnn3_pool = MaxPooling1D(pool_size=12,padding='same')(cnn3_cnn)
    cnn3_batchnorm = BatchNormalization()(cnn3_pool)
    cnn3_relu = ReLU()(cnn3_batchnorm)

    # cnn4_cnn = Conv1D(filters=256, kernel_size=1, activation='relu')(cnn3_relu)
    # cnn4_pool = MaxPooling1D(pool_size=2)(cnn4_cnn)
    # cnn4_batchnorm = BatchNormalization()(cnn4_pool)
    # cnn4_relu = ReLU()(cnn4_batchnorm)
    # cnn4_faltten = Flatten()(cnn4_relu)

    # return cnn4_relu
    return cnn3_relu
def build_model(num_signal):
    input_all = []
    cnn_all = []
    # cnn_all_c = []
    for j in range(num_signal):
        input_temp = Input(shape=(n_steps, n_features))
        cnn_temp = conv_1d_block(4,input_temp)
        input_all.append(input_temp)
        cnn_all.append(cnn_temp)
    cnn_all_c = concatenate(cnn_all)
    lstm_layer = Bidirectional(LSTM(256))(cnn_all_c)
    fc1_layer = Dense(512,activation='relu')(lstm_layer)
    fc2_layer = Dense(2,activation='softmax')(fc1_layer)
    output_layer = fc2_layer
    model = Model(inputs=input_all, outputs = output_layer)
    return model




n_features = 1
n_steps = 5000
directory = "images_dir"
train_dir = pathlib.Path(directory)
CLASS_NAMES = np.array([item.name for item in train_dir.glob('*') if item.name != "LICENSE.txt"])
print(CLASS_NAMES)
full_dataset = tf.data.Dataset.list_files(str(train_dir/'*/*'))
validation_split = 0.2

DATASET_SIZE = len(list(full_dataset))
print("Dataset size: ", DATASET_SIZE)
train_size = int((1-validation_split) * DATASET_SIZE)
print("train size: ", train_size)
train_dataset = full_dataset.take(train_size)
validation_dataset = full_dataset.skip(train_size)

def get_label(file_path):
  parts = tf.strings.split(file_path, os.path.sep)
  return parts[-2] == CLASS_NAMES


def load_img(image_path):
    img = tf.io.read_file(image_path)
    img = tf.image.decode_image(img, 3, expand_animations=False)
    img = tf.image.rgb_to_grayscale(img)
    # img = tf.image.rot90(img)
    img = tf.squeeze(img)
    img = tf.cast(img, tf.float32)
    return img

def normalize(image):
    image = (image / 127.5) - 1
    return image

def load_image_with_label(image_path):
    label = get_label(image_path)
    img = load_img(image_path)
    return img, label


def load_image_train(image_file):
    image, label = load_image_with_label(image_file)
    image = normalize(image)
    return image, label
def load_image_test(image_file):
    image, label = load_image_with_label(image_file)
    image = normalize(image)
    # image = tf.squeeze(image)
    return image, label

BATCH_SIZE = 5
SHUFFLE_BUFFER_SIZE = 1000

train_dataset1 = train_dataset.map(load_image_train)
train_dataset1 = train_dataset1.shuffle(SHUFFLE_BUFFER_SIZE)
# train_dataset = train_dataset.batch(BATCH_SIZE)
for image, label in train_dataset1.take(3):
    print(image.shape)
    print(label.shape)
    print(label)


# validation_dataset = validation_dataset.map(load_image_test)
# validation_dataset = validation_dataset.batch(BATCH_SIZE)

def input_solver(sample,label):
    keyf = "input_{}"
    valf = "{}"
    print("sample",sample[0])
    print("sample shape",sample.shape)
    # dictionary comprehension
    # a = {keyf.format(i): valf.format(i) for i in range(1,n_ch+1)}
    # can modify range to handle 1,000,000 if you wanted
    # print(a)
    return {'input_1': sample[0], 'input_2': sample[1],'input_3': sample[2],'input_4': sample[3],'input_5': sample[4],
            'input_6': sample[5], 'input_7': sample[6],'input_8': sample[7],'input_9': sample[8],'input_10': sample[9],
            'input_11': sample[10], 'input_12': sample[11],'input_13': sample[12],'input_14': sample[13],'input_15': sample[14],
            'input_16': sample[15], 'input_17': sample[16],'input_18': sample[17],'input_19': sample[18],'input_20': sample[19]
            }, label
    # return {keyf.format(i): valf.format(sample[i]) for i in range(1,21)},label
    # return {keyf.format(i): valf.format(sample[i]) for i in range(1,21)},label

# return {'input_1': sample[0], 'input_2': sample[1]}, sample[2]

# for image, label in validation_dataset.take(3):
#     print(image.shape)
#     print(label.shape)


# train_dataset2 = train_dataset1.map(input_solver)
for image, label in train_dataset1.take(3):
    print(image.shape)
    print(label.shape)
    print(label)


train_dataset2 = train_dataset1.map(input_solver)

n_ch = 20
model = build_model(n_ch)
# model.summary()
model.compile(loss=tf.keras.losses.categorical_crossentropy,optimizer='adam',metrics=['accuracy'])
history = model.fit(train_dataset1,
                    epochs=100)


# history = model.fit(train_dataset,
#                     epochs=100,
#                     validation_data=validation_dataset)
4

0 回答 0