1.keras_bert 和 kert4keras

keras_bert 是 CyberZHG 大佬封装好了Keras版的Bert,可以直接调用官方发布的预训练权重。

github:https://github.com/CyberZHG/keras-bert

快速安装:pip install keras-bert

kert4keras 是 苏剑林 大佬参考 keras-bert 重新编写的一个 keras 版的 bert,所以使用体验差不多,但 kert4keras 可以适配 albert

github:https://github.com/bojone/bert4keras

快速安装:pip install git+https://www.github.com/bojone/bert4keras.git

2.keras_bert

2.1.Tokenizer

在 keras-bert 里面,使用 Tokenizer 会将文本拆分成字并生成相应的id。

我们需要提供一个字典,字典存放着 token 和 id 的映射。字典里还有 BERT 里特别的 token。

[CLS],[SEP],[UNK]等

在下面的示例中,如果文本拆分出来的字在字典不存在,它的 id 会是 5,代表 [UNK],即 unknown

  1. from keras_bert import Tokenizer
  2. #字典
  3. token_dict = {
  4. '[CLS]': 0,
  5. '[SEP]': 1,
  6. 'un': 2,
  7. '##aff': 3,
  8. '##able': 4,
  9. '[UNK]': 5,
  10. }
  11.  
  12. tokenizer = Tokenizer(token_dict)
  13.  
  14. # 拆分单词实例
  15. print(tokenizer.tokenize('unaffable'))
  16. # ['[CLS]', 'un', '##aff', '##able', '[SEP]']
  17.  
  18. # indices是字对应索引
  19. # segments表示索引对应位置上的字属于第一句话还是第二句话
  20. # 这里只有一句话 unaffable,所以segments都是0
  21. indices, segments = tokenizer.encode('unaffable')
  22. print(indices)
  23. # [0, 2, 3, 4, 1]
  24. print(segments)
  25. # [0, 0, 0, 0, 0]

我们用同样的字典,拆分不存在 字典 中的单词,结果如下,可以看到英语中会直接把不存在字典中的部分直接按字母拆分

  1. print(tokenizer.tokenize('unknown'))
  2. # ['[CLS]', 'un', '##k', '##n', '##o', '##w', '##n', '[SEP]']
  3.  
  4. indices, segments = tokenizer.encode('unknown')
  5. # [0, 2, 5, 5, 5, 5, 5, 1]
  6. # [0, 0, 0, 0, 0, 0, 0, 0]

下面是输入两句话的例子,encode 函数中 我们可以带上参数 max_len,只看文本拆分出来的 max_len 个字

如果拆分完的字不超过max_len,则用 0 填充

  1. print(tokenizer.tokenize(first='unaffable', second='钢'))
  2. # ['[CLS]', 'un', '##aff', '##able', '[SEP]', '钢', '[SEP]']
  3. indices, segments = tokenizer.encode(first='unaffable', second='钢', max_len=10)
  4. print(indices)
  5. # [0, 2, 3, 4, 1, 5, 1, 0, 0, 0]
  6. print(segments)
  7. # [0, 0, 0, 0, 0, 1, 1, 0, 0, 0]

注意这个 max_len 包括 BERT 中的特殊 token,比如下面的代码

  1. tokenizer.encode('unaffable', max_len=3)
    # [0, 2, 1]

我们得到的结果是 [0, 2, 1],0 和 1 分别代表 [CLS] 和 [SEP]

2.2.模型的训练和使用

2.2.1.函数介绍

