『NLP经典项目集』05:新年到,飞桨带你对对联

基于seq2seq的对联生成
对联,是汉族传统文化之一,是写在纸、布上或刻在竹子、木头、柱子上的对偶语句。对联对仗工整,平仄协调,是一字一音的汉语独特的艺术形式,是中国传统文化瑰宝。

这里,我们将根据上联,自动写下联。这是一个典型的序列到序列(sequence2sequence, seq2seq)建模的场景,编码器-解码器(Encoder-Decoder)框架是解决seq2seq问题的经典方法,它能够将一个任意长度的源序列转换成另一个任意长度的目标序列:编码阶段将整个源序列编码成一个向量,解码阶段通过最大化预测序列概率,从中解码出整个目标序列。编码和解码的过程通常都使用RNN实现。



图1:encoder-decoder示意图

这里的Encoder采用LSTM,Decoder采用带有attention机制的LSTM。



图2:带有attention机制的encoder-decoder示意图

我们将以对联的上联作为Encoder的输出,下联作为Decoder的输入,训练模型。

AI Studio平台后续会默认安装PaddleNLP,在此之前可使用如下命令安装。

In [1]
!pip install paddlenlp==2.0.0rc12 -i https://pypi.org/simple
Requirement already satisfied: paddlenlp==2.0.0rc12 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (2.0.0rc12)
Requirement already satisfied: seqeval in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddlenlp==2.0.0rc12) (1.2.2)
Requirement already satisfied: h5py in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddlenlp==2.0.0rc12) (2.9.0)
Requirement already satisfied: jieba in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddlenlp==2.0.0rc12) (0.42.1)
Requirement already satisfied: colorlog in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddlenlp==2.0.0rc12) (4.1.0)
Requirement already satisfied: colorama in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddlenlp==2.0.0rc12) (0.4.4)
Requirement already satisfied: visualdl in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from paddlenlp==2.0.0rc12) (2.1.1)
Requirement already satisfied: scikit-learn>=0.21.3 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from seqeval->paddlenlp==2.0.0rc12) (0.22.1)
Requirement already satisfied: numpy>=1.14.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from seqeval->paddlenlp==2.0.0rc12) (1.16.4)
Requirement already satisfied: six in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from h5py->paddlenlp==2.0.0rc12) (1.15.0)
Requirement already satisfied: Pillow>=7.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl->paddlenlp==2.0.0rc12) (7.1.2)
Requirement already satisfied: flake8>=3.7.9 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl->paddlenlp==2.0.0rc12) (3.8.2)
Requirement already satisfied: Flask-Babel>=1.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl->paddlenlp==2.0.0rc12) (1.0.0)
Requirement already satisfied: pre-commit in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl->paddlenlp==2.0.0rc12) (1.21.0)
Requirement already satisfied: requests in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl->paddlenlp==2.0.0rc12) (2.22.0)
Requirement already satisfied: flask>=1.1.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl->paddlenlp==2.0.0rc12) (1.1.1)
Requirement already satisfied: shellcheck-py in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl->paddlenlp==2.0.0rc12) (0.7.1.1)
Requirement already satisfied: bce-python-sdk in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl->paddlenlp==2.0.0rc12) (0.8.53)
Requirement already satisfied: protobuf>=3.11.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl->paddlenlp==2.0.0rc12) (3.14.0)
Requirement already satisfied: scipy>=0.17.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from scikit-learn>=0.21.3->seqeval->paddlenlp==2.0.0rc12) (1.3.0)
Requirement already satisfied: joblib>=0.11 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from scikit-learn>=0.21.3->seqeval->paddlenlp==2.0.0rc12) (0.14.1)
Requirement already satisfied: importlib-metadata; python_version < "3.8" in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl->paddlenlp==2.0.0rc12) (0.23)
Requirement already satisfied: pycodestyle<2.7.0,>=2.6.0a1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl->paddlenlp==2.0.0rc12) (2.6.0)
Requirement already satisfied: pyflakes<2.3.0,>=2.2.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl->paddlenlp==2.0.0rc12) (2.2.0)
Requirement already satisfied: mccabe<0.7.0,>=0.6.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl->paddlenlp==2.0.0rc12) (0.6.1)
Requirement already satisfied: pytz in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Flask-Babel>=1.0.0->visualdl->paddlenlp==2.0.0rc12) (2019.3)
Requirement already satisfied: Babel>=2.3 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Flask-Babel>=1.0.0->visualdl->paddlenlp==2.0.0rc12) (2.8.0)
Requirement already satisfied: Jinja2>=2.5 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Flask-Babel>=1.0.0->visualdl->paddlenlp==2.0.0rc12) (2.10.1)
Requirement already satisfied: identify>=1.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl->paddlenlp==2.0.0rc12) (1.4.10)
Requirement already satisfied: cfgv>=2.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl->paddlenlp==2.0.0rc12) (2.0.1)
Requirement already satisfied: virtualenv>=15.2 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl->paddlenlp==2.0.0rc12) (16.7.9)
Requirement already satisfied: nodeenv>=0.11.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl->paddlenlp==2.0.0rc12) (1.3.4)
Requirement already satisfied: pyyaml in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl->paddlenlp==2.0.0rc12) (5.1.2)
Requirement already satisfied: aspy.yaml in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl->paddlenlp==2.0.0rc12) (1.3.0)
Requirement already satisfied: toml in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl->paddlenlp==2.0.0rc12) (0.10.0)
Requirement already satisfied: idna<2.9,>=2.5 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl->paddlenlp==2.0.0rc12) (2.8)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl->paddlenlp==2.0.0rc12) (1.25.6)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl->paddlenlp==2.0.0rc12) (3.0.4)
Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl->paddlenlp==2.0.0rc12) (2019.9.11)
Requirement already satisfied: click>=5.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl->paddlenlp==2.0.0rc12) (7.0)
Requirement already satisfied: itsdangerous>=0.24 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl->paddlenlp==2.0.0rc12) (1.1.0)
Requirement already satisfied: Werkzeug>=0.15 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl->paddlenlp==2.0.0rc12) (0.16.0)
Requirement already satisfied: future>=0.6.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from bce-python-sdk->visualdl->paddlenlp==2.0.0rc12) (0.18.0)
Requirement already satisfied: pycryptodome>=3.8.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from bce-python-sdk->visualdl->paddlenlp==2.0.0rc12) (3.9.9)
Requirement already satisfied: zipp>=0.5 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from importlib-metadata; python_version < "3.8"->flake8>=3.7.9->visualdl->paddlenlp==2.0.0rc12) (0.6.0)
Requirement already satisfied: MarkupSafe>=0.23 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Jinja2>=2.5->Flask-Babel>=1.0.0->visualdl->paddlenlp==2.0.0rc12) (1.1.1)
Requirement already satisfied: more-itertools in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from zipp>=0.5->importlib-metadata; python_version < "3.8"->flake8>=3.7.9->visualdl->paddlenlp==2.0.0rc12) (7.2.0)
In [2]
import paddlenlp
paddlenlp.__version__
'2.0.0rc12'
In [3]
import io
import os

from functools import partial

import numpy as np

import paddle
import paddle.nn as nn
import paddle.nn.functional as F
from paddlenlp.data import Vocab, Pad
from paddlenlp.metrics import Perplexity
from paddlenlp.datasets import load_dataset
数据部分
数据集介绍
采用开源的对联数据集couplet-clean-dataset,该数据集过滤了 couplet-dataset中的低俗、敏感内容。

这个数据集包含70w多条训练样本,1000条验证样本和1000条测试样本。

下面列出一些训练集中对联样例:

上联:晚风摇树树还挺	下联:晨露润花花更红

上联:愿景天成无墨迹	下联:万方乐奏有于阗

上联:丹枫江冷人初去	下联:绿柳堤新燕复来

上联:闲来野钓人稀处	下联:兴起高歌酒醉中

加载数据集
paddlenlp中提供多个常见数据集,包括这里的对联数据集Couplet。对联数据集分为上联(the first line)和下联(the second line)


获取数据集可以调用paddlenlp.datasets.load_dataset,传入splits ("train", "dev", "test"),即可获取对应的train_ds, dev_ds, test_ds。其中train_ds为训练集,用于模型训练; dev_ds为开发集,也称验证集,用于模型参数调优;test_ds为测试集,用于评估算法的性能,但不会根据测试集上的表现再去调整模型或参数。
调用map()函数,对数据集进行指定操作。

In [4]
train_ds, test_ds = load_dataset('couplet', splits=('train', 'test'))
2021-03-11 10:46:17,316 - INFO - unique_endpoints {''}
2021-03-11 10:46:17,317 - INFO - Downloading couplet.tar.gz from https://paddlenlp.bj.bcebos.com/datasets/couplet.tar.gz
100%|██████████| 21421/21421 [00:00<00:00, 51680.74it/s]
2021-03-11 10:46:17,809 - INFO - File /home/aistudio/.paddlenlp/datasets/Couplet/couplet.tar.gz md5 checking...
2021-03-11 10:46:17,861 - INFO - Decompressing /home/aistudio/.paddlenlp/datasets/Couplet/couplet.tar.gz...
来看看数据集有多大,长什么样:

In [5]
print (len(train_ds), len(test_ds))
for i in range(5):
    print (train_ds[i])

print ('\n')
for i in range(5):
    print (test_ds[i])
