首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带两个预训练ResNet 50的暹罗神经网络--测试模型中的奇异行为

带两个预训练ResNet 50的暹罗神经网络--测试模型中的奇异行为
EN

Stack Overflow用户
提问于 2019-05-27 09:48:10
回答 1查看 3.3K关注 0票数 0

我用Keras建立了暹罗神经网络。我的模型有两个形状输入(64,64,3),两个预培训的ResNet-50.损失函数是二元交叉熵。

该模型是建立在本文一个链接的基础上的。

在列车运行过程中,具有很好的特性/val精度,约为0.99/0.98,低损耗0.01/0.05。

但是当我测试我保存的模型时,我会得到不好的结果。这个模型连两幅相同的照片都认不出来。

我还注意到了奇怪的行为:时代越多,结果就越糟糕。以两幅相同图像为例,训练模型与10历元进行预测:"8.jpg":0.5180479884147644,而100 训练的模型“8.jpg”为"8.jpg":5.579867080537926E-13,而对于100历元,训练效果较好。

我为CNN尝试过不同的模式: ResNet18,不同的输入形状,比如(224,224,3)或(128,128,3)。

另外,我也有三合会使用的训练前模型,只有ResNet50/ResNet18没有预先训练的重量。但是我在测试真实模型的时候也有同样的坏结果。

我的代码是

代码语言:javascript
复制
def create_base_model(image_shape, dropout_rate, suffix=''):
    I1 = Input(shape=image_shape)
    model = ResNet50(include_top=False, weights='imagenet', input_tensor=I1, pooling=None)
    model.layers.pop()
    model.outputs = [model.layers[-1].output]
    model.layers[-1].outbound_nodes = []

    for layer in model.layers:
        layer.name = layer.name + str(suffix)
        layer.trainable = False

    flatten_name = 'flatten' + str(suffix)

    x = model.output
    x = Flatten(name=flatten_name)(x)
    x = Dense(1024, activation='relu')(x)
    x = Dropout(dropout_rate)(x)
    x = Dense(512, activation='relu')(x)
    x = Dropout(dropout_rate)(x)

    return x, model.input


def create_siamese_model(image_shape, dropout_rate):

    output_left, input_left = create_base_model(image_shape, dropout_rate)
    output_right, input_right = create_base_model(image_shape, dropout_rate, suffix="_2")

    L1_layer = Lambda(lambda tensors: tf.abs(tensors[0] - tensors[1]))
    L1_distance = L1_layer([output_left, output_right])
    L1_prediction = Dense(1, use_bias=True,
                          activation='sigmoid',
                          kernel_initializer=RandomNormal(mean=0.0, stddev=0.001),
                          name='weighted-average')(L1_distance)

    prediction = Dropout(0.2)(L1_prediction)

    siamese_model = Model(inputs=[input_left, input_right], outputs=prediction)

    return siamese_model

siamese_model = create_siamese_model(image_shape=(64, 64, 3),
                                         dropout_rate=0.2)

siamese_model.compile(loss='binary_crossentropy',
                      optimizer=Adam(lr=0.0001),
                      metrics=['binary_crossentropy', 'acc'])
siamese_model.fit_generator(train_gen,
                            steps_per_epoch=1000,
                            epochs=10,
                            verbose=1,
                            callbacks=[checkpoint, tensor_board_callback, lr_reducer, early_stopper, csv_logger],
                            validation_data=validation_data,
                            max_q_size=3)

siamese_model.save('siamese_model.h5')



# and the my prediction
siamese_net = load_model('siamese_model.h5', custom_objects={"tf": tf})

X_1 = [image, ] * len(markers)
batch = [markers, X_1]
result = siamese_net.predict_on_batch(batch)

# I've tried also to check identical images 
markers = [image]
X_1 = [image, ] * len(markers)
batch = [markers, X_1]
result = siamese_net.predict_on_batch(batch)

我对我的预测方法有些怀疑。有人能帮我找出预测的问题吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-27 10:26:45

你得到的一切都是意料之中的。我不知道你说的是什么

我还注意到了奇怪的行为:时代越多,结果就越糟糕。

但您所显示的结果是有效的和预期的。让我们从模型的输出开始。模型输出是第一输入和第二输入之间的(规范化)距离。如果输入是相似的,那么距离应该接近于零。随着训练步数的增加,模型学会识别输入,即当输入相似时,模型学习输出值接近于零,如果输入不同,模型学习到接近1的输出值。所以,

..。10个历元的训练模型预测为:"8.jpg":0.5180479884147644,而“8.jpg”为“8.jpg”,“8.jpg”为5.5798670537926E-13,而100个历元的训练效果较好。

,确认模型已经了解到这两个输入是相似的,并输出5.579867080537926E-13 ~ 0(大约接近0)。

尽管模型运行良好,但我在模型定义中注意到一个问题:-输出层是退出层。退出是无效的输出层。你通过这个设置所做的是,随机地将模型的输出设置为0,概率为0.2。

假设目标变量有1(两个输入是不同的),并且模型已经学会正确识别图像,并在退出层之前输出接近1的值。让我们进一步假设辍学层已经决定将输出设置为零。所以模型输出为零。虽然辍学前的各层表现良好,但由于辍学层的存在,它们将受到惩罚。如果这不是你所看到的,然后删除最后的辍学层。

代码语言:javascript
复制
L1_prediction = Dense(1, use_bias=True,
                    activation='sigmoid',
                    kernel_initializer=RandomNormal(mean=0.0, stddev=0.001),
                    name='weighted-average')(L1_distance)


siamese_model = Model(inputs=[input_left, input_right], outputs=L1_prediction)

但是,如果要向模型添加噪声,有时就需要这种行为。这与在值为1时随机更改目标变量具有相同的效果。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56323567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档