模型训练日志,刷屏使我痛苦,由此呢研发了VLog(附源码)
<a style="color: black;"><span style="color: black;"><img src="https://mmbiz.qpic.cn/mmbiz_gif/QWAZ7Ok6ecxlg4UicZFDZtejx9tbsaBteIhLotBAZb5WsBvo5jh6KnQe2Cjic2HxIMEib18dibIXoI7hgSQEfTC7FQ/640?wx_fmt=gif&wxfrom=5&wx_lazy=1&tp=webp" style="width: 50%; margin-bottom: 20px;"></span></a><p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">以下<span style="color: black;">文案</span><span style="color: black;">源自</span>于<span style="color: black;">微X</span>公众号:<span style="color: black;">算法美食屋</span></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">作者:<span style="color: black;"><span style="color: black;">梁云1991</span></span></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">链接:</span><span style="color: black;">https://mp.weixin.qq.com/s/KtXsPjmWhOpylO1EDdM7Fg</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">本文仅用于学术分享,如有侵权,请联系后台作删文处理</span></p><img src="https://mmbiz.qpic.cn/mmbiz_gif/Ljib4So7yuWhPmGHfBz7vlEFLwDwiaiaQoCQ1iaUGFFpV3z4Qq9uTTh0gibzDT52BKUwfAM5Kf2jsDpKRmuQuO2asXQ/640?wx_fmt=gif&wxfrom=5&wx_lazy=1&tp=webp" style="width: 50%; margin-bottom: 20px;"><strong style="color: blue;"><span style="color: black;">导读</span></strong>在模型训练过程中,常常会打印<span style="color: black;">每一个</span>epoch训练的日志,令人眼花缭乱。本文<span style="color: black;">运用</span>torchkeras库中的VLog,分别<span style="color: black;">仔细</span>的演示了在LightGBM、ultralytics、transformers中<span style="color: black;">运用</span>VLog,并<span style="color: black;">供给</span>了源码,<span style="color: black;">期盼</span>对<span style="color: black;">大众</span>有<span style="color: black;">帮忙</span>。<span style="color: black;">训练日志刷屏使我痛苦,我<span style="color: black;">研发</span>了VLog,<span style="color: black;">能够</span>在任意训练代码中<span style="color: black;">容易</span><span style="color: black;">运用</span>~</span><span style="color: black;">例如,<span style="color: black;">经过</span>callback嵌入到lightgbm/catboost/transformers/ultralytics,乃至keras库的训练代码流程中~</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">before</strong>:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/4WgILHBwVH8XJIyFWnENYfuRE1ianebUlpwZwbtklhw2jJicuLyvkiaz6GTn0dfNR6xuIdbaEsh3OPjgGwVL9KoeQ/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">after</strong>:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_gif/4WgILHBwVH8XJIyFWnENYfuRE1ianebUlPicLe3dSXkVMxX9xFDnt03MuYwnibYFYBU60O3gT0Ry85pNOWU8D57cw/640?wx_fmt=gif&tp=webp&wxfrom=5&wx_lazy=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;"><span style="color: black;">为何</span><span style="color: black;">不消</span>tensorboard<span style="color: black;">或</span>wandb?</strong></p><span style="color: black;">tensorboard需要开端口权限,服务器<span style="color: black;">研发</span>环境有时候<span style="color: black;">无</span>端口权限~</span><span style="color: black;">wandb需要联网,有时候网速很差<span style="color: black;">或</span><span style="color: black;">无</span>网,影响体验~</span><span style="color: black;">综合对比<span style="color: black;">思虑</span>如下表</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/4WgILHBwVH8XJIyFWnENYfuRE1ianebUlxwtOAaCtVjmPLwHOM1Eh9uSUXKYBhvDLMuegiblOL1oy3sFZRhu7vYg/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">一,VLog基本原理</span></h2><span style="color: black;">VLog类<span style="color: black;">重点</span>有以下5个<span style="color: black;">办法</span>。</span><span style="color: black;">from</span> torchkeras <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> VLog</p><span style="color: black;">#1, 初始化<span style="color: black;">办法</span></span>vlog = VLog(epochs=<span style="color: black;">20</span>, monitor_metric=<span style="color: black;">val_loss</span>, monitor_mode=<span style="color: black;">min</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">) </p><span style="color: black;">#2, <span style="color: black;">表示</span><span style="color: black;">起始</span>空图表</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">vlog.log_start()</p><span style="color: black;">#3, 更新step级别日志</span>vlog.log_step({<span style="color: black;">train_loss</span>:<span style="color: black;">0.003</span>,<span style="color: black;">val_loss</span>:<span style="color: black;">0.002</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">}) </p><span style="color: black;">#4, 更新epoch级别日志</span>vlog.log_epoch({<span style="color: black;">train_acc</span>:<span style="color: black;">0.9</span>,<span style="color: black;">val_acc</span>:<span style="color: black;">0.87</span>,<span style="color: black;">train_loss</span>:<span style="color: black;">0.002</span>,<span style="color: black;">val_loss</span>:<span style="color: black;">0.03</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">})</p><span style="color: black;">#5, 输出<span style="color: black;">最后</span>稳定状态图表</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">vlog.log_end()</p><span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> time</p><span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> math,random</p><span style="color: black;">from</span> torchkeras <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> VLog</p>epochs = <span style="color: black;">10</span>batchs = <span style="color: black;">30</span><span style="color: black;">#0, 指定监控北极星指标,以及指标优化方向</span>vlog = VLog(epochs, monitor_metric=<span style="color: black;">val_loss</span>, monitor_mode=<span style="color: black;">min</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">) </p><span style="color: black;">#1, log_start 初始化动态图表</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">vlog.log_start() </p><span style="color: black;">for</span> epoch <span style="color: black;">in</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> range(epochs):</p> <span style="color: black;">#train</span> <span style="color: black;">for</span> step <span style="color: black;">in</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> range(batchs):</p> <span style="color: black;">#2, log_step 更新step级别日志信息,打日志,并用小进度条<span style="color: black;">表示</span>进度</span> vlog.log_step({<span style="color: black;">train_loss</span>:<span style="color: black;">100-2.5</span>*epoch+math.sin(<span style="color: black;">2</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">*step/batchs)}) </p> time.sleep(<span style="color: black;">0.05</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p> <span style="color: black;">#eval </span> <span style="color: black;">for</span> step <span style="color: black;">in</span> range(<span style="color: black;">20</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">):</p> <span style="color: black;">#3, log_step 更新step级别日志信息,指定training=False说明在验证模式,只打日志不更新小进度条</span> vlog.log_step({<span style="color: black;">val_loss</span>:<span style="color: black;">100-2</span>*epoch+math.sin(<span style="color: black;">2</span>*step/batchs)},training=<span style="color: black;">False</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p> time.sleep(<span style="color: black;">0.05</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p> <span style="color: black;">#4, log_epoch 更新epoch级别日志信息,<span style="color: black;">每一个</span>epoch刷新一次动态图表和大进度条进度</span> vlog.log_epoch({<span style="color: black;">val_loss</span>:<span style="color: black;">100</span> - <span style="color: black;">2</span>*epoch+<span style="color: black;">2</span>*random.random()<span style="color: black;">-1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">train_loss</span>:<span style="color: black;">100-2.5</span>*epoch+<span style="color: black;">2</span>*random.random()<span style="color: black;">-1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">}) </p><span style="color: black;"># 5, log_end <span style="color: black;">调节</span>坐标轴范围,输出<span style="color: black;">最后</span>指标可视化图表</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">vlog.log_end()</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/4WgILHBwVH8XJIyFWnENYfuRE1ianebUlPXFibxtud3EEARtF2H8coZt6iafaOgHYcGKskOHURSUgNoWLayMBSiaug/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">二,在LightGBM中<span style="color: black;">运用</span>VLog</span></h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">设计一个简单的回调,就<span style="color: black;">能够</span>搞定~</span></p><span style="color: black;">from</span> torchkeras <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> VLog</p><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">VLogCallback</span>:</span> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__init__</span><span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(self, num_boost_round, </p> monitor_metric=<span style="color: black;">val_loss</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> monitor_mode=<span style="color: black;">min</span>)
</span>:</span> self.order = <span style="color: black;">20</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> self.num_boost_round = num_boost_round</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">self.vlog = VLog(epochs = num_boost_round, monitor_metric = monitor_metric,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> monitor_mode = monitor_mode)</p> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__call__</span><span style="color: black;">(self, env)</span> -> <span style="color: black;">None</span>:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> metrics = {}</p> <span style="color: black;">for</span> item <span style="color: black;">in</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> env.evaluation_result_list:</p> <span style="color: black;">if</span> len(item) == <span style="color: black;">4</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:</p>data_name, eval_name, result = item[:<span style="color: black;">3</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">]</p> metrics[data_name+<span style="color: black;">_</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">+eval_name] = result</p> <span style="color: black;">else</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:</p> data_name, eval_name = item[<span style="color: black;">1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">].split()</p> res_mean = item[<span style="color: black;">2</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">]</p> res_stdv = item[<span style="color: black;">4</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">]</p> metrics[data_name+<span style="color: black;">_</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">+eval_name] = res_mean</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> self.vlog.log_epoch(metrics)</p><span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> datetime</p><span style="color: black;">import</span> numpy <span style="color: black;">as</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> np</p><span style="color: black;">import</span> pandas <span style="color: black;">as</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> pd</p><span style="color: black;">import</span> lightgbm <span style="color: black;">as</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> lgb</p><span style="color: black;">from</span> sklearn <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> datasets</p><span style="color: black;">from</span>sklearn.model_selection<span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> train_test_split</p><span style="color: black;">from</span> sklearn.metrics <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> accuracy_score</p><span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">printlog</span><span style="color: black;">(info)</span>:</span> nowtime = datetime.datetime.now().strftime(<span style="color: black;">%Y-%m-%d %H:%M:%S</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p> print(<span style="color: black;">"\n"</span>+<span style="color: black;">"=========="</span>*<span style="color: black;">8</span> + <span style="color: black;">"%s"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">%nowtime)</p> print(info+<span style="color: black;">...\n\n</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p><span style="color: black;">#================================================================================</span><span style="color: black;"># 一,读取数据</span><span style="color: black;">#================================================================================</span>printlog(<span style="color: black;">"step1: reading data..."</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p><span style="color: black;"># 读取dftrain,dftest</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">breast = datasets.load_breast_cancer()</p>df = pd.DataFrame(breast.data,columns = [x.replace(,<span style="color: black;">_</span>) <span style="color: black;">for</span> x <span style="color: black;">in</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> breast.feature_names])</p>df[<span style="color: black;">label</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">] = breast.target</p>df[<span style="color: black;">mean_radius</span>] = df[<span style="color: black;">mean_radius</span>].apply(<span style="color: black;">lambda</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> x:int(x))</p>df[<span style="color: black;">mean_texture</span>] = df[<span style="color: black;">mean_texture</span>].apply(<span style="color: black;">lambda</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> x:int(x))</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">dftrain,dftest = train_test_split(df)</p>categorical_features = [<span style="color: black;">mean_radius</span>,<span style="color: black;">mean_texture</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">]</p>lgb_train = lgb.Dataset(dftrain.drop([<span style="color: black;">label</span>],axis = <span style="color: black;">1</span>),label=dftrain[<span style="color: black;">label</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">],</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> categorical_feature = categorical_features)</p>lgb_valid = lgb.Dataset(dftest.drop([<span style="color: black;">label</span>],axis = <span style="color: black;">1</span>),label=dftest[<span style="color: black;">label</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">],</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> categorical_feature = categorical_features,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> reference=lgb_train)</p><span style="color: black;">#================================================================================</span><span style="color: black;"># 二,设置参数</span><span style="color: black;">#================================================================================</span>printlog(<span style="color: black;">"step2: setting parameters..."</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>boost_round = <span style="color: black;">50</span>early_stop_rounds = <span style="color: black;">10</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">params = {</p> <span style="color: black;">boosting_type</span>: <span style="color: black;">gbdt</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">objective</span>:<span style="color: black;">binary</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">metric</span>: [<span style="color: black;">auc</span>], <span style="color: black;">#l2</span> <span style="color: black;">num_leaves</span>:<span style="color: black;">15</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">, </p> <span style="color: black;">learning_rate</span>: <span style="color: black;">0.05</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">feature_fraction</span>: <span style="color: black;">0.9</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">bagging_fraction</span>: <span style="color: black;">0.8</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">bagging_freq</span>: <span style="color: black;">5</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">verbose</span>: <span style="color: black;">0</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">early_stopping_round</span>:<span style="color: black;">5</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">}</p><span style="color: black;">#================================================================================</span><span style="color: black;"># 三,训练模型</span><span style="color: black;">#================================================================================</span>printlog(<span style="color: black;">"step3: training model..."</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">result = {}</p>vlog_cb = VLogCallback(boost_round, monitor_metric = <span style="color: black;">val_auc</span>, monitor_mode = <span style="color: black;">max</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">vlog_cb.vlog.log_start()</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">gbm = lgb.train(params,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> lgb_train,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> num_boost_round= boost_round,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> valid_sets=(lgb_valid, lgb_train),</p> valid_names=(<span style="color: black;">val</span>,<span style="color: black;">train</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">),</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> callbacks = [lgb.record_evaluation(result),</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">vlog_cb]</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> )</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">vlog_cb.vlog.log_end()</p><span style="color: black;">#================================================================================</span><span style="color: black;"># 四,<span style="color: black;">评定</span>模型</span><span style="color: black;">#================================================================================</span>printlog(<span style="color: black;">"step4: evaluating model ..."</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>y_pred_train = gbm.predict(dftrain.drop(<span style="color: black;">label</span>,axis = <span style="color: black;">1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">), num_iteration=gbm.best_iteration)</p>y_pred_test = gbm.predict(dftest.drop(<span style="color: black;">label</span>,axis = <span style="color: black;">1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">), num_iteration=gbm.best_iteration)</p>print(<span style="color: black;">train accuracy: {:.5} </span>.format(accuracy_score(dftrain[<span style="color: black;">label</span>],y_pred_train><span style="color: black;">0.5</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)))</p>print(<span style="color: black;">valid accuracy: {:.5} \n</span>.format(accuracy_score(dftest[<span style="color: black;">label</span>],y_pred_test><span style="color: black;">0.5</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)))</p><span style="color: black;">#================================================================================</span><span style="color: black;"># 五,<span style="color: black;">保留</span>模型</span><span style="color: black;">#================================================================================</span>printlog(<span style="color: black;">"step5: saving model ..."</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>model_dir = <span style="color: black;">"gbm.model"</span>print(<span style="color: black;">"model_dir: %s"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">%model_dir)</p>gbm.save_model(<span style="color: black;">"gbm.model"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>printlog(<span style="color: black;">"task end..."</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p><span style="color: black;">###</span><span style="color: black;">##</span><span style="color: black;">#</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">================================================================================2023-11-10 15:39:38</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">step1: reading data......</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">================================================================================2023-11-10 15:39:38</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">step2: setting parameters......</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">================================================================================2023-11-10 15:39:38</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">step3: training model......</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/4WgILHBwVH8XJIyFWnENYfuRE1ianebUlfYIzS6Qib3lNpbficqsIo4bDQmGOaUI6NjDS64bmNPvfcGOZFLBcW9zQ/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">================================================================================2023-11-10 15:39:44</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">step4: evaluating model ......</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">train accuracy: 0.95775 </p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">valid accuracy: 0.94406 </p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">================================================================================2023-11-10 15:39:44</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">step5: saving model ......</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">model_dir: gbm.model</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">================================================================================2023-11-10 15:39:44</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">task end......</p>
<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">三, 在ultralytics中<span style="color: black;">运用</span>VLog</span></h2><span style="color: black;">写个适配的回调~</span><span style="color: black;">ultralytics<span style="color: black;">能够</span>做 <span style="color: black;">归类</span>,检测,分割 等等。</span><span style="color: black;">这个回调函数是通用的,此处以<span style="color: black;">归类</span>问题为例,改个monitor_metric<span style="color: black;">就可</span>~</span><span style="color: black;">cats_vs_dogs数据集<span style="color: black;">能够</span>在公众号江大白后台回复:<strong style="color: blue;">torchkeras</strong> 获取~</span><span style="color: black;">from</span> torchkeras <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> VLog</p><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">VLogCallback</span>:</span> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__init__</span><span style="color: black;">(self,epochs,monitor_metric,monitor_mode)</span>:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">self.vlog = VLog(epochs,monitor_metric,monitor_mode)</p> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">on_train_batch_end</span><span style="color: black;">(self,trainer)</span>:</span> self.vlog.log_step(trainer.label_loss_items(trainer.tloss, prefix=<span style="color: black;">train</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">))</p> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">on_fit_epoch_end</span><span style="color: black;">(self,trainer)</span>:</span> metrics = {k.split(<span style="color: black;">/</span>)[<span style="color: black;">-1</span>]:v <span style="color: black;">for</span> k,v <span style="color: black;">in</span> trainer.metrics.items() <span style="color: black;">if</span> <span style="color: black;">loss</span> <span style="color: black;">not</span> <span style="color: black;">in</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> k}</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> self.vlog.log_epoch(metrics)</p> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">on_train_epoch_end</span><span style="color: black;">(self,trainer)</span>:</span> <span style="color: black;">pass</span><span style="color: black;">from</span> ultralytics <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> YOLO </p>epochs = <span style="color: black;">10</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">vlog_cb = VLogCallback(epochs = epochs,</p> monitor_metric=<span style="color: black;">accuracy_top1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> monitor_mode=<span style="color: black;">max</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">callbacks = {</p> <span style="color: black;">"on_train_batch_end"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: vlog_cb.on_train_batch_end,</p> <span style="color: black;">"on_fit_epoch_end"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: vlog_cb.on_fit_epoch_end</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">}</p>model = YOLO(model = <span style="color: black;">yolov8n-cls.pt</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p><span style="color: black;">for</span>event,func<span style="color: black;">in</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> callbacks.items():</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> model.add_callback(event,func)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">vlog_cb.vlog.log_start()</p>results = model.train(data=<span style="color: black;">cats_vs_dogs</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">, </p> epochs=epochs, workers=<span style="color: black;">4</span>) <span style="color: black;"># train the model</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">vlog_cb.vlog.log_end()</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/4WgILHBwVH8XJIyFWnENYfuRE1ianebUlYUGOsRX6lN7rcCIpM875JrClvMX0Mic6zt2nia7f6eIUuFtIIIBjE1Fw/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">四, 在transformers中<span style="color: black;">运用</span>VLog</span></h2><span style="color: black;">waimai评论数据集<span style="color: black;">能够</span>在公众号江大白后台回复:<strong style="color: blue;">torchkeras</strong> 获取~</span><span style="color: black;">#回调给你写好了~</span><span style="color: black;">from</span> torchkeras.tools.transformers <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">VLogCallback</p><span style="color: black;">import</span> numpy <span style="color: black;">as</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> np </p><span style="color: black;">import</span> pandas <span style="color: black;">as</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> pd </p><span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> torch </p><span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> datasets </p><span style="color: black;">from</span> transformers <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> AutoTokenizer,DataCollatorWithPadding</p><span style="color: black;">from</span> transformers <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">AutoModelForSequenceClassification</p><span style="color: black;">from</span> transformers <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> TrainingArguments,Trainer </p><span style="color: black;">from</span> transformers <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> EarlyStoppingCallback</p><span style="color: black;">from</span> tqdm <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> tqdm </p><span style="color: black;">from</span> transformers <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> AdamW, get_scheduler</p><span style="color: black;">#一,准备数据</span>df = pd.read_csv(<span style="color: black;">"waimai_10k.csv"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">ds = datasets.Dataset.from_pandas(df)</p>ds = ds.shuffle(<span style="color: black;">42</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">) </p>ds = ds.rename_columns({<span style="color: black;">"review"</span>:<span style="color: black;">"text"</span>,<span style="color: black;">"label"</span>:<span style="color: black;">"labels"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">})</p>tokenizer = AutoTokenizer.from_pretrained(<span style="color: black;">bert-base-chinese</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">) </p>ds_encoded = ds.map(<span style="color: black;">lambda</span> example:tokenizer(example[<span style="color: black;">"text"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">]),</p>remove_columns = [<span style="color: black;">"text"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">],</p> batched=<span style="color: black;">True</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p><span style="color: black;">#train,val,test split</span>ds_train_val,ds_test = ds_encoded.train_test_split(test_size=<span style="color: black;">0.2</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">).values()</p>ds_train,ds_val = ds_train_val.train_test_split(test_size=<span style="color: black;">0.2</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">).values() </p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">data_collator = DataCollatorWithPadding(tokenizer=tokenizer)</p>dl_train = torch.utils.data.DataLoader(ds_train, batch_size=<span style="color: black;">16</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">, collate_fn = data_collator)</p>dl_val = torch.utils.data.DataLoader(ds_val, batch_size=<span style="color: black;">16</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">, collate_fn = data_collator)</p>dl_test = torch.utils.data.DataLoader(ds_test, batch_size=<span style="color: black;">16</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">, collate_fn = data_collator)</p><span style="color: black;">for</span> batch <span style="color: black;">in</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> dl_train:</p> <span style="color: black;">break</span>print({k: v.shape <span style="color: black;">for</span> k, v <span style="color: black;">in</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> batch.items()})</p><span style="color: black;">#二,定义模型</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">model = AutoModelForSequenceClassification.from_pretrained(</p> <span style="color: black;">bert-base-chinese</span>,num_labels=<span style="color: black;">2</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p><span style="color: black;">#三,训练模型</span><span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">compute_metrics</span><span style="color: black;">(eval_preds)</span>:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">logits, labels = eval_preds</p> preds = np.argmax(logits, axis=<span style="color: black;">-1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> accuracy = np.sum(preds==labels)/len(labels)</p> precision = np.sum((preds==<span style="color: black;">1</span>)&(labels==<span style="color: black;">1</span>))/np.sum(preds==<span style="color: black;">1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>recall = np.sum((preds==<span style="color: black;">1</span>)&(labels==<span style="color: black;">1</span>))/np.sum(labels==<span style="color: black;">1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p> f1 = <span style="color: black;">2</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">*recall*precision/(recall+precision)</p> <span style="color: black;">return</span> {<span style="color: black;">"accuracy"</span>:accuracy,<span style="color: black;">"precision"</span>:precision,<span style="color: black;">"recall"</span>:recall,<span style="color: black;">f1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:f1}</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">training_args = TrainingArguments(</p> output_dir = <span style="color: black;">"bert_waimai"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> num_train_epochs = <span style="color: black;">3</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> logging_steps = <span style="color: black;">20</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> gradient_accumulation_steps = <span style="color: black;">10</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p>evaluation_strategy=<span style="color: black;">"steps"</span>, <span style="color: black;">#epoch</span> metric_for_best_model=<span style="color: black;">eval_f1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> greater_is_better=<span style="color: black;">True</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> report_to=<span style="color: black;">none</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> load_best_model_at_end=<span style="color: black;">True</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>callbacks = [EarlyStoppingCallback(early_stopping_patience=<span style="color: black;">10</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">),</p> VLogCallback()] <span style="color: black;">#监控指标同 metric_for_best_model</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">trainer = Trainer(</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> model,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> training_args,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> train_dataset=ds_train,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">eval_dataset=ds_val,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> compute_metrics=compute_metrics,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> callbacks = callbacks,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> data_collator=data_collator,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> tokenizer=tokenizer,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">trainer.train() </p><span style="color: black;">#四,<span style="color: black;">评定</span>模型</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">trainer.evaluate(ds_val)</p><span style="color: black;">#五,<span style="color: black;">运用</span>模型</span><span style="color: black;">from</span> transformers <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> pipeline</p>model.config.id2label = {<span style="color: black;">0</span>:<span style="color: black;">"差评"</span>,<span style="color: black;">1</span>:<span style="color: black;">"好评"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">}</p>classifier = pipeline(task=<span style="color: black;">"text-classification"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,tokenizer = tokenizer,model=model.cpu())</p>classifier(<span style="color: black;">"挺好吃的哦"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p><span style="color: black;">#六,<span style="color: black;">保留</span>模型</span>model.save_pretrained(<span style="color: black;">"waimai_10k_bert"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>tokenizer.save_pretrained(<span style="color: black;">"waimai_10k_bert"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>classifier = pipeline(<span style="color: black;">"text-classification"</span>,model=<span style="color: black;">"waimai_10k_bert"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>classifier([<span style="color: black;">"味道还不错,下次再来"</span>,<span style="color: black;">"我去,吃了我吐了三天"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">])</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p><span style="color: black;">万水千山总是情,点个赞赞行不行~ “板凳”(第三个回帖的人) 期待你更多的精彩评论,一起交流学习。 期待与你深入交流,共探知识的无穷魅力。 对于这个问题,我有不同的看法... 楼主的文章深得我心,表示由衷的感谢!
页:
[1]