首页 > 解决方案 > Tensorflow/Keras 模型输出是恒定的

问题描述

我正在尝试训练 CNN 使用 keras。输入是 128x128x3 rbg 图像,输出是 0 到 1 之间的单个值(这不是分类器模型)。我已经标准化了输入。最初,我的模型取得了一些合理的结果,平均绝对误差小于 0.1。当我尝试稍微调整模型时,我发现损失会很快稳定在 0.23 左右。我进一步调查发现它为每个输入输出相同的值

所以我把我的代码恢复到它工作的时候,但它不再工作了。我最终发现大约 90% 的时间它会卡在这个局部最小值,输出一个恒定值(我怀疑这是训练参考值的平均值(0.39)。另外 10% 的时间它会表现得很好并且回归到 < 0.1 的误差。所以它基本上是随机给出质量不同的行为,很少得到期望的结果。奇怪的是,我发誓它以前一直在工作。

我努力了:

def load_data(dir):
    csv_data = get_csv_data()
    xs = []
    ys = []
    for (name, y) in csv_data:
        path = DIR + dir + "/" + name
        img = tf.keras.preprocessing.image.load_img(path)
        xs.append(tf.keras.preprocessing.image.img_to_array(img) * (1 / 255.0))
        ys.append(normalize_output(float(y)))
    return np.array(xs).reshape(len(csv_data), IMAGE_DIM, IMAGE_DIM, 3), np.array(ys).reshape(len(csv_data), 1)

def gen_model():
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Conv2D(filters=64, kernel_size = (5, 5), activation='relu', input_shape=(IMAGE_DIM, IMAGE_DIM, CHAN_COUNT)))
    model.add(tf.keras.layers.MaxPool2D())
    model.add(tf.keras.layers.Conv2D(filters=64, kernel_size = (5, 5), activation='relu'))
    model.add(tf.keras.layers.MaxPool2D())
    model.add(tf.keras.layers.Conv2D(filters=128, kernel_size = (5, 5), activation='relu'))
    model.add(tf.keras.layers.MaxPool2D())
    model.add(tf.keras.layers.Flatten())
    model.add(tf.keras.layers.Dense(256, activation='relu'))
    model.add(tf.keras.layers.Dropout(0.1))
    model.add(tf.keras.layers.Dense(128, activation='relu'))
    model.add(tf.keras.layers.Dropout(0.1))
    model.add(tf.keras.layers.Dense(64, activation='relu'))
    model.add(tf.keras.layers.Dropout(0.1))
    model.add(tf.keras.layers.LeakyReLU())
    model.add(tf.keras.layers.Dense(16, activation='sigmoid'))
    model.add(tf.keras.layers.LeakyReLU())
    model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
    model.compile(loss=keras.losses.MeanSquaredError(),
                  optimizer=tf.keras.optimizers.Adam(),
                  metrics=[keras.metrics.MeanAbsoluteError()])
    return model

def run():
    model = gen_model()

    xs, ys = load_data("output")
   
    generator = tf.keras.preprocessing.image.ImageDataGenerator(featurewise_center=False,
                                                                samplewise_center=False,
                                                                featurewise_std_normalization=False,
                                                                samplewise_std_normalization=False,
                                                                validation_split=0.1,
                                                                rotation_range=12,
                                                                horizontal_flip=True,
                                                                vertical_flip=True)

    model.fit(generator.flow(xs, ys, batch_size=32, shuffle=True),
              steps_per_epoch=len(xs) / 32,
              epochs = 10,
              use_multiprocessing=False)

标签: pythontensorflowmachine-learningkerasconv-neural-network

解决方案


我重新安排了层上的激活。请试一试 :

def gen_model():
   model = tf.keras.Sequential()
   model.add(tf.keras.layers.Conv2D(filters=64, kernel_size = (5, 5), activation='relu', input_shape=(IMAGE_DIM, IMAGE_DIM, CHAN_COUNT)))
   model.add(tf.keras.layers.MaxPool2D())
   model.add(tf.keras.layers.Conv2D(filters=64, kernel_size = (5, 5), activation='relu'))
   model.add(tf.keras.layers.MaxPool2D())
   model.add(tf.keras.layers.Conv2D(filters=128, kernel_size = (5, 5), activation='relu'))
   model.add(tf.keras.layers.MaxPool2D())
   model.add(tf.keras.layers.Flatten())
   model.add(tf.keras.layers.Dense(256, activation='relu'))
   model.add(tf.keras.layers.Dropout(0.1))
   model.add(tf.keras.layers.Dense(128, activation='relu'))
   model.add(tf.keras.layers.Dropout(0.1))
   model.add(tf.keras.layers.Dense(64, activation='relu'))
   model.add(tf.keras.layers.Dropout(0.1))
   model.add(tf.keras.layers.Dense(16, activation='relu'))
   model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
   model.compile(loss=keras.losses.MeanSquaredError(),
              optimizer=tf.keras.optimizers.Adam(),
              metrics=[keras.metrics.MeanAbsoluteError()])
   return model

推荐阅读