Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 多实例学习问题的Tensorflow Keras实现_Python_Tensorflow_Keras_Nlp - Fatal编程技术网

Python 多实例学习问题的Tensorflow Keras实现

Python 多实例学习问题的Tensorflow Keras实现,python,tensorflow,keras,nlp,Python,Tensorflow,Keras,Nlp,我试图用TensorFlow Keras API实现一个多实例学习模型。假设输入的张量形状是(None,18,10300),我需要使用子模型沿轴=1执行多实例学习。因此,子模型的输入应该是(None,10300)。假设单个子模型的输出张量形状为(无,100),然后将子模型s的输出连接起来,从而创建输出形状(无,18100) 我用两种方法实现了这个机制,它们在功能上应该是相等的,但是,在训练模型时,第二种实现的精度比第一种实现高20%(尽管这两种方法都不够好)。我想知道这两种实现之间是否存在功能上

我试图用TensorFlow Keras API实现一个多实例学习模型。假设输入的张量形状是
(None,18,10300)
,我需要使用
子模型沿
轴=1
执行多实例学习。因此,
子模型
的输入应该是
(None,10300)
。假设单个
子模型
的输出张量形状为
(无,100)
,然后将
子模型
s的输出连接起来,从而创建输出形状
(无,18100)

我用两种方法实现了这个机制,它们在功能上应该是相等的,但是,在训练模型时,第二种实现的精度比第一种实现高20%(尽管这两种方法都不够好)。我想知道这两种实现之间是否存在功能上的差异?如果这两个实现都不是我想要做的,您能给出一个正确的实现吗

执行情况1。此实现使用keras
Lambda
层拆分输入张量,执行
子模型
,在
轴=1
中展开结果维度,然后沿
轴=1
连接结果

def get_branch_模型(输入_形状,子模型,args={}):
模型输入=tf.keras.input(输入形状)
切片_输入=[tf.keras.layers.Lambda(Lambda x:x[:,i])(模型_输入)
对于范围内的i(输入_形[0])]
sub_实例=子模型(**args)
分支_模型=[范围内i的子_实例(切片_输入[i])(输入_形状[0])]
expand_layer=tf.keras.layers.Lambda(Lambda x:tf.keras.backend.expand_dims(x,axis=1))
扩展的_输出=[扩展_层(分支_模型[i]),用于范围内的i(输入_形状[0])]
concated_layer=tf.keras.layers.Concatenate(轴=1)(扩展_输出)
返回tf.keras.Model(Model_输入,concated_层)
实施2。此实现使用
tf.slice
分割输入张量,执行
子模型
,在
轴=1
中展开结果的维度,然后沿
轴=1
连接结果

def\uu get\u filter\u层(总尺寸、目标尺寸、索引):
def张量过滤器(张量输入):
非局部索引
begin=[0如果i!=范围内i的目标尺寸else索引(总尺寸)]
大小=[-1如果i!=目标尺寸,则为1,对于范围内的i(总尺寸)]
返回tf.squence(tf.slice(张量、开始、大小),轴=目标尺寸)
返回tf.keras.models.Sequential([
tf.keras.layers.Lambda(张量滤波器)
])
def get_branch_模型(输入_形状、分支索引、输出_形状、子模型、args={}):
模型输入=tf.keras.input(输入形状)
切片_输入=[u获取_过滤器_层(len(输入_形状)+1,分支_索引,i)(模型_输入)
对于范围内的i(输入形状[分支索引-1])]
sub_实例=子模型(**args)
分支_模型=[子_实例(切片_输入[i])
对于范围内的i(输入形状[分支索引-1])]
expand_layer=tf.keras.layers.Lambda(Lambda x:tf.keras.backend.expand_dims(x,axis=1))
扩展的_输出=[扩展_层(分支_模型[i]),用于范围内的i(输入_形状[0])]
concated_layer=tf.keras.layers.Concatenate(轴=1)(扩展_输出)
返回tf.keras.Model(Model_输入,concated_层)
参数
input\u shape
的输入是
(18,10300)
,而
分支索引是
1
<代码>子模型是一个顺序模型,例如
tf.keras.Sequential([tf.keras.layers.Dense(…)])


您的多实例学习模型是否基于特定的参考模型/论文?我根据本文编写了一个玩具实现


ref

谢谢您的回答!我的是基于
# mitr.py
"""
  weakly supervised learning of a
  linear boundary
"""
import os
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import sys