keras_bert 中我们可以使用 get_model() 来取得 BERT 模型,它有以下参数可供选择

  • token_num:token 的数量
  • pos_num:最大 position 。默认512
  • seq_len:输入序列的最大长度,为 None 时不限制。默认512
  • embed_dim:嵌入维度,默认768
  • transformer_num:transformer的个数,默认12
  • head_num:每个 transformer 中 multi-head attention 中 heads 的个数,默认12
  • feed_forward_dim:每个 transformer 中 feed-forward 层的维度,默认3072
  • dropout_rate:dropout 的概率
  • attention_activation:attention 层的激活函数
  • feed_forward_activation:feed forward 层使用的激活函数,默认是gelu
  • training:如果为True,则将返回带有 MLM 和 NSP输出的模型;否则,将返回输入层和最后一个特征提取层。默认 True
  • trainable:模型是否是可训练的,默认和 training 一样的设置
  • output_layer_num:多少个FeedForward-Norm层的输出被连接为单个输出。仅在 training 为 False 时可用。默认1
  • use_task_embed:是否将 task embedding 加到现有的 embedding 中,默认 False
  • task_num:任务数,默认10
  • use_adapter:是否在每个残差网络前使用 feed-forward adapter,默认 False
  • adapter_units:feed-forward adapter 中第一个 transformation 的维度

关于adapter可以参考这篇论文:https://arxiv.org/pdf/1902.00751.pdf

gen_batch_inputs() 函数可以产生我们用于训练的数据,可用参数如下

  • sentence_pairs:列表,这个包含了许多 token 组成的句子对。
  • token_dict:包括 BERT 所用的特殊符号在内的字典
  • token_list:包括所有 token 的列表
  • seq_len:序列的长度,默认512
  • mask_rate:随机 token 被替换为 [MASK] 的概率,然后预测这个被替换的 token。默认0.15
  • mask_mask_rate:如果一个 token 要被替换为 [MASK],真正替换为 [MASK] 的概率。默认0.8
  • mask_random_rate:如果一个 token 要被替换为 [MASK],替换成一个随机的 token。默认0.1
  • swap_sentence_rate:交换第一个句子和第二个句子的概率。默认0.5
  • force_mask:至少一个位置的 token 被 masked,默认 True

compile_model() 函数用来编译我们的模型,可用参数如下

  • model:要编译的模型
  • weight_decay:权重衰减率,默认0.01
  • decay_steps:学习率会在这个步长中线性衰减至0,默认100000
  • warmup_steps:学习率会在预热步长中线性增长到设置的学习率,默认10000
  • learning_rate:学习率,默认1e-4

warmup可以参考这篇文章:https://yinguobing.com/tensorflowzhong-de-xue-xi-lu-re-shen/

当step小于warm up setp时,学习率等于基础学习率×(当前step/warmup_step),由于后者是一个小于1的数值,因此在整个warm up的过程中,学习率是一个递增的过程!当warm up结束后,学习率开始递减。

load_trained_model_from_checkpoint() 函数用来加载官方训练好的模型,可用参数如下

  • config_file:JSON 配置文件路径
  • checkpoint_file:checkpoint 文件路径
  • training:True 的话,会返回整个模型,否则会忽略 MLM 和 NSP 部分。默认 False
  • trainable:模型是否可训练,默认和 training 设置一样
  • output_layer_num:多少个FeedForward-Norm层的输出被连接为单个输出。仅在 training 为 False 时可用。默认1
  • seq_len:如果这个数值比配置文件中的长度小,position embeddings 会被切成适用于这个长度。默认1e9

2.2.2.构建和训练模型

这个例子里面,我们的不用 Tokenizer 将文本拆分成 “字”,而是使用 “词” 级别作为模型的输入

这里跟 keras 的文本处理很像,可以参考下面这篇文章

https://www.cnblogs.com/dogecheng/p/11565530.html

用keras_bert进行情感分析的实例可以参考下面的文章

