C# WebApi 快速配置log4net日志记录

1.环境

  • net45

  • swagger

2.log4net配置

  • nuget安装log4net

  • 项目主目录创建log3net.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
using log4net;
using log4net.Appender;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;

namespace yourspace
{
public class AppLog
{
private static string filepath = AppDomain.CurrentDomain.BaseDirectory + @"\SysLog\";

private static readonly log4net.ILog logComm = log4net.LogManager.GetLogger("AppLog");

static AppLog()
{
log4net.Config.XmlConfigurator.Configure(new FileInfo("log4net.config"));

if (!Directory.Exists(filepath))
{
Directory.CreateDirectory(filepath);
}
}
public static readonly object o = new object();
/// <summary>
/// 写入日志
/// </summary>
/// <param name="msg">日志内容</param>
/// <param name="isWrite">是否写</param>
/// <param name="action">写日志的方法</param>
/// <param name="info">日志文件名,便于分开日志文件</param>
private static void WriteLog(string msg, bool isWrite, Action<object> action, string info = "")
{
if (isWrite)
{
lock (o)
{
string filename = $"AppLog_{action.Method.Name}_{info}_{ DateTime.Now.ToString("yyyyMMdd_HH")}.log";
var repository = LogManager.GetRepository();

#region MyRegion
var appenders = repository.GetAppenders();
if (appenders.Length > 0)
{
RollingFileAppender targetApder = null;
foreach (var Apder in appenders)
{
if (Apder.Name == "AppLog")
{
targetApder = Apder as RollingFileAppender;
break;
}
}
if (targetApder.Name == "AppLog")//如果是文件输出类型日志,则更改输出路径
{
if (targetApder != null)
{
if (!targetApder.File.Contains(filename))
{
targetApder.File = @"SysLog\" + filename;
targetApder.ActivateOptions();
}
}
}
}
#endregion
action(msg);
//logComm.Error(msg + "\n");
}
}
}
/// <summary>
///
/// </summary>
/// <param name="msg">日志内容</param>
/// <param name="info">日志文件名,便于分开日志文件</param>
/// <param name="isWrite">是否写入</param>
public static void WriteError(string msg, string info = "", bool isWrite = true)
{
WriteLog(msg, isWrite, logComm.Error, info);
}
public static void WriteInfo(string msg, string info = "", bool isWrite = true)
{
WriteLog(msg, isWrite, logComm.Info, info);
}
public static void WriteWarn(string msg, string info = "", bool isWrite = true)
{
WriteLog(msg, isWrite, logComm.Warn, info);
}
public static void WriteFatal(string msg, string info = "", bool isWrite = true)
{
WriteLog(msg, isWrite, logComm.Fatal, info);
}
}
}
  • 主目录创建log4net.config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler,&#xD;&#xA;log4net-net-1.0"/>
</configSections>
<log4net>
<appender name="AppLog" type="log4net.Appender.RollingFileAppender">
<param name="File" value="SysLog/" />
<param name="AppendToFile" value="true" />
<param name="MaxSizeRollBackups" value="-1" />
<!--最小锁定模型以允许多个进程可以写入同一个文件-->
<param name="lockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
<param name="MaximumFileSize" value="10MB" />
<param name="RollingStyle" value="Size" />
<param name="DatePattern" value="yyyy-MM-dd" />
<param name="StaticLogFileName" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%-5p %d [%c] %m%n" />
</layout>
</appender>
<logger name="AppLog">
<level value="all" />
<appender-ref ref="AppLog" />
</logger>
<root>
<level value="all" />
</root>
</log4net>
</configuration>
  • 修改yourspace\Properties\AssemblyInfo.cs最末尾加入
1
2
3
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly:log4net.Config.XmlConfigurator(ConfigFile ="log4net.config",Watch =true)]

3.使用方法

在你想要的记录log的地方添加

1
AppLog.WriteInfo(“记录的字符串”, "日志名称", true);

4. 总结

会在你的主目录SysLog文件夹生成日志文件

参考文档

第一次论文失败经历

