使用百度 AI 進行智能寫詩 & 智能春聯

注:本博客爲博主在 百度 AI 社區 上分享的一篇文章,由於本博主也是作爲一個學習者,所以如果文章中存在錯誤或者不適合的地方還請見諒。

先來一波推薦:
如果你也喜歡開發,歡迎加入百度 AI 開發平臺的核心團隊,分享自己的 idea,當然也是有福利的,具體信息訪問以下鏈接:【招募令】核心團隊在找最優秀的你! 。如果不介意的話可以說是我推薦的喲,本博主百度AI社區ID:busyboxs

我爲什麼要做這個小項目?
要說起我爲什麼要做這個小項目,其實要從我的學習生涯談起。我本來是學深度學習圖像處理的,所以經常關注深度學習相關的諮詢。當然也喜歡將實際的理論知識用於實踐中,在兩年前,使用深度學習來對對聯火了一段時間,我當時也關注了這個,印象比較深刻的是 王斌給您對對聯 --!,這個是用 tensorflow 來實現的項目,但是由於我主要是做 CV 的,對於 NLP 很多東西不是很瞭解,所以沒有深入去理解裏面的網絡結構。後來一次偶然的機會接觸到了百度 AI 開放平臺,看到裏面有提供這個接口,所以打算嘗試寫一個我自己的對對聯項目。所以這個小項目得以誕生,雖然可能還是由很多問題,並不完善,但是在寫出這個小項目後還是蠻開心的。我從中也學會了一些新知識,比如 Flask 庫的使用以及 request 相關的知識。我的小項目裏也借用了 王斌給您對對聯 --! 中的一些網頁元素,在此對作者的分享表示感謝,同時感謝百度 AI 開放平臺提供的接口,只是遺憾的是這個接口的免費調用次數有所限制。


百度 AI 目前提供了智能寫作的接口,主要包括智能寫詩接口與智能春聯接口。具體的使用說明可以參考文檔 https://ai.baidu.com/ai-doc/NLP/Nk3ippdkc.

智能寫作接口說明

智能春聯接口

智能春聯是指根據用戶輸入的命題關鍵詞自動生成一副春聯,包括上聯、下聯和橫批。

智能春聯的請求參數如下表:

參數 是否必選 類型 描述
text string 字符串(限5字符數以內)即春聯的主題
index int 整數 默認爲數值爲0,即第一幅春聯。每換一次,數值加1即可,一定數量後會返回之前的春聯結果。

上面兩個字符段是接口的輸入,text 字數小於 5,是春聯的主題。 index 可以用來指定生成的對聯,不同的 index 可能會生成不同的對聯。

智能春聯的返回參數如下表:

參數 類型 描述
couplets object object嵌套結構,對應返回的春聯
+first string 春聯上聯:成7-9個字的上聯
+second string 春聯下聯:生成7-9個字的春聯下聯
+center string 春聯橫批:生成4個字的春聯橫批

其輸出爲 json 字符串。例如:“春節”對應的一個輸出爲

{
	'couplets': {
		'center': '迎春接福', 
		'first': '春節迎春新世紀', 
		'second': '福音報福小康年'
		}
}

智能寫詩接口

智能寫詩是指根據用戶輸入的命題關鍵詞自動生成一首7言絕句。

智能寫詩的請求參數如下表:

參數 是否必選 類型 描述
text string 字符串(限5字符數以內,)即作詩的主題
index int 整數 默認爲數值爲0,即第一首詩。每換一次,數值加1即可,一定數量後會返回之前的作詩結果

這兩個輸入字段和智能春聯的兩個輸入字段相同,只是,text 代表詩的主題

智能寫詩的返回參數如下表:

參數 類型 描述
poem array 數組結構,元素對應7言絕句詩
+title string 詩名,即用戶輸入作詩主題
+content string 作詩結果:爲一首7言絕句

其輸出也是 json 字符串,例如:“百度”對應的一個輸出爲

{
  "poem": [
  	{
  		"title":      "百度"
  	  	"content": "神州百度慶元功
              		華夏千秋唱大風
              		偉業宏圖開盛世
              		紅旗錦繡耀長空"
  	}
  ]
}

