Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
Dive-into-DL-PyTorch
提交
542f0593
D
Dive-into-DL-PyTorch
项目概览
OpenDocCN
/
Dive-into-DL-PyTorch
通知
9
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
Dive-into-DL-PyTorch
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
542f0593
编写于
4月 17, 2019
作者:
S
shusentang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix bug on GPU
上级
cbc10dbe
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
120 addition
and
42 deletion
+120
-42
code/chapter06_RNN/6.5_rnn-pytorch.ipynb
code/chapter06_RNN/6.5_rnn-pytorch.ipynb
+33
-42
code/d2lzh_pytorch/utils.py
code/d2lzh_pytorch/utils.py
+87
-0
未找到文件。
code/chapter06_RNN/6.5_rnn-pytorch.ipynb
浏览文件 @
542f0593
...
...
@@ -16,7 +16,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"
0.4.1 cpu
\n"
"
1.0.0 cuda
\n"
]
}
],
...
...
@@ -48,9 +48,7 @@
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"metadata": {},
"outputs": [],
"source": [
"num_hiddens = 256\n",
...
...
@@ -67,7 +65,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"torch.Size([35, 2, 256])
2 torch.Size([1,
2, 256])\n"
"torch.Size([35, 2, 256])
1 torch.Size([
2, 256])\n"
]
}
],
...
...
@@ -83,9 +81,7 @@
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": true
},
"metadata": {},
"outputs": [],
"source": [
"# 本类已保存在d2lzh_pytorch包中方便以后使用\n",
...
...
@@ -118,9 +114,7 @@
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": true
},
"metadata": {},
"outputs": [],
"source": [
"# 本函数已保存在d2lzh_pytorch包中方便以后使用\n",
...
...
@@ -140,7 +134,7 @@
" if t < len(prefix) - 1:\n",
" output.append(char_to_idx[prefix[t + 1]])\n",
" else:\n",
" output.append(int(Y.argmax(dim=1).
cpu().
item()))\n",
" output.append(int(Y.argmax(dim=1).item()))\n",
" return ''.join([idx_to_char[i] for i in output])"
]
},
...
...
@@ -152,7 +146,7 @@
{
"data": {
"text/plain": [
"'分开
女蟑正酒场蟑蟑半女蟑
'"
"'分开
戏想暖迎凉想征凉征征
'"
]
},
"execution_count": 6,
...
...
@@ -161,16 +155,14 @@
}
],
"source": [
"model = RNNModel(rnn_layer, vocab_size)\n",
"model = RNNModel(rnn_layer, vocab_size)
.to(device)
\n",
"predict_rnn_pytorch('分开', 10, model, vocab_size, device, idx_to_char, char_to_idx)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": true
},
"metadata": {},
"outputs": [],
"source": [
"# 本函数已保存在d2lzh_pytorch包中方便以后使用\n",
...
...
@@ -231,40 +223,39 @@
"name": "stdout",
"output_type": "stream",
"text": [
"epoch 50, perplexity 17.540257, time 1.24 sec\n",
" - 分开始的美 一场人 一个人 一人 一颗 三颗四颗 三颗四颗 连成线背著默默默许下愿 远方的星旧每\n",
" - 不分开始的美 一场人 我一的的河 一默默 娘子 娘子子依旧每日折一枝杨柳 在在在村外的溪边河默默默等等\n",
"epoch 100, perplexity 1.970755, time 1.25 sec\n",
" - 分开始的美 我给你的让我面 你的可爱女 坏坏的让我疯狂的可爱女人 坏坏的让我疯狂的可爱女人 坏坏的让我\n",
" - 不分开始的美 一场悲剧 我想要你的微笑每天都能看到 想这样的让我家的你的可爱你 坏坏的让我疯狂的可爱女\n",
"epoch 150, perplexity 1.165590, time 1.40 sec\n",
" - 分开始的美 我给你的风 不能够 我不 真真的你是我面 我不要再想这样打我妈妈 难道你的手 不著 你想\n",
" - 不分开始的美 我给你的风 不能再想我 我 你 是你不会 不要 我想你 爸打我妈 说你 是你怎么打我手 \n"
]
},
{
"ename": "KeyboardInterrupt",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-8-38e7594e6951>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mcorpus_indices\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0midx_to_char\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchar_to_idx\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mnum_epochs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnum_steps\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclipping_theta\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m batch_size, pred_period, pred_len, prefixes)\n\u001b[0m",
"\u001b[0;32m<ipython-input-7-63c70818229f>\u001b[0m in \u001b[0;36mtrain_and_predict_rnn_pytorch\u001b[0;34m(model, num_hiddens, vocab_size, device, corpus_indices, idx_to_char, char_to_idx, num_epochs, num_steps, lr, clipping_theta, batch_size, pred_period, pred_len, prefixes)\u001b[0m\n\u001b[1;32m 28\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 29\u001b[0m \u001b[0moptimizer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mzero_grad\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 30\u001b[0;31m \u001b[0ml\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbackward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 31\u001b[0m \u001b[0;31m# 梯度裁剪\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 32\u001b[0m \u001b[0md2l\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgrad_clipping\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparameters\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclipping_theta\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/anaconda3/lib/python3.6/site-packages/torch/tensor.py\u001b[0m in \u001b[0;36mbackward\u001b[0;34m(self, gradient, retain_graph, create_graph)\u001b[0m\n\u001b[1;32m 91\u001b[0m \u001b[0mproducts\u001b[0m\u001b[0;34m.\u001b[0m \u001b[0mDefaults\u001b[0m \u001b[0mto\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 92\u001b[0m \"\"\"\n\u001b[0;32m---> 93\u001b[0;31m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mautograd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbackward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgradient\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mretain_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcreate_graph\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 94\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 95\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mregister_hook\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhook\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/anaconda3/lib/python3.6/site-packages/torch/autograd/__init__.py\u001b[0m in \u001b[0;36mbackward\u001b[0;34m(tensors, grad_tensors, retain_graph, create_graph, grad_variables)\u001b[0m\n\u001b[1;32m 88\u001b[0m Variable._execution_engine.run_backward(\n\u001b[1;32m 89\u001b[0m \u001b[0mtensors\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgrad_tensors\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mretain_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcreate_graph\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 90\u001b[0;31m allow_unreachable=True) # allow_unreachable flag\n\u001b[0m\u001b[1;32m 91\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 92\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mKeyboardInterrupt\u001b[0m: "
"epoch 50, perplexity 10.658418, time 0.05 sec\n",
" - 分开始我妈 想要你 我不多 让我心到的 我妈妈 我不能再想 我不多再想 我不要再想 我不多再想 我不要\n",
" - 不分开 我想要你不你 我 你不要 让我心到的 我妈人 可爱女人 坏坏的让我疯狂的可爱女人 坏坏的让我疯狂的\n",
"epoch 100, perplexity 1.308539, time 0.05 sec\n",
" - 分开不会痛 不要 你在黑色幽默 开始了美丽全脸的梦滴 闪烁成回忆 伤人的美丽 你的完美主义 太彻底 让我\n",
" - 不分开不是我不要再想你 我不能这样牵着你的手不放开 爱可不可以简简单单没有伤害 你 靠着我的肩膀 你 在我\n",
"epoch 150, perplexity 1.070370, time 0.05 sec\n",
" - 分开不能去河南嵩山 学少林跟武当 快使用双截棍 哼哼哈兮 快使用双截棍 哼哼哈兮 习武之人切记 仁者无敌\n",
" - 不分开 在我会想通 是谁开没有全有开始 他心今天 一切人看 我 一口令秋软语的姑娘缓缓走过外滩 消失的 旧\n",
"epoch 200, perplexity 1.034663, time 0.05 sec\n",
" - 分开不能去吗周杰伦 才离 没要你在一场悲剧 我的完美主义 太彻底 分手的话像语言暴力 我已无能为力再提起\n",
" - 不分开 让我面到你 爱情来的太快就像龙卷风 离不开暴风圈来不及逃 我不能再想 我不能再想 我不 我不 我不\n",
"epoch 250, perplexity 1.021437, time 0.05 sec\n",
" - 分开 我我外的家边 你知道这 我爱不看的太 我想一个又重来不以 迷已文一只剩下回忆 让我叫带你 你你的\n",
" - 不分开 我我想想和 是你听没不 我不能不想 不知不觉 你已经离开我 不知不觉 我跟了这节奏 后知后觉 \n"
]
}
],
"source": [
"num_epochs, batch_size, lr, clipping_theta = 250, 32, 1e-3, 1e-2\n",
"num_epochs, batch_size, lr, clipping_theta = 250, 32, 1e-3, 1e-2
# 注意这里的学习率设置
\n",
"pred_period, pred_len, prefixes = 50, 50, ['分开', '不分开']\n",
"train_and_predict_rnn_pytorch(model, num_hiddens, vocab_size, device,\n",
" corpus_indices, idx_to_char, char_to_idx,\n",
" num_epochs, num_steps, lr, clipping_theta,\n",
" batch_size, pred_period, pred_len, prefixes)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
...
...
@@ -283,7 +274,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.
3
"
"version": "3.6.
8
"
}
},
"nbformat": 4,
...
...
code/d2lzh_pytorch/utils.py
浏览文件 @
542f0593
...
...
@@ -446,3 +446,90 @@ def train_and_predict_rnn(rnn, get_params, init_rnn_state, num_hiddens,
print
(
' -'
,
predict_rnn
(
prefix
,
pred_len
,
rnn
,
params
,
init_rnn_state
,
num_hiddens
,
vocab_size
,
device
,
idx_to_char
,
char_to_idx
))
# ################################### 6.5 ################################################
class
RNNModel
(
nn
.
Module
):
def
__init__
(
self
,
rnn_layer
,
vocab_size
):
super
(
RNNModel
,
self
).
__init__
()
self
.
rnn
=
rnn_layer
self
.
hidden_size
=
rnn_layer
.
hidden_size
*
(
2
if
rnn_layer
.
bidirectional
else
1
)
self
.
vocab_size
=
vocab_size
self
.
dense
=
nn
.
Linear
(
self
.
hidden_size
,
vocab_size
)
self
.
state
=
None
def
forward
(
self
,
inputs
,
state
):
# inputs: (batch, seq_len)
# 获取one-hot向量表示
X
=
d2l
.
to_onehot
(
inputs
,
vocab_size
)
# X是个list
Y
,
self
.
state
=
self
.
rnn
(
torch
.
stack
(
X
),
state
)
# 全连接层会首先将Y的形状变成(num_steps * batch_size, num_hiddens),它的输出
# 形状为(num_steps * batch_size, vocab_size)
output
=
self
.
dense
(
Y
.
view
(
-
1
,
Y
.
shape
[
-
1
]))
return
output
,
self
.
state
def
predict_rnn_pytorch
(
prefix
,
num_chars
,
model
,
vocab_size
,
device
,
idx_to_char
,
char_to_idx
):
state
=
None
output
=
[
char_to_idx
[
prefix
[
0
]]]
# output会记录prefix加上输出
for
t
in
range
(
num_chars
+
len
(
prefix
)
-
1
):
X
=
torch
.
tensor
([
output
[
-
1
]],
device
=
device
).
view
(
1
,
1
)
if
state
is
not
None
:
if
isinstance
(
state
,
tuple
):
# LSTM, state:(h, c)
state
=
(
state
[
0
].
to
(
device
),
state
[
1
].
to
(
device
))
else
:
state
=
state
.
to
(
device
)
(
Y
,
state
)
=
model
(
X
,
state
)
# 前向计算不需要传入模型参数
if
t
<
len
(
prefix
)
-
1
:
output
.
append
(
char_to_idx
[
prefix
[
t
+
1
]])
else
:
output
.
append
(
int
(
Y
.
argmax
(
dim
=
1
).
item
()))
return
''
.
join
([
idx_to_char
[
i
]
for
i
in
output
])
def
train_and_predict_rnn_pytorch
(
model
,
num_hiddens
,
vocab_size
,
device
,
corpus_indices
,
idx_to_char
,
char_to_idx
,
num_epochs
,
num_steps
,
lr
,
clipping_theta
,
batch_size
,
pred_period
,
pred_len
,
prefixes
):
loss
=
nn
.
CrossEntropyLoss
()
optimizer
=
torch
.
optim
.
Adam
(
model
.
parameters
(),
lr
=
lr
)
model
.
to
(
device
)
state
=
None
for
epoch
in
range
(
num_epochs
):
l_sum
,
n
,
start
=
0.0
,
0
,
time
.
time
()
data_iter
=
d2l
.
data_iter_consecutive
(
corpus_indices
,
batch_size
,
num_steps
,
device
)
# 相邻采样
for
X
,
Y
in
data_iter
:
if
state
is
not
None
:
# 使用detach函数从计算图分离隐藏状态, 这是为了
# 使模型参数的梯度计算只依赖一次迭代读取的小批量序列(防止梯度计算开销太大)
if
isinstance
(
state
,
tuple
):
# LSTM, state:(h, c)
state
=
(
state
[
0
].
detach
(),
state
[
1
].
detach
())
else
:
state
=
state
.
detach
()
(
output
,
state
)
=
model
(
X
,
state
)
# output: 形状为(num_steps * batch_size, vocab_size)
# Y的形状是(batch_size, num_steps),转置后再变成长度为
# batch * num_steps 的向量,这样跟输出的行一一对应
y
=
torch
.
transpose
(
Y
,
0
,
1
).
contiguous
().
view
(
-
1
)
l
=
loss
(
output
,
y
.
long
())
optimizer
.
zero_grad
()
l
.
backward
()
# 梯度裁剪
d2l
.
grad_clipping
(
model
.
parameters
(),
clipping_theta
,
device
)
optimizer
.
step
()
l_sum
+=
l
.
item
()
*
y
.
shape
[
0
]
n
+=
y
.
shape
[
0
]
try
:
perplexity
=
math
.
exp
(
l_sum
/
n
)
except
OverflowError
:
perplexity
=
float
(
'inf'
)
if
(
epoch
+
1
)
%
pred_period
==
0
:
print
(
'epoch %d, perplexity %f, time %.2f sec'
%
(
epoch
+
1
,
perplexity
,
time
.
time
()
-
start
))
for
prefix
in
prefixes
:
print
(
' -'
,
predict_rnn_pytorch
(
prefix
,
pred_len
,
model
,
vocab_size
,
device
,
idx_to_char
,
char_to_idx
))
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录