人工智慧PK高鶚,續寫《紅樓夢》

楊天超發表於2021-01-01

1.前言

既然曹老爺子的後四十回丟了,那麼對於每個熱愛她的人來說,續寫紅樓都是一件讓人熱血沸騰的事兒。正好最近不是很忙,作為一個自然語言處理的小學生,我大膽嘗試著使用人工智慧來實現我的願望。

2.環境準備

1.整體模型使用T1080 訓練了10分鐘左右,當然是一個比較簡單的模型
2.框架使用tensorflow2.1版本

3.程式碼

使用方式,給定第一個字,自動生成固定長度的文字。

import tensorflow as tf
import numpy as np
import os
import time
text = open('honglou.txt','r',encoding='gb18030').read()
vocab = sorted(set(text))
char2idx = {u:i for i,u in enumerate(vocab)}
text_as_int = np.array([char2idx[t] for t in text])
char_dataset = tf.data.Dataset.from_tensor_slices(text_as_int)
seq_length = 100
sequences = char_dataset.batch(seq_length+1,drop_remainder=True)

def split_input_target(chunk):
input_text = chunk[:-1]
target_text = chunk[1:]
return input_text,target_text
dataset = sequences.map(split_input_target)
BATCH_SIZE = 64
dataset = dataset.shuffle(1000).batch(BATCH_SIZE,drop_remainder=True)

#詞集的長度
vocab_size = len(vocab)
#嵌入的維度
embedding_dim = 256
#RNN 的單元數量
rnn_units = 1024
def build_model(vocab_size, embedding_dim, rnn_units, batch_size):
model = tf.keras.Sequential([
tf.keras.layers.Embedding(vocab_size, embedding_dim,
batch_input_shape=[batch_size, None]),
tf.keras.layers.GRU(rnn_units,
return_sequences=True,
stateful=True,
recurrent_initializer=‘glorot_uniform’),
tf.keras.layers.Dense(vocab_size)
])
return model
model = build_model(vocab_size = len(vocab),embedding_dim=embedding_dim,rnn_units=rnn_units,batch_size=BATCH_SIZE)

for input_example_batch, target_example_batch in dataset.take(1):
example_batch_predictions = model(input_example_batch)
def loss(labels, logits):
return tf.keras.losses.sparse_categorical_crossentropy(labels, logits, from_logits=True)
example_batch_loss = loss(target_example_batch, example_batch_predictions)
model.compile(optimizer=‘adam’, loss=loss)

#檢查點儲存至的目錄
checkpoint_dir = ‘./training_checkpoints’
#檢查點的檔名
checkpoint_prefix = os.path.join(checkpoint_dir, “ckpt_{epoch}”)
checkpoint_callback=tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_prefix,save_weights_only=True)

EPOCHS = 150
model.fit(dataset,epochs=EPOCHS,callbacks=[checkpoint_callback])

#使用模型
tf.train.latest_checkpoint(checkpoint_dir)
model = build_model(vocab_size,embedding_dim,rnn_units,1)
model.load_weights(tf.train.latest_checkpoint(checkpoint_dir))
model.build(tf.TensorShape([1, None]))

def generate_text(model, start_string):

評估步驟(用學習過的模型生成文字)

要生成的字元個數

num_generate = 1000

將起始字串轉換為數字(向量化)

input_eval = [char2idx[s] for s in start_string]
input_eval = tf.expand_dims(input_eval, 0)

空字串用於儲存結果

text_generated = []

低溫度會生成更可預測的文字

較高溫度會生成更令人驚訝的文字

可以通過試驗以找到最好的設定

temperature = 1.0

這裡批大小為 1

model.reset_states()
idx2char = np.array(vocab)
for i in range(num_generate):
predictions = model(input_eval)
# 刪除批次的維度
predictions = tf.squeeze(predictions, 0)

  # 用分類分佈預測模型返回的字元
  predictions = predictions / temperature
  predicted_id = tf.random.categorical(predictions, num_samples=1)[-1,0].numpy()

  # 把預測字元和前面的隱藏狀態一起傳遞給模型作為下一個輸入
  input_eval = tf.expand_dims([predicted_id], 0)
 
  text_generated.append(idx2char[predicted_id])

return (start_string + ‘’.join(text_generated))
print(generate_text(model, start_string=u"話說金桂聽了"))

4.我的一天

我去使用飲水機打水,剛開始的時候水杯發出的聲音很大,一度會擔心吵到別人。隨著杯子中水量的增加,聲音越來越小,直到最後聽不見,我就將水關掉了。這就是人們常說的滿瓶不響半瓶響吧!是說一個人沒有什麼水平的時候,總是表現的特別高調,等到這個人成熟了,見過大的世面,就懂得謙遜和低調。可是我不禁的去想,為什麼我們總是在空瓶的時候,希望它的聲音小一點。對於不成熟的人,高調不是一件很正常的事情嗎?既然大自然不嫌棄會響的空瓶,我們有什麼資格嫌棄那些不成熟的人呢?這種嫌棄的心才是真的應該被嫌棄的吧!算了,不想了,繼續努力工作吧!在我工作的累的時候,我就聽會兒個放鬆一下。這時候突然想起了一個農民,大熱的天他在田地裡辛苦的勞動,這時候也累了找個樹蔭處休息休息,吹吹風。再看看我的四周,我還真是羨慕那個農民。突然間覺得土地無比的親切,我想家了,想回到自己出生的地方去,聽聽田裡蟋蟀的聲音。

愣著幹什麼?進來選老婆!

相關文章