defto_onehot(X, n_class): # X shape: (batch, seq_len), output: seq_len elements of (batch, n_class) return [one_hot(X[:, i], n_class) for i inrange(X.shape[1])]
X = torch.arange(10).view(2, 5) inputs = to_onehot(X, vocab_size) print(len(inputs), inputs[0].shape)
相当于 原本的 (批量大小, 时间步数) 转换成了
(时间步数, 批量大小, 词典大小)
代码很简单。按照时间步 for i in range(X.shape[1]) 提取第i步所在的
X[:, i] 元素,提取的内容形状类似于之前我们说的tensor([[2], [0],
[1]]),然后将该元素放到one_hot(X[:, i], n_class) 获取所需的 (批量大小,
词典大小) 形状的one_hot数组。
for epoch inrange(num_epochs): ifnot is_random_iter: # 如使用相邻采样,在epoch开始时初始化隐藏状态 state = init_rnn_state(batch_size, num_hiddens, device) l_sum, n, start = 0.0, 0, time.time()
data_iter = data_iter_fn(corpus_indices, batch_size, num_steps, device) for X, Y in data_iter: # X,Y都是 (batch_size,steps)
if is_random_iter: # 如使用随机采样,在每个小批量更新前初始化隐藏状态 state = init_rnn_state(batch_size, num_hiddens, device) else: # 否则需要使用detach函数从计算图分离隐藏状态, 这是为了 # 使模型参数的梯度计算只依赖一次迭代读取的小批量序列(防止梯度计算开销太大) for s in state: s.detach_()
for prefix in prefixes: print(' -', predict_rnn(prefix, pred_len, rnn, params, init_rnn_state, num_hiddens, vocab_size, device, idx_to_char, char_to_idx))
首先说明上面的这部分代码
1 2 3 4 5 6 7 8 9
for X, Y in data_iter: # X,Y都是 (batch_size,steps) if is_random_iter: # 如使用随机采样,在每个小批量更新前初始化隐藏状态 state = init_rnn_state(batch_size, num_hiddens, device) else: # 否则需要使用detach函数从计算图分离隐藏状态, 这是为了 # 使模型参数的梯度计算只依赖一次迭代读取的小批量序列(防止梯度计算开销太大) for s in state: s.detach_()