이 동일한 문제를 처리했습니다. 처리해야 할 두 가지 문제가 있습니다. 첫 번째는 일괄 처리 크기와 단계 크기를 1로 조정하는 것입니다. 입력 시퀀스의 배치 및 길이 치수를 none으로 설정하면 쉽게 수행 할 수 있습니다. 즉 [없음, 없음, 128], 128은 128 자의 ASCII 문자를 나타냅니다 (문자의 하위 집합 만 필요하기 때문에 더 적은 문자를 사용할 수도 있음).
초기 상태를 처리하는 것이 가장 많이 사용됩니다. 이것은 session.run() 호출 사이에 저장해야하기 때문입니다. 귀하의 num_steps가 하나이므로 각 단계의 시작 부분에서 0으로 초기화됩니다. 내가 권장하는 것은 초기 상태가 자리 표시 자로 전달되고 session.run()에서 반환되도록 허용하는 것입니다. 이렇게하면 모델 사용자는 배치간에 현재 상태를 계속할 수 있습니다. 이를 수행하는 가장 쉬운 방법은 state_is_tupel이 사용하는 모든 RNN에 대해 False로 설정되어 있는지 확인하는 것입니다. 그러면 동적 RNN 함수에서 최종 상태 텐서를 간단히 얻을 수 있습니다.
개인적으로 state_is_tupel을 False로 설정하는 것이 좋지 않으므로 사용하지 않으므로 상태 튜플을 병합하기 위해 자체 코드를 작성했습니다. 다음 코드는 내 프로젝트에서 소리를 생성하는 코드입니다.
batch_size = tf.shape(self.input_sound)[0]
rnn = tf.nn.rnn_cell.MultiRNNCell([tf.nn.rnn_cell.LSTMCell(self.hidden_size) for _ in range(self.n_hidden)])
zero_state = pack_state_tupel(rnn.zero_state(batch_size, tf.float32))
self.input_state = tf.placeholder_with_default(zero_state, None)
state = unpack_state_tupel(self.input_state, rnn.state_size)
rnn_input_seq = tf.cond(self.is_training, lambda: self.input_sound[:, :-1], lambda: self.input_sound)
output, final_state = tf.nn.dynamic_rnn(rnn, rnn_input_seq, initial_state = state)
with tf.variable_scope('output_layer'):
output = tf.reshape(output, (-1, self.hidden_size))
W = tf.get_variable('W', (self.hidden_size, self.sample_length))
b = tf.get_variable('b', (self.sample_length,))
output = tf.matmul(output, W) + b
output = tf.reshape(output, (batch_size, -1, self.sample_length))
self.output_state = pack_state_tupel(final_state)
self.output_sound = output
이 모델에서만 테스트 했는데도 모든 유형의 RNN에서 작동하는 다음 두 가지 기능이 사용됩니다.
def pack_state_tupel(state_tupel):
if isinstance(state_tupel, tf.Tensor) or not hasattr(state_tupel, '__iter__'):
return state_tupel
else:
return tf.concat(1, [pack_state_tupel(item) for item in state_tupel])
def unpack_state_tupel(state_tensor, sizes):
def _unpack_state_tupel(state_tensor_, sizes_, offset_):
if isinstance(sizes_, tf.Tensor) or not hasattr(sizes_, '__iter__'):
return tf.reshape(state_tensor_[:, offset_ : offset_ + sizes_], (-1, sizes_)), offset_ + sizes_
else:
result = []
for size in sizes_:
s, offset_ = _unpack_state_tupel(state_tensor_, size, offset_)
result.append(s)
if isinstance(sizes_, tf.nn.rnn_cell.LSTMStateTuple):
return tf.nn.rnn_cell.LSTMStateTuple(*result), offset_
else:
return tuple(result), offset_
return _unpack_state_tupel(state_tensor, sizes, 0)[0]
마지막으로 내 생성 기능에서 숨겨진 상태를 관리하는 방법을 알아보십시오 s
.
def generate(self, seed, steps):
def _step(x, s = None):
feed_dict = {self.input_sound: np.reshape(x, (1, -1, self.sample_length))}
if s is not None:
feed_dict[self.input_state] = s
return self.session.run([self.output_sound, self.output_state], feed_dict)
seed_pad = self.sample_length - len(seed) % self.sample_length
if seed_pad: seed = np.pad(seed, (seed_pad, 0), 'constant')
y, s = _step(seed)
y = y[:, -1:]
result = [seed, y.flatten()]
for _ in range(steps):
y, s = _step(y, s)
result.append(y.flatten())
return np.concatenate(result)