2017-10-05 10 views
0

TL; DR, 안드로이드 애플리케이션에서 bi-lstm-ctc tensorflow 모델을 사용하는 방법을 알고 싶습니다.Android에서 BI LSTM CTC Tensorflow 모델을 사용하는 경우

필자는 bi-lstm-ctc tensorflow 모델을 교육하는 데 성공했으며 지금은 필기 인식 안드로이드 응용 프로그램에 사용하고 싶습니다. 여기 내가 사용하는 그래프를 정의하는 코드의 일부는 다음과 같습니다

self.inputs = tf.placeholder(tf.float32, [None, None, network_config.num_features], name="input") 
self.labels = tf.sparse_placeholder(tf.int32, name="label") 
self.seq_len = tf.placeholder(tf.int32, [None], name="seq_len_input") 

logits = self._bidirectional_lstm_layers(
    network_config.num_hidden_units, 
    network_config.num_layers, 
    network_config.num_classes 
) 

self.global_step = tf.Variable(0, trainable=False) 
self.loss = tf.nn.ctc_loss(labels=self.labels, inputs=logits, sequence_length=self.seq_len) 
self.cost = tf.reduce_mean(self.loss) 

self.optimizer = tf.train.AdamOptimizer(network_config.learning_rate).minimize(self.cost) 
self.decoded, self.log_prob = tf.nn.ctc_beam_search_decoder(inputs=logits, sequence_length=self.seq_len, merge_repeated=False) 
self.dense_decoded = tf.sparse_tensor_to_dense(self.decoded[0], default_value=-1, name="output") 

나는 또한 동결에 성공하고 동결을 다음 그래프를 최적화하고이 tutorial에서 그래프 코드를 최적화 할 수 있습니다.

bitmap = Bitmap.createScaledBitmap(bitmap, 1024, 128, true); 
int[] intValues = new int[bitmap.getWidth() * bitmap.getHeight()]; 
bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight()); 
float[] floatValues = new float[bitmap.getWidth() * bitmap.getHeight()]; 
for (int i = 0; i < intValues.length; ++i) { 
    final int val = intValues[i]; 
    floatValues[i] = (((val >> 16) & 0xFF)); 
} 
float[] result = new float[80]; 
long[] INPUT_SIZE = new long[]{1, bitmap.getHeight(), bitmap.getWidth()}; 
inferenceInterface.feed(config.getInputName(), floatValues, INPUT_SIZE); 
inferenceInterface.feed("seq_len_input", new int[]{bitmap.getWidth()}, 1); 
inferenceInterface.run(config.getOutputNames()); 
inferenceInterface.fetch(config.getOutputNames()[0], result); 

return result.toString(); 

그러나, 내가 사용하는 모델에 따라 이러한 문제가 발생 다음은 모델을 실행하도록되어 코드의 일부이다. 내가 가지고있는 이러한 오류를 해결하는 방법을 제외하고

java.io.IOException: Not a valid TensorFlow Graph serialization: NodeDef expected inputs '' do not match 1 inputs 
specified; Op<name=Const; signature= -> output:dtype; attr=value:tensor; attr=dtype:type>; 
NodeDef: stack_bidirectional_rnn/cell_0/bidirectional_rnn/bw/bw/while/add/y = Const[dtype=DT_INT32, 
value=Tensor<type: int32 shape: [] values: 1>](stack_bidirectional_rnn/cell_0/bidirectional_rnn/bw/bw/while/Switch:1) 

: 나는 최적화 된 냉동 그래프를 사용하는 경우

Caused by: java.lang.IllegalArgumentException: No OpKernel was registered to support 
Op 'SparseToDense' with these attrs. Registered devices: [CPU], Registered kernels: 
device='CPU'; T in [DT_STRING]; Tindices in [DT_INT64] 
device='CPU'; T in [DT_STRING]; Tindices in [DT_INT32] 
device='CPU'; T in [DT_BOOL]; Tindices in [DT_INT64] 
device='CPU'; T in [DT_BOOL]; Tindices in [DT_INT32] 
device='CPU'; T in [DT_FLOAT]; Tindices in [DT_INT64] 
device='CPU'; T in [DT_FLOAT]; Tindices in [DT_INT32] 
device='CPU'; T in [DT_INT32]; Tindices in [DT_INT64] 
device='CPU'; T in [DT_INT32]; Tindices in [DT_INT32] 

[[Node: output = SparseToDense[T=DT_INT64, Tindices=DT_INT64, validate_indices=true](CTCBeamSearchDecoder, CTCBeamSearchDecoder:2, CTCBeamSearchDecoder:1, output/default_value)]] 

, 나는이 오류가 발생 : 나는 냉동 그래프를 사용하는 경우,이 오류가 발생 기타 질문/설명 :

어떻게 이러한 오류를 해결할 수 있습니까?

답변

1

이미 제작되었습니다. 해결책은 github issue에서도 찾을 수 있습니다.

명백하게 문제는 사용 된 유형입니다. int32 만 허용되는 곳에서 int64를 전달하고있었습니다. 그 날이 오류 준 후

self.dense_decoded = tf.sparse_to_dense(tf.to_int32(self.decoded[0].indices), 
       tf.to_int32(self.decoded[0].dense_shape), 
       tf.to_int32(self.decoded[0].values), 
       name="output") 

응용 프로그램을 실행 : 몇 가지 이상한 이유로

java.lang.IllegalArgumentException: Matrix size-incompatible: In[0]: [1,1056], In[1]: [160,128] 
[[Node:stack_bidirectional_rnn/cell_0/bidirectional_rnn/bw/bw/while/bw/basic_lstm_cell/basic_lstm_cell/ 

MatMul = MatMul[T=DT_FLOAT, transpose_a=false, transpose_b=false, _device="/job:localhost/replica:0/task:0/cpu:0"] 

(stack_bidirectional_rnn/cell_0/bidirectional_rnn/bw/bw/while/bw/basic_lstm_cell/basic_lstm_cell/concat, 
stack_bidirectional_rnn/cell_0/bidirectional_rnn/bw/bw/while/bw/basic_lstm_cell/basic_lstm_cell/MatMul/Enter)]] 

self.dense_decoded = tf.sparse_tensor_to_dense(self.decoded[0], default_value=-1, name="output") 

그 문제를 해결하기 위해, 나는이 int32하는 스파 스 텐서 요소를 주조 자바 코드에서 이미지 너비를 1024에서 128로 변경하면 오류가 해결됩니다. 앱을 다시 실행하면 다음 오류가 발생합니다.

java.lang.IllegalArgumentException: cannot use java.nio.FloatArrayBuffer with Tensor of type INT32 

출력을 가져올 때 문제가 발생합니다. 이를 통해 모델이 성공적으로 실행되었음을 알았지 만 애플리케이션에서 결과를 가져올 수 없었습니다.

inferenceInterface.run(outputs); 
inferenceInterface.fetch(outputs[0], result); //where the error happens 

실례로 출력은 정수 배열이고 float 배열은 아님을 잊어 버렸습니다. 그래서 결과 배열의 타입을 int 배열로 변경했습니다 :

//float[] result = new float[80]; 
int[] result = new int[80]; 

따라서 응용 프로그램이 작동합니다. 모델의 정확성은 제대로 훈련되지 않았기 때문에 좋지 않습니다. 난 그걸 응용 프로그램에서 작동 시키려고 했었어. 진지한 훈련이 필요합니다!