Natural Language Processing相关概念理解

NLP一般流程 文本预处理->词向量与文本表示->特征选择与特征抽取->分类算法 词向量与文本表示 词袋模型(BOW) 将所有词汇放进一个袋子里,假设有n个词,则每个句子表示为一个长度为n的词频向量,词频即对应词在句子里出现的次数,如果没有出现就是0。这种方法句子里的语义信息被完全遗失了。 word based encodings 另一种思路是表示句子,这样就可以把词在句子中的位置关系考虑进去,例如 “我 喜欢 猫”和 “我 喜欢 狗”分别表示为(0 1 2)和(0 1 3),这里的数字不再是词频,而是对应单词被分配的编码,如果词重复了,显然在数组中对应的数字也会重复。 padding 句子长度不同时,需要将他们转化为统一长度的向量输入到神经网络中训练,这时就要padding,设置一个长度n,如果句子长度小于n,就在数组左侧或右侧填充0,如果句子长了,就把左侧或右侧多余的部分忽略,具体方位由自己选择。 词向量模型(word embedding) 考虑词与词之间的位置关系。原本用随机分配的数字代表每一个词,词与词之间是完全独立的,而embedding使得每一个词成为了一个n维空间中的向量,如果两个词的含义相近,那么相应的向量距离也就进,这样就考虑到了词的含义。 word2Vec : 底层采用基于CBOW和Skip-Gram算法的神经网络模型。 CBOW模型: CBOW模型的训练输入是某一个特征词的上下文相关的词对应的词向量,而输出就是这特定的一个词的词向量。由于CBOW使用的是词袋模型,因此上下文的几个词都是平等的,也就是不考虑他们和我们关注的词之间的距离大小,只要在我们上下文之内即可。 这样我们这个CBOW的例子里,我们的输入是上下文选定的词向量,输出是所有词的softmax概率(训练的目标是期望训练样本特定词对应的softmax概率最大),对应的CBOW神经网络模型输入层有4个神经元,输出层有词汇表大小个神经元。隐藏层的神经元个数我们可以自己指定。通过DNN的反向传播算法,我们可以求出DNN模型的参数,同时得到所有的词对应的词向量。这样当我们有新的需求,要求出某4个词对应的最可能的输出中心词时,我们可以通过一次DNN前向传播算法并通过softmax激活函数找到概率最大的词对应的神经元即可。 Skip-Gram模型: Skip-Gram模型和CBOW的思路是反着来的,即输入是特定的一个词的词向量,而输出是特定词对应的上下文词向量。 这样我们这个Skip-Gram的例子里,我们的输入是特定词, 输出是softmax概率排前几的词,对应的Skip-Gram神经网络模型输入层有1个神经元,输出层有词汇表大小个神经元。隐藏层的神经元个数我们可以自己指定。通过DNN的反向传播算法,我们可以求出DNN模型的参数,同时得到所有的词对应的词向量。这样当我们有新的需求,要求出某1个词对应的最可能的4个上下文词时,我们可以通过一次DNN前向传播算法得到概率大小排前4的softmax概率对应的神经元所对应的词即可。 词向量模型突出特点: 在词向量模型中,词向量与词向量之间有这非常特殊的特性。例如现在存在国王、男生、女人、皇后四个词向量,那么一个完善的词向量模型,就存在“国王-男人+女人=皇后”这样的关系。 参考: 词袋模型(BOW,bag of words)和词向量模型(Word Embedding)概念介绍

May 21, 2020 · Xiangtao XIAO

NLP数据准备相关代码记录