702594 999
{'first': '晚\x02风\x02摇\x02树\x02树\x02还\x02挺', 'second': '晨\x02露\x02润\x02花\x02花\x02更\x02红'}
{'first': '愿\x02景\x02天\x02成\x02无\x02墨\x02迹', 'second': '万\x02方\x02乐\x02奏\x02有\x02于\x02阗'}
{'first': '丹\x02枫\x02江\x02冷\x02人\x02初\x02去', 'second': '绿\x02柳\x02堤\x02新\x02燕\x02复\x02来'}
{'first': '闲\x02来\x02野\x02钓\x02人\x02稀\x02处', 'second': '兴\x02起\x02高\x02歌\x02酒\x02醉\x02中'}
{'first': '投\x02石\x02向\x02天\x02跟\x02命\x02斗', 'second': '闭\x02门\x02问\x02卷\x02与\x02时\x02争'}


{'first': '心\x02尘\x02须\x02自\x02扫', 'second': '意\x02念\x02总\x02虚\x02空'}
{'first': '碧\x02涧\x02飞\x02泉\x02山\x02笑\x02语', 'second': '惊\x02涛\x02啸\x02海\x02浪\x02呼\x02声'}
{'first': '即\x02景\x02即\x02心\x02无\x02机\x02不\x02被', 'second': '非\x02空\x02非\x02色\x02有\x02感\x02灵\x02通'}
{'first': '袋\x02鼓\x02黎\x02民\x02乐', 'second': '粮\x02丰\x02社\x02稷\x02安'}
{'first': '相\x02通\x02心\x02意\x02何\x02须\x02语', 'second': '难\x02解\x02情\x02丝\x02不\x02用\x02说'}
In [6]
vocab = Vocab.load_vocabulary(**train_ds.vocab_info)
trg_idx2word = vocab.idx_to_token
vocab_size = len(vocab)

pad_id = vocab[vocab.eos_token]
bos_id = vocab[vocab.bos_token]
eos_id = vocab[vocab.eos_token]
print (pad_id, bos_id, eos_id)
2 1 2
将数据集文本转成id
想将数据集文本转成id,需要实现一个convert_example函数,然后传入map函数,用map将带有文本的数据集转成带id的数据集。



图3:token-to-id示意图

In [7]
def convert_example(example, vocab):
    pad_id = vocab[vocab.eos_token]
    bos_id = vocab[vocab.bos_token]
    eos_id = vocab[vocab.eos_token]
    source = [bos_id] + vocab.to_indices(example['first'].split('\x02')) + [eos_id]
    target = [bos_id] + vocab.to_indices(example['second'].split('\x02')) + [eos_id]
    return source, target

trans_func = partial(convert_example, vocab=vocab)
train_ds = train_ds.map(trans_func, lazy=False)
test_ds = test_ds.map(trans_func, lazy=False)
构造dataloder
使用paddle.io.DataLoader来创建训练和预测时所需要的DataLoader对象。

paddle.io.DataLoader返回一个迭代器,该迭代器根据batch_sampler指定的顺序迭代返回dataset数据。支持单进程或多进程加载数据,快!


接收如下重要参数:

batch_sampler:批采样器实例,用于在paddle.io.DataLoader 中迭代式获取mini-batch的样本下标数组,数组长度与 batch_size 一致。
collate_fn:指定如何将样本列表组合为mini-batch数据。传给它参数需要是一个callable对象,需要实现对组建的batch的处理逻辑,并返回每个batch的数据。在这里传入的是prepare_input函数,对产生的数据进行pad操作,并返回实际长度等。
PaddleNLP提供了许多NLP任务中,用于数据处理、组batch数据的相关API。

API	简介
paddlenlp.data.Stack	堆叠N个具有相同shape的输入数据来构建一个batch
paddlenlp.data.Pad	将长度不同的多个句子padding到统一长度,取N个输入数据中的最大长度
paddlenlp.data.Tuple	将多个batchify函数包装在一起
更多数据处理操作详见: https://github.com/PaddlePaddle/PaddleNLP/blob/develop/docs/data.md

In [8]
def create_data_loader(dataset):
    data_loader = paddle.io.DataLoader(
        dataset,
        batch_sampler=None,
        batch_size = batch_size,
        collate_fn=partial(prepare_input, pad_id=pad_id))
    return data_loader

def prepare_input(insts, pad_id):
    src, src_length = Pad(pad_val=pad_id, ret_length=True)([inst[0] for inst in insts])
    tgt, tgt_length = Pad(pad_val=pad_id, ret_length=True)([inst[1] for inst in insts])
    tgt_mask = (tgt[:, :-1] != pad_id).astype(paddle.get_default_dtype())
    return src, src_length, tgt[:, :-1], tgt[:, 1:, np.newaxis], tgt_mask
In [9]
device = "gpu" # or cpu
device = paddle.set_device(device)

batch_size = 128
num_layers = 2
dropout = 0.2
hidden_size =256
max_grad_norm = 5.0
learning_rate = 0.001
max_epoch = 20
model_path = './couplet_models'
log_freq = 200

# Define dataloader
train_loader = create_data_loader(train_ds)
test_loader = create_data_loader(test_ds)

print(len(train_ds), len(train_loader), batch_size)
# 702594 5490 1285490个batch

for i in train_loader:
    print (len(i))
    for ind, each in enumerate(i):
        print (ind, each.shape)
    break
702594 5490 128
5
0 [128, 18]
1 [128]
2 [128, 17]
3 [128, 17, 1]
4 [128, 17]
模型部分
下图是带有Attention的Seq2Seq模型结构。下面我们分别定义网络的每个部分,最后构建Seq2Seq主网络。



图5:带有attention机制的encoder-decoder原理示意图

定义Encoder
Encoder部分非常简单,可以直接利用PaddlePaddle2.0提供的RNN系列API的nn.LSTM。

nn.Embedding:该接口用于构建 Embedding 的一个可调用对象,根据输入的size (vocab_size, embedding_dim)自动构造一个二维embedding矩阵,用于table-lookup。查表过程如下:


图5:token-to-id & 查表获取向量示意图

nn.LSTM:提供序列,得到encoder_output和encoder_state。
参数:
input_size (int) 输入的大小。
hidden_size (int) - 隐藏状态大小。
num_layers (int,可选) - 网络层数。默认为1。
direction (str,可选) - 网络迭代方向,可设置为forward或bidirect(或bidirectional)。默认为forward。
time_major (bool,可选) - 指定input的第一个维度是否是time steps。默认为False。
dropout (float,可选) - dropout概率,指的是出第一层外每层输入时的dropout概率。默认为0。
https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/rnn/LSTM_cn.html

输出:

outputs (Tensor) - 输出,由前向和后向cell的输出拼接得到。如果time_major为True,则Tensor的形状为[time_steps,batch_size,num_directions * hidden_size],如果time_major为False,则Tensor的形状为[batch_size,time_steps,num_directions * hidden_size],当direction设置为bidirectional时,num_directions等于2,否则等于1。

final_states (tuple) - 最终状态,一个包含h和c的元组。形状为[num_lauers * num_directions, batch_size, hidden_size],当direction设置为bidirectional时,num_directions等于2,否则等于1。

In [10]
class Seq2SeqEncoder(nn.Layer):
    def __init__(self, vocab_size, embed_dim, hidden_size, num_layers):
        super(Seq2SeqEncoder, self).__init__()
        self.embedder = nn.Embedding(vocab_size, embed_dim)
        self.lstm = nn.LSTM(
            input_size=embed_dim,
            hidden_size=hidden_size,
            num_layers=num_layers,
            dropout=0.2 if num_layers > 1 else 0.)

    def forward(self, sequence, sequence_length):
        inputs = self.embedder(sequence)
        encoder_output, encoder_state = self.lstm(
            inputs, sequence_length=sequence_length)
        
        # encoder_output [128, 18, 256]  [batch_size, time_steps, hidden_size]
        # encoder_state (tuple) - 最终状态,一个包含h和c的元组。 [2, 128, 256] [2, 128, 256] [num_layers * num_directions, batch_size, hidden_size]
        return encoder_output, encoder_state
定义Decoder
定义AttentionLayer
nn.Linear线性变换层传入2个参数
in_features (int) – 线性变换层输入单元的数目。
out_features (int) – 线性变换层输出单元的数目。


paddle.matmul用于计算两个Tensor的乘积,遵循完整的广播规则,关于广播规则,请参考广播 (broadcasting) 。 并且其行为与 numpy.matmul 一致。
x (Tensor) : 输入变量,类型为 Tensor,数据类型为float32, float64。
y (Tensor) : 输入变量,类型为 Tensor,数据类型为float32, float64。
transpose_x (bool,可选) : 相乘前是否转置 x,默认值为False。
transpose_y (bool,可选) : 相乘前是否转置 y,默认值为False。

paddle.unsqueeze用于向输入Tensor的Shape中一个或多个位置(axis)插入尺寸为1的维度

paddle.add逐元素相加算子,输入 x 与输入 y 逐元素相加,并将各个位置的输出元素保存到返回结果中。

输入 x 与输入 y 必须可以广播为相同形状。

In [11]
class AttentionLayer(nn.Layer):
    def __init__(self, hidden_size):
        super(AttentionLayer, self).__init__()
        self.input_proj = nn.Linear(hidden_size, hidden_size)
        self.output_proj = nn.Linear(hidden_size + hidden_size, hidden_size)

    def forward(self, hidden, encoder_output, encoder_padding_mask):
        encoder_output = self.input_proj(encoder_output)
        attn_scores = paddle.matmul(
            paddle.unsqueeze(hidden, [1]), encoder_output, transpose_y=True)
        # print('attention score', attn_scores.shape) #[128, 1, 18]

        if encoder_padding_mask is not None:
            attn_scores = paddle.add(attn_scores, encoder_padding_mask)

        attn_scores = F.softmax(attn_scores)
        attn_out = paddle.squeeze(
            paddle.matmul(attn_scores, encoder_output), [1])
        # print('1 attn_out', attn_out.shape) #[128, 256]

        attn_out = paddle.concat([attn_out, hidden], 1)
        # print('2 attn_out', attn_out.shape) #[128, 512]

        attn_out = self.output_proj(attn_out)
        # print('3 attn_out', attn_out.shape) #[128, 256]
        return attn_out
