《信息网络综合研究课》学习报告

应用层机器学习部分

班级：    通信1706  
姓名：     贾羿铨   
学号：    17221338  

实验目的
了解机器学习，在pycharm+pytorch环境下跑通一些深度学习程序，并对程序进行分析。

实验原理和内容
本次实验主要运行两个程序。
1.linear_regression
第一个是简单的线性回归）linear-regession，它体现的就是在深度学习中最基础的梯度下降算法。所谓梯度下降算法简单说就是一种利用梯度是函数减小最快的方向这一思想来求解目标函数的最小值。这个目标函数是损失函数，在回归问题中，即测试数据和训练结果函数的差值的一个函数。例如在这次运行的程序中，线性回归目标函数定义为f（x）=wx+b的话，w和b为通过训练得到的参数。

pytorch中构建线性函数。
model = nn.Linear(input_size, output_size)
这个程序使用SGD优化算法，即随机梯度下降。这个算法是用来计算梯度。他的特点是每次梯度计算只使用一个样本。
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate) 
loss函数用输出和目标差值的平方。
loss = criterion(outputs, targets.reshape(-1))

2.language_model
语言模型研究的问题也是一个概率问题，就是说衡量一句话出现和合理的概率，包括选词和语序。
在这个语言模型中，主要用到的是RNN（Recurrent Neural Network）循环神经网络。在这个例子中，RNN以每一个单词作为输入，并每次都生成一个hiden state隐状态ht，这个隐状态包含了所有前面出现的单词信息，用它来进行预测下一个单词。相当于是把很多个前向反馈神经网络组合到一起得到的。

标准RNN

LSTM是长短记忆网络，他是在标准RNN网络基础上的改进。标准RNN在实践中被证明是难以具有长距离的记忆的，LSTM则天生的能够记住较长的历史记忆。这个程序中每一个节点使用的是LSTM神经网络。

LSTM中重复模块包含四层交互神经网络层
    
LSTM与标准RNN相比多了一条控制全局的记忆，也就是上图中的上方的线，也就是说他有两个hiden state同时向前传输。 
评价语言模型用到的是Perplexity，他是把一句话出现的概率取一个-1/N次幂，N是句子的长度（单词数），这里既放大了这个评估的数字也考虑到了句子长度的影响，Perplexity越低表示这个语言模型越好。

首先进行模型建立，
def __init__(self, vocab_size, embed_size, hidden_size, num_layers):
    super(RNNLM, self).__init__()
    self.embed = nn.Embedding(vocab_size, embed_size)
    self.lstm = nn.LSTM(embed_size, hidden_size, num_layers, batch_first=True)
    self.linear = nn.Linear(hidden_size, vocab_size)

训练这个语言模型用Cross Entropy损失函数。他定义在每一个输出的单词上
criterion = nn.CrossEntropyLoss()

和Adam优化算法（在语言模型中似乎常用Adam）。
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
在forward的定义过程中，涉及到了一些向量维度的变换，例如在
out = out.reshape(out.size(0)*out.size(1), out.size(2))
这一行代码中，最初的out是由
out, (h, c) = self.lstm(x, h)
得出的一个三个维度的量，但是在之后的decode也就是一个线性变换中只能取一个两维量，所以要把前两个维度拼到一起即seq_lenth*batch_size.
最后将模型初始化，其中的参数在一开始进行设定。
model = RNNLM(vocab_size, embed_size, hidden_size, num_layers).to(device)
至此模型建立完成了。
之后进行模型的训练。
首先对hiden进行初始化，把它设为一个全0向量，来确保在开始训练时其中没有数据。

得到输入input和目标target，：
for i in range(0, ids.size(1) - seq_length, seq_length):
    inputs = ids[:, i:i+seq_length].to(device)
    targets = ids[:, (i+1):(i+1)+seq_length].to(device)
计算loss和backward
# Forward pass
states = detach(states)
outputs, states = model(inputs, states)
loss = criterion(outputs, targets.reshape(-1))

# Backward and optimize
optimizer.zero_grad()
loss.backward()
clip_grad_norm_(model.parameters(), 0.5)
optimizer.step()
在这个模型训练中还用到了Gradient Clipping，它的作用是防止出现梯度爆炸，虽然LSTM对这种情况有预防，但是这里还是加上这一功能。在RNN中梯度是一个连续相乘的结果，它很容易造成最终梯度的过大，所以在每一个求导之后用这个方法定下一个阈值，这样可以解决这个问题。

step = (i+1) // seq_length
if step % 100 == 0:
    print ('Epoch [{}/{}], Step[{}/{}], Loss: {:.4f}, Perplexity: {:5.2f}'
           .format(epoch+1, num_epochs, step, num_batches, loss.item(), np.exp(loss.item())))
