【发布时间】:2020-07-16 21:51:05
【问题描述】:
我正在尝试训练 CNN 使用 keras。输入是 128x128x3 的 rbg 图像,输出是 0 到 1 之间的单个值(这不是分类器模型)。我已经标准化了输入。最初,我的模型取得了一些合理的结果,平均绝对误差小于 0.1。当我尝试稍微调整模型时,我发现损失会很快稳定在 0.23 左右。我进一步调查发现它为每个输入输出相同的值。
所以我将我的代码恢复到它工作的时候,但它不再工作了。我最终发现大约 90% 的时间它会卡在这个局部最小值,输出一个恒定值(我怀疑这是训练参考值的平均值(0.39)。另外 10% 的时间它会表现得很好并且回归到
我试过了:
- 更改输入大小
- 将学习率提高/降低 10 倍
- 删除几个密集层
- 将“relu”更改为“泄漏的 relu”
- 增加/消除辍学
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)
【问题讨论】:
-
嗨!您可以尝试使用 BatchNormalization 吗?并且您的 16 大小的 Dense 层具有 sigmoid 激活,然后是 LeakyReLU 激活!如果你想对这些层使用 LeakyReLU,你应该考虑删除activation='sigmoid'。在 Dense(64) 之后您也有相同的配置。对于 0 到 1 之间的值,只有最后一层必须是 activation='sigmoid'。
标签: python tensorflow machine-learning keras conv-neural-network