#python #html #nlp #pytorch #recurrent-neural-network
#python #HTML #nlp #pytorch #рекуррентная нейронная сеть
Вопрос:
Я застрял на пару дней, пытаясь создать сеть RNN, чтобы изучить базовый HTML-шаблон. Я пробовал разные подходы и даже переработал следующие данные:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1>This is a Heading</h1>
<p>This is a paragraph.</p>
</body>
</html>
Получение 100% точности при обучении и проверке, используя Adam Optimizer и CrossEntropyLoss.
Проблема в том, что когда я пытаюсь выполнить выборку из сети, результаты полностью случайны, и я не знаю, в чем проблема:
..<a<a<a<a<aa<ttp11111b11111b11111111b11b1bbbb<btttn111
Моя функция выборки заключается в следующем:
def sample_sentence():
words = list()
count = 0
modelOne.eval()
with torch.no_grad():
# Setup initial input state, and input word (we use "the").
previousWord = torch.LongTensor(1, 1).fill_(trainData.vocabulary['letter2id']['[START]'])
hidden = Variable(torch.zeros(6, 1, 100).to(device))
while True:
# Predict the next word based on the previous hidden state and previous word.
inputWord = torch.autograd.Variable(previousWord.to(device))
predictions, newHidden = modelOne(inputWord, hidden)
hidden = newHidden
pred = torch.nn.functional.softmax(predictions.squeeze()).data.cpu().numpy().astype('float64')
pred = pred/np.sum(pred)
nextWordId = np.random.multinomial(1, pred, 1).argmax()
if nextWordId == 0:
continue
words.append(trainData.vocabulary['id2letter'][nextWordId])
# Setup the inputs for the next round.
previousWord.fill_(nextWordId)
# Keep adding words until the [END] token is generated.
if nextWordId == trainData.vocabulary['letter2id']['[END]']:
break
if count>20000:
break
count = 1
words.insert(0, '[START]')
return words
И моя сетевая архитектура здесь:
class ModelOne(Model) :
def __init__(self,
vocabulary_size,
hidden_size,
num_layers,
rnn_dropout,
embedding_size,
dropout,
num_directions):
super(Model, self).__init__()
self.vocabulary_size = vocabulary_size
self.hidden_size = hidden_size
self.num_layers = num_layers
self.rnn_dropout = rnn_dropout
self.dropout = dropout
self.num_directions = num_directions
self.embedding_size = embedding_size
self.embeddings = nn.Embedding(self.vocabulary_size, self.embedding_size)
self.rnn = nn.GRU(self.embedding_size,
self.hidden_size,
num_layers=self.num_layers,
bidirectional=True if self.num_directions==2 else False,
dropout=self.rnn_dropout,
batch_first=True)
self.linear = nn.Linear(self.hidden_size*self.num_directions, self.vocabulary_size)
def forward(self, paddedSeqs, hidden):
batchSequenceLength = paddedSeqs.size(1)
batchSize = paddedSeqs.size(0)
lengths = paddedSeqs.ne(0).sum(dim=1)
embeddingVectors = self.embeddings(paddedSeqs)
x = torch.nn.utils.rnn.pack_padded_sequence(embeddingVectors, lengths, batch_first=True)
self.rnn.flatten_parameters()
x,hid = self.rnn(x, hidden)
output, _ = torch.nn.utils.rnn.pad_packed_sequence(x, batch_first=True, padding_value=0, total_length=batchSequenceLength)
predictions = self.linear(output)
return predictions.view(batchSize, self.vocabulary_size, batchSequenceLength), hid
def init_hidden(self, paddedSeqs):
hidden = Variable(torch.zeros(self.num_layers*self.num_directions,
1,
self.hidden_size).to(device))
return hidden
modelOne =ModelOne(vocabulary_size=vocabularySize,
hidden_size=100,
embedding_size=50,
num_layers=3,
rnn_dropout=0.0,
dropout=0,
num_directions=2).to(device)
Если у вас есть какие-либо идеи о том, что нужно изменить, пожалуйста, дайте мне знать.
Я добавил весь код в репозиторий github здесь:https://github.com/OverclockRo/HTMLGeneration/blob/SamplingTestTemplate/Untitled.ipynb
Ответ №1:
Прежде всего, чтобы GRU (RNN) был эффективным, вам может потребоваться больше данных для обучения.
Во-вторых, похоже, у вас проблема с внедрением. Похоже, словарь сопоставления[‘id2letter’] не работает, иначе вы получили бы последовательности тегов типа <head><title><title><title>
, вместо p111
.
Редактировать
Я обучал эту сеть GRU на уровне символов на исходном HTML-коде этой страницы в течение 1700 эпох. И вот пример 2000-символьной выдержки из того, что он генерирует:
A Implexementation--nope bande that shoos</td></tr><tr><td class="line-number" value="296"></td><td class="line-content"> </td></tr><tr><td class="line-number" value="1437"></td><td class="line-content"> <span class="html-tag">amp;</aamp;></span></td></tr><tr><td class="line-number" value="755"></td><td class="line-content"> </td></tr><tr><td class="line-number" value="584"></td><td class="line-content"> <span class="html-tag">amp;<a <span class="html-attribute-name">data-controller</span>="<span class="html-attribute-value">footer__menu__link</span>"amp;></span><span class="html-tag">amp;<div <span class="html-attribute-name">data-target</span>="<span class="html-attribute-value">release__line</span>"amp;></span><span class="html-tag">amp;<a <span class="html-attribute-name">class</span>="<span class="html-attribute-value">/hase__version-date</span>"amp;></span></td></tr><tr><td class="line-number" value="174"></td><td class="line-content"><br></td></tr><tr><td class="line-number" value="1315"></td><td class="line-content">Bule and the use the twith a hoas suiecode excess ardates</td></tr><tr><td class="line-number" value="1003"></td><td class="line-content"><span class="html-tag">amp;</aamp;></span></td></tr><tr><td class="line-number" value="129"></td><td class="line-content"> </td></tr><tr><td class="line-number" value="269"></td><td class="line-content"> <span class="html-tag">amp;</ulamp;></span></td></tr><tr><td class="line-number" value="591"></td><td class="line-content"> <span class="html-tag">amp;</divamp;></span></td></tr><tr><td class="line-number" value="553"></td><td class="line-content"> <span class="html-tag">amp;<div <span class="html-attribute-name">href</span>="<a class="html-attribute-value html-external-link" target__link</td><td class="line-content"> </td></tr><tr><td class="line-number" value="103"></td><td class="line-content"> </td></tr><tr><td cla
Я надеюсь, это поможет.
Комментарии:
1. Большое спасибо за ответ, сэр. Это генератор символов посимвольно, поэтому он должен научиться генерировать теги.
2. Проблема в том, что это не так, и, честно говоря, я не знаю, что делать с этим шагом вперед.
3. Если это генератор символов посимвольно, то ‘[Start]’ и ‘[End]’ также должны быть escape-символами, а не строками.
4. Я также расширил ответ примером RNN на уровне символов.
5. Это правда. Я закодировал [START] и [END] как отдельные значения int в тензорах и просто отображаю их таким образом. Большое спасибо за предложенное решение, сэр. Это действительно полезно.