錯誤碼說明

錯誤碼 錯誤信息 描述
52000 成功
52001 請求超時 重試
52002 系統錯誤 重試
52003 未授權用戶 檢查您的appid是否正確
52004 輸入解析失敗 檢查輸入編碼格式,有無特殊字符,是否是json格式
52005 輸入字段有誤 是否包含text字段
52006 輸入文本長度有誤 輸入不能超過5個字符
52007 輸入文本包含政治&黃色內容 換輸入文本
52008 後臺服務返回錯誤 重試
54003 訪問頻率受限 請降低您的調用頻率
54100 查詢接口參數爲空 檢查是否少傳參數
54102 無寫詩結果 重試
2 後端連接超時 重試

代碼實現

本文使用 python3 來調用智能春聯和智能寫詩接口,接下來一步一步進行說明。

創建應用

首先進入到控制檯,然後在“總覽”下找到“產品服務” -> “人工智能” -> “自然語言處理”。

在這裏插入圖片描述
然後點擊創建應用,填寫好“應用名稱”、“應用描述”,其他默認就行,然後點擊“創建”。
在這裏插入圖片描述
在這裏插入圖片描述

創建好應用之後,進入“應用列表”,就能看到應用的相關信息,我們需要的是 API KeySecret Key

在這裏插入圖片描述

獲取 access token

通過 API KeySecret Key 獲取的 access_token。更多關於 access_token 的獲取方法參考 https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjhhu

下面代碼是 python3 獲取 access_token 的代碼

# 獲取 token
def get_token_key():
    token_key = ''
    # client_id 爲官網獲取的AK, client_secret 爲官網獲取的SK
    client_id = '【百度雲應用的AK】'
    client_secret = '【百度雲應用的SK】'

    host = f'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials' \
        f'&client_id={client_id}&client_secret={client_secret}'

    request = Request(host)
    request.add_header('Content-Type', 'application/json; charset=UTF-8')
    response = urlopen(request)
    token_content = response.read()
    if token_content:
        token_info = json.loads(token_content)
        token_key = token_info['access_token']
    return token_key

token_content 中包含很多信息,例如輸出如下(爲了我個人信息安全,部分內容用 * 代替):

{'access_token': '****************************************',
 'expires_in': 2592000,
 'refresh_token': '*******************************************',
 'scope': 'brain_nlp_sentiment_classify_custom public nlp_simnet nlp_wordemb '
          'nlp_comtag nlp_dnnlm_cn brain_nlp_lexer brain_all_scope '
          'brain_nlp_comment_tag brain_nlp_dnnlm_cn brain_nlp_word_emb_vec '
          'brain_nlp_word_emb_sim brain_nlp_sentiment_classify '
          'brain_nlp_simnet brain_nlp_depparser brain_nlp_wordembedding '
          'brain_nlp_dnnlm_cn_legacy brain_nlp_simnet_legacy '
          'brain_nlp_comment_tag_legacy brain_nlp_lexer_custom '
          'brain_nlp_keyword brain_nlp_topic brain_nlp_ecnet brain_nlp_emotion '
          'brain_nlp_comment_tag_custom wise_adapt lebo_resource_base '
          'lightservice_public hetu_basic lightcms_map_poi kaidian_kaidian '
          'ApsMisTest_Test權限 vis-classify_flower lpq_開放 cop_helloScope '
          'ApsMis_fangdi_permission smartapp_snsapi_base iop_autocar '
          'oauth_tp_app smartapp_smart_game_openapi oauth_sessionkey '
          'smartapp_swanid_verify smartapp_opensource_openapi',
 'session_key': '*****************************',
 'session_secret': '*******************************'}

而我們需要的只是 access_token,因此只需獲取該字段就行。

調用智能春聯接口

調用智能春聯接口的 python3 實現代碼如下:

注:由於文檔和接口有更新,請求 URL 有修改
如下
請求URL:https://aip.baidubce.com/rpc/2.0/creation/v1/couplets
請求URL: https://aip.baidubce.com/rpc/2.0/nlp/v1/couplets(邀測期用戶)

