pytochの下でLSTM神経ネットワークを使って詩の実例を書きます。
pytouchの下で、数万首の唐詩を素材にして、二層LSTM神経ネットを訓練して、唐詩の方式で詩を書くことができます。
コード構造は四つの部分に分けられ、それぞれ
1.model.pyは、二層LSTMモデルを定義しています。
2.data.pyは、ネットで得られた唐詩データの処理方法を定義しています。
3.utlis.pyは損失可視化の関数を定義しています。
4.main.pyはモデルパラメータを定義し、トレーニング、唐詩生成関数を定義しています。
参考:電子工業出版社の「深さ学習フレームワークPyTorch:入門と実践」第九章
mainコードとコメントは以下の通りです。
1.pythonのプログラミング方法を理解し、スペース、改行など;pythonの各基本モジュールをさらに理解する。
2.出す可能性のあるエラー:関数名が間違っています。大文字と小文字、変数名が間違っています。括弧が不完全です。
3.cuda()の使い方をさらに認識しました。
4.デバッグプログラムを習得しました。
5.トレーニング結果の可視化を習得しました。
6.LSTMをさらに理解し、深度学習の仕組み、マクロコントロールを実現しました。
このpytouchでLSTM神経ネットワークを使って詩を書いた例は、小編集が皆さんのすべての内容を共有しています。参考にしていただければと思います。どうぞよろしくお願いします。
コード構造は四つの部分に分けられ、それぞれ
1.model.pyは、二層LSTMモデルを定義しています。
2.data.pyは、ネットで得られた唐詩データの処理方法を定義しています。
3.utlis.pyは損失可視化の関数を定義しています。
4.main.pyはモデルパラメータを定義し、トレーニング、唐詩生成関数を定義しています。
参考:電子工業出版社の「深さ学習フレームワークPyTorch:入門と実践」第九章
mainコードとコメントは以下の通りです。
import sys, os
import torch as t
from data import get_data
from model import PoetryModel
from torch import nn
from torch.autograd import Variable
from utils import Visualizer
import tqdm
from torchnet import meter
import ipdb
class Config(object):
data_path = 'data/'
pickle_path = 'tang.npz'
author = None
constrain = None
category = 'poet.tang' #or poet.song
lr = 1e-3
weight_decay = 1e-4
use_gpu = True
epoch = 20
batch_size = 128
maxlen = 125
plot_every = 20
#use_env = True # visodm
env = 'poety'
#visdom env
max_gen_len = 200
debug_file = '/tmp/debugp'
model_path = None
prefix_words = ' , 。'
# ,
start_words = ' '
#
acrostic = False
#
model_prefix = 'checkpoints/tang'
#
opt = Config()
def generate(model, start_words, ix2word, word2ix, prefix_words=None):
'''
,
'''
results = list(start_words)
start_word_len = len(start_words)
# <START>
# ,
input = Variable(t.Tensor([word2ix['<START>']]).view(1,1).long())
if opt.use_gpu:input=input.cuda()
hidden = None
if prefix_words:
for word in prefix_words:
output,hidden = model(input,hidden)
# input 1*1?
input = Variable(input.data.new([word2ix[word]])).view(1,1)
for i in range(opt.max_gen_len):
output,hidden = model(input,hidden)
if i<start_word_len:
w = results[i]
input = Variable(input.data.new([word2ix[w]])).view(1,1)
else:
top_index = output.data[0].topk(1)[1][0]
w = ix2word[top_index]
results.append(w)
input = Variable(input.data.new([top_index])).view(1,1)
if w=='<EOP>':
del results[-1] #-1
break
return results
def gen_acrostic(model,start_words,ix2word,word2ix, prefix_words = None):
'''
start_words : u' '
:
, 。
, 。
, 。
, 。
'''
results = []
start_word_len = len(start_words)
input = Variable(t.Tensor([word2ix['<START>']]).view(1,1).long())
if opt.use_gpu:input=input.cuda()
hidden = None
index=0 #
#
pre_word='<START>'
if prefix_words:
for word in prefix_words:
output,hidden = model(input,hidden)
input = Variable(input.data.new([word2ix[word]])).view(1,1)
for i in range(opt.max_gen_len):
output,hidden = model(input,hidden)
top_index = output.data[0].topk(1)[1][0]
w = ix2word[top_index]
if (pre_word in {u'。',u'!','<START>'} ):
# ,
if index==start_word_len:
# ,
break
else:
#
w = start_words[index]
index+=1
input = Variable(input.data.new([word2ix[w]])).view(1,1)
else:
# ,
input = Variable(input.data.new([word2ix[w]])).view(1,1)
results.append(w)
pre_word = w
return results
def train(**kwargs):
for k,v in kwargs.items():
setattr(opt,k,v) # apt
vis = Visualizer(env=opt.env)
#
data, word2ix, ix2word = get_data(opt) #get_data data.py
data = t.from_numpy(data)
# , L
dataloader = t.utils.data.DataLoader(data,
batch_size = opt.batch_size,
shuffle = True,
num_workers = 1) # python , ?
#
model = PoetryModel(len(word2ix), 128, 256)
optimizer = t.optim.Adam(model.parameters(), lr=opt.lr)
criterion = nn.CrossEntropyLoss()
if opt.model_path:
model.load_state_dict(t.load(opt.model_path))
if opt.use_gpu:
model.cuda()
criterion.cuda()
#The tnt.AverageValueMeter measures and returns the average value
#and the standard deviation of any collection of numbers that are
#added to it. It is useful, for instance, to measure the average
#loss over a collection of examples.
#The add() function expects as input a Lua number value, which
#is the value that needs to be added to the list of values to
#average. It also takes as input an optional parameter n that
#assigns a weight to value in the average, in order to facilitate
#computing weighted averages (default = 1).
#The tnt.AverageValueMeter has no parameters to be set at initialization time.
loss_meter = meter.AverageValueMeter()
for epoch in range(opt.epoch):
loss_meter.reset()
for ii,data_ in tqdm.tqdm(enumerate(dataloader)):
#tqdm python
#
data_ = data_.long().transpose(1,0).contiguous()
# , data_ long , 1 0 ,
if opt.use_gpu: data_ = data_.cuda()
optimizer.zero_grad()
input_, target = Variable(data_[:-1,:]), Variable(data_[1:,:])
# , ,
output,_ = model(input_)
loss = criterion(output, target.view(-1))
loss.backward()
optimizer.step()
loss_meter.add(loss.data[0]) # data[0]?
# utlis.py
if (1+ii)%opt.plot_every ==0:
if os.path.exists(opt.debug_file):
ipdb.set_trace()
vis.plot('loss',loss_meter.value()[0])
# ,
poetrys = [[ix2word[_word] for _word in data_[:,_iii]]
for _iii in range(data_.size(1))][:16]
# ,
vis.text('</br>'.join([''.join(poetry) for poetry in
poetrys]),win = u'origin_poem')
gen_poetries = []
# , 8
for word in list(u' '):
gen_poetry = ''.join(generate(model,word,ix2word,word2ix))
gen_poetries.append(gen_poetry)
vis.text('</br>'.join([''.join(poetry) for poetry in
gen_poetries]), win = u'gen_poem')
t.save(model.state_dict(), '%s_%s.pth' %(opt.model_prefix,epoch))
def gen(**kwargs):
'''
,
'''
for k,v in kwargs.items():
setattr(opt,k,v)
data, word2ix, ix2word = get_data(opt)
model = PoetryModel(len(word2ix), 128, 256)
map_location = lambda s,l:s
# map_location load , CPU GPU,
# GPU
state_dict = t.load(opt.model_path, map_location = map_location)
model.load_state_dict(state_dict)
if opt.use_gpu:
model.cuda()
if sys.version_info.major == 3:
if opt.start_words.insprintable():
start_words = opt.start_words
prefix_words = opt.prefix_words if opt.prefix_words else None
else:
start_words = opt.start_words.encode('ascii',\
'surrogateescape').decode('utf8')
prefix_words = opt.prefix_words.encode('ascii',\
'surrogateescape').decode('utf8') if opt.prefix_words else None
start_words = start_words.replace(',',u',')\
.replace('.',u'。')\
.replace('?',u'?')
gen_poetry = gen_acrostic if opt.acrostic else generate
result = gen_poetry(model,start_words,ix2word,word2ix,prefix_words)
print(''.join(result))
if __name__ == '__main__':
import fire
fire.Fire()
以上のコードは経験をくれました。1.pythonのプログラミング方法を理解し、スペース、改行など;pythonの各基本モジュールをさらに理解する。
2.出す可能性のあるエラー:関数名が間違っています。大文字と小文字、変数名が間違っています。括弧が不完全です。
3.cuda()の使い方をさらに認識しました。
4.デバッグプログラムを習得しました。
5.トレーニング結果の可視化を習得しました。
6.LSTMをさらに理解し、深度学習の仕組み、マクロコントロールを実現しました。
このpytouchでLSTM神経ネットワークを使って詩を書いた例は、小編集が皆さんのすべての内容を共有しています。参考にしていただければと思います。どうぞよろしくお願いします。