https://www.cnblogs.com/dogecheng/p/11824494.html

  1. import keras
  2. from keras_bert import get_base_dict, get_model, compile_model, gen_batch_inputs
  3.  
  4. # 输入示例
  5. sentence_pairs = [
  6. [['all', 'work', 'and', 'no', 'play'], ['makes', 'jack', 'a', 'dull', 'boy']],
  7. [['from', 'the', 'day', 'forth'], ['my', 'arm', 'changed']],
  8. [['and', 'a', 'voice', 'echoed'], ['power', 'give', 'me', 'more', 'power']],
  9. ]
  10.  
  11. # 构建 token 字典
  12. # 这个字典存放的是【词】
  13. token_dict = get_base_dict()
  14. # get_base_dict()返回一个字典
  15. # 字典预置了一些特殊token,具体内容如下
  16. # {'': 0, '[UNK]': 1, '[CLS]': 2, '[SEP]': 3, '[MASK]': 4}
  17. for pairs in sentence_pairs:
  18. for token in pairs[0] + pairs[1]:
  19. if token not in token_dict:
  20. token_dict[token] = len(token_dict)
  21. # token_dict 是由词组成的字典,大致如下
  22. # {'': 0, '[UNK]': 1, '[CLS]': 2, '[SEP]': 3, '[MASK]': 4, 'all': 5, 'work': 6,..., 'me': 26, 'more': 27}
  23.  
  24. token_list = list(token_dict.keys())
  25.  
  26. # 构建和训练模型
  27. model = get_model(
  28. token_num=len(token_dict),
  29. head_num=5,
  30. transformer_num=12,
  31. embed_dim=25,
  32. feed_forward_dim=100,
  33. seq_len=20,
  34. pos_num=20,
  35. dropout_rate=0.05,
  36. )
  37. compile_model(model)
  38. model.summary()
  39.  
  40. def _generator():
  41. while True:
  42. yield gen_batch_inputs(
  43. sentence_pairs,
  44. token_dict,
  45. token_list,
  46. seq_len=20,
  47. mask_rate=0.3,
  48. swap_sentence_rate=1.0,
  49. )
  50.  
  51. model.fit_generator(
  52. # 这里测试集和验证集使用了同样的数据
  53. # 实际中使用时不能这样
  54. generator=_generator(),
  55. steps_per_epoch=1000,
  56. epochs=100,
  57. validation_data=_generator(),
  58. validation_steps=100,
  59. callbacks=[
  60. keras.callbacks.EarlyStopping(monitor='val_loss', patience=5)
  61. ],
  62. )
  63.  
  64. # 使用训练好的模型
  65. # 取出 输入层 和 最后一个特征提取层
  66. inputs, output_layer = get_model(
  67. token_num=len(token_dict),
  68. head_num=5,
  69. transformer_num=12,
  70. embed_dim=25,
  71. feed_forward_dim=100,
  72. seq_len=20,
  73. pos_num=20,
  74. dropout_rate=0.05,
  75. training=False,
  76. trainable=False,
  77. output_layer_num=4,
  78. )

2.2.3下载和使用预训练模型

参考地址:https://github.com/CyberZHG/keras-bert/tree/master/demo

我们可以使用 load_trained_model_from_checkpoint() 函数使用本地已经下载好的预训练模型,可以从 BERT 的 github 上获取下载地址

谷歌BERT地址:https://github.com/google-research/bert

中文预训练BERT-wwm:https://github.com/ymcui/Chinese-BERT-wwm

下面是使用预训练模型提取输入文本的特征

  1. import os
  2.  
  3. # 设置预训练模型的路径
  4. pretrained_path = 'chinese_L-12_H-768_A-12'
  5. config_path = os.path.join(pretrained_path, 'bert_config.json')
  6. checkpoint_path = os.path.join(pretrained_path, 'bert_model.ckpt')
  7. vocab_path = os.path.join(pretrained_path, 'vocab.txt')
  8.  
  9. # 构建字典
  10. # 也可以用 keras_bert 中的 load_vocabulary() 函数
  11. # 传入 vocab_path 即可
  12. # from keras_bert import load_vocabulary
  13. # token_dict = load_vocabulary(vocab_path)
  14. import codecs
  15. token_dict = {}
  16. with codecs.open(vocab_path, 'r', 'utf8') as reader:
  17. for line in reader:
  18. token = line.strip()
  19. token_dict[token] = len(token_dict)
  20.  
  21. # 加载预训练模型
  22. from keras_bert import load_trained_model_from_checkpoint
  23. model = load_trained_model_from_checkpoint(config_path, checkpoint_path)
  24.  
  25. # Tokenization
  26. from keras_bert import Tokenizer
  27.  
  28. tokenizer = Tokenizer(token_dict)
  29. text = '语言模型'
  30. tokens = tokenizer.tokenize(text)
  31. # ['[CLS]', '语', '言', '模', '型', '[SEP]']
  32. indices, segments = tokenizer.encode(first=text, max_len=512)
  33. print(indices[:10])
  34. # [101, 6427, 6241, 3563, 1798, 102, 0, 0, 0, 0]
  35. print(segments[:10])
  36. # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  37.  
  38. # 提取特征
  39. import numpy as np
  40.  
  41. predicts = model.predict([np.array([indices]), np.array([segments])])[0]
  42. for i, token in enumerate(tokens):
  43. print(token, predicts[i].tolist()[:5])

