bert中文分类模型训练+推理+部署

article/2025/10/29 15:27:46

文章预览:

    • 0. bert简介
    • 1. bert结构
    • 1. bert中文分类模型训练
      • 1 下载bert项目代码
        • 代码结构
      • 2 下载中文预训练模型
      • 3 制作中文训练数据集
    • 2. bert模型推理
      • 1.tensorflow推理
    • 2. onnxruntime推理
      • 1. checkpoint格式转换为saveModel格式
      • 2. saveModel格式转换为onnx格式
      • 3. 使用onnxruntime推理onnx格式模型


0. bert简介

  • BERT(Bidirectional Encoder Representation from Transformers)是google-research在2018年10月提出的一种预训练模型,在11种不同NLP测试中创出SOTA表现,成为NLP发展史上里程碑式的模型成就。
  • 本篇文章从实践入手,带领大家进行Bert的中文文本分类模型的训练和推理的使用教程。

1. bert结构

1. bert中文分类模型训练

bert训练主要分为两个阶段:预训练阶段和 Fine-tuning 阶段。

什么是预训练?
BERT是一个预训练的模型,那么什么是预训练呢?举例子进行简单的介绍
假设已有A训练集,先用A对网络进行预训练,在A任务上学会网络参数,然后保存以备后用,当来一个新的任务B,采取相同的网络结构,网络参数初始化的时候可以加载A学习好的参数,其他的高层参数随机初始化,之后用B任务的训练数据来训练网络,当加载的参数保持不变时,称为"frozen",当加载的参数随着B任务的训练进行不断的改变,称为“fine-tuning”,即更好地把参数进行调整使得更适合当前的B任务
优点:当任务B的训练数据较少时,很难很好的训练网络,但是获得了A训练的参数,会比仅仅使用B训练的参数更优

预训练
预训练阶段与 Word2Vec,ELMo 等类似,是在大型数据集上根据一些预训练任务训练得到。预训练需要巨大的运算资源,google官方预训练一个语言模型,需要在 4 到 16 个 Cloud TPU 训练四天的时间,幸运的是,google官方开源了许多预训练模型,包括中文预训练模型。大多数 NLP 研究人员永远不需要从头开始预训练他们自己的模型。

微调
Fine-tuning 阶段是后续用于一些下游任务的时候,在预训练模型基础之上进行微调,例如文本分类,词性标注,问答系统等,BERT 无需调整结构就可以在不同的任务上进行微调。


1 下载bert项目代码

https://github.com/google-research/bert

代码结构

  • 预训练
    在开源的代码中,预训练的入口是在run_pretraining.py。
  • 微调
    而微调的入口针对不同的任务分别在run_classifier.py和run_squad.py。
    其中run_classifier.py用于文本分类任务的训练。
    而run_squad.py用于阅读理解任务的训练。
    在这里插入图片描述

2 下载中文预训练模型

对于中文而言,google公布了一个参数较小的BERT预训练模型。

  • 模型下载地址
https://github.com/google-research/bert/blob/master/multilingual.md
  • 进入下载页面,选择:BERT-Base, Chinese进行下载。

在这里插入图片描述

  • 下载完成后,解压至与run_classifier.py同一级目录。

  • 模型文件说明
    在这里插入图片描述
    bert_model.ckpt:存储得模型变量
    vocab.txt:中文文本采用的字典,
    bert_config.json:是bert在训练时,可选调整的一些配置参数。


3 制作中文训练数据集

对中文文本数据进行分类模型的训练,需要编写程序对训练数据进行处理,使其按照要求传入bert模型进行训练,而BERT代码中processor类就是负责对模型的输入数据进行处理。

们以分类任务为例,介绍如何修改processor类来运行自己数据集上的fine-tune。在run_classsifier.py文件中我们可以看到,google对于一些公开数据集已经写了一些processor,如XnliProcessor,MnliProcessor,MrpcProcessor和ColaProcessor。这给我们提供了一个很好的示例,指导我们如何针对自己的数据集来写processor。