去年九月份,采购问答机器人项目由于缺乏数据,原始文件就几百条,导致模型准确率较低,老板催促解决这个问题,在组会上提出了数据扩充技术,下来实验,采用回译尝试了一下,遂进入数据增强方面工作,由于国庆结束,去兵科院实习了三个月,在实习之余完成了 基本实验,开年2-4月继续实验,改论文,4月初在老板的要求下投了一个CCF C类期刊,计算机应用,感觉这个名字还挺好听,当时幻想着一投就中,所以改了又改,图画了又画(全文唯一满意的就是模型图了)。然后7月第一天,下午去实验室,收到邮件,让修改后录增刊,给老板发消息,老板说不投了,再想办法。


全过程

投递全过程

耗费了3个月,6-7月其实光在等结果了,无心第二篇的写作。ε=(´ο`*)))唉

本来6月10号三审就结束了,中间直接停滞了半个月。

希望下次运气好一点。

近期再写一篇,继续投,缓解一下焦虑。没论文在手里可太难了。都不能全身心投入工作准备中…

祝好运!加油


计算机工程CCF-C

image-20220818164358521


计算机应用与软件CCF-C

image-20220818164608343


真是个学术小垃圾呀

换了新主题,显示不了LaTeX公式

昨天下午心血来潮,想换一个博客主题,然后捣腾半天,睡前弄好了。

文章迁移,公式又显示不了,尝试了多种方法,还是没有解决。哎

难道以后公式只能截图嘛😭

样例-快速入门Pytorch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from torch.autograd import Variable
from sklearn.model_selection import train_test_split
import torch.optim as optim

class modellogit(nn.Module):
def __init__(self):
nn.Module.__init__(self)
self.fc1 = nn.Linear(2,16)
self.fc2 = nn.Linear(16,8)
self.fc3 = nn.Linear(8,1)

def forward(self,x):
x = torch.relu(self.fc1(x))
x = torch.relu(self.fc2(x))
x = self.fc3(x)
return x

class hello_model(object):
def __init__(self,max_iter=200,learning_rate=0.01,l1=1e-4):
self.model = modellogit()
self.max_iter = max_iter
self.learning_rate = learning_rate
self.l1 = l1

def fit(self,train_x,train_y):
optimizer = optim.Adam(self.model.parameters(),lr = self.learning_rate)
criterion = nn.MSELoss()
print('训练开始')
for epoch in range(self.max_iter):
input_x = torch.from_numpy(train_x).float()
target = torch.from_numpy(train_y).float()
#梯度置零
optimizer.zero_grad()
#正向传播
output = self.model(input_x)
#反向传播
loss = criterion(output, target)
regular_loss = 0
for param in self.model.parameters():
regular_loss += torch.sum(torch.abs(param))
loss += self.l1*regular_loss
loss.backward()
#优化
optimizer.step()
if epoch%int(self.max_iter/5) == 0:
print('[%d, %5d] loss: %.3f'%(epoch+1, epoch+1, loss.data))
print('训练结束')
def predict(self,test_x):
y_hat = self.model(torch.from_numpy(test_x).float())
y_hat = y_hat.detach()
y_hat = y_hat.numpy()
return(y_hat)

data_x = np.random.normal(size = (30000,2))
data_y = data_x[:,[0]] + data_x[:,[0]]**2 + data_x[:,[1]]**2+\
data_x[:,[1]]*4+np.random.normal(size = (30000,1))*0.1
train_x,test_x,train_y,test_y = train_test_split(data_x,data_y,test_size=0.33, random_state=42)

model = hello_model(max_iter=5000,learning_rate=0.001)
model.fit(train_x,train_y)
model.predict(test_x)

TreeMix:基于组合的数据增强方法

Publish

NAACL2022

Title

TreeMix: Compositional Constituency-based Data Augmentation for Natural Language Understanding

Abstract

数据增强是解决过度拟合问题的一种有效方法。前人针对自然语言处理提出了不同的数据扩充策略,如噪声注入、单词替换、回译等。虽然有效,但它们忽略了语言的一个重要特征-组合性复杂表达的意义是从其子部分建立起来的。受此启发,我们提出了一种用于自然语言理解的成分数据扩充方法TreeMix。具体地说,TreeMix利用选区分析树将句子分解成构成子结构,并利用Mixup数据增强技术对它们进行重组以生成新的句子。与以前的方法相比,TreeMix在生成的样本中引入了更大的多样性,并鼓励模型学习NLP数据的组合性。在文本分类和SCAN的大量实验表明,TreeMix的性能优于目前最先进的数据增强方法。

Solution problem

合成性是语言的一个关键方面,因为复句的意义是从它的子部分建立起来的。先前的工作还表明,语法树(例如,基于树的LSTM)有助于对句子结构进行建模,以便更好地进行文本分类。然而,在语言技术社区中,除了在语义分析方面的一些例外情况外,利用组合结构进行数据扩充并没有受到太多关注

image-20220613135315056

我们提出了一种用于自然语言理解的成分数据增强方法,即TreeMix(图1)。TreeMix是一种输入级混合方法,它利用成分分析信息,将来自不同句子的不同片段(子树的短语)进行重组,以创建训练集中从未见过的新示例;同时还将基于这些片段策略性地创建新的软标签。这样,TreeMix不仅利用了构成语言的特征来增加扩充的多样性,而且为这些混合的例子提供了合理的软标签。

mixup定义为

其中$(x_i,x_j),(y_i,y_j)$为从训练数据中随机抽出两个目标特征向量,$\lambda\in[0,1]$

我们通过融入语言的组合性来改进Mixup,这是泛化所必需的一个关键特征,但神经模型往往无法捕捉到这一点。我们新提出的方法TreeMix不是用整个样本进行内插,而是通过删除句子的短语并重新插入其他句子的子部分来创建新句子。TreeMix利用选民树将句子分解成有意义的组成部分,然后将这些组成部分移除并重新组合,以生成新的扩充样本。我们的目标是通过对TreeMix生成的大量样本进行训练来提高模型的组合性泛化能力。一个使用TreeMix进行单句分类的例子如上图所示。

TreeMix 详细过程

${x}{i}=\left{x{i}^{1}, x{i}^{2}, \ldots, x{i}^{l}\right}$表示长度为$l$的序列,其对应的one-hot编码label为$yi$,我们在$x_i$上运行一个解析器得到它的解析树$T(x_i)$,为了获取序列中有意义的子部分,采用递归遍历解析树,获得所有具有一个以上child的子树。表示子树的集合为$S(x_i)= {t_i^k}$.其中$t_i^k$表示样本$x_i$的第k个子树,对于子树$t_i^k$连续覆盖了$x_i$的$t{i}^{k} \triangleq\left[x{i}^{r{k} }, \ldots, x{i}^{s{k} }\right]$,索引$r_k$为开始,$s_k$为结束。例如图一左侧所示,例句子树可以cover span 的有1.this poor film,2. in this poor film, 3.no interest …etc

对于给定的样本$(x_i,y_i)$,我们从训练集中随机抽取另一个数据点$(x_j, y_j)$。我们对这两个句子运行选区解析器,得到它们的子树集$S(x_i)$和$S(x_j)$,我们可以对要交换的子树进行采样。我们引入两个额外的超参数$λ_L$和$λ_U$来约束待采样子树的长度。$λ_L$和$λ_U$,用子树与原始句子的长度之比来衡量要采样子树的上下限。直观地说,$λ$控制着我们想要交换的短语的粒度。我们希望交换的长度是合理的。如果它太短,那么交换不能给增强样本引入足够的多样性;否则,如果太长,这个过程可能会给原句注入太多噪音。我们设置λ为比率,以便与原句子的长度不变。表2显示了一些具有不同长度约束的子树示例。我们将长度受限子树集合定义为:

其中$|·|$表示序列或子树的长度,对于两个句子$xi$和$x_j$,我们随机采样两个子树$t{i}^{k} \in S{\lambda}\left(\mathbf{x}{i}\right)$和$t{j}^{l} \in S{\lambda}\left(\mathbf{x}_{j}\right)$并且通过$t_j^l$替换$t_i^k$构建新的样本。例如

其中$t{j}^{l}=\left[x{j}^{r{l} }, \ldots, x{j}^{s{l} }\right]$替换$t{i}^{k}=$ $\left[x{i}^{r{k}}, \ldots, x{i}^{s{k} }\right]$如上图1所示a touching transcend love story 替换this poor film.

TreeMix制作标签

为扩充的样本$\overline{x}$创建有效标签是一个具有挑战性的问题。类似于Mixup,我们使用原始的凸组合两个句子的标签作为扩充样本的标签。

其中$l_i$为$x_i$的长度,$|t_i^k|$为子树的长度,在新的句子中,从$x_i$中保留$l_i-|t_i^k|$个words,从句子$x_j$插入$|t_j^l|$个words。

$\frac{l{i}-\left|t{i}^{k}\right|}{l{i}-\left|t{i}^{k}\right|+\left|t_{j}^{l}\right|}$是来自$x_i$的words的分数,其可以决定$y_i$的权重,然后,基于标签的变化与原始句子中的长度变化成比例的猜想来创建标签。附录提供样本。

image-20220614162150953

组合算法

我们的主要算法如算法1所示。虽然TreeMix创建的句子并不都是流畅的甚至有效的新句子,但它们包含具有不同含义的子部分,这鼓励模型以组合的方式构建丰富的句子表示。需要注意的是,扩展后的标签是原始标签的凸组合,只有当模型学习到两个部分的表示在一起时,它们才能预测具有不同权重的两个标签

Training Objective

我们的模型是在原始样本和增强样本的组合上训练,以获得正则化和噪声注入之间的权衡。最终的培训目标是:

$\gamma$i是增强样本的权重

Experiment

  • 数据集

    image-20220614164635190

  • Baseline

    | approaches | 简介 |
    | ———————— | —————————————————————————————— |
    | BERT | |
    | EDA | 由四个简单操作组成:同义词替换、随机插入、随机交换和随机删除。 |
    | AEDA | 在文本中随机插入标点符号的AEDA |
    | Back Translation | 将句子翻译成临时语言(EN-DE),然后将先前翻译的文本翻译回源语言(DE-EN) |
    | GPT3Mix | 设计提示并利用GPT3生成新的示例来训练模型。 |
    | SSMix | 通过在给定类的所有示例前添加类标签来为条件BART。BARTword屏蔽了单个单词,而BARTspan屏蔽了连续的区块。 |
    | EmbedMix | |
    | Tmix | 首先对两个输入分别编码,然后在某一编码器层a处对两个嵌入进行线性插值,最终向前传递组合嵌入到其余层中。 |

  • 结果

    image-20220614170349622

image-20220614170416075

image-20220614170443863

Conclusion

没找到代码,自己摸索了。

Counter-Contrastive 学习:训练Language GAN

Publish

2021EMNLP

title

Counter-Contrastive Learning for Language GANs

摘要

生成对抗网络(GANs)在图像合成方面取得了巨大的成功,但在生成自然语言方面存在一定的困难。挑战来自于鉴别器传递的uninformative learning signal。换句话说,糟糕的learning singnal限制了生成结构丰富、语义丰富的语言的学习能力。在本文中,我们提出在语言gan中采用反对比学习(CCL)方法来支持生成器的训练。与标准的GANs采用简单的二元分类器来区分样本的真假相比,我们采用了一种反对比学习信号,通过提高语言合成器的训练

  • (1)把生成样本与真实样本 放在一起(以生成真实的数据)
  • (2)推开真实的样本(以阻碍鉴别的训练)从而防止鉴别器被过度训练。

我们在合成基准和实际基准上评估了我们的方法,并与以前的GAN相比,在对抗序列生成方面产生了具有竞争力的性能。

Solution problem

CCL

Experiment

Conclusion

没代码,不看了。

GAN原理总结及对比

原始GAN

GAN的主要灵感来源于博弈论中零和博弈的思想,应用到深度学习神经网络上来说,就是通过生成网络G(Generator)和判别网络D(Discriminator)不断博弈,进而使G学习到数据的分布,如果用到图片生成上,则训练完成后,G可以从一段随机数中生成逼真的图像。G, D的主要功能是:

● G是一个生成式的网络,它接收一个随机的噪声z(随机数),通过这个噪声生成图像

● D是一个判别网络,判别一张图片是不是“真实的”。它的输入参数是x,x代表一张图片,输出D(x)代表x为真实图片的概率,如果为1,就代表100%是真实的图片,而输出为0,就代表不可能是真实的图片

训练过程中,生成网络G的目标就是尽量生成真实的图片去欺骗判别网络D。而D的目标就是尽量辨别出G生成的假图像和真实的图像。这样,G和D构成了一个动态的“博弈过程”,最终的平衡点即纳什均衡点。

GAN的特点:

● 相比较传统的模型,他存在两个不同的网络,而不是单一的网络,并且训练方式采用的是对抗训练方式

● GAN中G的梯度更新信息来自判别器D,而不是来自数据样本

GAN 的优点:

(以下部分摘自ian goodfellow 在Quora的问答)

● GAN是一种生成式模型,相比较其他生成模型(玻尔兹曼机和GSNs)只用到了反向传播,而不需要复杂的马尔科夫链

● 相比其他所有模型, GAN可以产生更加清晰,真实的样本

● GAN采用的是一种无监督的学习方式训练,可以被广泛用在无监督学习和半监督学习领域

● 相比于变分自编码器, GANs没有引入任何决定性偏置( deterministic bias),变分方法引入决定性偏置,因为他们优化对数似然的下界,而不是似然度本身,这看起来导致了VAEs生成的实例比GANs更模糊

● 相比VAE, GANs没有变分下界,如果鉴别器训练良好,那么生成器可以完美的学习到训练样本的分布.换句话说,GANs是渐进一致的,但是VAE是有偏差的

● GAN应用到一些场景上,比如图片风格迁移,超分辨率,图像补全,去噪,避免了损失函数设计的困难,不管三七二十一,只要有一个的基准,直接上判别器,剩下的就交给对抗训练了。

GAN的缺点:

● 训练GAN需要达到纳什均衡,有时候可以用梯度下降法做到,有时候做不到.我们还没有找到很好的达到纳什均衡的方法,所以训练GAN相比VAE或者PixelRNN是不稳定的,但我认为在实践中它还是比训练玻尔兹曼机稳定的多

● GAN不适合处理离散形式的数据,比如文本

● GAN存在训练不稳定、梯度消失、模式崩溃的问题(目前已解决)

模式崩溃(model collapse)原因

一般出现在GAN训练不稳定的时候,具体表现为生成出来的结果非常差,但是即使加长训练时间后也无法得到很好的改善。

具体原因可以解释如下:GAN采用的是对抗训练的方式,G的梯度更新来自D,所以G生成的好不好,得看D怎么说。具体就是G生成一个样本,交给D去评判,D会输出生成的假样本是真样本的概率(0-1),相当于告诉G生成的样本有多大的真实性,G就会根据这个反馈不断改善自己,提高D输出的概率值。但是如果某一次G生成的样本可能并不是很真实,但是D给出了正确的评价,或者是G生成的结果中一些特征得到了D的认可,这时候G就会认为我输出的正确的,那么接下来我就这样输出肯定D还会给出比较高的评价,实际上G生成的并不怎么样,但是他们两个就这样自我欺骗下去了,导致最终生成结果缺失一些信息,特征不全。

关于梯度消失的问题可以参考郑华滨的令人拍案叫绝的wassertein GAN,里面给出了详细的解释,不过多重复
img

局部极小值点

原始GAN中判别器要最小化如下损失函数,尽可能把真实样本分为正例,生成样本分为负例:

$-\mathbb{E}{x \sim P{r}}[\log D(x)]-\mathbb{E}{x \sim P{g}}[\log (1-D(x))]$(公式1 )

其中P_r是真实样本分布,P_g是由生成器产生的样本分布。对于生成器,Goodfellow一开始提出来一个损失函数,后来又提出了一个改进的损失函数,分别是

$\mathbb{E}{x \sim P{g}}[\log (1-D(x))]$(公式2)

$\mathbb{E}{x \sim P{g}}[-\log D(x)]$(公式3)

为什么GAN不适合处理文本数据

  1. 文本数据相比较图片数据来说是离散的,因为对于文本来说,通常需要将一个词映射为一个高维的向量,最终预测的输出是一个one-hot向量,假设softmax的输出是(0.2, 0.3, 0.1,0.2,0.15,0.05)那么变为onehot是(0,1,0,0,0,0),如果softmax输出是(0.2, 0.25, 0.2, 0.1,0.15,0.1 ),one-hot仍然是(0, 1, 0, 0, 0, 0),所以对于生成器来说,G输出了不同的结果但是D给出了同样的判别结果,并不能将梯度更新信息很好的传递到G中去,所以D最终输出的判别没有意义。

  2. 另外就是GAN的损失函数是JS散度,JS散度不适合衡量不想交分布之间的距离。

(WGAN虽然使用wassertein距离代替了JS散度,但是在生成文本上能力还是有限,GAN在生成文本上的应用有seq-GAN,和强化学习结合的产物)

训练GAN的一些技巧

  1. 输入规范化到(-1,1)之间,最后一层的激活函数使用tanh(BEGAN除外)

  2. 使用wassertein GAN的损失函数,

  3. 如果有标签数据的话,尽量使用标签,也有人提出使用反转标签效果很好,另外使用标签平滑,单边标签平滑或者双边标签平滑

  4. 使用mini-batch norm, 如果不用batch norm 可以使用instance norm 或者weight norm

  5. 避免使用RELU和pooling层,减少稀疏梯度的可能性,可以使用leakrelu激活函数

  6. 优化器尽量选择ADAM,学习率不要设置太大,初始1e-4可以参考,另外可以随着训练进行不断缩小学习率,

  7. 给D的网络层增加高斯噪声,相当于是一种正则


来源

Text Smoothing:一种数据结合mix-up的数据增强方法

Publish

2022ACL

title

Text Smoothing: Enhance Various Data Augmentation Methods on Text Classification Tasks

solution problem

进入神经网络之前,标记通常被转换为对应的One-hot表示,这是词汇表的离散分布。平滑表示是从预先训练的MLM中获得候选token的概率,它可以被视为对onr-hot表示的更多信息的替代。我们提出了一种有效的数据增强方法,称为文本平滑,通过将句子从其one-hot表示转换为可控的平滑表示。我们在低资源条件下对不同基准的文本平滑进行了评估。实验结果表明,文本平滑方法的性能明显优于各种主流数据增强方法。此外,文本平滑可以与这些数据增强方法相结合,以获得更好的性能。

image-20220526171221247

image-20220526175945737

文本平滑代码:Pytorch

1
2
3
4
5
6
7
sentence = "My favorite fruit is pear ."
lambd = 0.1 # interpolation hyperparameter
mlm.train() # enable dropout, dynamically mask
tensor_input = tokenizer(sentence, return_tensors="pt")
onehot_repr = convert_to_onehot(**tensor_input)
smoothed_repr = softmax(mlm(**tensor_input).logits[0])
interpolated_repr = lambd * onehot_repr + (1 - lambd) * smoothed_repr
  1. 使用BERT作为MLM,给定下游数据集命名为:$D={ti,p_i,s_i,l_i}{i=1}^{N}$ ,N表示样本数量,$t_i$表示文本one-hot 编码,$p_i$表示$t_i$位置编码,$s_i$表示$t_i$的段编码,$l_i$表示实例标签。

  2. 将$t_i,p_i,s_i$送入BERT

  3. 取回BERT中Transformer-encoder最后一层的输出表示为

    其中$\overrightarrow{t_i}$形状为[seq_len,emb_size]

  4. 然后乘以$\overrightarrow{t_i}$乘以BERT中词嵌入矩阵$W$,其形状为[vocab_size,embed_size]

    其中$MLM(t_i)$中每一行是token词汇表中的概率分布,表示了预训练BERT学习到输入文本所在位置的包含上下文 的标记选项(信息)。

  1. mixup定义为

    其中$(x_i,x_j),(y_i,y_j)$为从训练数据中随机抽出两个目标特征向量,$\lambda\in[0,1]$在文本平滑中,One-hot表示和平滑表示来自相同的原始输入,标签相同,其内部插入操作不会改变标签,因此mixup操作可以简化为

    其中$t_i$为one-hot表示,$MLM(t_i)$为平滑表示,$\widetilde{t_i}$为联合插入表示,$\lambda$为用于控制插入的超参数。下游任务中我们使用联合表示代替one-hot变化表示作为输入。

Experiment

  • 数据集

    image-20220526201719743

  • Baseline

    | approaches | 简介 |
    | ———————————- | —————————————————————————————— |
    | EDA | 由四个简单操作组成:同义词替换、随机插入、随机交换和随机删除。 |
    | Back Translation | 将句子翻译成临时语言(EN-DE),然后将先前翻译的文本翻译回源语言(DE-EN) |
    | CBERT | 用预先训练的BERT mask一些标记并预测它们的上下文替换。 |
    | BERTexpand, BERTprepend | 通过在给定类的所有示例中添加类标签来满足BERT条件。“expand”标签以 模拟 词汇表,而“prepend”则没有 |
    | GPT2context | 为预先训练的GPT模型提供提示,并持续生成,直到[EOS]token |
    | BARTword, BARTspan | 通过在给定类的所有示例前添加类标签来为条件BART。BARTword屏蔽了单个单词,而BARTspan屏蔽了连续的区块。 |

  • 结果

    image-20220526202740487

Conclusion

小数据,可控,目前优于其他,未来,结合其他DA=顶会。我也想发顶会啊。

第二篇小论文的思考记录

大论文的开题核心为”问句语义识别应用研究“。

第一篇小论文采用预训练模型进行数据增强以提升文本表征能力,主要研究集中在问句识别前期工作,并没有聚焦到语义识别。

对中文论文进行调研,大部分paper都将问句语义识别定义为一个文本分类问题,即问句分类。

所以第二篇小论文优先考虑文本分类问题

近期又不可避免的 看了写GAN的文章,生成对抗网络,用于图像生成的确很不错。但是在nlp效果很一般,唯一给我的感觉就是这是一个很有学术价值的东西,适合写论文。

seqGAN: sequence generative adversarial nets with policy gradient

2017年发表 代码比较老 判别器用cnn,生成器rnn,改进点没想法,换成transformer?

TT-gan:Text-to-Text Generative Adversarial Networks 2018年 模型不但可以生成真实文本,还能生成源文本释义或语义摘要。作者说是第一个 语义层面上生成自然语言的框框架。 无代码 没想法

重点来了“GAN-BERT”

GAN-BERT: Generative Adversarial Learning for Robust Text Classification with a Bunch of Labeled Examples 2020acl。这篇文献我详细阅读了。 其判别器和生成器都是多层感知机,输入 noise(向量h) 进入生成器,输出$h_{fake}$ 然后在将真实数据 输入bert 获得向量 进行判别器。设置一个多分类任务进行训练,设置k+1个类,其中k为真实的类,k+1为生成器产生的类。过程如下:

  1. 经过bert的向量设为$h{cls}$ ,训练目标: 判别器真实样本将其归为k类,$h{fake}$归为k类
  2. 反向传播阶段, 无监督学习:无标签数据被错误归入k+1类时 优化 判别器的损失。有监督学习, 通同1要求 优化判别器损失。
  3. 训练结束,丢弃生成器,利用原始bert进行推理。(应该是bert+判别器)

我的想法 能不能 用其他model替换mlp。(但是原文的一个创新就是 没有使用cnn),然后融入一些其他trick,提升分类效果。

更新于2022年05月01日


最近忙东忙西,不知道在干嘛。互联网+比赛,项目书、PPT、视频,小论文返修…

实验做了一点点。GAN,生成器,判别器,多层感知机 换成RNN。…

更新于2022年05月26日


SeqGAN:具有Policy梯度的序列生成对抗网络

Publish

AAAI-2017

title

SeqGAN: Sequence Generative Adversarial Nets with Policy Gradient

solution problem

生成对抗网络(GAN)在生成real_value数据取得了巨大的成功,但是在用于生成离散数据具有局限性,主要原因在于:来自生成模型的离散输出使其难以从判别模型的梯度更新传递给生成模型。此外:判别模型只能评估完整的序列,而对于部分生成的序列,一旦生成完整序列,就需要去平衡当前和未来的评分。

Summary

  1. 提出一种训练生成模型的新方法SeqGAN
  2. 其数据生成器建模使用强化学习中的随机策略,其中RL奖励值来自GAN判别器对完整序列的评判。使用蒙特卡洛搜索传回中间状态。

    Conclusion

    在合成数据和现实任务上进行的大量实验表明,与强大的基线相比,有了显著的改进.

    Other

    蒙特卡洛搜索

    学习资料
    1
    2