下面我们用预训练模型预测句子中被 MASKED 掉的词语是什么

  1. token_dict = {}
  2. with codecs.open(vocab_path, 'r', 'utf8') as reader:
  3. for line in reader:
  4. token = line.strip()
  5. token_dict[token] = len(token_dict)
  6.  
  7. token_dict_rev = {v: k for k, v in token_dict.items()}
  8.  
  9. model = load_trained_model_from_checkpoint(config_path, checkpoint_path, training=True)
  10.  
  11. text = '数学是利用符号语言研究数量、结构、变化以及空间等概念的一门学科'
  12. tokens = tokenizer.tokenize(text)
  13. tokens[1] = tokens[2] = '[MASK]'# ['[CLS]', '[MASK]', '[MASK]', '是', '利',..., '学', '科', '[SEP]']
  14.  
  15. indices = np.array([[token_dict[token] for token in tokens] + [0] * (512 - len(tokens))])
  16. segments = np.array([[0] * len(tokens) + [0] * (512 - len(tokens))])
  17. masks = np.array([[0, 1, 1] + [0] * (512 - 3)])
  18. predicts = model.predict([indices, segments, masks])[0].argmax(axis=-1).tolist()
  19. print('Fill with: ', list(map(lambda x: token_dict_rev[x], predicts[0][1:3])))
  20. # Fill with: ['数', '学']

3.albert 和 keras4bert

使用示例:https://github.com/bojone/bert4keras/tree/master/examples

albert中文预训练模型:https://github.com/brightmart/albert_zh

3.1.基本使用

本文代码已不全部适用最新的bert4keras,部分函数名字、位置发生了变化

最新版本的可以看:https://www.cnblogs.com/dogecheng/p/11824494.html

keras4bert 是基于 keras-bert 重新编写的一个 keras 版的 bert,可以适配 albert,只需要在load_pretrained_model函数里加上albert=True。

使用体验和 keras_bert 差不多,下面是 github 提供的使用例子。

SimpleTokenizer是一个简单的分词器,直接将文本分割为单字符序列,专为中文处理设计,原则上只适用于中文模型。

load_pretrained_model 可用参数如下

  • config_path:JSON 配置文件路径
  • checkpoint_file:checkponit 文件路径
  • with_mlm:是否包含 MLM 部分,默认 False
  • seq2seq:True 则用来做seq2seq任务的Bert,默认 False
  • keep_words:要保留的词ID列表
  • albert:是否是 ALBERT 模型
  1. from bert4keras.bert import load_pretrained_model
  2. from bert4keras.utils import SimpleTokenizer, load_vocab
  3. import numpy as np
  4.  
  5. config_path = './albert/albert_config_large.json'
  6. checkpoint_path = './albert/albert_model.ckpt'
  7. dict_path = './albert/vocab.txt'
  8.  
  9. token_dict = load_vocab(dict_path)
  10. tokenizer = SimpleTokenizer(token_dict)
  11. # 使用ALBERT
  12. model = load_pretrained_model(config_path, checkpoint_path, albert=True)
  13.  
  14. # 编码测试
  15. token_ids, segment_ids = tokenizer.encode(u'语言模型')
  16. print(model.predict([np.array([token_ids]), np.array([segment_ids])]))