csv文件 什么是csv文件 csv既逗号分隔符文件,行数据用’,‘分隔,列数据用换行符’\n’分隔 读取与写入csv文件 with open(filename, 'r', encoding='gbk') as rf: reader = csv.reader(rf, dialect=csv.excel) # 按行读取,读取的是存储为excel可读格式的csv文件,这个文件可以用excel打开查看 with open(r'clean_data\clean_data_0.5_no_repeat.csv', 'w', encoding='gbk', newline='') as f: writer = csv.writer(f, dialect=csv.excel, delimiter=',') for data in final_dataset: writer.writerow(data) # 按行写入,写入格式也是csv.excel,会把一个二维列表自动存储为表格,行列对应,存储的内容是原封不动的 csv文件存储格式与换行问题 用以上方法读取的csv文件每一行每一列取出的都是字符串’str’格式,对于字典要用eval()函数自动转回原本对应的格式,而int等也要用对应函数转换 newline=’’“设置存储的行与行之间没有空行,否则会隔行存储。 json格式 json格式文件特点 json格式文本对{对象:值},例如: {“name”: “John Doe”, “age”: 18, “address”: {“country” : “china”, “zip-code”: “10000”}},和字典有些相似,存储的值可以是字符串,数组,字典等,这个格式好处在于可以存储结构相对复杂的数据并且易于存取。 json与str,json的读取 在实际操作中似乎直接把json放在列表里就可以和其他数据一样存储到csv文件中,在使用csv.writer方法时,双引号的问题被自动解决了,取出以后和其他数据一样都是str,使用json.loads()方法即可转换为json格式数据,写入的时候可以用同样的方法转换。 转换后的json格式数据按对象取值的方法与字典相似,即data[‘对象名’]->值 python集合、列表、字典 在处理重复数据时(这里指字符串或数值的数据),可以采用集合进行存储,因为集合中元素不能重复,可以很简单的使用set()或list()方法将集合和列表相互转换,因此可以利用集合去重后在转换为list存储。 要注意的是,创建空的集合要使用a = set()方法,如果是a={}则是一个空的字典。 当存储集合时如果集合为空会存储一个空集,内容为set()。 集合增加元素要用add()方法,集合没有列表的append()方法。 在处理数据时,字典一个很大的用处在于给出的key是有语义的,这提高了代码的可读性,list[1]中的数据是什么我们是不知道的,而dict[‘key’]则很好懂。 tensorflow输入数据格式转化 constant方法生成张量,tensorflow搭建的算法输入数据都是相应格式的张量,而不是列表,因此如果采用csv.reader读取csv文件而不是tensorflow自带的方法读取csv文件的话,要用对应的tensorflow或者numpy方法将数据转化为张量,通常为[None,*]None为数据量比如有2000条训练文本,None就是2000,后面的就是处理后的数据格式,比如设置的padding,maxlen=500的embedding size=12后的文本数据,格式就是[None,500,12],label数据格式也要与之相对应。 tensorflow自带的读取csv文件的方法可以直接得到tensor格式的数据,但是由于我要处理的csv文件是文本文件并且包含json,这个时候还是先用csv的方法处理完比较好。

May 21, 2020 · Xiangtao XIAO

TensorFlow基础API

看网课视频老师讲的一些,实际上官方文档有非常详细的介绍 import numpy as np import tensorflow as tf # tf基础api:常量 t = tf.constant([[1., 2., 3.], [4., 5., 6.]]) # index索引操作 print(t) print(t[:, 1:]) print(t[..., 1]) #%% # ops算数操作 print(t+10) print(tf.square(t)) print(t @ tf.transpose(t)) # 乘转置 #%% # numpy conversion print(t.numpy()) print(np.square(t)) np_t = np.array([[1., 2., 3.], [4., 5., 6.]]) print(tf.constant(np_t)) #%% # Scalars tensor可以使0维、1维... t = tf.constant(2.718) print(t.numpy()) print(t.shape) #%% # strings t = tf.constant('cafe') print(t) print(tf.strings.length(t)) print(tf.strings.length(t, unit='UTF8_CHAR')) print(tf.strings.unicode_decode(t, 'UTF8')) #%% # string array t = tf.constant(['cafe', 'coffee', '咖啡']) print(tf.strings.length(t, unit='UTF8_CHAR')) r = tf.strings.unicode_decode(t, 'UTF8') print(r) #%% # ragged tensor r = tf.ragged.constant([[11, 12], [21, 22, 23], [], [41]]) # index op print(r) print(r[1]) print(r[1:2]) #%% # ops on ragged tensor r2 = tf.ragged.constant([[51, 52], [], [71]]) print(tf.concat([r, r2], axis=0)) r3 = tf.ragged.constant([[13, 14], [15], [], [41, 42, 43]]) print(tf.concat([r, r3], axis=1)) # ragged tensor 变成 普通tensor 空位用0补齐,注意0永远在正常值的后面 print(r.to_tensor()) #%% # sparse tensor 0可以在正常值前面 s = tf.SparseTensor(indices=[[0, 1], [1, 0], [2, 3]], values=[1., 2., 3.], dense_shape=[3, 4]) print(s) print(tf.sparse.to_dense(s)) # 稀疏矩阵转密集矩阵,这样的稀疏矩阵不能用ragged tensor来表示 #%% # ops on sparse tensors s2 = s * 2.0 print(s2) try: s3 = s + 1 except TypeError as ex: print(ex) s4 = tf.constant([[10., 20.], [30., 40.], [50., 60.], [70., 80.]]) print(tf.sparse.sparse_dense_matmul(s, s4)) #%% s5 = tf.SparseTensor(indices=[[0, 2], [0, 1], [2, 3]], # 没有排好序的稀疏矩阵无法被转换为密集矩阵 values=[1., 2., 3.], dense_shape=[3, 4]) print(s5) s6 = tf.sparse.reorder(s5) # 对s5进行排序 print(tf.sparse.to_dense(s6)) #%% # Variable 变量 v = tf.Variable([[1., 2., 3.], [4., 5., 6.]]) print(v) print(v.value()) print(v.numpy()) #%% # assign value 变量重新赋值 v.assign(2*v) print(v.numpy()) v[0, 1].assign(42) print(v.numpy()) v[1].assign([7., 8., 9.]) print(v.numpy()) #%% # 不能用=号,只能用assign()重新赋值 try: v[1] = [7., 8., 9.] except TypeError as ex: print(ex) # 'ResourceVariable' object does not support item assignment