class kedataProcessor(DataProcessor):"""Processor for the XNLI data set."""def get_train_examples(self, data_dir):return self._create_examples(self._read_tsv(os.path.join(data_dir, "train.tsv")), "train")def get_dev_examples(self, data_dir):return self._create_examples(self._read_tsv(os.path.join(data_dir, "dev.tsv")), "dev")def get_test_examples(self, data_dir):return self._create_examples(self._read_tsv(os.path.join(data_dir, "test.tsv")), "test")def get_labels(self):# 这里返回的为具体的你的分类的类别labelf = open(FLAGS.data_dir+'\label.csv', 'r', newline='', encoding = 'gb2312')labeldata = csv.reader(labelf, delimiter="\t")labelList=[]for line in labeldata:label=line[1]labelList.append(label)return labelListdef _create_examples(self, lines, set_type):"""Creates examples for the training and dev sets."""examples = []for (i, line) in enumerate(lines):guid = "%s-%s" % (set_type, i)text_a = tokenization.convert_to_unicode(line[1])label = tokenization.convert_to_unicode(line[0])# print('guid:',guid," text:",text_a,' label:',label)examples.append(InputExample(guid=guid, text_a=text_a, text_b=None, label=label))return examples

自定义的processor里需要继承DataProcessor,并重载获取label的get_labels和获取单个输入的get_train_examples,get_dev_examples和get_test_examples函数。其分别会在main函数的FLAGS.do_train、FLAGS.do_eval和FLAGS.do_predict阶段被调用。
这三个函数的内容是相差无几的,区别只在于需要指定各自读入文件的地址。

以get_train_examples为例,函数需要返回一个由InputExample类组成的list。InputExample类是一个很简单的类,只有初始化函数,需要传入的参数中guid是用来区分每个example的,可以按照train-%d’%(i)的方式进行定义。text_a是一串字符串,text_b则是另一串字符串。在进行后续输入处理后(BERT代码中已包含,不需要自己完成) text_a和text_b将组合成[CLS] text_a [SEP] text_b [SEP]的形式传入模型。最后一个参数label也是字符串的形式,label的内容需要保证出现在get_labels函数返回的list里。

举一个例子,假设我们想要处理一个能够判断句子相似度的模型,现在在data_dir的路径下有一个名为train.csv的输入文件,如果我们现在输入文件的格式如下csv形式:

肯定	嗯,对,是。
求职状态_已找到工作	呃,我有工作了谢谢。
中性	哦,你您说吧。
询问岗位地址	嗯那,那你们就是上班的话,是就近安排吗,我看有很多你们那个
肯定	在听得见我说话吗。
中性	啊,你说你说。
智能助理	的用户暂时无法接听你的电话,短信通知请挂机语音留言,请按一如需人工帮助,请按零
没听清什么事	干啥呀什么事情?
在忙	哦,等会我现在在去面试的路上。
否定	嗯,现在没有了,不好意思啊。

label.csv

0	打错了	226
1	打过电话	127
2	拒绝来电	177
3	电话号码获取	19
4	反问听见与否	55
5	非机主	285
6	否定	4477
7	福利_其他	15
8	福利_食宿	47
9	福利_五险一金	83
10	岗位_年龄要求	58

修改processor字典
修改完成processor后,需要在在原本main函数的processor字典里,加入修改后的processor类,即可在运行参数里指定调用该processor。

processors = {"cola": ColaProcessor,"mnli": MnliProcessor,"mrpc": MrpcProcessor,"xnli": XnliProcessor,"kedata": kedataProcessor,}

运行run_classifier.py
之后就可以直接运行run_classsifier.py进行模型的训练。在运行时需要制定一些参数,一个较为完整的运行参数如下所示:

BERT_BASE_DIR=/path/to/bert/chinese_L-12_H-768_A-12 #全局变量 下载的预训练bert地址
MY_DATASET=/path/to/kedata #全局变量 数据集所在地址python run_classifier.py \--task_name=kedata \ #自己添加processor在processors字典里的key名--do_train=true \--do_eval=true \--dopredict=true \--data_dir=$MY_DATASET \--vocab_file=$BERT_BASE_DIR/vocab.txt \--bert_config_file=$BERT_BASE_DIR/bert_config.json \--init_checkpoint=$BERT_BASE_DIR/bert_model.ckpt \--max_seq_length=128 \ #模型参数--train_batch_size=32 \--learning_rate=5e-5 \--num_train_epochs=2.0 \--output_dir=/tmp/selfsim_output/ #模型输出路径

