我想对序列的一部分进行分类 . 因此,类别1可以是从时间步骤14到16,并且可能在10到14的序列中也存在类别2.这些部分的长度可以改变 . 我认为最好的方法是获取网络时间步的输出并使用完全连接的层 . 在我的设置中,这导致6个分类 .

  • 是否有1级[batch_size,2]

  • 是否有第2类[batch_size,2]

  • 类1的开始时间步长[batch_size,time_steps]

  • 类1的结束时间步[batch_size,time_steps]

  • 类2的开始时间步长[batch_size,time_steps]

  • 类2的结束时间步[[批量参数,时间_步]

我的问题是2折:

  • 前两个分类并没有变得更好

  • 最后4个分类偏向0级变为高

这是我创建数据的代码:

def make_data(y = None,batch_size = 1, max_length = 100):
    f_name_values = []
    l_name_values = []
    X = np.random.randn(max_length,batch_size,1)
    if y is None:
        y_ = np.random.randint(0,2,(batch_size,2))
    else:
        y_ = y
    y_1 = np.zeros((batch_size,4),dtype =int)    
    y = np.concatenate([y_,y_1],axis = 1)
    seq_len = np.random.randint(int(max_length*0.2),int(max_length*0.6),(batch_size,1))

    for i in range(batch_size):
        f_name = np.random.randint(0,seq_len[i,0]-3)
        if y[i,0] == 1:
            y[i,2], y[i,3] = int(f_name), int(f_name + np.random.randint(1,3))
            X[y[i,2]:y[i,3],i,:] += 10

        l_name_list = [j for j in range(seq_len[i,0]) if not( j <= y[i,3] and j > y[i,2]) ]
        l_name = np.random.choice(l_name_list)        

        if y[i,1] == 1:            
            y[i,4], y[i,5] = int(l_name), int(l_name + np.random.randint(1,4))
            X[y[i,4]:y[i,5],i,:] += 10.5

    return X, y , seq_len

我的网络的一部分:

# Build RNN cell

    multi_encoder_cell = tf.contrib.rnn.MultiRNNCell([tf.contrib.rnn.BasicLSTMCell(num_units) for _ in range(layers)])
    # init_state = multi_encoder_cell.zero_state(tf_batch_size, tf.float32)
    # Run Dynamic RNN
    #   encoder_outputs: [max_time, batch_size, num_units]
    #   encoder_state: [batch_size, num_units]
    #   input: [max_time, batch_size, depth] w/ time_major= True
    encoder_outputs, encoder_state = tf.nn.dynamic_rnn(
        cell = multi_encoder_cell, inputs = X,
        sequence_length=s_sequence_length[:,0], time_major=True,dtype = 'float32')

def rnn_out_2_logit(scope_name, encoder_outputs_, y, num_of_classes,w,b,is_from_certain_class = None):
    with tf.variable_scope(scope_name + '_2_logit'):
        output_ = encoder_outputs_[-1,:,:]
        logit = tf.matmul(output_,w) + b
        if num_of_classes > 10:
        # if the class (either 1 or 2) is not in the time serie their is no cost for the wrong class with the last 4 classifications
            bool_if_greater = tf.greater(is_from_certain_class,tf.zeros_like(is_from_certain_class)) 
            int_bool = tf.cast(bool_if_greater,tf.float32)
            cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels = y, logits = logit)
            cross_entropy = cross_entropy * int_bool
            t_cross_entropy = tf.where(tf.less(tf.reduce_sum(int_bool), 1e-7),1e-7,(tf.reduce_mean(cross_entropy)/tf.reduce_sum(int_bool) )* batch_size)            
            t_cross_entropy = tf.Print(t_cross_entropy, [t_cross_entropy, cross_entropy, int_bool],"cross_entrpy: ")
        else:
            t_cross_entropy = tf.reduce_mean(
                tf.nn.sparse_softmax_cross_entropy_with_logits(labels = y, logits = logit))

在这里我调用函数:

#class_1
cross_entropy_1, logit_l, l, acc_l = rnn_out_2_logit("class_1",encoder_outputs,y[:,0], num_class_f_l, w_l, b_l)
#class_2
cross_entropy_2, logit_f, f, acc_f = rnn_out_2_logit("class_2",encoder_outputs,y[:,1], num_class_f_l, w_f, b_f)
#class_1_start
cross_entropy_3, logit_f_num_start, _f_num_start, acc_f_s = rnn_out_2_logit("class_1_start",
                                                                            encoder_outputs,
                                                                            y[:,2],
                                                                            max_words+1,
                                                                            w_l_e, b_l_e, y[:,1])
#class_1_end
cross_entropy_4, logit_f_num_end, _f_num_end, acc_f_e = rnn_out_2_logit("class_1_end",
                                                                        encoder_outputs,y[:,3],
                                                                        max_words+1,
                                                                        w_f_e, b_f_e, y[:,1])
#class_2_start
cross_entropy_5, logit_l_num_start, _l_num_start, acc_l_s = rnn_out_2_logit("class_2_start",
                                                                            encoder_outputs,y[:,4],
                                                                            max_words+1,
                                                                            w_l_s, b_l_s, y[:,0])
#class_2_end
cross_entropy_6, logit_l_num_end, _l_num_end, acc_l_e = rnn_out_2_logit("class_2_end",
                                                                        encoder_outputs,y[:,5],
                                                                        max_words+1,
                                                                        w_l_e, b_l_e, y[:,0])

我认为if else结构正在工作,因为我使用tf.Print打印结果,并且输出的示例(使用batch_size = 3)是:

cross_entropy:[4.7751608] [0 5.9443221 3.605999] [0 1 1]

我看到我在张量板和此印刷品上制作的图表并没有变得更好:

epoch = 0

预测y [[2.16714668 -1.0374999]] [[-0.30407697 0.01561086]] 99 3 35 99 true y [[1 1 21 22 13 15]]

epoch = 100

预测y [[1.26584482 -0.13619883]] [[-0.17700087 -0.11146521]] 99 3 35 99 true y [[1 1 5 6 32 33]]

epoch = 200

预测y [[0.70634729 0.42329881]] [[-0.1597006 -0.12876543]] 0 0 0 0 true y [[1 1 22 24 38 40]]

我知道我可以通过其他方式(conv-net或seq2seq)来实现它,但是为了推广使用我希望这个布局是首选 .

任何帮助深表感谢 . 感谢任何完成整个问题的人 .

update 1

我首先应该拼接任务 . 所以第一个问题1然后2.然后我会用第二个尝试回归 . 未完待续 .

update 2

最后,我在每个时间步长输出了一个带有输出的双向rnn . 似乎工作oke .