定义Seq2SeqDecoderCell
由于Decoder部分是带有attention的LSTM,我们不能复用nn.LSTM,所以需要定义Seq2SeqDecoderCell

nn.LayerList 用于保存子层列表,它包含的子层将被正确地注册和添加。列表中的子层可以像常规python列表一样被索引。这里添加了num_layers=2层lstm。
In [12]
class Seq2SeqDecoderCell(nn.RNNCellBase):
    def __init__(self, num_layers, input_size, hidden_size):
        super(Seq2SeqDecoderCell, self).__init__()
        self.dropout = nn.Dropout(0.2)
        self.lstm_cells = nn.LayerList([
            nn.LSTMCell(
                input_size=input_size + hidden_size if i == 0 else hidden_size,
                hidden_size=hidden_size) for i in range(num_layers)
        ])

        self.attention_layer = AttentionLayer(hidden_size)
    
    def forward(self,
                step_input,
                states,
                encoder_output,
                encoder_padding_mask=None):
        lstm_states, input_feed = states
        new_lstm_states = []
        step_input = paddle.concat([step_input, input_feed], 1)
        for i, lstm_cell in enumerate(self.lstm_cells):
            out, new_lstm_state = lstm_cell(step_input, lstm_states[i])
            step_input = self.dropout(out)
            new_lstm_states.append(new_lstm_state)
        out = self.attention_layer(step_input, encoder_output,
                                   encoder_padding_mask)
        return out, [new_lstm_states, out]
定义Seq2SeqDecoder
有了Seq2SeqDecoderCell,就可以构建Seq2SeqDecoder了


paddle.nn.RNN 该OP是循环神经网络(RNN)的封装,将输入的Cell封装为一个循环神经网络。它能够重复执行 cell.forward() 直到遍历完input中的所有Tensor。
cell (RNNCellBase) - RNNCellBase类的一个实例。
In [13]
class Seq2SeqDecoder(nn.Layer):
    def __init__(self, vocab_size, embed_dim, hidden_size, num_layers):
        super(Seq2SeqDecoder, self).__init__()
        self.embedder = nn.Embedding(vocab_size, embed_dim)
        self.lstm_attention = nn.RNN(
            Seq2SeqDecoderCell(num_layers, embed_dim, hidden_size))
        self.output_layer = nn.Linear(hidden_size, vocab_size)

    def forward(self, trg, decoder_initial_states, encoder_output,
                encoder_padding_mask):
        inputs = self.embedder(trg)

        decoder_output, _ = self.lstm_attention(
            inputs,
            initial_states=decoder_initial_states,
            encoder_output=encoder_output,
            encoder_padding_mask=encoder_padding_mask)
        predict = self.output_layer(decoder_output)

        return predict
构建主网络Seq2SeqAttnModel
Encoder和Decoder定义好之后,网络就可以构建起来了

In [14]
class Seq2SeqAttnModel(nn.Layer):
    def __init__(self, vocab_size, embed_dim, hidden_size, num_layers,
                 eos_id=1):
        super(Seq2SeqAttnModel, self).__init__()
        self.hidden_size = hidden_size
        self.eos_id = eos_id
        self.num_layers = num_layers
        self.INF = 1e9
        self.encoder = Seq2SeqEncoder(vocab_size, embed_dim, hidden_size,
                                      num_layers)
        self.decoder = Seq2SeqDecoder(vocab_size, embed_dim, hidden_size,
                                      num_layers)

    def forward(self, src, src_length, trg):
        # encoder_output 各时刻的输出h
        # encoder_final_state 最后时刻的输出h,和记忆信号c
        encoder_output, encoder_final_state = self.encoder(src, src_length)
        print('encoder_output shape', encoder_output.shape)  #  [128, 18, 256]  [batch_size,time_steps,hidden_size]
        print('encoder_final_states shape', encoder_final_state[0].shape, encoder_final_state[1].shape) #[2, 128, 256] [2, 128, 256] [num_lauers * num_directions, batch_size, hidden_size]

        # Transfer shape of encoder_final_states to [num_layers, 2, batch_size, hidden_size]???
        encoder_final_states = [
            (encoder_final_state[0][i], encoder_final_state[1][i])
            for i in range(self.num_layers)
        ]
        print('encoder_final_states shape', encoder_final_states[0][0].shape, encoder_final_states[0][1].shape) #[128, 256] [128, 256]


        # Construct decoder initial states: use input_feed and the shape is
        # [[h,c] * num_layers, input_feed], consistent with Seq2SeqDecoderCell.states
        decoder_initial_states = [
            encoder_final_states,
            self.decoder.lstm_attention.cell.get_initial_states(
                batch_ref=encoder_output, shape=[self.hidden_size])
        ]

        # Build attention mask to avoid paying attention on padddings
        src_mask = (src != self.eos_id).astype(paddle.get_default_dtype())
        print ('src_mask shape', src_mask.shape)  #[128, 18]
        print(src_mask[0, :])

        encoder_padding_mask = (src_mask - 1.0) * self.INF
        print ('encoder_padding_mask', encoder_padding_mask.shape)  #[128, 18]
        print(encoder_padding_mask[0, :])

        encoder_padding_mask = paddle.unsqueeze(encoder_padding_mask, [1])
        print('encoder_padding_mask', encoder_padding_mask.shape)  #[128, 1, 18]

        predict = self.decoder(trg, decoder_initial_states, encoder_output,
                               encoder_padding_mask)
        print('predict', predict.shape)   #[128, 17, 7931]

        return predict
定义损失函数
这里使用的是交叉熵损失函数,我们需要将padding位置的loss置为0,因此需要在损失函数中引入trg_mask参数,由于PaddlePaddle框架提供的paddle.nn.CrossEntropyLoss不能接受trg_mask参数,因此在这里需要重新定义:

In [15]
class CrossEntropyCriterion(nn.Layer):
    def __init__(self):
        super(CrossEntropyCriterion, self).__init__()

    def forward(self, predict, label, trg_mask):
        cost = F.softmax_with_cross_entropy(
            logits=predict, label=label, soft_label=False)
        cost = paddle.squeeze(cost, axis=[2])
        masked_cost = cost * trg_mask
        batch_mean_cost = paddle.mean(masked_cost, axis=[0])
        seq_cost = paddle.sum(batch_mean_cost)

        return seq_cost
执行过程
训练过程
使用高层API执行训练,需要调用prepare和fit函数。

在prepare函数中,配置优化器、损失函数,以及评价指标。其中评价指标使用的是PaddleNLP提供的困惑度计算API paddlenlp.metrics.Perplexity。

如果你安装了VisualDL,可以在fit中添加一个callbacks参数使用VisualDL观测你的训练过程,如下:

model.fit(train_data=train_loader,
            epochs=max_epoch,
            eval_freq=1,
            save_freq=1,
            save_dir=model_path,
            log_freq=log_freq,
            callbacks=[paddle.callbacks.VisualDL('./log')])
在这里,由于对联生成任务没有明确的评价指标,因此,可以在保存的多个模型中,通过人工评判生成结果选择最好的模型。

本项目中,为了便于演示,已经将训练好的模型参数载入模型,并省略了训练过程。读者自己实验的时候,可以尝试自行修改超参数,调用下面被注释掉的fit函数,重新进行训练。

如果读者想要在更短的时间内得到效果不错的模型,可以使用预训练模型技术,例如《预训练模型ERNIE-GEN自动写诗》项目为大家展示了如何利用预训练的生成模型进行训练。

In [16]
model = paddle.Model(
    Seq2SeqAttnModel(vocab_size, hidden_size, hidden_size,
                        num_layers, pad_id))

optimizer = paddle.optimizer.Adam(
    learning_rate=learning_rate, parameters=model.parameters())
ppl_metric = Perplexity()
model.prepare(optimizer, CrossEntropyCriterion(), ppl_metric)

# model.fit(train_data=train_loader,
#             epochs=max_epoch,
#             eval_freq=1,
#             save_freq=1,
#             save_dir=model_path,
#             log_freq=log_freq)
模型预测
定义预测网络Seq2SeqAttnInferModel
预测网络继承上面的主网络Seq2SeqAttnModel,定义子类Seq2SeqAttnInferModel

In [17]
class Seq2SeqAttnInferModel(Seq2SeqAttnModel):
    def __init__(self,
                 vocab_size,
                 embed_dim,
                 hidden_size,
                 num_layers,
                 bos_id=0,
                 eos_id=1,
                 beam_size=4,
                 max_out_len=256):
        self.bos_id = bos_id
        self.beam_size = beam_size
        self.max_out_len = max_out_len
        self.num_layers = num_layers
        super(Seq2SeqAttnInferModel, self).__init__(
            vocab_size, embed_dim, hidden_size, num_layers, eos_id)

        # Dynamic decoder for inference
        self.beam_search_decoder = nn.BeamSearchDecoder(
            self.decoder.lstm_attention.cell,
            start_token=bos_id,
            end_token=eos_id,
            beam_size=beam_size,
            embedding_fn=self.decoder.embedder,
            output_fn=self.decoder.output_layer)

    def forward(self, src, src_length):
        encoder_output, encoder_final_state = self.encoder(src, src_length)

        encoder_final_state = [
            (encoder_final_state[0][i], encoder_final_state[1][i])
            for i in range(self.num_layers)
        ]

        # Initial decoder initial states
        decoder_initial_states = [
            encoder_final_state,
            self.decoder.lstm_attention.cell.get_initial_states(
                batch_ref=encoder_output, shape=[self.hidden_size])
        ]
        # Build attention mask to avoid paying attention on paddings
        src_mask = (src != self.eos_id).astype(paddle.get_default_dtype())

        encoder_padding_mask = (src_mask - 1.0) * self.INF
        encoder_padding_mask = paddle.unsqueeze(encoder_padding_mask, [1])

        # Tile the batch dimension with beam_size
        encoder_output = nn.BeamSearchDecoder.tile_beam_merge_with_batch(
            encoder_output, self.beam_size)
        encoder_padding_mask = nn.BeamSearchDecoder.tile_beam_merge_with_batch(
            encoder_padding_mask, self.beam_size)

        # Dynamic decoding with beam search
        seq_output, _ = nn.dynamic_decode(
            decoder=self.beam_search_decoder,
            inits=decoder_initial_states,
            max_step_num=self.max_out_len,
            encoder_output=encoder_output,
            encoder_padding_mask=encoder_padding_mask)
        return seq_output