May 21, 2020 · Xiangtao XIAO

卷积神经网络(CNN)理论与实现

一、理论 卷积神经网络结构:(卷积层+(可选)池化层)*N+全连接层*M(M>=0),卷积层的输入输出是矩阵,全连接层输入输出是向量,在卷积层的最后一层做一个展平。 主要用于分类任务 全卷积神经网络:(卷积层+(可选)池化层)*N+反卷积层*K,可以做物体分割类任务 卷积操作 解决参数过多导致的计算资源不足,容易过拟合的问题。解决方法:局部连接(基于图像的区域性)、参数共享(基于图像特征与位置无关) 卷积核是反向传播计算出的参数,卷积:卷积核与输入做点积乘法。步长:卷积核每次在输入上滑动的距离。padding:使输出size不变。 池化操作 类似卷积,计算方式不同,最大值池化:池化核滑动覆盖区域的最大值作为结果输出。 特点:常使用不重叠(kernal-size=步长)、不补零的操作。参数即为步长和池化核大小。用于减少图像尺寸,从而减少计算量。一定程度平移鲁棒。损失了空间精度。 二、实现 embedding_dim = 16 batch_size = 128 cnn_model = keras.models.Sequential([ keras.layers.Embedding(vocab_size, embedding_dim, input_length=max_length), keras.layers.Conv1D(filters=256,kernel_size=2,kernel_initializer='he_normal', strides=1,padding='SAME',activation='relu'), keras.layers.GlobalMaxPooling1D(), keras.layers.Dropout(rate=0.5), keras.layers.Dense(12, activation='sigmoid') ]) cnn_model.summary() cnn_model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) Conv1D 在文本中,卷积的某一维大小往往为embedding长度,即在宽度上不需要窗口移动,宽度就是整个窗口,所以conv1d默认卷积的宽度就为embedding维度,长度通过kernel_size来指定的,此处为2,即卷积核的大小为2*embedding_size。strides为步长,此处为1,即卷积核每隔一个单词移动一次。filters是卷积核的个数,即输出的维度。padding有valid和same两种选择,valid在长度方向(宽度方向不padding)不进行padding,而same则在长度方向进行padding,保证输入句子长度和卷积后输出的句子长度一致。 //blog.csdn.net/bobobe/article/details/87923618 tensorflow fit()方法:参考 //blog.csdn.net/crazyman2010/article/details/103705318 TextCNN //blog.csdn.net/u014732537/article/details/79573174

May 21, 2020 · Xiangtao XIAO

MNIST手写数字识别实践