Epoch数是一个超参数，它定义了学习算法在整个训练数据集中的工作次数。一个Epoch意味着训练数据集中的每个样本都有机会更新内部模型参数。Epoch由一个或多个Batch组成。也就是说，在每一个Epoch中是把所有的样本都进行了训练，然后对模型的参数进行改变，epoch的数量也就是遍历样本的次数。在这里的epoch数定为5，在上一个线性回归中因为样本较少，epoch数为60. 
之后进行模型的测试。
测试时最初选定一个随机的单词作为输入和文章的开头
prob = torch.ones(vocab_size)
input = torch.multinomial(prob, num_samples=1).unsqueeze(1).to(device)
这里想要生成1000个词的sample，所以在一个1000次的循环中每次把一个单词输入到训练出来的模型中，得到下一个单词的预测output和一个hiden state
for i in range(num_samples):
       output, state = model(input, state)
之后是把一个多维向量转换成这个单词的index，就是word_id，这个过程用torch.multionomial完成，之后就再把这个输出作为输入再输入到模型中进行下一次循环。
output, state = model(input, state)

prob = output.exp()
word_id = torch.multinomial(prob, num_samples=1).item()

input.fill_(word_id)
最后保存句子文件。

运行结果
linear_regression
训练过程：

程序中学习率定为0.001，Epoch数为60，可以看出，随着计算次数增多，Loss函数的值逐渐在减小，最终到达一个较小的值。这表明这个模型是有效的。最后得到的回归函数如蓝色线所示。

可以看出结果是十分令人满意的。
Language_model
    这里仅截取最初和最后一部分训练结果，可以看出这里的训练过程与之前相比会复杂很多，loss函数也不是一个完全递减，但是总体来看还是一个减小的过程，Perlexity也一样

值得一提的是在一般训练模型中，epoch会设置的较大，在这里是为了提高训练速度而取一个较小的数。在这个语言模型的例子中，我的机器用CPU训练这样一个模型也用了七八分钟，用GPU训练则非常快。这说明深度学习对机器的算力要求比较高。
然后我们看一下生成的句子，截取一部分。
would shield mr. gorbachev would be an economy in the coming months 
economists may have a strong <unk> prospect and lack of privately funded and treatment to seasonal adjustments 
the unexpectedly wide there 's only consensus among them huge <unk> who wanted to be an israeli products term <unk> one month by an outside settlement 
the head coach of <unk> will start make off the network to <unk> paper operations does n't contain the business world he says 
<unk> owner who had a student company with tire king and apple had last july N pages in training areas and a fraud in south africa and six new york began <unk> and announced an old job so the network has kept any flexibility about the bottom line 
these and other problems fear a higher show marketer for <unk> machine tools just one attempt to a seemingly an morning role in lebanon 's security business and cancer coverage <unk> from the parts ' <unk> for the youth and his <unk> <unk> five years more 
the giants scored <unk> in that time for <unk> such as those red as part of their image and the league of new 
<unk> come alive with no <unk> between damage mr. <unk> has <unk> a newport beach <unk> and the <unk> former premier where it <unk> the architectural even though it is 
unfortunately engelken officials lie too damaging for much as many <unk> and allowed to turn the strong men for only N 
other people are saying the same phenomenon are as <unk> for wines and treatment based on the old crowd and its players

文本中的<unk>表示超出词汇表的词汇。
这些句子很有意思，句子中的词之间确实是有一定联系的，但是他们的组合让人有些感到好笑。例如 “会保护戈尔巴乔夫在几个月内成为一个经济体”，这些词之间总有一些莫名其妙的联系，但是他们的组合还是有些问题，让人情不自禁想到机器人说出的话（确实如此）。在短一些的句子中会表现得好一些，越长的句子我发现它的含义越让人无法理解。同时我感觉这个测试结果对于语序还是做的不错的，句子让人迷惑的点主要还是在一些具体词汇在某个语境下的不适合。

心得体会
这次的学习对于没有接触过python也没有接触过机器学习的我来说很有挑战，但是也让我很感兴趣，我之前只知道机器学习在未来将会发挥越来越大的作用，在经过这次的学习后我更加相信这一点。我在视频网站上看了一些了有关环境搭建、机器学习、pytorch等的课程，它们对我从python和pytorch的使用到对具体深度学习的一些概念和具体算法的认识都有很大的帮助。当然这中间也有很多困难，比如在一开始的环境搭建就遇到了一些困难，pytorch和Nvidia驱动的安装就耗费了很多时间（最后发现这些简单的例子甚至可以不用显卡训练），在程序中几乎所有函数都要一个个的查询其作用。
但是通过这次的学习让我收获很多，在这种新的方法在层出不穷的领域，其工具也是在不断更新来方便人们实现自己想法的，有一个很直观的印象就是pytorch中的lstm这个函数其背后其实是一个复杂的模型，然而在pytorch里只需要把相应的一些参数作为输入就可以，这大大简化了整个网络在人们眼前所展示的样子，我觉得这也简化了人们要学习的内容，不必把太多时间用在前人已经探索过的道路上，极端一些说，甚至可以直接把它作为黑盒使用。另外让我体会到所谓深度学习也好人工智能也好其背后没有那么神秘，它很大程度上是依靠着现代设备越来越强大的算力，但是他能做到的事情确实让人着迷，我希望在未来能够更深入地研究它。