预测 MASKED 掉的词汇

  1. # 建立ALBERT模型,加载权重
    # 预测 MASKED 掉的词汇,需要 MLM 层
  2. model = load_pretrained_model(config_path, checkpoint_path, with_mlm=True, albert=True)
  3.  
  4. token_ids, segment_ids = tokenizer.encode(u'科学技术是第一生产力')
  5.  
  6. # mask掉“技术”
  7. token_ids[3] = token_ids[4] = token_dict['[MASK]']
  8.  
  9. # 用mlm模型预测被mask掉的部分
  10. probas = model.predict([np.array([token_ids]), np.array([segment_ids])])[0]
  11. print(tokenizer.decode(probas[3:5].argmax(axis=1)))
  12. # 技术

3.2.情感分析实例

数据集:https://github.com/bojone/bert4keras/tree/master/examples/datasets

或百度网盘下载:链接: https://pan.baidu.com/s/1OAhNbRYpU1HW25_vChdRng 提取码: uxax

测试环境:

Ubuntu 16.04.6

Anaconda Python 3.7.3

数据集是两个 excel 表,分别存放着正面和负面评价,下面是负面评价的内容

先设置预训练模型的路径,并读取原始数据

  1. # 序列最大长度
  2. maxlen = 100
  3. config_path = './albert_base_zh/bert_config.json'
  4. checkpoint_path = './albert_base_zh/bert_model.ckpt'
  5. dict_path = './albert_base_zh/vocab.txt'
  6.  
  7. neg = pd.read_excel('datasets/neg.xls', header=None)
  8. pos = pd.read_excel('datasets/pos.xls', header=None)

构建字典并建立分词器

  1. # 字出现的次数
  2. chars = {}
  3. # 数据集
  4. data = []
  5.  
  6. for d in neg[0]:
  7. data.append((d, 0))
  8. for c in d:
  9. chars[c] = chars.get(c, 0) + 1
  10.  
  11. for d in pos[0]:
  12. data.append((d, 1))
  13. for c in d:
  14. chars[c] = chars.get(c, 0) + 1
  15.  
  16. # 保留出现次数大于 4 次的字
  17. chars = {i: j for i, j in chars.items() if j >= 4}
  18.  
  19. # 读取字典
  20. _token_dict = load_vocab(dict_path)
  21. # 构造字典
  22. # token_dict 里是存放的都是本任务里用得到的字
  23. # keep_words 存放的是索引
  24. token_dict, keep_words = {}, []
  25.  
  26. for c in ['[PAD]', '[UNK]', '[CLS]', '[SEP]', '[unused1]']:
  27. token_dict[c] = len(token_dict)
  28. keep_words.append(_token_dict[c])
  29.  
  30. for c in chars:
  31. if c in _token_dict:
  32. token_dict[c] = len(token_dict)
  33. keep_words.append(_token_dict[c])
  34.  
  35. tokenizer = SimpleTokenizer(token_dict) # 建立分词器