from __future__ import absolute_import, division, print_function, unicode_literals import tensorflow as tf mnist = tf.keras.datasets.mnist (x_train, y_train), (x_test, y_test) = mnist.load_data() # 加载数据 x_train, x_test = x_train / 255.0, x_test / 255.0 # /255:将RGB数值归一化 #%% print(y_train.shape) #%% model = tf.keras.models.Sequential([ tf.keras.layers.Flatten(input_shape=(28, 28)), # 张量扁平化,将28*28的图片矩阵转化为784的向量 tf.keras.layers.Dense(128, activation='relu'), # 全连接层,128个神经元,激活函数为relu(The Rectified Linear Unit) # y=max(0,x) tf.keras.layers.Dropout(0.2), # 防止过拟合,drop out 80% of inputs,使用0.2*cell_size个神经元进行训练 tf.keras.layers.Dense(10, activation='softmax') # 全连接层输出 softmax激活函数 ]) model.compile(optimizer='adam', # 梯度下降策略 adam loss='sparse_categorical_crossentropy', # 损失函数 sparse:y独热化编码 交叉熵 metrics=['accuracy']) # metrics 列表,包含评估模型在训练和测试时的性能的指标,典型用法是metrics=[‘accuracy’]。 # 如果要在多输出模型中为不同的输出指定不同的指标,可向该参数传递一个字典,例如metrics={‘output_a’: ‘accuracy’} model.fit(x_train, y_train, epochs=5) # 训练5轮 model.evaluate(x_test, y_test, verbose=1) # Verbosity mode. 0 = silent, 1 = progress bar. # fit()用于使用给定输入训练模型. # evaluate()用于评估已经训练过的模型.返回损失值&模型的度量值.

May 20, 2020 · Xiangtao XIAO

TensorFlow2.0安装

清华镜像源安装 pip install tensorflow-gpu==1.12.0 -i //pypi.tuna.tsinghua.edu.cn/simple #可改成任意版本 CPU版本安装 pip install tensorflow -i //pypi.tuna.tsinghua.edu.cn/simple Pycharm环境配置 (一)导入TensorFlow模块测试 import tensorflow as tf hello = tf.constant() sess = tf.Session() sess.run(hello) 结果如下:ModuleNotFoundError: No module named ’tensorflow' (二)加入运行路径 设置项目的编译器为python安装位置的python.exe,勾选导入所有的模块,显示如上图所示。再次运行出现同样的错误,查了一些资料应该是电脑的CPU太老了,我下载的tensorflow2.1.0版本不支持。 (三)安装2.0.0版本并测试 运行代码: pip unintall tensorflow 重新运行安装代码:pip install tensorflow==2.0.0 -i //pypi.tuna.tsinghua.edu.cn/simple 再次测试成功! 由于笔记本没有英伟达显卡,配置较低,只安装了CPU版本,后续使用有较好配置的电脑尝试安装GPU版本。确实CPU版本速度比较慢。

May 19, 2020 · Xiangtao XIAO

平面构成方法总结

平面构成的三大元素 构成题的基本要求 完成度高 画面丰富,层次感强 笔触细腻 建议:配色明快,色彩明度高,纯度不要太高。 点 点的大小不固定:点的形态大小在于比较,没有比较,点的大小不确定,点也可以被看做面。 点的形状不固定:点可以是任意形状,只要这个形态在画面上与其他元素的大小关系满足我们从感性的角度判断其为一点。 点能够塑造空间感:点可以塑造空间的明暗和虚实关系。 点能够作为肌理。 线 线有多种类型,包括直线、曲线、虚线等。线的形态不固定。 线有粗细变化,一般满足近实远虚、在转折处加粗的特点。 线能够勾勒轮廓,闭合的线就形成了面。 与点类似,线也可以塑造肌理和空间感。 线能够表达情感:直线一般代表着坚定、硬朗、速度等,曲线代表着韵动、柔韧、感性等。 面 面分为 几何面 与 自由面 ,自由面是不规律的,随意的面,或者边界不明确、随意,类似于水墨晕开形成的面。 面也分为 虚面 与 实面 ,点和线构成的面便是虚面。 面具有正负形态:面正负形产生的错视。也就是我们常说的图与底的关系。图,就是形,也叫正形,位于画面醒目的位置,表达主要思想的元素,底,就是背景,也叫负形,位于正形的后面,对正形起衬托装饰的作用,让人感觉正形的存在。任何的图形都由正形和负形两部分组成,正形靠负形来衬托,负形需正形来界定。图底分明的图像层次感鲜明,更容易吸引关注的目光。不仅如此,还有一种矛盾图形,比如说太极图,分辨不出图与底。 面可以突出重点,增加对比效果。 面与面有许多不同的结合方式:重叠、透叠、分离、相切、重合等。 构成法则 重复 有规律的进行排列组合。 近似 确定基本形不变,基本形的内容与组成形式改变。 特异 有规律的形态中进行小部分的变异,形成视觉中心点,使画面生动活泼。 渐变 指基本形进行规律化的渐变处理:比如产品造型上有植物渐变到灯具。带来节奏感和韵律感(进行构图和构思比较耗时),渐变可以是九宫格的形式或者综合的形式。重点在于渐变过程的展现。 发射 从画面的视觉中心点出发,带来空间感和动感,发射的基本形可以任意变化(不是非要直线)。 对比 具有差异元素构成的作品,对比包括色彩、大小、虚实、曲直对比等。 密集 疏密关系,画面具有节奏感。 分割 可以以等形、等量、重复、自由等形式进行分割。参考毕加索的画作。 异构(同构) 基本形局部元素图形变化,比如一个肺部形状,内容替换为西蓝花。一般变化的就是要表达的主题本身。 一般在画面中会使用多种构成法则进行组合,综合体现效果。 平面构成的表现形式 概念 元素:构成画面的基本形,由造型基本元素点线面组成。 构成法则:对元素进行组合的一些规则。