2. bert模型推理

1.tensorflow推理

在这里插入图片描述

  • 问题:
    用Estimater.predict总是把模型重新load一遍,这样工程业务根本没法用。
  • 解决方案:
  1. 使用python的生成器,让程序“误以为”有很多序列需要预测,这里构造yield形式即可;
  2. 利用tf.data.Dataset.from_generator,加载生成器,声明好数据结构和类型;
  3. 利用class类的实例变量self的全局性,通过self.inputs把数据“喂给到”生成器内部,这样就保证了数据的“源源不断”;
  4. 程序需要close的机制,用于保证停掉生成器的工作。
from tokenization import FullTokenizer, validate_case_matches_checkpoint
from modeling import BertConfig
from run_classifier import model_fn_builder
import tensorflow as tf
from tensorflow.python.estimator.estimator import Estimator
from tensorflow.python.estimator.run_config import RunConfig
from run_classifier import FLAGS,InputExample,convert_single_example
import csv
import os
import numpy as npclass model(object):def __init__(self, labelfile,vocabfile,bert_config_file,init_checkpoint,ckptdir,max_seq_length):self.label = self.loadLabel(labelfile)self.closed = Falseself.first_run = Trueself.bert_config_file=bert_config_fileself.ckptdir=ckptdirself.tokenizer = FullTokenizer(vocab_file=vocabfile,do_lower_case=True)self.init_checkpoint = init_checkpointself.seq_length = max_seq_lengthself.text = Noneself.num_examples = Noneself.predictions = Noneself.estimator = self.get_estimator()def loadLabel(sel, labelfile):labelf = open(labelfile, 'r', newline='', encoding='gbk')labeldata = csv.reader(labelf, delimiter="\t")labelList = []for line in labeldata:label = line[1]labelList.append(label)return labelListdef get_estimator(self):validate_case_matches_checkpoint(True, self.init_checkpoint)bert_config = BertConfig.from_json_file(self.bert_config_file)  # 载入bert自定义配置if FLAGS.max_seq_length > bert_config.max_position_embeddings:  # 验证配置信息准确性raise ValueError("Cannot use sequence length %d because the BERT pre_model ""was only trained up to sequence length %d" %(self.seq_length, bert_config.max_position_embeddings))run_config = RunConfig(model_dir=self.ckptdir,save_checkpoints_steps=FLAGS.save_checkpoints_steps,session_config=None)model_fn = model_fn_builder(  # 估计器函数,提供Estimator使用的model_fn,内部使用EstimatorSpec构建的bert_config=bert_config,num_labels=len(self.label),init_checkpoint=self.init_checkpoint,learning_rate=FLAGS.learning_rate,num_train_steps=0,num_warmup_steps=0,use_tpu=FLAGS.use_tpu,use_one_hot_embeddings=FLAGS.use_tpu)estimator = Estimator(  # 实例化估计器model_fn=model_fn,config=run_config,warm_start_from=self.init_checkpoint  # 新增预热)return estimatordef get_feature(self, index, text):example = InputExample(f"text_{index}", text, None, self.label[0])feature = convert_single_example(index, example, self.label, self.seq_length, self.tokenizer)return feature.input_ids, feature.input_mask, feature.segment_ids, feature.label_iddef create_generator(self):"""构建生成器"""while not self.closed:self.num_examples = len(self.text)features = (self.get_feature(*f) for f in enumerate(self.text))yield dict(zip(("input_ids", "input_mask", "segment_ids", "label_ids"), zip(*features)))def input_fn_builder(self):"""用于预测单独对预测数据进行创建,不基于文件数据"""dataset = tf.data.Dataset.from_generator(self.create_generator,output_types={'input_ids': tf.int32,'input_mask': tf.int32,'segment_ids': tf.int32,'label_ids': tf.int32},output_shapes={'label_ids': (None),'input_ids': (None, None),'input_mask': (None, None),'segment_ids': (None, None)})return datasetdef predict(self, text):self.text = textif self.first_run:self.predictions = self.estimator.predict(input_fn=self.input_fn_builder, yield_single_examples=True)self.first_run = Falseprobabilities = next(self.predictions)# 获取最大值索引index = np.argmax(probabilities["probabilities"])label = self.label[index]# return [self.label[i] for i in probabilities["probabilities"].argmax(axis=1)]return labeldef close(self):self.closed = True
pythonfile=os.path.realpath(os.path.realpath(__file__))
pardir=os.path.abspath(os.path.join(pythonfile,os.path.pardir))
labelfile=os.path.join(pardir,'ckpt/label.csv')
init_checkpoint=os.path.join(pardir,'chinese_L-12_H-768_A-12/bert_model.ckpt')
vocabfile=os.path.join(pardir,'chinese_L-12_H-768_A-12/vocab.txt')
bert_config_file=os.path.join(pardir,'chinese_L-12_H-768_A-12/bert_config.json')
ckptdir=os.path.join(pardir,'ckpt/')
max_seq_length=128
def getModel():bert = model(labelfile,vocabfile,bert_config_file,init_checkpoint,ckptdir,max_seq_length)bert.predict([""])return bertif __name__=="__main__":bert=getModel()for i in range(1000):label=bert.predict(["打错了"])