解码部分
接下来对我们的任务选择beam search解码方式,可以指定beam_size为10。

In [18]
def post_process_seq(seq, bos_idx, eos_idx, output_bos=False, output_eos=False):
    """
    Post-process the decoded sequence.
    """
    eos_pos = len(seq) - 1
    for i, idx in enumerate(seq):
        if idx == eos_idx:
            eos_pos = i
            break
    seq = [
        idx for idx in seq[:eos_pos + 1]
        if (output_bos or idx != bos_idx) and (output_eos or idx != eos_idx)
    ]
    return seq
In [19]
beam_size = 10
model = paddle.Model(
    Seq2SeqAttnInferModel(
        vocab_size,
        hidden_size,
        hidden_size,
        num_layers,
        bos_id=bos_id,
        eos_id=eos_id,
        beam_size=beam_size,
        max_out_len=256))

model.prepare()
在预测之前,我们需要将训练好的模型参数load进预测网络,之后我们就可以根据对联的上联,生成对联的下联啦!

In [20]
model.load('couplet_models/model_18')
In [21]
idx = 0
for data in test_loader():
    inputs = data[:2]
    finished_seq = model.predict_batch(inputs=list(inputs))[0]
    finished_seq = finished_seq[:, :, np.newaxis] if len(
        finished_seq.shape) == 2 else finished_seq
    finished_seq = np.transpose(finished_seq, [0, 2, 1])
    for ins in finished_seq:
        for beam in ins:
            id_list = post_process_seq(beam, bos_id, eos_id)
            word_list_f = [trg_idx2word[id] for id in test_ds[idx][0]][1:-1]
            word_list_s = [trg_idx2word[id] for id in id_list]
            sequence = "上联: "+"".join(word_list_f)+"\t下联: "+"".join(word_list_s) + "\n"
            print(sequence)
            idx += 1
            break
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/fluid/layers/utils.py:77: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
  return (isinstance(seq, collections.Sequence) and
上联: 心尘须自扫	下联: 世事不由人

上联: 碧涧飞泉山笑语	下联: 青山叠翠鸟谈天

上联: 即景即心无机不被	下联: 有情有意有意相随

上联: 袋鼓黎民乐	下联: 胸怀社稷安

上联: 相通心意何须语	下联: 不解情怀不必言

上联: 促公义一身正气	下联: 保民生两袖清风

上联: 重建黉宫犹忆院中曾起凤	下联: 弘扬国粹更期天下再腾龙

上联: 落字不从奇巧胜	下联: 行文自有古今同

上联: 拂水柳丝撩碎月	下联: 落花花影醉清风

上联: 千载长城历尽沧桑烽火连绵留胜迹	下联: 万年大业历经坎坷英雄浩荡展雄风

上联: 核能火箭穿空跃	下联: 气定神州逐梦飞

上联: 正道不衰书不朽	下联: 清风常在德无穷

上联: 月倚高楼风送爽	下联: 花开小院雪添香

上联: 联网怡情寻妙语	下联: 春风得意送佳音

上联: 项羽吹风真霸气	下联: 刘伶煮酒忒精神

上联: 税企展宏图促小康圆梦	下联: 民生兴伟业兴大业兴邦

上联: 几字箴言德养清廉贪养腐	下联: 一腔热血情融诚信爱扶贫

上联: 歌摇香雾鬟朱唇浅破桃花萼	下联: 画卷春风韵翠袖轻摇杨柳枝

上联: 积德累仁远矣一本水木	下联: 高山流水长哉千古风流

上联: 花言巧语迷心窍	下联: 月色清风入梦乡

上联: 执杖空山风问道	下联: 弹琴古寺月知音

上联: 叹亘古英雄欲铸和平刀泣血	下联: 看今朝壮志更添华夏志凌云

上联: 一盘蒸出三湘韵	下联: 四海迎来四海春

上联: 良辰美景三春绿	下联: 明月清风一夜香

上联: 秦岭修行淮水斩蛟万民拥戴歌千载	下联: 东风浩荡春风化雨百业兴隆颂九州

上联: 结友还应诚以待	下联: 修身不必俭而勤

上联: 放大肚皮容难事	下联: 放开眼界见真情

上联: 长篙撑破烟波绿	下联: 短笛吹开雨露红

上联: 几句五言诗便教胜地生辉王郎载誉	下联: 千年千古史犹记春风化雨桃李芬芳

上联: 风乱诗文期断句	下联: 月移花影惹残花

上联: 一捧清凉半瓢月	下联: 半窗寂寞满江红

上联: 关注民生服务民生保障民生兴国祚	下联: 弘扬国粹弘扬国粹和谐社会富民生

上联: 书香醉倒窗前月	下联: 月色迷离梦里人

上联: 楼高不碍闲云渡	下联: 路远何妨野鹤归

上联: 以汤沃雪	下联: 临水流云

上联: 紫燕携春来探我	下联: 红梅傲雪去迎宾

上联: 崖悬风雨骤	下联: 月落月光寒

上联: 白石清江留月影	下联: 清风明月醉花香

上联: 流金时节云霞展梦	下联: 大地春秋桃李争春

上联: 打趣不识趣自讨没趣	下联: 求真务求真何必求真

上联: 最宜词客题襟结对赏花来杏岭	下联: 更有诗人醉酒邀朋邀月醉诗心

上联: 名山不必高千仞	下联: 大海何须纳百川

上联: 共赋新诗发宫徵	下联: 不将名字负春秋

上联: 体健神怡晚景好	下联: 风和日丽晚霞红

上联: 好书好读直须读	下联: 好事难求不必求

上联: 马驰和县康庄道	下联: 羊跃祥云锦绣春

上联: 舟泊寒汀惊雁字	下联: 月临古寺悟禅机

上联: 卖菜上京经上蔡	下联: 寻春故里醉桃花

上联: 谁解清泉低语意	下联: 我知明月近人心

上联: 朝登剑阁云随马	下联: 风过泸州带酒香

上联: 低吟浅唱一纸风流字句	下联: 浅唱轻歌几弦寂寞弦弦

上联: 戏中文文中戏看戏看文各得雅趣	下联: 天上人地天下知音知音都是知音

上联: 先贤圣哲书中坐	下联: 后辈英雄笔下行

上联: 尚义崇文法治护航中国梦	下联: 崇文尚武文明铺锦上河图

上联: 公平端起水一碗	下联: 正气正直风满怀

上联: 一山胜概华表高标犹见硕儒题柱句	下联: 千古文章清风明月更闻雏凤振龙声

上联: 天临暮晚余辉灿	下联: 风过泸州带酒香

上联: 岁月悠悠绿水微澜帆影梦	下联: 江山漫漫红尘不染雁声情

上联: 香山一染深秋色	下联: 绿水长流碧水情

上联: 无事聊天能咋地	下联: 有情对月可当家

上联: 快马加鞭妃子笑	下联: 春风得意美人来

上联: 夏至荷塘香两岸	下联: 春分柳岸绿千畴

上联: 芳草绿阳关塞上春风入户	下联: 清风明月渡江边月色盈窗

上联: 致富思源跟党走	下联: 脱贫致富为民生

上联: 欣然入梦抱书睡	下联: 何必登楼赏月眠

上联: 诗赖境奇赢感动	下联: 心随心静悟禅机

上联: 栀子牵牛犁熟地	下联: 莲花吐蕊吐香香

上联: 廿载相交成知己	下联: 千秋不朽著文章

上联: 润	下联: 修

上联: 设帏遇芳辰百岁期颐刚一半	下联: 簪缨逢盛世千秋俎豆祀千秋

上联: 波光云影满目葱茏谁道人间无胜地	下联: 鸟语花香一帘幽梦我知天下有知音

上联: 眸中映月心如镜	下联: 笔下生花气若虹

上联: 何事营生闲来写幅青山卖	下联: 此情入世静坐读书明月来

上联: 学海钩深毫挥具见三长足	下联: 书山登绝顶放开怀一片天

上联: 女子千金一笑贵	下联: 人生万事两相宜

上联: 柏叶为铭椒花献瑞	下联: 芝兰在抱芝草生香

上联: 众佛群灵光圣地	下联: 众生一念证菩提

上联: 乡愁何处解	下联: 故事几时休

上联: 清池荷试墨	下联: 碧水柳含情

上联: 既近浅流安笔砚	下联: 欲将直气定乾坤

上联: 日丽萱闱祝无量寿	下联: 月明桂殿祝有余龄

上联: 一地残红风拾起	下联: 半窗疏影月窥来

上联: 白塔有情泪弹翠岛三生梦	下联: 红尘无恙心系苍生一片心

上联: 霜华浓似雪	下联: 冰雪冷如冰

上联: 小子听之濯足濯缨借自取	下联: 高僧悟也修身养性即如来

上联: 踏雪寻梅句	下联: 寻春觅柳诗

上联: 无水不清一鉴尽传云外意	下联: 有山皆洗千秋不染世间尘

上联: 拜竹为师一生常对虚心客	下联: 寻梅作伴半世每逢知己人

上联: 眄晓日朝霞祥光万里苍茫外	下联: 对清风明月明月千秋寂寞中

上联: 忠孝节义萃于一门间披南宋伤心史	下联: 忠孝忠孝昭其千载后继东方继往开

上联: 一枕云山观自在	下联: 半窗竹影任逍遥

上联: 秀丽堂皇延好客	下联: 和谐社会庆新春

上联: 配偶	下联: 交朋

上联: 故事含章吐曜清明一曲千秋醉	下联: 春风得意流光溢彩千秋万代兴

上联: 仁和信义安民清心自律查风纪	下联: 诚信文明治国富国强民奔小康

上联: 一言难尽同窗梦	下联: 半世不知两鬓秋

上联: 酒高好看东篱菊	下联: 月老难寻北斗星

上联: 百味溢琴弦几许青春流淌	下联: 千秋留笔墨千秋翰墨芬芳

上联: 惜有花开人去后	下联: 愁无月落梦来时

上联: 满月可观仙子泪	下联: 清风不负故人情

上联: 月遮白雪夜织女	下联: 风过泸州带酒香

上联: 兰舟野渡逍遥梦	下联: 明月清风自在诗

上联: 带俏含羞梅弄雪	下联: 乘风破浪浪淘沙

上联: 何去何从须看红包厚度	下联: 不来不见莫言白发多情

上联: 梅花三弄风和雨	下联: 柳絮一飞雨顺风

上联: 绿蚁杯中物	下联: 红尘梦里人

上联: 胜友如云赞壮丽名楼重光故郡	下联: 高朋似海赞英雄伟业永耀神州

上联: 画栋雕梁门启千般风物秀	下联: 琼楼玉宇梦圆万里画图新

上联: 牛车行马路	下联: 骏马跃龙门

上联: 半夏当归熟地总比生地好	下联: 千秋不老高山流水上天高

上联: 走兽	下联: 飞禽

上联: 青山不改三贤赋	下联: 碧水长流四海歌

上联: 拈雁字韵山风敢问醉处	下联: 把酒诗情月色不知愁时

上联: 栈道连云引无数英雄豪杰登天摘月	下联: 春风化雨催万千豪杰英雄壮志凌云

上联: 梦里情人情里梦	下联: 杯中月色梦中人

上联: 文明古国励精图治新崛起	下联: 和谐社会勤劳致富大腾飞

上联: 话旧老翁漫忆当年骑马马	下联: 情归故里遥思往日驾龙舟

上联: 花香常绕笔	下联: 鸟语总关情

上联: 凭本领冲冠	下联: 靠科学创新

上联: 无欲自然心似水	下联: 有情何必梦如烟

上联: 脉脉人千里念两处风情万重烟水	下联: 幽幽梦一帘思一帘梦梦几度春秋

上联: 千朵红莲三里水	下联: 一轮皓月一轮星

上联: 尽夜观灯夜夜夜灯灯不夜	下联: 临晨听雨声声声鼓鼓长鸣

上联: 嘉施利根动力再接再厉	下联: 展宏图展宏图如画如诗

上联: 绸缎满天风带走	下联: 琴弦一曲月携来

上联: 鞠松陶令宅	下联: 垂柳侍郎家

上联: 感恩观世界	下联: 济世度人生

上联: 淇淋藏雪柜	下联: 趵突淌冰泉

上联: 科学绘就民生景	下联: 勤俭浇开幸福花

上联: 佛道参茶参造化	下联: 禅心悟道悟禅机

上联: 清风远播凤城爱	下联: 明月长留天井红

上联: 菡萏开花吐艳	下联: 蜻蜓点水含情

上联: 读书需用意	下联: 处世要修身

上联: 无聊友	下联: 有瘾人

上联: 春花桃叶渡	下联: 秋月桂花香

上联: 一钩小月斜檐角	下联: 两袖清风入画中

上联: 李李桃桃香一苑	下联: 梅兰竹菊韵千秋

上联: 谁人能解落花梦	下联: 哪个可知流水情

上联: 善报恶报迟报速报终须有报	下联: 天知地知我知我知何谓无知

上联: 记得与君花下别	下联: 不知何处水中央

上联: 春风送暖催花艳	下联: 旭日迎新映日红

上联: 林深路险人难越	下联: 海阔天空志不移

上联: 兽王不敌群虫搏	下联: 牛鬼何须众鸟鸣

上联: 敞大关门平垭口	下联: 开新路路上层楼

上联: 过隧道不得超车	下联: 过关关关关关关

上联: 老来渐得湖山味	下联: 老去方知岁月情

上联: 老了还难说真话	下联: 新来未必见真情

上联: 天人合一新城市	下联: 日月同辉大地天

上联: 树发孙枝方茂盛	下联: 花开果果更繁荣

上联: 缘枝摘果和风伴	下联: 梦笔生花细雨随

上联: 血肉筑长城八年悲壮铭千古	下联: 锤镰开盛世万里江山耀九州

上联: 一径飞花寻旧梦	下联: 两行雁字寄新愁

上联: 与尔同销万古	下联: 同君共享千秋

上联: 明文传素志	下联: 大笔写春秋

上联: 苍苔路熟僧归寺	下联: 红叶楼高月满楼

上联: 一帘卷走清风夜	下联: 两袖清来明月天

上联: 蓝天绿地山川美	下联: 绿水青山日月新

上联: 清思似水洞察秋毫策已决	下联: 正气如山气冲霄汉展雄姿

上联: 宝篆焚香留睡鸭	下联: 清风拂槛送归鸿

上联: 飞花一径随风袅	下联: 落叶千山伴月眠

上联: 动守其时静随其势不倚不偏循本位	下联: 安居此处安得安居安居乐业享安康

上联: 弹琴又为相思梦	下联: 把酒还吟寂寞诗

上联: 郑知县描竹临傲骨	下联: 陈美人泼墨写春秋

上联: 妙质因风剪	下联: 真情似水流

上联: 登梅喜鹊开春运	下联: 踏雪梅花报福音

上联: 金人汉满皆兄弟	下联: 天下人和是弟兄

上联: 巴人兴吃火锅鸭	下联: 老鬼出山山水鸡

上联: 文艺迎春春风激发正能量	下联: 楹联贺岁喜气盈门新画图

上联: 奥运福娃喜迎天下客	下联: 神州奥运喜报世间春

上联: 四面晴光对屏障	下联: 一江春水向东流

上联: 春雨读花信	下联: 秋风扫草原

上联: 称胡师督辫军光绪班班可仿	下联: 夺冠军营销战功勋处处如何

上联: 口技演员说鸟话	下联: 神州大业展鸿图

上联: 庙堂雨露何关我	下联: 山水风流自在人

上联: 走金光道擎特色旗鹿洼崛起前程远	下联: 奔富路路拓新程路龙马腾飞骏业兴

上联: 秋风琴瑟弹高调	下联: 冬雪梅花伴暗香

上联: 久坐深窗听花跌落	下联: 曾经沧海看月沉浮

上联: 社稷言称将相	下联: 江山气壮神州

上联: 有热情何须三把火	下联: 无杂念不必一身轻

上联: 大梁凌霄云浩荡	下联: 高山仰岳日辉煌

上联: 钟声嘹亮感恩亿万勤劳客	下联: 瑞气氤氲喜气千千幸福人

上联: 员树出天	下联: 天地成地

上联: 拂镜羞温峤	下联: 垂帘静倚窗

上联: 松翠自洁梅雅无争百里悬冰春在望	下联: 花香扑面花香溢彩千年流韵梦生香

上联: 滚动新闻反复念	下联: 风流旧事总关情

上联: 今年逢狗	下联: 昨日逢猪

上联: 雾里群峰如有约	下联: 云中一月似无眠

上联: 收缩天地穿越时空千载戏文千载梦	下联: 传递古今传承古今万年功业万年春

上联: 同仇抗日歌才子且为战士	下联: 克己捐躯颂英雄还是英雄

上联: 墨香如酒千层浪	下联: 墨韵似诗万卷诗

上联: 半世情怀敲案问	下联: 一蓑烟雨任平生

上联: 瞻大贵大雄诵大悲顿生大觉	下联: 念慈悲慈善念慈念普度众生

上联: 二三鸟语消春困	下联: 一片冰心在玉壶

上联: 风梳柳髻青丝乱	下联: 雨润桃腮粉面娇

上联: 成败不由人惟求尽力	下联: 死生皆自己但愿无忧

上联: 爱国重家君子义	下联: 修身养性圣贤心

上联: 云移月伴难留步	下联: 日丽风和不动心

上联: 归山已绝沧桑泪	下联: 逝水难留岁月痕

上联: 万里海涛千卷画	下联: 一江春水一湖诗

上联: 百年紫木固根基回望陈门进士	下联: 万里青山如画本展望锦绣前程

上联: 风华减去谁留住	下联: 岁月添来我自来

上联: 望赤壁流丹问谁挥梦笔皴红苗寨	下联: 看青山焕彩看我挥毫书写绿诗篇

上联: 福娃盛邀五洲客	下联: 宝鸡欢唱万户春

上联: 久知鹄自飞新得	下联: 常见龙能起大来

上联: 我曾置盏邀明月	下联: 谁与拈花问落花

上联: 彰一代君臣表率	下联: 仰千秋俎豆馨香

上联: 枝繁叶茂拔萃精英拟决策	下联: 国富民强扬鞭骏马奋腾飞

上联: 勤志有为千般陶冶终成器	下联: 勤劳无限万种芬芳总是春

上联: 亦静不哗听涓滴天来甘露	下联: 亦真亦幻见沧桑世外桃源

上联: 打胡说	下联: 刮肚搜

上联: 长街扫落三秋叶	下联: 短笛吹开一剪梅

上联: 不懂古文编白话	下联: 常闻新曲奏清音

上联: 往来不少响各客	下联: 生死何妨说是非

上联: 风云乍向怀中起	下联: 岁月常从梦里来

上联: 摇橹荡舟寻美境	下联: 挥毫泼墨写华章

上联: 漫天瑞雪千山秀	下联: 遍地春风万里香

上联: 改革革出万亩粮田田聚宝	下联: 科学发展千家事业业增辉

上联: 劈疯癫营造精神蓝天绿地	下联: 治病病保持保障绿水青山

上联: 小妹东坡留佛印	下联: 高僧西子悟禅机

上联: 赞荷文创基业枝荣本固昌万代	下联: 赞桃李育桃李果硕果丰誉千秋

上联: 酒烈风高山路远望君珍重	下联: 月圆花好月光高照我婵娟

上联: 沐八载春风艺花吐艳今朝多异彩	下联: 兴千秋伟业联苑增辉此日尽奇香

上联: 入口已然年味道	下联: 回头不见旧风情

上联: 围炉夜话新醅酒	下联: 把盏晨钟旧鼓声

上联: 春风一顾山花笑	下联: 秋雨几时柳絮飞

上联: 雾花水月清心逸	下联: 冰雪冰霜白骨精

上联: 飞雪片片凝瑞	下联: 落花声声唤春

上联: 东风乍喜还沧海	下联: 紫燕初裁又剪春

上联: 桃花窥镜珠江羞红两岸	下联: 燕子裁春锦绣喜绿千畴

上联: 高者顶天不霸道	下联: 大夫拔地莫欺天

上联: 草木蒙茸露湿青皋闲数鹭峰泛舟待月	下联: 山峦叠翠风来碧水静听渔歌唱晚听涛

上联: 瑞兆千秋骏业	下联: 春回万里春光

上联: 月半举杯圆月下	下联: 风中吹笛落花间

上联: 庠序百年为大本	下联: 英雄千古仰高风

上联: 推杯换盏频交手	下联: 拍马溜须总动心

上联: 悲歌动地	下联: 喜气盈门

上联: 随水逝泪成行落花空散去	下联: 随风飘梦入梦流水自生来

上联: 牛肚	下联: 马蹄

上联: 狡诈	下联: 愚公

上联: 植竹培兰修心养性	下联: 栽花种竹养性修身

上联: 天地间日星河岳正气	下联: 山河里日月日月光华

上联: 常常喝常常醉常常喝醉	下联: 多多多多少多多多少多

上联: 似水流年闲愁万种何人会	下联: 如烟往事旧梦千重哪个知

上联: 一起同尊泽后土苍天共弘道脉	下联: 百年共仰光前天大地同仰灵光

上联: 承厚重人文千古徽风排闼入	下联: 展宏图气象万家春色入怀来

上联: 强弓射透百步杨	下联: 大笔写出千年文

上联: 常思灯下老妈影	下联: 不见人间老子心

上联: 春风绿染千家树	下联: 旭日红燃万户门

上联: 香阁春回风送暖	下联: 寒窗夜静月生凉

上联: 一竿竹影横窗乱	下联: 十里荷香扑面香

上联: 冲一盏清茶细品前尘往事	下联: 看千年老酒闲斟往事沧桑

上联: 梦筑中华全民追梦	下联: 春回大地大地飞歌

上联: 精做郇阳地道家常思乡菜	下联: 闲游宝岛人间客醉醉乡人

上联: 风调雨顺百花艳	下联: 国泰民安万事兴

上联: 庭竹不收帘影去	下联: 梅花犹带雪香来

上联: 近梅已是三分雅	下联: 临水方知一脉香

上联: 城开山日早	下联: 鸟啭鸟声甜

上联: 春夜疏帘邀月影	下联: 秋风小院惹花香

上联: 一生老病死	下联: 千古古风流

上联: 水白如冰粉藕如弯饼圆如月	下联: 山青似画图山似画图画似诗

上联: 欢天喜地笑迎乖兔宝贝	下联: 乐地乐天乐奏好猫哆哩

上联: 杜门远万马兵尘海上引年仙枣大	下联: 孔子长千年俎豆山中留俎豆馨香

上联: 红丝穿露珠帘冷	下联: 紫燕穿云玉指凉

上联: 访山问水知音渺	下联: 踏雪寻梅雅韵悠

上联: 万里长江华夏文明扬海外	下联: 千秋大业神州伟业耀中华

上联: 兄及弟矣式相好矣无相尤矣	下联: 夫之子也有所谓乎有所谓乎

上联: 韬光养晦风云独秀潇湘竹	下联: 反腐倡廉日月长辉舜尧天

上联: 风清月白闲鸥鹭	下联: 日丽花红醉蝶蜂

上联: 千里目	下联: 万年春

上联: 燕唱山歌催嫩绿	下联: 莺歌燕舞唤春红

上联: 猪八戒扮姑娘好歹不像	下联: 鼠百年谋大计输赢难得

上联: 石洞流甘露	下联: 山泉洗俗尘

上联: 山能醉意常流韵	下联: 水可怡情总动情

上联: 新朋老友夸廉吏	下联: 美酒佳肴赞美人

上联: 并蒂花开连理树	下联: 并蒂蒂开并蒂花

上联: 秋河曙耿耿	下联: 夜雨夜凄凄

上联: 云连瀑布悬岩秀	下联: 风过泸州带酒香

上联: 济水自清河自浊	下联: 江山如画水长流

上联: 利害当头操守见	下联: 风云在上任行行

上联: 道路畅通车如流水	下联: 佛光普照佛即菩提

上联: 檐雨连珠难剪断	下联: 秋风入梦不回头

上联: 统一齐民心民心连两岸	下联: 同心协力力国力振千秋

上联: 民常有德犹多福	下联: 国是无忧不少忧

上联: 宴罢兰亭留墨宝	下联: 风来柳榭醉花香

上联: 搅出新纹鱼共舞	下联: 搅浑浊水月相随

上联: 五岳德高儒释道	下联: 千秋功伟武功勋

上联: 打草寻山勤动手	下联: 乘风破浪正当头

上联: 千年余庆千秋颂	下联: 万里长城万代兴

上联: 最喜老头无赖	下联: 不知大梦难圆

上联: 满心眷恋情荡荡	下联: 一梦缠绵梦悠悠

上联: 社会和谐担于肩上	下联: 人民富裕乐在心中

上联: 宝墨寄闲情紫洞清歌听一曲鱼游春水	下联: 清风传雅韵清风明月看千年龙跃龙门

上联: 八一高歌万里长城担日月	下联: 千秋大业千秋伟业铸辉煌

上联: 对月吟须浮白醉	下联: 临风把酒醉红尘

上联: 应法闻鸡起舞	下联: 为民跃马扬鞭

上联: 笛弄梅花五岭三山飘瑞雪	下联: 风吹柳絮一江一水荡春潮

上联: 与月交心知照顾	下联: 随风入梦觉相思

上联: 鹏程万里身须健	下联: 骏业千秋气自雄

上联: 古道经年无信使	下联: 高山流水有知音

上联: 穿云海两肩担水	下联: 破雾天一手遮天

上联: 愁情由曲解	下联: 爱意自天然

上联: 平天湖上赏明月	下联: 杏花村里品清香

上联: 烟雨雾绕江心岛	下联: 日月星辉海角天

上联: 一生功过盖棺定	下联: 半世沧桑世事空

上联: 负手云烟流水高山闲自在	下联: 放怀风月清风明月乐逍遥

上联: 每感言轻难表意	下联: 常思正直不关心

上联: 平天湖上嫦娥舒广袖	下联: 杏花村里蝴蝶舞春风

上联: 敬业乐群疏导源头活水	下联: 求真务实弘扬正气清风

上联: 无所不通无所事	下联: 不知难得有知音

上联: 风烛何堪空落泪	下联: 梅花未必枉凝眉

上联: 浇科学水挥智慧锄韶华七秩同文曲	下联: 育李培桃育桃李育李李千秋大业篇

上联: 欲学狂人发酵芝麻捕风捉影求轰动	下联: 不知老鬼出山山水擒虎捉刀富富强

上联: 采一篮童年往事	下联: 赊几分月色闲情

上联: 灵地棉湖镇	下联: 青山碧水环

上联: 山巅茶场散清馨松竹瀑泉美	下联: 门外春风化雨露桃花春意浓

上联: 春蚕又吐新茧把人生画卷织成美锦	下联: 蜡炬将燃旧情将梦想文章铸就丰碑

上联: 客来把酒花间醉	下联: 风过泸州梦里香

上联: 枕上轻寒窗外雨	下联: 枕边寂寞梦中人

上联: 闹井	下联: 喧天

上联: 马蹄奋起追欧美	下联: 羊角顶开揽月光

上联: 字到无锋称极品	下联: 情于有意是真情

上联: 执掌三铡刀诚彰正义	下联: 挥毫一蜕纸不负春秋

上联: 英雄不问出处	下联: 儿女难得糊涂

上联: 见也难别也难形如彩凤双飞翼	下联: 闻之乐乐之乐天下神龙一啸风

上联: 勤俭生富贵	下联: 勤劳致富强

上联: 慢赏好书如品酒	下联: 闲吟佳句似吟诗

上联: 伴随经史同游古	下联: 共赏春秋共读书

上联: 梅子流酸怜苦李	下联: 梅花傲雪傲寒梅

上联: 岁前事真仿佛	下联: 天上人不如神

上联: 归去来兮见放魂萦三户地	下联: 归来去矣何堪梦断一江秋

上联: 岳色河声韵满京畿盛象宏开中国画	下联: 山光水色花香燕赵春风浩荡大江潮

上联: 凝心总把锤镰举	下联: 放眼常将梦想飞

上联: 乡村六秩恍如隔世	下联: 岁月千秋恰似当时

上联: 喜庆三春红我容颜莫过新天美酒	下联: 欣逢五福喜咱梦想能成大地欢歌

上联: 德政归心燕舞秦川祥气绕	下联: 春风得意莺歌燕岭紫气腾

上联: 四朝长乐老	下联: 千古古风流

上联: 古月光明新世界	下联: 春风浩荡旧乾坤

上联: 古域春光六旬伟业逾千载	下联: 中华骏业万里宏图壮九州

上联: 溪声流入砚	下联: 月色碾成诗

上联: 鸟雀交鸣诗有韵	下联: 莺莺婉转曲无声

上联: 老了流年无悲无喜	下联: 时来往事有梦有香

上联: 门通小径连芳草	下联: 风过泸州带酒香

上联: 嫁得潘家郎有水有田有米	下联: 迎来女子女无男无女无男

上联: 往事淘空将身独许这般月	下联: 相思寄尽把酒相邀那段情

上联: 走基层听民声向下扎根接地气	下联: 创大业兴国运中华崛起展雄风

上联: 嘉树来西域凤翥龙翔十里市城添秀色	下联: 祥云起东风龙腾虎跃九州大地焕新颜

上联: 盛世抒怀笔舞云龙同作赋	下联: 春风得意诗吟雅韵共吟诗

上联: 杨柳小腰难把握	下联: 桃花依旧笑春风

上联: 衣沾月色如霜洗	下联: 袖拂清风似水流

上联: 中秋醉也二婆挥泪砸三少	下联: 大地悲哉一女伤心泣几人

上联: 松桧老依云外地	下联: 楼台深锁洞中天

上联: 时绎古书以明古义	下联: 人登高阁而上高楼

上联: 论语无平调	下联: 文章有古风

上联: 柳色常随春意绿	下联: 梅香总伴腊梅香

上联: 人兴财旺年年好	下联: 日丽风和处处春

上联: 文化添新拳石喷泉堪驻足	下联: 人文焕彩心潮逐浪更扬帆

上联: 夜色难留君去意	下联: 春风不度我归心

上联: 乡书一字千金贵	下联: 老酒三杯万事休

上联: 星斗满天难比月	下联: 风云一路不如云

上联: 归处不知风几度	下联: 归时已觉月三更

上联: 忍性吞气茹苦饮痛	下联: 披肝沥胆忠肝义胆

上联: 各有千秋兄弟三人相继去	下联: 相期一日江山一统共争先

上联: 瘦月斜眯千涧水	下联: 清风漫卷万山云

上联: 知春雨滴藏金地	下联: 晓夏风吹绽玉花

上联: 秋灯千点雨	下联: 雁字几行诗

上联: 明花许我三分色	下联: 明月谁人一段情

上联: 韵流青史丹樨在	下联: 风过泸州带酒香

上联: 苍海扬波高歌始祖恩深似海	下联: 青山耸翠大展宏图志壮如山

上联: 烟柳斜阳归去东南余半壁	下联: 桃花流水归来春夏第一枝

上联: 一朝飞雪满天字	下联: 几度流云遍地诗

上联: 杨柳多情笑问春风桃李事	下联: 桃花依旧笑看明月水云心

上联: 新月如钩钩起心田多少事	下联: 春风似剪裁成梦幻几分愁

上联: 龙陪旭日观奇景	下联: 蛇伴春风入画图

上联: 一亭诗韵夸儿孝	下联: 两袖清风赞子孙

上联: 灵羊奉献兴邦硕果	下联: 骏马奔腾富国宏图

上联: 卓越超群德达三江通四海	下联: 达观致远文明四海耀千秋

上联: 抚石可辨文章影	下联: 挥笔能书翰墨香

上联: 红桃笑破胭脂口	下联: 绿柳轻摇翡翠裙

上联: 室陋几曾输月色	下联: 人闲何处觅花香

上联: 舍经难顿悟未上此楼永与佛天离咫尺	下联: 修道可修行无边彼岸长随法雨洗尘心

上联: 春风已过斜阳道	下联: 明月还临明月楼

上联: 数遍千官无所事	下联: 几多万事有知音

上联: 四面荷花三面柳于泉城润色	下联: 万家灯火万家灯照梦想成真

上联: 嫁女婚男百年合	下联: 结婚婚姻四海同

上联: 人在征途满园春色谁关注	下联: 情牵故里一片冰心我自由

上联: 厨艺高超工境界	下联: 匠心巧妙妙文章

上联: 踏浪归来风雨江湖犹识我	下联: 登楼望远江山山水不知年

上联: 落纸云烟凝往事	下联: 挥毫笔墨写新篇

上联: 艺苑腾蛟圣域方收硕果	下联: 联坛跃马神州更上层楼

上联: 歧路	下联: 长江

上联: 鹊飞疑是银河渡	下联: 雁去疑为玉簟秋

上联: 创业创新天下道源新故事	下联: 承前启后世间遗产大文章

上联: 红尘信似云霞聚	下联: 青史犹如日月长

上联: 燕舞新年喜	下联: 莺歌盛世春

上联: 红绿青黄黑白皆都有	下联: 红红绿绿红红各样红

上联: 祥光烁破千生病	下联: 瑞气迎来万里春

上联: 灵似甘霖解口渴	下联: 心如明月照人心

上联: 清风拂面迷人意	下联: 明月盈怀醉客心

上联: 欲邀我佛来执意催山起祥云莲开宝座	下联: 不染尘嚣去修身养性修善果我悟禅机

上联: 千篇一律无新意	下联: 万古千秋有古风

上联: 法乃国纲行廉反腐一身胆	下联: 德为民本治国安邦两袖风

上联: 书中便晓人间事	下联: 笔下方知世上情

上联: 坐拥湖山淡看利名鹤子梅妻仙是我	下联: 卧听风月闲听风雨松风竹韵月为邻

上联: 寂寞溪边客	下联: 相思陌上人

上联: 湖中玉镜邀明月	下联: 岭上青山伴夕阳

上联: 两井水何奇活人济世苍天鉴	下联: 九州山不老壮志凌云白鹤飞

上联: 拾级上天都赏景健身臂展青松迎奥运	下联: 登峰登绝顶登高极目胸怀赤县展雄风

上联: 三门组稿紫燕编排采撷春光镶版面	下联: 四海蜚声金鸡报晓迎来喜气满人间

上联: 窑火旺千秋光耀中华美誉长随丝路远	下联: 城乡兴百业兴隆大业宏图大展画图新

上联: 竹篙桂楫飞如箭	下联: 铢襻香腰巧似珠

上联: 新岁新景新气象	下联: 好风好雨好风光

上联: 促寿	下联: 延年

上联: 青春无价没人卖	下联: 岁月有情有酒浇

上联: 知我法随缘不生执念	下联: 悟禅心自悟即是修行

上联: 墨笔狂书龙飞凤舞出神韵	下联: 联花怒放蝶舞蜂飞入画图

上联: 茂星环月天重笑	下联: 明月清风夜未央

上联: 一片春云凝紫气	下联: 满园秋色染红霞

上联: 葡萄架下斟新酒	下联: 橄榄枝头唱大风

上联: 清江一盏多情月	下联: 明月千秋有意人

上联: 贺新春换新居心花怒放	下联: 迎盛世兴骏业骏业兴隆

上联: 股逢牛市套方解	下联: 脚踏马鞍车上行

上联: 死生今忽异	下联: 死死自生悲

上联: 云锁山门关俗客	下联: 月临水榭洗尘心

上联: 花香难果腹	下联: 月色不关心

上联: 淡了红尘淡了往事我心谁洗	下联: 抛开俗念抛却尘缘梦幻我来

上联: 平安竹报全家庆	下联: 幸福花开满院春

上联: 盛世添筹娱晚景	下联: 高山流水遇知音

上联: 纵览古今中外千年史	下联: 纵观天地人间一片天

上联: 润物滋春甘作雨	下联: 修身养性乐为天

上联: 苦口婆心是佛	下联: 清风明月为人

上联: 长大知才须有用	下联: 少年学问要无求

上联: 及此春初因时游目	下联: 与时俱进自有知音

上联: 求真务实锤炼工匠精神助力调转促	下联: 利国利民利民家庭幸福安居乐升平

上联: 日丽鲜花含淑气	下联: 风和紫燕舞春风

上联: 时时灵气时时趣	下联: 处处风情处处春

上联: 鹏起抗英捐热血	下联: 龙腾盛世展雄风

上联: 眼皮打架不如去	下联: 眉眼看穿无奈何

上联: 拜佛许下千钧愿	下联: 读书读书一卷书

上联: 乐有诗书墙上挂	下联: 乐无日月水中捞

上联: 清廉简约护州政	下联: 正气清廉民族魂

上联: 钟高密地灵官居著作	下联: 鼓高高天地帝业传承

上联: 野火烧不尽	下联: 春风吹得来

上联: 杯水可容天上月	下联: 春风不度世间花

上联: 宝鸡报晓十五年看创新绘出和谐画	下联: 金凤朝阳万千里喜发展绘成富裕图

上联: 生日星光晃晃	下联: 死年月色朦胧

上联: 香雪无声自好色	下联: 春风有意总关情

上联: 上海自来水来自海上	下联: 南山东阿阿阿阿胶胶

上联: 立志增才饱含昌珏千滴汗	下联: 修身致富勤奋骅骝一片天

上联: 今生缘尽无相欠	下联: 来世相逢不再来

上联: 螺尖蚌扁鳖甲圆满盘皆壳	下联: 凤尾凰雏凤翅飞一翅齐毛

上联: 未把萤虫当蜡烛	下联: 常将雁字作文章

上联: 得意春风莫忘我	下联: 无心明月不知年

上联: 长天待我舒鹏翼	下联: 大地回春入马蹄

上联: 凭栏望月佳人泪尽关山远	下联: 把酒临风故友情深岁月长

上联: 秋翻枫页谁为画	下联: 月落荷塘我作诗

上联: 一夜春风千岭翠	下联: 满山秋色满山红

上联: 泄柳	下联: 舂薪

上联: 周报传八卦	下联: 文章耀九州

上联: 一亭风月冷	下联: 两岸水云闲

上联: 桃红残雪尽	下联: 柳绿暖风来

上联: 江清随月老	下联: 海阔任风狂

上联: 千秋扬正气	下联: 万里荡春风

上联: 一亭风雨过	下联: 千古古今传

上联: 科技兴邦旧岁已添三道喜	下联: 勤劳致富新年更上一层楼

上联: 年来惆怅还依旧	下联: 风过泸州带酒香

上联: 一叶归帆天际远	下联: 千帆破浪水中央

上联: 道德文章都入理	下联: 文章笔墨总关情

上联: 一宵大雨蛙声乱	下联: 半夜清风燕影斜

上联: 叽哩咕噜怪话	下联: 汪汪汪汪真情

上联: 细雨梦回鸡塞远	下联: 春风春暖马蹄香

上联: 春风不解花间语	下联: 明月难知梦里人

上联: 上下五千年龙族问天华夏煌煌谁肇造	下联: 纵横八万里人文蔚起神州熠熠我争先

上联: 先锋奋击除倭寇	下联: 大业宏开振国威

上联: 龙荣半世千秋贵	下联: 蛇舞三春万里香

上联: 解粽筵开老翁半日斟蒲酒	下联: 寻梅酒醉稚子一庭摘菊诗

上联: 门迎紫气铺天福	下联: 户纳春风入画图

上联: 云开雾散	下联: 电闪雷鸣

上联: 藏书集画展艺施才巧手掀开新世界	下联: 泼墨挥毫挥毫泼墨丹心写就大文章

上联: 浮云窥海月	下联: 明月照天心

上联: 寸阴宁越度	下联: 寸草不争荣

上联: 莫让光阴如水逝	下联: 休将岁月似风流

上联: 水秀山青花容月貌	下联: 花香鸟语鸟语花香

上联: 我劝天公重抖擞	下联: 谁怜月老再团圆

上联: 日序班头如候补	下联: 春风拂面似花开

上联: 喜逢盛世频增寿	下联: 欢庆新年喜报春

上联: 玉笛约春峰染翠	下联: 金樽邀月酒飘香

上联: 云梦八千里	下联: 风情一万年

上联: 圣代即今多雨露	下联: 名山何处有烟霞

上联: 花影云拖地	下联: 月光月照天

上联: 家中自有春秋韵	下联: 笔下常留岁月痕

上联: 乌有	下联: 黄无

上联: 心头苇荡笔底牧歌风华十秩弘联韵	下联: 笔下风流笔端墨韵锦绣千秋绘画图

上联: 欲静憎蝉噪	下联: 方知喜鹊鸣

上联: 春信千家传紫燕	下联: 花香万里绽红花

上联: 槐花落尽无心事	下联: 柳絮飞空有意思

上联: 赏松风格学竹虚心藏梅傲骨真君子	下联: 敬业精神培桃育李继往开来大丈夫

上联: 涑水欢歌桃醉杜康三千岁月	下联: 瑶山焕彩燕飞燕赵一派春光

上联: 欲穷千里宏观目	下联: 不负一生大爱心

上联: 饮酒花间酒散花间花亦醉	下联: 吟诗月下风流月下月犹寒

上联: 磊成三块石	下联: 风过一重山

上联: 栉风沐雨人生路	下联: 戴月披星世界观

上联: 山中宰相南朝典	下联: 门外仙人北国风

上联: 前浪陈江缺后浪	下联: 高山流水遇知音

上联: 心能转物	下联: 志可凌云

上联: 古狗	下联: 新人

上联: 姥姥	下联: 公公

上联: 书中自出千钟粟取之有道	下联: 笔下难求万卷书得者无忧

上联: 桃红李白妃子醉	下联: 柳绿花红美人娇

上联: 对月梳妆青丝钩角挂	下联: 临风把盏红袖画眉开

上联: 信手拈来神笔已臻诗境妙	下联: 随心放下神州更上画堂高

上联: 一杯相送花辞去	下联: 两袖清风月照来

上联: 无缝对接华阳喜逢日月同辉	下联: 万象更新大地春到春夏秋冬

上联: 先声传喜讯有幸居楼多年愿望一朝遂	下联: 大业展宏图无忧处世万里欣逢百业兴

上联: 岩乃山下石	下联: 山如水中山

上联: 廉启新章正气敢教风气爽	下联: 德扬正气清风不让党旗红

上联: 风定秋千闲卧月	下联: 月明夜半静敲诗

上联: 笔有深情耕月夜	下联: 心无俗虑洗尘心

上联: 端午万村包粽子	下联: 元宵一夜挂灯花

上联: 花落一窗诗串起	下联: 月圆半夜梦随来

上联: 刘剑胆	下联: 李文心

上联: 口齿不清常跑调	下联: 嘴巴巴肉好揩油

上联: 鸟语花香有声有色三春景	下联: 花香鸟语无语无声四季歌

上联: 一对手纹启一宗始祖	下联: 两行文字传万代宗师

上联: 伏枥雄心在	下联: 扬鞭壮志坚

上联: 云边路绕秋山色	下联: 月下花开春水香

上联: 星淡月明天气派	下联: 风和日丽地精神

上联: 翠竹黄花皆佛性	下联: 清风明月是禅心

上联: 按经济规律发展经济	下联: 以经济经济和谐社会

上联: 寒梅已作东风信	下联: 明月还为北斗星

上联: 大火焚林真够呛	下联: 小桥流水不糊涂

上联: 星斗满天无月亮	下联: 春风遍地有花香

上联: 依诗咏对须遵格	下联: 对酒当歌不厌烦

上联: 林间鸟奏笙簧月	下联: 陌上花开蝶恋花

上联: 济世良方除病患	下联: 修身正道济民生

上联: 锐气千年盈北海	下联: 雄心万里壮南疆

上联: 寨外涓溪流我泪	下联: 门前紫燕舞春风

上联: 风一动千般变化	下联: 月半轮万里乾坤

上联: 青山昨夜风吹过	下联: 碧水今宵月照来

上联: 作后学津梁藜照年年旧梦未抛天禄阁	下联: 为先生典范读书代代高风不负栋梁材

上联: 闲云拂岫时舒展	下联: 明月临窗每觊觎

上联: 挥笔如剑倚麓山豪气干云揽月去	下联: 挥毫似刀挥铁马豪情壮志踏云来

上联: 执镫引缰扶农跃上千里马	下联: 乘风破浪破浪冲开一片天

上联: 桃呈福寿李呈喜	下联: 梅吐芬芳李贺春

上联: 应虎步春声和风带雨谁施泽	下联: 为龙腾盛世盛世扬帆我领航

上联: 独览群峰高低不论皆平视	下联: 常思大道远近无争尽远观

上联: 塔影梅香山色千般秀	下联: 山光水色湖光万里春

上联: 春雨依然有意绿	下联: 桃花依旧笑颜红

上联: 双龙曾献瑞	下联: 百鸟不争春

上联: 表面	下联: 开心

上联: 业内富者者又者者者富者	下联: 家中家家家家家家家家家

上联: 心为业本	下联: 德是人才

上联: 扇转非为己	下联: 杯空不是人

上联: 云石足勾留稔知清气源山野	下联: 江山须造就明察古今论古今

上联: 卓荦岂共红尘误	下联: 达人何必白云归

上联: 民安国泰三春送暖三农活	下联: 政善人和万象更新百业兴

上联: 睡前添一笔	下联: 醉后醉三杯

上联: 环球通讯	下联: 大地回春

上联: 登宝塔品中山松醪庆贺民强国富	下联: 登高楼看大地春色迎来国泰民安

上联: 鸟语空山惊寂寞	下联: 花香小院惹相思

上联: 生发灵可医疗毛病	下联: 死生命能医疗病灾

上联: 对连错	下联: 联对联

上联: 松下下棋寻子路	下联: 月中中箭有嫦娥

上联: 柳枕湖边鱼戏月	下联: 梅开岭上鸟争春

上联: 山色泉声涵静照	下联: 松风竹韵入清流

上联: 清明尘世清明景	下联: 雨露风情淡雅情

上联: 魔日逆天曾使樱花泣血	下联: 春风得意不教柳絮伤心

上联: 纵横笔下三千意	下联: 俯仰胸中万仞峰

上联: 盛世春临小康在望喜听农家储百万	下联: 小康福满大有无边欣看大业耀千秋

上联: 源浊难见流清水	下联: 望重方知望远山

上联: 一波情浪涌平湖	下联: 满目春光入画图

上联: 箬笠红尘外	下联: 瑶琴绿绮中

上联: 望路烟霞外	下联: 登山日月中

上联: 奇文共欣赏偶尔重温陶令句	下联: 佳句同吟咏何须再诵谢公诗

上联: 花香一盏收浓淡	下联: 月色半窗照浅深

上联: 新月初悬没线银钩能钓海	下联: 清风乍起无声玉笛可吹箫

PaddleNLP更多教程
使用seq2vec模块进行句子情感分析
使用预训练模型ERNIE优化情感分析
使用BiGRU-CRF模型完成快递单信息抽取
使用预训练模型ERNIE优化快递单信息抽取
使用预训练模型ERNIE-GEN实现智能写诗
使用TCN网络完成新冠疫情病例数预测
使用预训练模型完成阅读理解
自定义数据集实现文本多分类任务
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值