构建训练数据和测试数据

  1. if not os.path.exists('./random_order.json'):
  2. random_order = list(range(len(data)))
  3. np.random.shuffle(random_order)
  4. json.dump(
  5. random_order,
  6. open('./random_order.json', 'w'),
  7. indent=4
  8. )
  9. else:
  10. random_order = json.load(open('./random_order.json'))
  11.  
  12. # 按照9:1的比例划分训练集和验证集
  13. train_data = [data[j] for i, j in enumerate(random_order) if i % 10 != 0]
  14. valid_data = [data[j] for i, j in enumerate(random_order) if i % 10 == 0]
  15.  
  16. def seq_padding(X, padding=0):
  17. # 用 0 填充序列
  18. # 让所有输入序列长度一致
  19. L = [len(x) for x in X]
  20. ML = max(L)
  21. return np.array([
  22. np.concatenate([x, [padding] * (ML - len(x))]) if len(x) < ML else x for x in X
  23. ])
  24.  
  25. class data_generator:
  26. def __init__(self, data, batch_size=32):
  27. self.data = data
  28. self.batch_size = batch_size
  29. self.steps = len(self.data) // self.batch_size
  30. if len(self.data) % self.batch_size != 0:
  31. self.steps += 1
  32. def __len__(self):
  33. return self.steps
  34. def __iter__(self):
  35. while True:
  36. idxs = list(range(len(self.data)))
  37. np.random.shuffle(idxs)
  38. X1, X2, Y = [], [], []
  39. for i in idxs:
  40. d = self.data[i]
  41. text = d[0][:maxlen]
  42. # x1 是字对应的索引
  43. # x2 是句子对应的索引
  44. x1, x2 = tokenizer.encode(first=text)
  45. y = d[1]
  46. X1.append(x1)
  47. X2.append(x2)
  48. Y.append([y])
  49. if len(X1) == self.batch_size or i == idxs[-1]:
  50. X1 = seq_padding(X1)
  51. X2 = seq_padding(X2)
  52. Y = seq_padding(Y)
  53. yield [X1, X2], Y
  54. [X1, X2, Y] = [], [], []
  55.  
  56. train_D = data_generator(train_data)
  57. valid_D = data_generator(valid_data)

构建模型并训练

  1. from keras.layers import *
  2. from keras.models import Model
  3. import keras.backend as K
  4. from keras.optimizers import Adam
  5.  
  6. model = load_pretrained_model(
  7. config_path,
  8. checkpoint_path,
  9. keep_words=keep_words,
  10. albert=True
  11. )
  12.  
  13. output = Lambda(lambda x: x[:, 0])(model.output)
  14. output = Dense(1, activation='sigmoid')(output)
  15. model = Model(model.input, output)
  16.  
  17. model.compile(
  18. loss='binary_crossentropy',
  19. optimizer=Adam(1e-5), # 用足够小的学习率
  20. # optimizer=PiecewiseLinearLearningRate(Adam(1e-5), {1000: 1e-5, 2000: 6e-5}),
  21. metrics=['accuracy']
  22. )
  23. model.summary()
  24.  
  25. model.fit_generator(
  26. train_D.__iter__(),
  27. steps_per_epoch=len(train_D),
  28. epochs=10,
  29. validation_data=valid_D.__iter__(),
  30. validation_steps=len(valid_D)
  31. )

BERT实战——基于Keras的更多相关文章

  1. [深度应用]·首届中国心电智能大赛初赛开源Baseline(基于Keras val_acc: 0.88)

    [深度应用]·首届中国心电智能大赛初赛开源Baseline(基于Keras val_acc: 0.88) 个人主页--> https://xiaosongshine.github.io/ 项目g ...

  2. 《Selenium2自动化测试实战--基于Python语言》 --即将面市

    发展历程: <selenium_webdriver(python)第一版>   将本博客中的这个系列整理为pdf文档,免费. <selenium_webdriver(python)第 ...

  3. 【阿里云产品公测】云引擎ACE新手实战基于Wordpress

    [阿里云产品公测]云引擎ACE新手实战基于Wordpress 作者:阿里云用户imnpc ACE(Aliyun Cloud Engine) 是一款弹性.分布式的应用托管环境,支持Java.php多种语 ...

  4. Swift项目开发实战-基于分层架构的多版本iPhone计算器-直播公开课

    Swift项目开发实战-基于分层架构的多版本iPhone计算器-直播公开课 本课程采用Q Q群直播方式进行直播,价值99元视频课程免费直播.完整的基于Swift项目实战,手把手教你做一个Swift版i ...

  5. [AI开发]centOS7.5上基于keras/tensorflow深度学习环境搭建

    这篇文章详细介绍在centOS7.5上搭建基于keras/tensorflow的深度学习环境,该环境可用于实际生产.本人现在非常熟练linux(Ubuntu/centOS/openSUSE).wind ...

  6. 基于 Keras 用 LSTM 网络做时间序列预测

    目录 基于 Keras 用 LSTM 网络做时间序列预测 问题描述 长短记忆网络 LSTM 网络回归 LSTM 网络回归结合窗口法 基于时间步的 LSTM 网络回归 在批量训练之间保持 LSTM 的记 ...

  7. 基于 Keras 用深度学习预测时间序列

    目录 基于 Keras 用深度学习预测时间序列 问题描述 多层感知机回归 多层感知机回归结合"窗口法" 改进方向 扩展阅读 本文主要参考了 Jason Brownlee 的博文 T ...

  8. 关于《Selenium3自动化测试实战--基于python语言》

    2016年1月,机缘巧合下我出版了<Selenium2自动化测试实战--基于python语言>这本书,当时写书的原因是,大部分讲Selenium的书并不讲编程语言和单元测试框,如果想在项目 ...

  9. Bert实战---情感分类

    1.情感分析语料预处理 使用酒店评论语料,正面评论和负面评论各5000条,用BERT参数这么大的模型, 训练会产生严重过拟合,,泛化能力差的情况, 这也是我们下面需要解决的问题; 2.sigmoid二 ...