May 16, 2020 · Xiangtao XIAO

机器学习入门基本概念理解

张量 张量=容器 张量是现代机器学习的基础。它的核心是一个数据容器,多数情况下,它包含数字,有时候它也包含字符串,但这种情况比较少。因此把它想象成一个数字的水桶。 0维张量=数字;1维张量=向量;2维张量=矩阵;3维张量=公用数据存储在张量,彩色图片等… one-hot vector 独热编码,用于分类标记。比如(猫,狗,鼠)对应(1,0,0)代表猫,(0,1,0)代表狗…将离散型特征采用独热编码,会使得特征之间的距离计算更加合理。 softmax函数 softmax函数的作用主要是:1.通过将模型的预测结果转化到指数函数上将预测结果转化为非负数;2.归一化处理,使各种结果概率之和等于1. //blog.csdn.net/lz_peter/article/details/84574716 交叉熵 对于单标签多分类问题,p(x)表示是否为标记的类,如果用独热编码表示分类,则取值0或1;q(x)则是预测结果为该类的概率。用交叉熵做损失函数,值越小,表示模型预测结果与实际情况一致性越高。 单标签多分类问题所有类别概率和为1,多标签二分类问题所有类别和不为1,交叉熵的计算针对的是单个类别(即二分类),然后单张样本计算多个二分类交叉熵的和。 //blog.csdn.net/tsyccnh/article/details/79163834 欧式空间 欧几里得空间就是在对现实空间的规则抽象和推广(从n<=3推广到有限n维空间)。 欧几里得几何就是中学学的平面几何、立体几何, 在欧几里得几何中,平行线任何位置的间距相等。 而中学学的几何空间一般是2维,3维(所以,我们讨论余弦值、点间的距离、内积都是在低纬空间总结的),如果将这些低维空间所总结的规律推广到有限的n维空间,那这些符合定义的空间则被统称为 欧几里得空间(欧式空间,Euclidean Space)。而欧几里得空间主要是定义了 内积、距离、角(没错,就是初中的那些定义),理解了这些再去理解数学定义就很明确了。 //www.zhihu.com/question/27903807/answer/699570097 梯度弥散与梯度爆炸 靠近输出层的hidden layer 梯度大,参数更新快,所以很快就会收敛; 而靠近输入层的hidden layer 梯度小,参数更新慢,几乎就和初始状态一样,随机分布。 在上面的四层隐藏层网络结构中,第一层比第四层慢了接近100倍!! 这种现象就是梯度弥散(vanishing gradient problem)。而在另一种情况中,前面layer的梯度通过训练变大,而后面layer的梯度指数级增大,这种现象又叫做梯度爆炸(exploding gradient problem)。 总的来说,就是在这个深度网络中,梯度相当不稳定(unstable)。 //www.cnblogs.com/yangmang/p/7477802.html batch_size batch的选择首先决定的是下降的方向,batch_size越大,下降的方向越准确。 综合考虑数据集的大小,数据集比较小的时候,用整个数据集作为batch_size就可以,这时候下降的方向也是最精准的,数据集比较大的时候,相对小的batch可以达到和用整个数据集相似的全局学习率,综合考量学习的效果以及电脑内存是否撑得住,目的是尽量让学习效果和效率同时最大化。 在合理范围内,增大 Batch_Size 有何好处? 内存利用率提高了,大矩阵乘法的并行化效率提高。 跑完一次 epoch(全数据集)所需的迭代次数减少,对于相同数据量的处理速度进一步加快。 在一定范围内,一般来说 Batch_Size 越大,其确定的下降方向越准,引起训练震荡越小。 batch_size增大到一定程度后,再增大则效率变差,下降方向也基本不再变化。 //blog.csdn.net/starzhou/article/details/53692248 学习率 梯度下降的伪代码如下: 重复已下过程,直到收敛为止{ωj=ωj-λF(ωj) /ωj} λ就是学习率,学习率过小,优化效率可能很低,学习率过大则有可能越过最优值,收敛到局部最优解。 关于解决学习率的一些问题,如选择合适的学习率,动态调整学习率,归一化等参考: //www.cnblogs.com/mazhujun/p/9633576.html 如何通俗地解释欧氏空间? - 知乎 //www.zhihu.com/question/27903807/answer/699570097