2. onnxruntime推理

ONNX Runtime是一个高性能的机器学习模型推理引擎。它与PyTorch、TensorFlow以及许多其他支持ONNX标准的框架和工具兼容。ONNX Runtime设计了一个开放和可扩展的体系结构,通过利用内置的图形优化和跨CPU、GPU和边缘设备的各种硬件加速功能,可以轻松地优化和加速推理。ONNX Runtime可以很容易地插入到你的技术堆栈中,因为它可以在Linux、Windows、Mac和Android上工作,并且为Python、c#、c++、C和Java提供了方便的api。

为加快bert的推理时间,部署到服务器上,可食用onnxruntime进行推理加速。

1. checkpoint格式转换为saveModel格式

在这里插入图片描述

from tokenization import FullTokenizer, validate_case_matches_checkpoint
from modeling import BertConfig
from run_classifier import model_fn_builder
import tensorflow as tf
from tensorflow.python.estimator.estimator import Estimator
from tensorflow.python.estimator.run_config import RunConfig
from run_classifier import FLAGS
import csvclass Fast(object):def __init__(self, labelfile,vocabfile,bert_config_file,init_checkpoint,ckptdir):self.label = self.loadLabel(labelfile)self.closed = Falseself.first_run = Trueself.bert_config_file=bert_config_fileself.ckptdir=ckptdirself.tokenizer = FullTokenizer(vocab_file=vocabfile,do_lower_case=True)self.init_checkpoint = init_checkpoint# self.seq_length = FLAGS.max_seq_lengthself.seq_length = 128self.text = Noneself.num_examples = Noneself.predictions = Noneself.estimator = self.get_estimator()def loadLabel(sel, labelfile):labelf = open(labelfile, 'r', newline='', encoding='gbk')labeldata = csv.reader(labelf, delimiter="\t")labelList = []# for i in range(60):#    labelList.append(i)for line in labeldata:label = line[1]labelList.append(label)return labelListdef get_estimator(self):validate_case_matches_checkpoint(True, self.init_checkpoint)print("FLAGS.bert_config_file:",FLAGS.bert_config_file)bert_config = BertConfig.from_json_file(self.bert_config_file)  # 载入bert自定义配置if FLAGS.max_seq_length > bert_config.max_position_embeddings:  # 验证配置信息准确性raise ValueError("Cannot use sequence length %d because the BERT pre_model ""was only trained up to sequence length %d" %(self.seq_length, bert_config.max_position_embeddings))print("FLAGS.save_checkpoints_steps:",FLAGS.save_checkpoints_steps)run_config = RunConfig(model_dir=self.ckptdir,save_checkpoints_steps=FLAGS.save_checkpoints_steps,session_config=None)model_fn = model_fn_builder(  # 估计器函数,提供Estimator使用的model_fn,内部使用EstimatorSpec构建的bert_config=bert_config,num_labels=len(self.label),init_checkpoint=self.init_checkpoint,learning_rate=FLAGS.learning_rate,num_train_steps=0,num_warmup_steps=0,use_tpu=FLAGS.use_tpu,use_one_hot_embeddings=FLAGS.use_tpu)print("model_fn:",model_fn)estimator = Estimator(  # 实例化估计器model_fn=model_fn,config=run_config,warm_start_from=self.init_checkpoint  # 新增预热)print("estimator.params:",estimator.params)print("estimator:",estimator)return estimatordef serving_input_fn(self):receiver_tensors = {'input_ids': tf.compat.v1.placeholder(dtype=tf.int64, shape=[None, self.seq_length], name='input_ids'),'input_mask': tf.compat.v1.placeholder(dtype=tf.int64, shape=[None, self.seq_length], name='input_mask'),'segment_ids': tf.compat.v1.placeholder(dtype=tf.int64, shape=[None, self.seq_length], name='segment_ids'),'label_ids': tf.compat.v1.placeholder(dtype=tf.int64, shape=[None], name="label_ids")}return tf.estimator.export.ServingInputReceiver(features= receiver_tensors ,receiver_tensors=receiver_tensors)def transModel(self):self.estimator.export_saved_model('./savemodel',self.serving_input_fn)labelfile='./ckpt/label.csv'
init_checkpoint='./chinese_L-12_H-768_A-12/bert_model.ckpt'
vocabfile='./chinese_L-12_H-768_A-12/vocab.txt'
bert_config_file='./chinese_L-12_H-768_A-12/bert_config.json'
ckptdir='./ckpt/'
model = Fast(labelfile,vocabfile,bert_config_file,init_checkpoint,ckptdir)
model.transModel()