随机推荐

  1. 通过设置代理解决AndroidStudio无法下载gradle问题

    一.AndroidStudio代理 我们平时在使用android studio时,难免需要从android官网下载一些项目运行所需要的SDK文件,但是因为android官网在国外,访问起来会比较慢,所 ...

  2. linux安装 inotify

    [root@rsync-client-inotify ~]# yum install make gcc gcc-c++ [root@rsync-client-inotify ~]# wget http ...

  3. linux强制用户下线命令

    linux强制用户下线命令   前提:必须是root权限操作:(1)使用who查看目前有哪些用户登录了服务器,见下图(2)使用pkill -kill -t pts/1命令踢出第一个用户.命令解释:pt ...

  4. 基于双TMS320C6678+双XC6VSX315T的6U VPX高速数据处理平台

    基于双TMS320C6678+双XC6VSX315T的6U VPX高速数据处理平台   一.板卡概述 板卡由我公司自主研发,基于VPX架构,主体芯片为两片 TI DSP TMS320C6678,两片V ...

  5. MongoDb学习 自定义配置mongodb连接

    最近研究了mongodb获取本地连接属性的方案,场景就是mongodb的连接地址不在配置文件中配置,而是在代码中写好,代码中是从本地文件读取地址. public class MongoConfig { ...

  6. C++数组读入MATLAB数据

    data = rand(8, 10); fid = fopen('File.data', 'w'); if fid == - 1 error('Cannot open file for writing ...

  7. APP稳定性测试-monkey执行

    Monkey命令行可用的全部选项 *示例 : adb shell monkey -p cn.lejiayuan.alpha --pct-touch 30 --pct-motion 15 --pct-t ...

  8. Linux学习-DNS服务相关

    一.DNS服务简介 1.基本概念 (1) DNS( Domain Name System )域名系统,是一种组织成域层次结构的计算机和网络服务命名系统,是一个应用层协议,使用TCP与UDP的53端口, ...

  9. 本页面用来演示如何通过JS SDK,创建完整的QQ登录流程,并调用openapi接口

    QQ登录将用户信息存储在cookie中,命名为__qc__k ,请不要占用 __qc__k : 1) :: 在页面顶部引入JS SDK库: 将“js?”后面的appid参数(示例代码中的:100229 ...

  10. 【CF1243C】 Tile Painting【思维】

    题意:给定长度为n的方块,要求染色,需要满足:当|j-i|>1且n%|j-i|==0时,两格颜色相同,求做多可以染多少种颜色 题解:求出n的所有质因子 1.若只有一种质因子,则答案为该质因子 2 ...