May 16, 2020 · Xiangtao XIAO

空间/色彩构成简介

空间构成的方法 图形重叠 大小变化 倾斜变化 弯曲变化 投影效果 透视效果 面的链接 疏密变化 色彩构成基本原理与法则 曼塞尔色环 色彩概念 基于纸上绘画的体系,是色彩颜料调色为准的显色系。 色相:不同的颜色,红色对应绿色,蓝色对应黄色等。 明度:由黑到白,明度最高为白色,明度最低为黑色,对于同一色相的颜色,明度越高颜色给人感觉越亮,反之则暗,接近黑色。 纯度:色彩的纯度越低越接近灰色,最终纯度最低就是灰色。 基本配色法则 色彩对比构成: 将颜色分为主色、搭配色和点缀色,注意三者之间的比例关系 色彩的调和构成: 属性统一调和:即色相、明度或者纯度三者之一保持相同使画面和谐(但配色应当注意突出重点) 连贯统一调和:用黑色或白色勾边,将对比强烈的色彩贯穿起来 建议使用低明度高纯度的色彩(应试) 色彩情感 通过不同的色彩搭配烘托氛围,给人以忧伤或者喜悦的感受。

May 16, 2020 · Xiangtao XIAO

UEditor部署到个人站点

一、下载UEditor //ueditor.baidu.com/website/download.html 在以上链接下载,选择自己需要的语言版本,我用的是jsp,就下载jsp版本。将下载的压缩包解压,可以直接将解压的文件导入到Eclipse中自己的项目中,导入到文件夹WebContent中即可。 二、配置 将jsp/lib中的jar包全部复制到WEB-INF/lib下 修改输入字符数统计、上限,自定义工具栏可以参考官方说明文档,配置项可在ueditor.config.js中修改。 修改图片上传路径等在官方说明文档中有详细的介绍。 注:这里仅仅是在一个项目中使用UEditor,还用别的使用方法,也可以直接部署到tomcat中。 三、在页面中插入Ueditor编辑器 首先要引用文件 <link rel="stylesheet" type="text/css" href="<%= request.getContextPath() %>/thirdparts/utf8-jsp/themes/default/css/ueditor.change.css"> <script type="text/javascript" charset="utf-8" src="<%= request.getContextPath() %>/thirdparts/utf8-jsp/ueditor.config.js"></script> <script type="text/javascript" charset="utf-8" src="<%= request.getContextPath() %>/thirdparts/utf8-jsp/ueditor.all.min.js"> </script> <script type="text/javascript" charset="utf-8" src="<%= request.getContextPath() %>/thirdparts/utf8-jsp/lang/zh-cn/zh-cn.js"></script> 接着在需要插入编辑器的位置插入以下代码 <textarea id="content" name="content" style="width:100%;height:500px"></textarea> <script type="text/javascript" charset="utf-8"> UE.getEditor('content',{toolbars: [[ 'fullscreen', 'source', '|', 'undo', 'redo', '|','bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc']]}); </script> toolbars控制工具栏显示哪些工具 textarea是显示编辑器的容器,其id与UE.getEditor(‘id’,{})要一致。 不一定要是textarea,div等都可以,可以自己试一试,我没有深入研究,凑合着用了。

May 15, 2020 · Xiangtao XIAO