# 調用百度 AI 智能春聯接口(用於測試)
def get_couplets(text, token_key, index=0):
    """
    調用百度AI智能春聯接口,並生成橫批、上聯和下聯
    :param text: 智能春聯的主題(官方限制不超過5個字)
    :param token_key: 通過調用 get_token_key() 獲取的 token
    :param index: 不同的 index 會生成不同的春聯
    :return: 調用智能春聯生成的數據
    """
    request_url = 'https://aip.baidubce.com/rpc/2.0/nlp/v1/couplets'
    params_d = dict()
    params_d['text'] = text
    params_d['index'] = index
    params = json.dumps(params_d).encode('utf-8')
    access_token = token_key
    request_url = request_url + "?access_token=" + access_token
    request = Request(url=request_url, data=params)
    request.add_header('Content-Type', 'application/json')
    response = urlopen(request)
    content = response.read()
    if content:
        data = json.loads(content)
        return data

# 解析生成的春聯
def parse_couplets(data):
    """
    解析調用智能春聯生成的數據
    :param data: 調用智能春聯生成的有效數據
    :return: 橫批(center)、上聯(first)和下聯(second)
    """
    center = data['couplets']['center']
    first = data['couplets']['first']
    second = data['couplets']['second']
    # print(f'上聯:{first}')
    # print(f'下聯:{second}')
    # print(f'橫批:{center}')
    return center, first, second

get_couplets 函數調用接口得到返回的值,parse_couplets 函數解析調用智能春聯生成的有效數據。這裏所說的有效數據是指調用接口沒有發生錯誤的情況。在正確調用接口時,data 輸出示例如下:

{
	'couplets': {
		'center': '迎春接福', 
		'first': '春節迎春新世紀', 
		'second': '福音報福小康年'
		}
}

是一個字典型數據,直接進行解析就能得到橫批、上聯和下聯。如果想要獲取同一主題不同的對聯,可以嘗試不同的 index

當調用接口失敗時,就會得到無效的 data,通過解析 data,能夠獲得錯誤信息,下面是解析錯誤的代碼,能夠返回對應錯誤的中文描述。

# 錯誤代碼
ERROR_DICT = {
    '2': '後端連接超時請重試',
    '52001': '請求超時請重試',
    '52002': '系統錯誤請重試',
    '52003': '未授權用戶',
    '52004': '輸入解析失敗',
    '52005': '輸入字段有誤',
    '52006': '輸入文本長度不超過5',
    '52007': '輸入文本包含政治&黃色內容',
    '52008': '後臺服務返回錯誤請重試',
    '54003': '訪問頻率受限',
    '54100': '查詢接口參數爲空',
    '54102': '無寫詩結果請重試'
}

# 解析是否調用接口錯誤,如果有返回對應的提示,沒有返回None
def parse_error(data):
    """
    解析是否調用接口錯誤
    :param data: 調用接口生成的數據
    :return: 如果出錯,返回對應的錯誤信息,否則返回None
    """
    if 'error_code' in data:
        code = data['error_code']
        error = ERROR_DICT[str(code)]
        return error
    return None

調用智能寫詩接口

調用智能寫詩接口的 python3 實現代碼如下:

注:由於文檔和接口有更新,請求 URL 有修改
如下
請求URL:https://aip.baidubce.com/rpc/2.0/creation/v1/poem
請求URL: https://aip.baidubce.com/rpc/2.0/nlp/v1/poem(邀測期用戶)

# 調用百度 AI 智能寫詩接口(用於測試)
def get_poem(text, token_key, index=0):
    """
    調用百度AI智能寫詩接口,並生成七言詩
    :param text: 智能寫詩的主題(官方限制不超過5個字)
    :param token_key: 通過調用 get_token_key() 獲取的 token
    :param index: 不同的 index 會生成不同的七言詩
    :return: 調用智能寫詩生成的數據
    """
    request_url = 'https://aip.baidubce.com/rpc/2.0/nlp/v1/poem'
    params_d = dict()
    params_d['text'] = text
    params_d['index'] = index
    params = json.dumps(params_d).encode('utf-8')
    access_token = token_key
    request_url = request_url + "?access_token=" + access_token
    request = Request(url=request_url, data=params)
    request.add_header('Content-Type', 'application/json')
    response = urlopen(request)
    content = response.read()
    if content:
        data = json.loads(content)
        return data


