ようやくRNNの入り口までたどりついた。 参考にしたのは、このサイト。
いつものように、変数の型を調べてみた。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
import numpy as np import torch def make_data(num_div, cycles, offset=0): step = 2 * np.pi / num_div res0 = [np.sin(step * i + offset) for i in range(num_div * cycles + 1)] res1 = [np.sin(step * i + offset) + uniform(-0.05, 0.05) for i in range(num_div * cycles + 1)] return res0, res1 def make_train_data(num_div, cycles, num_batch, offset=0): x, x_noise, = make_data(num_div, cycles, offset) data, labels = [], [] count = len(x) - num_batch data = [x_noise[idx:idx+num_batch] for idx in range(count)] labels = [x[idx+num_batch] for idx in range(count)] num_items = len(data) train_data = torch.tensor(data, dtype=torch.float) train_data = train_data.reshape(num_items, num_batch, -1) train_labels = torch.tensor(labels, dtype=torch.float) train_labels = train_labels.reshape(num_items, -1) return train_data, train_labels class Net(torch.nn.Module): def __init__(self, input_size, hidden_size): super().__init__() self.rnn = torch.nn.RNN(input_size, hidden_size) self.fc = torch.nn.Linear(hidden_size, 1) def forward(self, x, hidden): output, h = self.rnn(x, hidden) output = self.fc(output[:,-1]) return output, h num_div = 100 cycles = 2 num_batch = 5 X_train, y_train = make_train_data(num_div, cycles, num_batch) input_size = 1 hidden_size = 10 net = Net(input_size, hidden_size) num_layers = 1 hidden = torch.zeros(num_layers, num_batch, hidden_size) print(f'hidden initial: {hidden}') output, h = net(X_train[0:5], hidden) print(f'output: {output}') print(f'hidden: {h}') |
出力が見難くなるので、バッチ数や隠れ層のノード数は少なめにした。
隠れ層に渡すhiddenの初期値は、要素が全て0。 出力はバッチ数だけ出て、hiddenは、hidden_size * num_batchになった。
これと正解の出力と比較して重みとバイアスを修正していって、NNの時と同じように次の出力が推定できるということらしい。
隠れ層のノード数をどういう風に決めるのかとか重みやバイアスの修正のしかたのアルゴリズムとか理解できていないけど、PyTorchを使えば何とかなりそうな気がしてきた。