def mitr(data_gen, batch_size, input_dim, ngroups):

    input = tf.placeholder(tf.float32, [None, input_dim])
    # fraction of training sample containing positive instances
    pos_class_ratio = tf.placeholder(tf.float32, name='pos_class_ratio')
    # group indices present
    group_labels_input = tf.placeholder(tf.int32, [None])
    # sort inputs by group label index
    values, indices = tf.nn.top_k(group_labels_input, k=tf.shape(group_labels_input)[0], sorted=True)
    input = tf.gather(input, indices[::-1], axis=0)
    unique_group_labels_input, unique_group_enum = tf.unique(values[::-1])
    global_step = tf.Variable(0, dtype=tf.int32, trainable=False, name='global_step')

    def lr(x):
        w = tf.Variable(tf.random_normal((2, 1)), dtype=tf.float32)
        b = tf.Variable(tf.random_normal((1,)), dtype=tf.float32)
        return tf.nn.sigmoid(tf.add(tf.matmul(x, w), b))

    def gpp(l, lh):
        l = tf.expand_dims(l, -1)
        lh = tf.expand_dims(lh, -1)
        l_sq = tf.reduce_sum(tf.square(l))
        lh_sq = tf.reduce_sum(tf.square(lh))
        l_lh_dp = tf.matmul(tf.transpose(l), lh)
        return tf.reduce_sum(l_sq - 2 * l_lh_dp + lh_sq)

    def pp(y):
        return pr_sq_diff(y)

    def pr_sq_diff(x):
        x_sq = tf.reduce_sum(tf.square(x), axis=-1)
        x_dp = tf.matmul(x, tf.transpose(x))
        return tf.abs(x_sq - 2 * x_dp + tf.transpose(x_sq))

    def rbf_kernal(x):
        gamma = 1.0
        return tf.exp(-gamma * pr_sq_diff(x))

    def aggpred(y):
        return tf.segment_mean(y[:, 0], unique_group_enum)

    N = tf.constant(batch_size, dtype=tf.float32)
    lambda_c = tf.constant(1.0, dtype=tf.float32)
    K = tf.constant(ngroups, dtype=tf.float32)

    ypred = lr(input)
    loss_1 = 1.0 / tf.square(N) * tf.reduce_sum(rbf_kernal(input) * pp(ypred))
    loss_2 = lambda_c / K * gpp(tf.cast(unique_group_labels_input, tf.float32), aggpred(ypred))
    loss = loss_1 + loss_2
    optimizer = tf.train.AdamOptimizer(learning_rate=1e-3).minimize(loss, global_step=global_step)
    writer = tf.summary.FileWriter("mitr_logs")
    saver = tf.train.Saver()
    with tf.name_scope("summaries"):
        tf.summary.scalar("loss", loss)
        tf.summary.scalar("loss1", loss_1)
        tf.summary.scalar("loss2", loss_2)
        tf.summary.histogram("positive class ratio", pos_class_ratio)

        summary_op = tf.summary.merge_all()

    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        cpkt = tf.train.get_checkpoint_state(os.path.dirname("mitr" + "/checkpoint"))
        if cpkt and cpkt.model_checkpoint_path:
            saver.restore(sess, cpkt.model_checkpoint_path)
            print("Loaded checkpointed model:\n {} for {}.".format(cpkt.model_checkpoint_path,
                                                                   "mitr"))

        fig, axes = plt.subplots(nrows=4, ncols=4)
        fig.set_size_inches(11, 20)

        plt_ix = 0
        for X, group_labels, y, ratio in data_gen(batch_size):
            _, ls, ls1, ls2, step, summary, posrt = sess.run([optimizer, loss, loss_1, loss_2, global_step, summary_op, pos_class_ratio],
                                   feed_dict={input: X, group_labels_input: group_labels, pos_class_ratio: ratio})
            if step % 300 == 0:
                print("Loss: {} Loss1: {} Loss2: {}".format(ls, ls1, ls2))
                print("Fraction of sample data in positive class: {}".format(ratio))
                saver.save(sess, "mitr" + "/" + "mitr", global_step=step)
                writer.add_summary(summary, step)
                writer.flush()
                print("Saved to {}".format("mitr" + "/" + "mitr"))
                heatmap_pred = sess.run(ypred, feed_dict={input: heatmap_input(), group_labels_input: group_labels})
                heatmap(heatmap_pred, axes.flatten()[plt_ix])
                axes.flatten()[plt_ix].set_title("step: {}".format(step))
                plt_ix += 1
                if plt_ix > 15:
                    plt.savefig('heatmap.png', dpi=100)
                    print("Saved heatmap.png")
                    sys.exit(0)



def sample_decision_boundary_small_uniform(batch_size):
    """ Sample random small squares uniformly to learn
    linear decision surface in multi-instance learning. """
    def boundary_label(e):
        if e[1] + e[0] > 0:
            return 1
        return 0

    sq_len = 1.5

    while True:
        p = np.random.uniform(-5, 5, size=(2))
        x = np.random.uniform(0, sq_len, size=(100, 2)) + p
        y = np.apply_along_axis(boundary_label, 1, x).astype(np.float32)
        n_in_group = np.sum(y)
        ratio = n_in_group * 1.0 / batch_size
        y_group = np.zeros((batch_size,))
        y_group[:] = ratio
        yield x, y_group, y, ratio


def heatmap(heatmap_values, axes):
    """ heatmap_values is given in order rows then
        columns: 00, 01, 02,..etc
    """

    n = 100

    data = np.zeros(shape=(n, n))
    for i in range(n):
        for j in range(n):
            data[(i, j)] = heatmap_values[n * i + j]
    axes.pcolor(data, cmap=plt.cm.Blues)


def heatmap_input():
    l = 10.0
    n = 100
    column_labels = np.linspace(-l, l, n)
    row_labels = np.linspace(-l, l, n)
    x = np.zeros(shape=(n**2, 2))
    for i in range(n):
        for j in range(n):
            x[i * n + j] = [row_labels[i], column_labels[j]]
    return x

if __name__ == "__main__":
    mitr(sample_decision_boundary_small_uniform, 100, 2, 2)