2. saveModel格式转换为onnx格式

import ospbdir="1631247382"
onnxname="model.onnx"
cmdstr="python -m tf2onnx.convert --saved-model ./savemodel/{pbdir} --output ./onnx/{onnxname}".format(pbdir=pbdir,onnxname=onnxname)os.system(cmdstr)

3. 使用onnxruntime推理onnx格式模型

在这里插入图片描述

import onnxruntime as ort
from tokenization import FullTokenizer
from run_classifier import convert_single_example
from run_classifier import InputExample
import time
import numpy as np
import csvimport osclass model(object):def __init__(self, vocab_file,labelfile,modelfile,max_seq_length):self.closed = Falseself.first_run = Trueself.tokenizer = FullTokenizer(vocab_file=vocab_file,do_lower_case=True)self.seq_length = max_seq_lengthself.label = self.loadLabel(labelfile)so = ort.SessionOptions()#so.execution_mode = ort.ExecutionMode.ORT_SEQUENTIAL# so.execution_mode = ort.ExecutionMode.ORT_PARALLELso.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL#self.model = ort.InferenceSession(modelfile,sess_options=so,providers=['CPUExecutionProvider'])self.model = ort.InferenceSession(modelfile,sess_options=so,providers=['CUDAExecutionProvider'])#self.model.set_providers(['CUDAExecutionProvider'], [{'device_id': device_id,"gpu_mem_limit" :  3  *  1024  *  1024  *  1024}])# self.model.set_providers(['CUDAExecutionProvider'], [{'device_id': device_id }])def loadLabel(sel,labelfile):labelf = open(labelfile, 'r', newline='',encoding='gbk')labeldata = csv.reader(labelf, delimiter="\t")labelList = []#for i in range(60):#    labelList.append(i)for line in labeldata:label = line[1]labelList.append(label)return labelListdef get_feature(self, index, text):example = InputExample(f"text_{index}", text, None, self.label[0])feature = convert_single_example(index, example, self.label, self.seq_length, self.tokenizer)return feature.input_ids, feature.input_mask, feature.segment_ids, feature.label_iddef predict(self, text):dataList=[]input_ids_L=[]input_mask_L=[]segment_ids_L=[]label_ids_L=[]for i in range(len(text)):input_ids,input_mask,segment_ids,label_ids=self.get_feature(i,text[i])input_ids_L.append(input_ids)input_mask_L.append(input_mask)segment_ids_L.append(segment_ids)label_ids_L.append(label_ids)data = {"input_ids:0": np.array(input_ids_L, dtype=np.int64),"input_mask:0": np.array(input_mask_L, dtype=np.int64),"label_ids:0": np.array(label_ids_L, dtype=np.int64),"segment_ids:0": np.array(segment_ids_L, dtype=np.int64)}dataList.append(data)result = self.model.run(output_names=["loss/Softmax:0"], input_feed=data)label_l=[]for i in range(len(text)):# 获取最大值索引maxProbabilities=max(result[0][i])index=np.argmax(result[0][i])label=self.label[index]item={"label":label,"score":maxProbabilities}label_l.append(label)return label_lpythonfile=os.path.realpath(os.path.realpath(__file__))
pardir=os.path.abspath(os.path.join(pythonfile,os.path.pardir))
datadir=os.path.join(pardir,'zhaopin')labelfile=os.path.join(datadir,'label.csv')
modelfile=os.path.join(datadir,'model.onnx')
vocabfile=os.path.join(pardir,'vocab.txt')
max_seq_length=128def getModel():bert = model(vocabfile,labelfile,modelfile ,max_seq_length)return bertif __name__=="__main__":bert=getModel()for i in range(1000):time1=time.time()bert.predict(["已经打过电话了"])