# 解析生成的詩句
def parse_poem(data):
    """
    解析調用智能寫詩生成的數據
    :param data: 調用智能寫詩生成的有效數據
    :return: 詩的題目(title)和詩的內容(content)
    """
    title = data['poem'][0]['title']
    poem = data['poem'][0]['content'].replace('\t', '\n')
    # print(title)
    # print(poem)
    return title, poem

在正確調用接口時,data 輸出如下:

{
  "poem": [
  	{
  		"title":      "百度"
  	  	"content": "神州百度慶元功
              		華夏千秋唱大風
              		偉業宏圖開盛世
              		紅旗錦繡耀長空"
  	}
  ]
}

是一個字典型數據,直接進行解析就能得到題目和內容。如果想要獲取同一主題不同的詩,可以嘗試不同的 index

案例應用

本文進一步通過網頁的形式將上述功能進行實現,使用Flask來部署。

首先創建一個文件夾 flaskr,該文件夾下有一個名爲 static 的文件夾,用於存放 css 樣式和背景圖片,還有一個文件夾名爲 templates 用於存放 html 網頁,另外還有一個 python 文件,用於執行 flask。

以下是 Flask 相關代碼

from flask import Flask, render_template, request, redirect, url_for, session
from flaskr.poem import nlp_result, parse_error, parse_couplets, parse_poem
import random

app = Flask(__name__)

token_key = '【你獲取的token】'


@app.route("/", methods=('GET', 'POST'))
def index():
    if request.method == 'POST':
        couplets = request.form.get('couplets')
        if couplets is not None:
            return redirect(url_for('get_couplets'))
        poem = request.form.get('poem')
        if poem is not None:
            return redirect(url_for('get_poem'))

    return render_template('couplets/index.html')


@app.route("/couplets", methods=('GET', 'POST'))
def get_couplets():
    if request.method == 'POST':
        center = None
        first = None
        second = None
        title = request.form.get('theme')
        back = request.form.get('back')
        if back == '返回':
            return redirect(url_for('index'))
        index = random.randint(0, 10)
        data = nlp_result(title, token_key, index, way='couplets')
        error = parse_error(data)
        if not error:
            center, first, second = parse_couplets(data)
        return render_template('couplets/show.html',
                               center=center,
                               first=first,
                               second=second,
                               title=title,
                               error=error)
    return render_template('couplets/base.html')


@app.route("/poem", methods=('GET', 'POST'))
def get_poem():
    if request.method == 'POST':
        title = None
        poem = None
        title = request.form.get('theme')
        back = request.form.get('back')
        if back == '返回':
            return redirect(url_for('index'))
        index = random.randint(0, 10)
        data = nlp_result(title, token_key, index, way='poem')
        error = parse_error(data)
        if not error:
            title, poem = parse_poem(data)
        return render_template('couplets/poem_show.html',
                               title=title,
                               poem=poem,
                               error=error)
    return render_template('couplets/poem_index.html')


if __name__ == '__main__':
    app.run(debug=True)

該代碼中有三個函數,分別對應三個界面,如果運行地址爲 http://127.0.0.1:5000/,那麼三個界面對應的網址分別爲 http://127.0.0.1:5000/http://127.0.0.1:5000/coupletshttp://127.0.0.1:5000/poem。表示主頁、對聯頁和寫詩頁。

其效果展示如下:

主頁頁面
寫詩頁面
對聯頁面

處理錯誤信息的效果展示如下:

在這裏插入圖片描述
在這裏插入圖片描述
完整代碼請移步 https://github.com/busyboxs/couplet-and-poem

發佈了22 篇原創文章 · 獲贊 11 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章