我想对序列的一部分进行分类 . 因此,类别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 .