http://chatgpt.dhexx.cn/article/wDExniTO.shtml

相关文章

Bert模型详解和训练实例

前面已经介绍了transformer,理解了transformer,那么理解bert就简单多了。对transformer不是很了解的可以跳转到https://blog.csdn.net/one_super_dreamer/article/details/105181690 bert的核心代码解读在https://blog.csdn.net/one_super_dreamer/arti…

无监督模型 训练过程_监督使用训练模型

无监督模型 训练过程 Machine Learning, Artificial Intelligence, and Deep Learning are some of the most complex, yet highly demanded fields of expertise today. There are innumerable resources and tools to work in these fields, and one such popular tool is Su…

Tensorflow V2 图像识别模型训练流程

Tensorflow V2.0 图像识别教程 代码: https://github.com/dwSun/classification-tutorial.git 教程参考官方专家高级教程: https://tensorflow.google.cn/tutorials/quickstart/advanced?hlen 这里以 TinyMind 《汉字书法识别》比赛数据为例&#xf…

(三)mmclassification图像分类——模型训练

(三)mmclassification图像分类——模型训练和测试 1.模型训练1.1使用预训练模型1.2使用自己的数据训练1.2.1制作数据集1.2.2修改模型参数(configs文件)(1)models(2)datasets(3)schedules(4)新建mobilenet_v2_b32x8_car.py 1.3训练…

tensorflow CNN模型训练+优化参数+实战

训练线性函数 import numpy as np import tensorflow.keras as keras # 构建模型 model keras.Sequential([keras.layers.Dense(units1,input_shape[1])]) # optimizer优化,loss损失 model.compile(optimizersgd, lossmean_squared_error) #准备训练数据 xsnp.ar…

nanodet训练手势识别模型

序言 前段时间nanodet爆火,以非常小的模型和运算量,取得了超过tiny-yolov4的精度,非常惊艳,因为时间问题一直没有尝试,最近有空决定尝试一下。先来看下作者给的模型效果 一、nanodet安装 首先安装nanodet的环境包…

Pytorch教程[10]完整模型训练套路

一般的模型构建都是按照下图这样的流程 下面分享一个自己手动搭建的网络 from model import * import torchvision import torch from torch.utils.tensorboard import SummaryWriter from torchvision import transforms from torch import nn from torch.utils.data import …

PaddleOCR学习(二)PaddleOCR检测模型训练

这一部分主要介绍,如何使用自己的数据库去训练PaddleOCR的文本检测模型。 官方教程https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_ch/detection.md 一、准备训练数据 首先你需要有自己的数据,如果没有自己的数据,推荐使…

迁移学习的模型训练

用深度学习解决目标检测有两个重要工作: 1、设计、实现、训练和验证模型 模型如果设计模型如何编程实现如何收集足够的数据来训练并验证模型是否符合预期 从头开始设计、实现、训练和验证模型是需要有众多深度学习算法人才做支撑,并且极其耗时耗力 2、…

TF2.0模型训练

TF2.0模型训练 概述数据集介绍1、通过fit方法训练模型准备数据创建模型编译模型训练模型 2、通过fit_generator方法训练模型构建生成器创建模型编译模型训练模型 3、自定义训练准备数据创建模型定义损失函数及优化器训练模型 下一篇TF2.0模型保存 概述 这是TF2.0入门笔记【TF2…

TensorFlow 2.0 —— 模型训练

目录 1、Keras版本模型训练1.1 构造模型(顺序模型、函数式模型、子类模型)1.2 模型训练:model.fit()1.3 模型验证:model.evaluate()1.4 模型预测:model.predict()1.5 使用样本加权和类别加权1.6 回调函数1.6.1 EarlySt…

如何在jupyter上运行Java代码(适用LINUX)

如何在jupyter上运行Java代码 1.下载必须软件 下载JDK且JDK版本必须 ≥ 9 ≥9 ≥9从github上下载ijava 附 : ijava下载链接.装有jupyter,我在LINUX上是直接装的anaconda 安装过程 将下载的ijava压缩包解压出来,并在此路径用该命令 : sudo…

Java单元测试介绍

文章目录 单元测试单元测试基本介绍单元测试快速入门单元测试常用注解 单元测试 单元测试基本介绍 单元测试: 单元测试就是针对最小的功能单元编写测试代码,Java程序最小的功能单元是方法,因此,单元测试就是针对Java方法的测试,…

Jupyter 配置 Java环境,写Java代码,测试成功

本次简单诉说下怎么通过jupyter安装iJava,写Java代码。 安装Java的不说了 我使用的是Java15 然后去:https://github.com/SpencerPark/IJava/releases 下载zip,不要下载其他的 得到就是一个py文件 下面就是一个 python install.py 我这里就…

java调用python执行脚本,附代码

最近有个功能需要java调用python脚本实现一些功能,前期需要做好的准备:配置好python环境,如下: 以下展示的为两种,一种为生成图片,另一种为生成字符串。 package com.msdw.tms.common.utils.py;import ja…

Selenium Java自动化测试环境搭建

IDE用的是Eclipse。 步骤1:因为是基于Java,所以首先要下载与安装JDK(Java Development Kit) 下载: 点击这里下载JDK 安装:按照默认安装一路点next就可以了。 验证:安装完成后,在命…

java单元测试(Junit)

相关代码下载链接: http://download.csdn.net/detail/stevenhu_223/4884357 在有些时候,我们需要对我们自己编写的代码进行单元测试(好处是,减少后期维护的精力和费用),这是一些最基本的模块测试。当然&…

Java单元测试工具:JUnit4(一)——概述及简单例子

(一)JUnit概述及一个简单例子 看了慕课网的JUnit视频教程: http://www.imooc.com/learn/356,总结笔记。 这篇笔记记录JUnit的概述,以及一个快速入门的例子。 1.概述 1.1 什么是JUnit ①JUnit是用于编写可复用测试集的…

Linux下执行Python脚本

1.Linux Python环境 Linux系统一般集成Python,如果没有安装,可以手动安装,联网状态下可直接安装。Fedora下使用yum install,Ubuntu下使用apt-get install,前提都是root权限。安装完毕,可将Python加入环境变…

python pytest脚本执行工具

pytest脚本执行工具 支持获取当前路径下所有.py脚本 添加多个脚本,一起执行 import tkinter as tk from tkinter import filedialog import subprocess import os from datetime import datetimedef select_script():script_path filedialog.askopenfilename(fil…